# SPDX-License-Identifier: CC0-1.0 project('libcamera', 'c', 'cpp', meson_version : '>= 0.63', version : '0.3.2', default_options : [ 'werror=true', 'warning_level=2', 'cpp_std=c++17', ], license : 'LGPL 2.1+') # Generate version information. The libcamera_git_version variable contains the # full version with build metadata (patch count and SHA1, e.g. # 1.2.3+211-c94a24f4), while the libcamera_version variable contains the # major.minor.patch (e.g. 1.2.3) only. # # If the source tree matches the last git version tag, the build metadata # (e.g. +211-c94a24f4) is omitted from libcamera_git_version. libcamera_git_version = run_command('utils/gen-version.sh', meson.project_build_root(), meson.project_source_root(), check : false).stdout().strip() # If the source tree isn't under git control, set libcamera_git_version to the # meson project version. if libcamera_git_version == '' libcamera_git_version = meson.project_version() endif libcamera_version = libcamera_git_version.split('+')[0] project_version = meson.project_version().split('+')[0] # A shallow clone, or a clone without a reachable tag equivalent to the # meson.project_version() could leave the project in a mis-described state. # Produce a warning in this event, and fix to a best effort. if libcamera_version != project_version warning('The sources and meson.build disagree about the version: ' + libcamera_version + ' != ' + project_version) summary({'libcamera git version' : libcamera_git_version, 'Source version match' : false, }, bool_yn : true, section : 'Versions') # Re-run gen-version.sh to replace the git version (major.minor.patch) with # the meson project version. The build metadata provided by git are kept. libcamera_git_version = run_command('utils/gen-version.sh', meson.project_build_root(), meson.project_source_root(), project_version, check : false).stdout().strip() libcamera_version = project_version # Append a marker to show we have modified this version string. libcamera_git_version += '-nvm' endif # The major and minor libcamera version components are used as the soname. # No ABI/API compatibility is guaranteed between releases (x.y). # # When we declare a stable ABI/API we will provide a 1.0 release and the # soversion at that point will be the 'major' release value (x). semver = libcamera_version.split('.') libcamera_soversion = semver[0] + '.' + semver[1] summary({ 'Sources': libcamera_git_version, }, section : 'Versions') # This script generates the .tarball-version file on a 'meson dist' command. meson.add_dist_script('utils/run-dist.sh') # Configure the build environment. cc = meson.get_compiler('c') cxx = meson.get_compiler('cpp') config_h = configuration_data() if cc.has_header_symbol('fcntl.h', 'F_ADD_SEALS', prefix : '#define _GNU_SOURCE') config_h.set('HAVE_FILE_SEALS', 1) endif if cc.has_header_symbol('unistd.h', 'issetugid') config_h.set('HAVE_ISSETUGID', 1) endif if cc.has_header_symbol('locale.h', 'locale_t', prefix : '#define _GNU_SOURCE') config_h.set('HAVE_LOCALE_T', 1) endif if cc.has_header_symbol('sys/mman.h', 'memfd_create', prefix : '#define _GNU_SOURCE') config_h.set('HAVE_MEMFD_CREATE', 1) endif ioctl_posix_test = ''' #include <sys/ioctl.h> int ioctl (int, int, ...); ''' if cc.compiles(ioctl_posix_test) config_h.set('HAVE_POSIX_IOCTL', 1) endif if cc.has_header_symbol('stdlib.h', 'secure_getenv', prefix : '#define _GNU_SOURCE') config_h.set('HAVE_SECURE_GETENV', 1) endif common_arguments = [ '-Wmissing-declarations', '-Wshadow', '-include', meson.current_build_dir() / 'config.h', ] c_arguments = [] cpp_arguments = [] if cc.get_id() == 'clang' if cc.version().version_compare('<9') error('clang version is too old, libcamera requires 9.0 or newer') endif # Turn _FORTIFY_SOURCE by default on. This is needed on clang only as gcc # enables it by default. FORTIFY will not work properly with `-O0`, and may # result in macro redefinition errors if the user already has a setting for # `-D_FORTIFY_SOURCE`. Do not enable FORTIFY in either of those cases. if get_option('optimization') != '0' fortify = cc.get_define('_FORTIFY_SOURCE') if fortify == '' message('Adding _FORTIFY_SOURCE') common_arguments += [ '-D_FORTIFY_SOURCE=2', ] endif endif # Use libc++ by default if available instead of libstdc++ when compiling # with clang. if cc.find_library('c++', required : false).found() cpp_arguments += [ '-stdlib=libc++', ] endif cpp_arguments += [ '-Wextra-semi', '-Wthread-safety', ] endif if cc.get_id() == 'gcc' if cc.version().version_compare('<9') error('gcc version is too old, libcamera requires 9.0 or newer') endif # gcc 13 implements the C++23 version of automatic move from local # variables in return statements (see # https://en.cppreference.com/w/cpp/language/return). As a result, some # previously required explicit std::move() in return statements generate # warnings. Those moves can't be removed as older compiler versions could # use copy constructors instead of move constructors. The easiest fix is to # disable the warning. With -Wpessimizing-move enabled, the compiler will # still warn of pessimizing moves, only the redundant but not pessimizing # moves will be ignored. if cc.version().version_compare('>=13') cpp_arguments += [ '-Wno-redundant-move', ] endif # gcc 7.1 introduced processor-specific ABI breakages related to parameter # passing on ARM platforms. This generates a large number of messages # during compilation. Silence them. if host_machine.cpu_family() == 'arm' cpp_arguments += [ '-Wno-psabi', ] endif endif # We use C99 designated initializers for arrays as C++ has no equivalent # feature. Both gcc and clang support this extension, but recent # versions of clang generate a warning that needs to be disabled. if cc.has_argument('-Wno-c99-designator') common_arguments += [ '-Wno-c99-designator', ] endif c_arguments += common_arguments cpp_arguments += common_arguments add_project_arguments(c_arguments, language : 'c') add_project_arguments(cpp_arguments, language : 'cpp') add_project_link_arguments(cpp_arguments, language : 'cpp') libcamera_includes = include_directories('include') # Sub-directories fill py_modules with their dependencies. py_modules = [] # Libraries used by multiple components liblttng = dependency('lttng-ust', required : get_option('tracing')) # Pipeline handlers # pipelines = get_option('pipelines') arch_arm = ['arm', 'aarch64'] arch_x86 = ['x86', 'x86_64'] pipelines_support = { 'imx8-isi': arch_arm, 'ipu3': arch_x86, 'mali-c55': arch_arm, 'rkisp1': arch_arm, 'rpi/vc4': arch_arm, 'simple': ['any'], 'uvcvideo': ['any'], 'vimc': ['test'], } if pipelines.contains('all') pipelines = pipelines_support.keys() elif pipelines.contains('auto') host_cpu = host_machine.cpu_family() pipelines = [] foreach pipeline, archs : pipelines_support if host_cpu in archs or 'any' in archs pipelines += pipeline endif endforeach endif # Tests require the vimc pipeline handler, include it automatically when tests # are enabled. if get_option('test') foreach pipeline, archs : pipelines_support if 'test' in archs and pipeline not in pipelines message('Enabling ' + pipeline + ' pipeline handler for tests') pipelines += pipeline endif endforeach endif # Utilities are parsed first to provide support for other components. subdir('utils') subdir('include') subdir('src') # The documentation and test components are optional and can be disabled # through configuration values. They are enabled by default. subdir('Documentation') subdir('test') if not meson.is_cross_build() kernel_version_req = '>= 5.0.0' kernel_version = run_command('uname', '-r', check : true).stdout().strip() if not kernel_version.version_compare(kernel_version_req) warning('The current running kernel version @0@ is too old to run libcamera.' .format(kernel_version)) warning('If you intend to use libcamera on this machine, please upgrade to a kernel @0@.' .format(kernel_version_req)) endif endif # Create a symlink from the build root to the source root. This is used when # running libcamera from the build directory to locate resources in the source # directory (such as IPA configuration files). run_command('ln', '-fsT', meson.project_source_root(), meson.project_build_root() / 'source', check : true) configure_file(output : 'config.h', configuration : config_h) # Check for python installation and modules. py_mod = import('python') py_mod.find_installation('python3', modules : py_modules) ## Summarise Configurations summary({ 'Enabled pipelines': pipelines, 'Enabled IPA modules': enabled_ipa_names, 'Controls files': controls_files_names, 'Properties files': properties_files_names, 'Hotplug support': libudev.found(), 'Tracing support': tracing_enabled, 'Android support': android_enabled, 'GStreamer support': gst_enabled, 'Python bindings': pycamera_enabled, 'V4L2 emulation support': v4l2_enabled, 'cam application': cam_enabled, 'qcam application': qcam_enabled, 'lc-compliance application': lc_compliance_enabled, 'Unit tests': test_enabled, }, section : 'Configuration', bool_yn : true)