project('libfprint', [ 'c', 'cpp' ], version: '1.94.10', license: 'LGPLv2.1+', default_options: [ 'buildtype=debugoptimized', 'warning_level=1', 'c_std=gnu99', ], meson_version: '>= 0.59.0') fs = import('fs') gnome = import('gnome') libfprint_conf = configuration_data() libfprint_conf.set_quoted('LIBFPRINT_VERSION', meson.project_version()) prefix = get_option('prefix') libdir = prefix / get_option('libdir') libexecdir = prefix / get_option('libexecdir') datadir = prefix / get_option('datadir') cc = meson.get_compiler('c') cpp = meson.get_compiler('cpp') host_system = host_machine.system() libfprint_sanitizers = get_option('b_sanitize').split(',') if libfprint_sanitizers == ['none'] libfprint_sanitizers = [] endif glib_min_version = '2.68' glib_version_def = 'GLIB_VERSION_@0@_@1@'.format( glib_min_version.split('.')[0], glib_min_version.split('.')[1]) common_cflags = cc.get_supported_arguments([ '-Wcast-align', '-Wformat-nonliteral', '-Wformat-security', '-Wformat=2', '-Wignored-qualifiers', '-Wlogical-op', '-Wmissing-declarations', '-Wmissing-format-attribute', '-Wmissing-include-dirs', '-Wmissing-noreturn', '-Wpointer-arith', '-Wshadow', '-Wswitch-enum', '-Wtype-limits', '-Wundef', '-Wunused', '-Werror=address', '-Werror=array-bounds', '-Werror=empty-body', '-Werror=init-self', '-Werror=int-to-pointer-cast', '-Werror=main', '-Werror=missing-braces', '-Werror=nonnull', '-Werror=redundant-decls', '-Werror=return-type', '-Werror=sequence-point', '-Werror=trigraphs', '-Werror=write-strings', '-fno-strict-aliasing', '-DGLIB_VERSION_MIN_REQUIRED=' + glib_version_def, '-DGLIB_VERSION_MAX_ALLOWED=' + glib_version_def, '-D_GNU_SOURCE', '-DG_LOG_DOMAIN="@0@"'.format(meson.project_name()), ]) c_cflags = cc.get_supported_arguments([ '-Wimplicit-function-declaration', '-Wmissing-prototypes', '-Wnested-externs', '-Wold-style-definition', '-Wstrict-prototypes', '-Werror=implicit', '-Werror=pointer-to-int-cast', ]) add_project_arguments(common_cflags + c_cflags, language: 'c') add_project_arguments(common_cflags, language: 'cpp') # maintaining compatibility with the previous libtool versioning # current = binary - interface # revision = interface soversion = 2 current = 0 revision = 0 libversion = '@0@.@1@.@2@'.format(soversion, current, revision) versioned_libname = meson.project_name() + '-' + soversion.to_string() # Dependencies glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version) gio_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version) gobject_dep = dependency('gobject-2.0', version: '>=' + glib_min_version) gmodule_dep = dependency('gmodule-2.0', version: '>=' + glib_min_version) gusb_dep = dependency('gusb', version: '>= 0.2.0') mathlib_dep = cc.find_library('m', required: false) # The following dependencies are only used for tests sh = find_program('sh', required: true) cairo_dep = dependency('cairo', required: false) # introspection scanning and Gio-2.0.gir gobject_introspection = dependency('gobject-introspection-1.0', required: get_option('introspection')) # SPI have_spi = host_machine.system() == 'linux' # Drivers drivers = get_option('drivers').split(',') drivers_info = { 'upektc_img': {}, 'vfs5011': { 'endian_dependent': true }, 'vfs7552': {}, 'aes3500': { 'helper': ['aeslib', 'aes3k', 'pixman'] }, 'aes4000': { 'helper': ['aeslib', 'aes3k', 'pixman'] }, 'aes1610': { 'helper': ['aeslib'] }, 'aes1660': { 'helper': ['aeslib', 'aesx660'] }, 'aes2660': { 'helper': ['aeslib', 'aesx660'] }, 'aes2501': { 'helper': ['aeslib'], 'endian_dependent': true }, 'aes2550': { 'helper': ['aeslib'] }, 'vfs101': {}, 'vfs301': { 'endian_dependent': true }, 'vfs0050': { 'endian_dependent': true }, 'etes603': {}, 'egis0570': {}, 'egismoc': {}, 'egis_etu905': {}, 'vcom5s': {}, 'synaptics': {}, 'elan': { 'endian_dependent': true }, 'elanmoc': {}, 'uru4000': { 'helper': ['openssl'], 'endian_dependent': true }, 'upektc': {}, 'upeksonly': {}, 'upekts': {}, 'goodixmoc': { 'endian_dependent': true }, 'nb1010': {}, 'fpcmoc': {}, 'realtek': {}, 'focaltech_moc': {}, 'mafpmoc': { 'endian_dependent': true }, 'secugen': {}, # SPI driver (non-optional if SPI is available) 'elanspi': { 'spi': true, 'helper': ['udev'], 'optional': not have_spi, 'endian_dependent': true }, # Virtual drivers (test-only, optional) 'virtual_image': { 'virtual': true, 'helper': ['virtual'], 'optional': true }, 'virtual_device': { 'virtual': true, 'helper': ['virtual'], 'optional': true }, 'virtual_device_storage': { 'virtual': true, 'helper': ['virtual'], 'optional': true }, } default_drivers = [] virtual_drivers = [] foreach name, info : drivers_info if not info.get('optional', false) default_drivers += name endif if info.get('virtual', false) virtual_drivers += name endif endforeach all_drivers = default_drivers + virtual_drivers if drivers == [ 'all' ] drivers = all_drivers endif if drivers == [ 'default' ] drivers = default_drivers endif if not have_spi foreach driver: drivers if drivers_info[driver].get('spi', false) error('SPI driver @0@ is not supported'.format(driver)) endif endforeach endif driver_helpers = [] foreach driver : drivers if driver in drivers_info foreach helper : drivers_info[driver].get('helper', []) if helper not in driver_helpers driver_helpers += helper endif endforeach endif endforeach if drivers.length() == 0 or drivers[0] == '' error('Cannot build libfprint without drivers, please specify a valid value for the drivers option') endif if drivers == all_drivers or drivers == default_drivers default_drivers_are_enabled = true else default_drivers_are_enabled = true foreach driver: default_drivers if driver not in drivers default_drivers_are_enabled = false break endif endforeach endif udev_rules = get_option('udev_rules') install_udev_rules = udev_rules.enabled() optional_deps = [] # Resolve extra dependencies foreach i : driver_helpers foreach name, info : drivers_info if i in info.get('helper', []) driver = name break endif endforeach if i == 'pixman' imaging_dep = dependency('pixman-1', required: false) if not imaging_dep.found() error('pixman is required for @0@ and possibly others'.format(driver)) endif libfprint_conf.set10('HAVE_PIXMAN', true) optional_deps += imaging_dep elif i == 'openssl' openssl_dep = dependency('openssl', version: '>= 3.0', required: false) if not openssl_dep.found() error('OpenSSL is required for @0@ and possibly others'.format(driver)) endif optional_deps += openssl_dep elif i == 'udev' install_udev_rules = true gudev_dep = dependency('gudev-1.0', required: false) if not gudev_dep.found() error('udev is required for SPI support') endif libfprint_conf.set10('HAVE_UDEV', true) optional_deps += gudev_dep endif endforeach if udev_rules.disabled() install_udev_rules = false endif if install_udev_rules udev_rules_dir = get_option('udev_rules_dir') if udev_rules_dir == 'auto' udev_dep = dependency('udev') udev_rules_dir = udev_dep.get_variable(pkgconfig: 'udevdir') + '/rules.d' endif endif # FIXME: All the drivers should be fixed by adjusting the byte order. # See https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/236 supported_drivers = [] foreach driver: drivers if build_machine.endian() == 'little' or not drivers_info[driver].get('endian_dependent', false) supported_drivers += driver else warning('Driver @0@ is not supported by big endian cpu @1@. Please, fix it!'.format( driver, build_machine.cpu())) endif endforeach if default_drivers_are_enabled and supported_drivers != drivers default_drivers_are_enabled = false endif root_inc = include_directories('.') udev_hwdb = get_option('udev_hwdb') if not udev_hwdb.disabled() # systemd v248 includes our autosuspend rules udev_versioned_dep = dependency('udev', version: '>= 248', required: false) udev_hwdb_dir = get_option('udev_hwdb_dir') if udev_hwdb.auto() if udev_versioned_dep.found() udev_hwdb_dir = '' endif else if udev_versioned_dep.found() warning('udev hwdb will be installed by both systemd and libfprint') endif endif if udev_hwdb_dir == 'auto' udev_dep = dependency('udev') udev_hwdb_dir = udev_dep.get_variable(pkgconfig: 'udevdir') + '/hwdb.d' endif else udev_hwdb_dir = '' endif if get_option('gtk-examples') gtk_dep = dependency('gtk+-3.0', required: false) if not gtk_dep.found() error('GTK+ 3.x is required for GTK+ examples') endif endif # Some dependency resolving happens inside here subdir('libfprint') configure_file(output: 'config.h', configuration: libfprint_conf) if get_option('doc') subdir('doc') endif if get_option('gtk-examples') subdir('demo') endif subdir('data') subdir('tests') subdir('examples') pkgconfig = import('pkgconfig') pkgconfig.generate( name: versioned_libname, description: 'Generic C API for fingerprint reader access', version: meson.project_version(), libraries: libfprint, requires: [gio_dep, gobject_dep], subdirs: versioned_libname, filebase: versioned_libname, ) summary({'Drivers': drivers, }, section: 'Drivers')