[libcamera-devel] [PATCH] meson: Use library() in order to let user chose the library type

Christian Rauch Rauch.Christian at gmx.de
Fri Dec 2 21:56:10 CET 2022


Hi Laurent,

Am 29.11.22 um 00:23 schrieb Laurent Pinchart:
> Hi Christian,
>
> On Tue, Nov 29, 2022 at 12:00:26AM +0100, Christian Rauch wrote:
>> Am 28.11.22 um 06:29 schrieb Laurent Pinchart:
>>> On Mon, Nov 28, 2022 at 12:01:10AM +0100, Christian Rauch via libcamera-devel wrote:
>>>> Defining libraries via shared_library() prevents compiling libcamera as
>>>> static library. The meson project recommends using library() instead of
>>>> shared_library(), static_library() or both_libraries():
>>>> https://mesonbuild.com/Reference-manual_functions.html#library
>>>
>>> I'm curious, do you personally have use cases for libcamera as a static
>>> library ?
>>
>> Yes. I want/have to distribute my application with a statically linked
>> libcamera in order to avoid dynamic linking issues with the libcamera
>> package distributed by Ubuntu.
>
> Note that IPA modules are always loaded dynamically.
>
>>>> Signed-off-by: Christian Rauch <Rauch.Christian at gmx.de>
>>>> ---
>>>>    src/android/meson.build        | 16 ++++++++--------
>>>>    src/gstreamer/meson.build      |  2 +-
>>>>    src/libcamera/base/meson.build | 18 +++++++++---------
>>>>    src/libcamera/meson.build      | 18 +++++++++---------
>>>>    src/v4l2/meson.build           | 12 ++++++------
>>>>    5 files changed, 33 insertions(+), 33 deletions(-)
>>>>
>>>> diff --git a/src/android/meson.build b/src/android/meson.build
>>>> index 1bba54de..51b365e3 100644
>>>> --- a/src/android/meson.build
>>>> +++ b/src/android/meson.build
>>>> @@ -67,11 +67,11 @@ android_camera_metadata = static_library('camera_metadata',
>>>>                                             c_args : '-Wno-shadow',
>>>>                                             include_directories : android_includes)
>>>>
>>>> -libcamera_hal = shared_library('libcamera-hal',
>>>> -                               android_hal_sources,
>>>> -                               name_prefix : '',
>>>> -                               link_with : android_camera_metadata,
>>>> -                               install : true,
>>>> -                               cpp_args : android_cpp_args,
>>>> -                               include_directories : android_includes,
>>>> -                               dependencies : android_deps)
>>>> +libcamera_hal = library('libcamera-hal',
>>>> +                        android_hal_sources,
>>>> +                        name_prefix : '',
>>>> +                        link_with : android_camera_metadata,
>>>> +                        install : true,
>>>> +                        cpp_args : android_cpp_args,
>>>> +                        include_directories : android_includes,
>>>> +                        dependencies : android_deps)
>>>
>>> I'm curious, how do you envision the HAL to be loaded by the Android
>>> camera service if it's a static library ? :-)
>>
>> Isn't it possible to link the libraries statically on Android too?
>
> The Android camera HAL is a shared object loaded dynamically by the
> camera service.
>
>>>> diff --git a/src/gstreamer/meson.build b/src/gstreamer/meson.build
>>>> index eda246d7..b364837d 100644
>>>> --- a/src/gstreamer/meson.build
>>>> +++ b/src/gstreamer/meson.build
>>>> @@ -39,7 +39,7 @@ if cc.get_id() == 'clang' and glib_dep.version().version_compare('<2.63.0')
>>>>        libcamera_gst_cpp_args += ['-Wno-unused-function']
>>>>    endif
>>>>
>>>> -libcamera_gst = shared_library('gstlibcamera',
>>>> +libcamera_gst = library('gstlibcamera',
>>>
>>> Same here, and for the V4L2 compat library.
>>
>> I might have overdone this. How is this library supposed to be used? Do
>> you preload it in order to emulate V4L2 APIs?
>
> Yes, it's LD_PRELOADed and overrides several libc symbols.
>
>> Could this also be done with a 'shared_module'?
>
> Possibly, but
> https://mesonbuild.com/Reference-manual_functions.html#shared_module
> notes that
>
>    Linking to a shared module on platforms other than Android is
>    deprecated, and will be an error in the future. It was previously
>    allowed because it was the only way to have a shared-library-like
>    target that contained references to undefined symbols. However, since
>    0.40.0, the override_options: build_target() keyword argument can be
>    used to create such a shared_library() by passing override_options:
>    'b_lundef=false'. Shared modules have other characteristics that make
>    them incompatible with linking, such as a lack of SONAME. On macOS and
>    iOS, linking to shared modules is disallowed by the linker, so we
>    disallow it at configure time. On Android, if a shared module foo uses
>    symbols from another shared module bar, foo must also be linked to
>    bar. Hence, linking one shared module to another will always be
>    allowed when building for Android.
>
> But in any case, I think you can keep using shared_library() here (and
> in src/android/meson.build) while switching libcamera and libcamera-base
> to library().
>
>>>>        libcamera_gst_sources,
>>>>        cpp_args : libcamera_gst_cpp_args,
>>>>        dependencies : [libcamera_private, gstvideo_dep, gstallocator_dep],
>>>> diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build
>>>> index 7a7fd7e4..91dc1e71 100644
>>>> --- a/src/libcamera/base/meson.build
>>>> +++ b/src/libcamera/base/meson.build
>>>> @@ -48,15 +48,15 @@ libcamera_base_deps = [
>>>>    # the use of headers which must not be exposed to the libcamera public api.
>>>>    libcamera_base_args = [ '-DLIBCAMERA_BASE_PRIVATE' ]
>>>>
>>>> -libcamera_base_lib = shared_library('libcamera-base',
>>>> -                                    [libcamera_base_sources, libcamera_base_headers],
>>>> -                                    version : libcamera_version,
>>>> -                                    soversion : libcamera_soversion,
>>>> -                                    name_prefix : '',
>>>> -                                    install : true,
>>>> -                                    cpp_args : libcamera_base_args,
>>>> -                                    include_directories : libcamera_includes,
>>>> -                                    dependencies : libcamera_base_deps)
>>>> +libcamera_base_lib = library('libcamera-base',
>>>> +                             [libcamera_base_sources, libcamera_base_headers],
>>>> +                             version : libcamera_version,
>>>> +                             soversion : libcamera_soversion,
>>>> +                             name_prefix : '',
>>>> +                             install : true,
>>>> +                             cpp_args : libcamera_base_args,
>>>> +                             include_directories : libcamera_includes,
>>>> +                             dependencies : libcamera_base_deps)
>>>>
>>>>    libcamera_base = declare_dependency(sources : [
>>>>                                            libcamera_base_headers,
>>>> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
>>>> index 0494e808..cd1bf4ed 100644
>>>> --- a/src/libcamera/meson.build
>>>> +++ b/src/libcamera/meson.build
>>>> @@ -163,15 +163,15 @@ libcamera_deps = [
>>>>    # runtime if the library is running from an installed location by checking
>>>>    # for the presence or abscence of the dynamic tag.
>>>>
>>>> -libcamera = shared_library('libcamera',
>>>> -                           libcamera_sources,
>>>> -                           version : libcamera_version,
>>>> -                           soversion : libcamera_soversion,
>>>> -                           name_prefix : '',
>>>> -                           install : true,
>>>> -                           include_directories : includes,
>>>> -                           build_rpath : '/',
>>>> -                           dependencies : libcamera_deps)
>>>> +libcamera = library('libcamera',
>>>> +                    libcamera_sources,
>>>> +                    version : libcamera_version,
>>>> +                    soversion : libcamera_soversion,
>>>> +                    name_prefix : '',
>>>> +                    install : true,
>>>> +                    include_directories : includes,
>>>> +                    build_rpath : '/',
>>>> +                    dependencies : libcamera_deps)
>>>
>>> Do libcameraBuildPath() and libcameraSourcePath() still work as expected
>>> when compiling libcamera as a static library ?
>>
>> I haven't tested this yet. I only tested that I can build and link
>> libcamera statically. I added this option in order to test this and get
>> some feedback. The default behaviour will still build a shared library.
>
> The default behaviour is fine, but I'd like to know if
> libcameraBuildPath() and libcameraSourcePath() work as expected with
> static libraries or if we should fix them. It could possibly be done on
> top.
>
Those functions will not work, i.e. it will assume libcamera got
installed and return an empty string.

The way the source/build path is determined looks quite unreliable. I
guess one could use meson to set the source or build path in a config
variable more robustly.

Nevertheless, if I compile and install libcamera via:
   meson build_inst --prefix=/tmp/libcamera-install --default-library=static
   meson install -C build_inst

and run the cam demo with debug information:
   LIBCAMERA_LOG_LEVELS=*:DEBUG /tmp/libcamera-install/bin/cam -l

then I can see that IPAs are correctly loaded, but there are still no
cameras:

DEBUG IPAModule ipa_module.cpp:329 ipa_ipu3.so: IPA module
/tmp/libcamera-install/lib/x86_64-linux-gnu/libcamera/ipa_ipu3.so is signed
DEBUG IPAManager ipa_manager.cpp:245 Loaded IPA module
'/tmp/libcamera-install/lib/x86_64-linux-gnu/libcamera/ipa_ipu3.so'
DEBUG IPAModule ipa_module.cpp:329 ipa_rkisp1.so: IPA module
/tmp/libcamera-install/lib/x86_64-linux-gnu/libcamera/ipa_rkisp1.so is
signed
DEBUG IPAManager ipa_manager.cpp:245 Loaded IPA module
'/tmp/libcamera-install/lib/x86_64-linux-gnu/libcamera/ipa_rkisp1.so'
DEBUG IPAModule ipa_module.cpp:329 ipa_rpi.so: IPA module
/tmp/libcamera-install/lib/x86_64-linux-gnu/libcamera/ipa_rpi.so is signed
DEBUG IPAManager ipa_manager.cpp:245 Loaded IPA module
'/tmp/libcamera-install/lib/x86_64-linux-gnu/libcamera/ipa_rpi.so'
DEBUG IPAModule ipa_module.cpp:329 ipa_vimc.so: IPA module
/tmp/libcamera-install/lib/x86_64-linux-gnu/libcamera/ipa_vimc.so is signed
DEBUG IPAManager ipa_manager.cpp:245 Loaded IPA module
'/tmp/libcamera-install/lib/x86_64-linux-gnu/libcamera/ipa_vimc.so'
  INFO Camera camera_manager.cpp:299 libcamera v0.0.2+47-9a08048e
DEBUG Camera camera_manager.cpp:108 Starting camera manager
DEBUG DeviceEnumerator device_enumerator.cpp:224 New media device
"uvcvideo" created from /dev/media0
DEBUG DeviceEnumerator device_enumerator_udev.cpp:95 Defer media device
/dev/media0 due to 2 missing dependencies
DEBUG DeviceEnumerator device_enumerator_udev.cpp:320 All dependencies
for media device /dev/media0 found
DEBUG DeviceEnumerator device_enumerator.cpp:252 Added device
/dev/media0: uvcvideo
DEBUG DeviceEnumerator device_enumerator.cpp:224 New media device
"uvcvideo" created from /dev/media1
DEBUG DeviceEnumerator device_enumerator_udev.cpp:95 Defer media device
/dev/media1 due to 2 missing dependencies
DEBUG DeviceEnumerator device_enumerator_udev.cpp:320 All dependencies
for media device /dev/media1 found
DEBUG DeviceEnumerator device_enumerator.cpp:252 Added device
/dev/media1: uvcvideo
Available cameras:


>>>>
>>>>    libcamera_public = declare_dependency(sources : [
>>>>                                              libcamera_ipa_headers,
>>>> diff --git a/src/v4l2/meson.build b/src/v4l2/meson.build
>>>> index f132103c..46dab168 100644
>>>> --- a/src/v4l2/meson.build
>>>> +++ b/src/v4l2/meson.build
>>>> @@ -27,12 +27,12 @@ v4l2_compat_cpp_args = [
>>>>        '-fvisibility=hidden',
>>>>    ]
>>>>
>>>> -v4l2_compat = shared_library('v4l2-compat',
>>>> -                             v4l2_compat_sources,
>>>> -                             name_prefix : '',
>>>> -                             install : true,
>>>> -                             dependencies : [libcamera_private, libdl],
>>>> -                             cpp_args : v4l2_compat_cpp_args)
>>>> +v4l2_compat = library('v4l2-compat',
>>>> +                      v4l2_compat_sources,
>>>> +                      name_prefix : '',
>>>> +                      install : true,
>>>> +                      dependencies : [libcamera_private, libdl],
>>>> +                      cpp_args : v4l2_compat_cpp_args)
>>>>
>>>>    # Provide a wrapper script to support easily loading applications with the V4L2
>>>>    # adaptation layer.
>


More information about the libcamera-devel mailing list