From eb6dbb6953037e2369a489fe67b01c6b99ea4aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 22 Jan 2020 13:57:01 +0100 Subject: [PATCH] build: Add meson build system Reuse the generated dbus interface .xml files from fprintd to avoid unnecessary copies. --- .gitignore | 1 + config.h.meson | 11 +++ data/meson.build | 77 ++++++++++++++++ doc/dbus/meson.build | 28 ++++++ doc/meson.build | 27 ++++++ meson.build | 159 +++++++++++++++++++++++++++++++++ meson_options.txt | 18 ++++ pam/meson.build | 27 ++++++ pam/pam_fprintd.ver | 6 ++ po/meson.build | 1 + src/meson.build | 81 +++++++++++++++++ tests/meson.build | 46 ++++++++++ tests/pam/meson.build | 26 ++++++ tests/pam/services/meson.build | 13 +++ tests/pam/test_pam_fprintd.py | 2 +- utils/meson.build | 67 ++++++++++++++ 16 files changed, 589 insertions(+), 1 deletion(-) create mode 100644 config.h.meson create mode 100644 data/meson.build create mode 100644 doc/dbus/meson.build create mode 100644 doc/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 pam/meson.build create mode 100644 pam/pam_fprintd.ver create mode 100644 po/meson.build create mode 100644 src/meson.build create mode 100644 tests/meson.build create mode 100644 tests/pam/meson.build create mode 100644 tests/pam/services/meson.build create mode 100644 utils/meson.build diff --git a/.gitignore b/.gitignore index c32a846..1765692 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ /Makefile /Makefile.in /TAGS +/_build /_libs /autom4te.cache /config.cache diff --git a/config.h.meson b/config.h.meson new file mode 100644 index 0000000..ebab457 --- /dev/null +++ b/config.h.meson @@ -0,0 +1,11 @@ +/* Define to the Gettext package name */ +#mesondefine GETTEXT_PACKAGE + +/* Version number of package */ +#mesondefine PACKAGE_VERSION + +/* Where the configuration file will be located */ +#mesondefine SYSCONFDIR + +/* Define to the version of this package. */ +#mesondefine VERSION diff --git a/data/meson.build b/data/meson.build new file mode 100644 index 0000000..b007b46 --- /dev/null +++ b/data/meson.build @@ -0,0 +1,77 @@ +install_data('net.reactivated.Fprint.conf', + install_dir: dbus_conf_dir) + +configure_file( + configuration: configuration_data({ + 'LIBEXECDIR': fprintd_installdir, + }), + input: 'net.reactivated.Fprint.service.in', + output: 'net.reactivated.Fprint.service', + install: true, + install_dir: dbus_service_dir, +) + +configure_file( + configuration: configuration_data({ + 'libexecdir': fprintd_installdir, + }), + input: 'fprintd.service.in', + output: 'fprintd.service', + install: true, + install_dir: systemd_unit_dir, +) + +polkit_policy = 'net.reactivated.fprint.device.policy' +polkit_policy_target = custom_target(polkit_policy, + input: '@0@.in'.format(polkit_policy), + output: polkit_policy, + command: [ + find_program('intltool-merge'), + '-x', + '-u', + meson.source_root() / 'po', + '@INPUT@', + '@OUTPUT@', + ], + install: true, + install_dir: polkit_policy_directory, +) + +if xmllint.found() + test(polkit_policy, + xmllint, + depends: polkit_policy_target, + args: [ + '--noout', + polkit_policy_target.full_path(), + ]) +endif + +install_data('fprintd.conf', + install_dir: sysconfdir) + +if get_option('man') + manfiles = { + 'fprintd': 1, + 'pam_fprintd': 8, + } + + foreach man_name, man_section: manfiles + custom_target('man_' + man_name + '.' + man_section.to_string(), + input: man_name + '.pod', + output: man_name + '.' + man_section.to_string(), + command: [ + pod2man, + '-c', '', + '-s', man_section.to_string(), + '-q', 'none', + '-n', man_name, + '-r', 'freedesktop', + '@INPUT@', + '@OUTPUT@', + ], + install: true, + install_dir: datadir / 'man' / 'man' + man_section.to_string(), + ) + endforeach +endif diff --git a/doc/dbus/meson.build b/doc/dbus/meson.build new file mode 100644 index 0000000..012daca --- /dev/null +++ b/doc/dbus/meson.build @@ -0,0 +1,28 @@ +docbook_xml_header = custom_target('docbook_xml_header', + output: 'docbook-xml-header.xml', + command: [ + 'echo', '-n', + '', + '', + ], + capture: true, +) + +dbus_interfaces_refs = [] +foreach interface_file: dbus_interfaces_files + basename = run_command('basename', interface_file.full_path(), '.xml').stdout().strip() + dbus_interfaces_refs += custom_target(basename + '_ref', + input: docbook_xml_header, + output: basename + '.ref.xml', + depends: interface_file, + capture: true, + command: [ + bash, '-c', + 'cat @INPUT@;' + + xsltproc.path() + ' @0@/@1@ '.format( + meson.source_root(), + files('spec-to-docbook.xsl')[0]) + + interface_file.full_path() + '| tail -n +2;', + ], + ) +endforeach diff --git a/doc/meson.build b/doc/meson.build new file mode 100644 index 0000000..27432b5 --- /dev/null +++ b/doc/meson.build @@ -0,0 +1,27 @@ +subdir('dbus') + +version_file = configure_file( + input: 'version.xml.in', + output: 'version.xml', + configuration: configuration_data({ + 'VERSION': meson.project_version(), + }), +) + +gnome.gtkdoc(meson.project_name(), + main_xml: 'fprintd-docs.xml', + src_dir: meson.source_root() / 'src', + dependencies: [ + declare_dependency( + sources: dbus_interfaces_refs, + link_with: libfprintd_private, + ), + ], + content_files: [ + version_file, + dbus_interfaces_refs, + ], + ignore_headers: [ + 'config.h', + ], + install: true) diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..b4cb373 --- /dev/null +++ b/meson.build @@ -0,0 +1,159 @@ +project('fprintd', 'c', + version: '1.90.0', + license: 'GPLv2+', + default_options: [ + 'buildtype=debugoptimized', + 'warning_level=1', + 'c_std=gnu99', + ], + meson_version: '>= 0.50.0') + +gnome = import('gnome') +i18n = import('i18n') + +cc = meson.get_compiler('c') +host_system = host_machine.system() +glib_min_version = '2.56' +libfprint_min_version = '1.90.0' + +fprintd_installdir = get_option('prefix') / get_option('libexecdir') +fprintd_plugindir = get_option('prefix') / get_option('libdir') / meson.project_name() / 'modules' +storage_path = get_option('prefix') / get_option('localstatedir') / 'lib/fprint' +localedir = get_option('prefix') / get_option('localedir') +datadir = get_option('prefix') / get_option('datadir') +sysconfdir = get_option('sysconfdir') +if get_option('prefix') != '/usr' + sysconfdir = get_option('prefix') / sysconfdir +endif + +common_cflags = cc.get_supported_arguments([ + '-fno-strict-aliasing', + '-Wall', + '-Wcast-align', + '-Werror=address', + '-Werror=array-bounds', + '-Werror=empty-body', + '-Werror=implicit', + '-Werror=init-self', + '-Werror=int-to-pointer-cast', + '-Werror=main', + '-Werror=missing-braces', + '-Werror=nonnull', + '-Werror=pointer-to-int-cast', + '-Werror=return-type', + '-Werror=sequence-point', + '-Werror=trigraphs', + '-Werror=write-strings', + '-Wformat-nonliteral', + '-Wformat-security', + '-Wformat=2', + '-Wignored-qualifiers', + '-Wimplicit-function-declaration', + '-Wlogical-op', + '-Wmissing-declarations', + '-Wmissing-format-attribute', + '-Wmissing-include-dirs', + '-Wmissing-noreturn', + '-Wmissing-prototypes', + '-Wnested-externs', + '-Wold-style-definition', + '-Wpointer-arith', + '-Wshadow', + '-Wstrict-prototypes', + '-Wtype-limits', + '-Wundef', + '-Wunused', +]) +add_project_arguments(common_cflags, language: 'c') + +# Dependencies +glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version) +gio_dep = dependency('gio-2.0', version: '>=' + glib_min_version) +gmodule_dep = dependency('gmodule-2.0', version: '>=' + glib_min_version) +libfprint_dep = dependency('libfprint-2', version: '>=' + libfprint_min_version) +polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.91') +dbus_dep = dependency('dbus-1', required: false) +dbus_glib_dep = dependency('dbus-glib-1') +libsystemd_dep = dependency('libsystemd', required: get_option('pam')) +pam_dep = cc.find_library('pam', + required: get_option('pam'), + has_headers: 'security/pam_modules.h', +) + +pod2man = find_program('pod2man', required: get_option('man')) +xsltproc = find_program('xsltproc', required: get_option('gtk_doc')) + +# StateDirectory was introduced in systemd 235 +systemd_dep = dependency('systemd', version: '>= 235') +systemd_unit_dir = get_option('systemd_system_unit_dir') + +if systemd_unit_dir == '' + systemd_unit_dir = systemd_dep.get_pkgconfig_variable('systemdsystemunitdir') +endif + +dbus_service_dir = get_option('dbus_service_dir') +dbus_data_dir = datadir +dbus_interfaces_dir = '' + +if dbus_dep.found() + if dbus_service_dir == '' + dbus_service_dir = dbus_dep.get_pkgconfig_variable('system_bus_services_dir') + endif + dbus_interfaces_dir = dbus_dep.get_pkgconfig_variable('interfaces_dir') + dbus_data_dir = dbus_dep.get_pkgconfig_variable('datadir') +endif + +dbus_conf_dir = dbus_data_dir / 'dbus-1/system.d' + +if dbus_service_dir == '' + dbus_service_dir = datadir / 'dbus-1/system-services' +endif +if dbus_interfaces_dir == '' + dbus_interfaces_dir = datadir / 'dbus-1/interfaces' +endif + +polkit_policy_directory = polkit_gobject_dep.get_pkgconfig_variable('policydir') + +# Tests dependencies +pam_wrapper_dep = dependency('pam_wrapper', required: get_option('pam')) + +xmllint = find_program('xmllint', required: false) +python3 = find_program('python3') # No meson without it! +python3_test_modules = { + 'cairo': true, + 'dbus': true, + 'dbusmock': true, + 'gi': true, + 'pypamtest': get_option('pam'), +} +python3_available_modules = [] + +foreach module, required : python3_test_modules + if required and run_command(python3, '-c', 'import @0@'.format(module)).returncode() != 0 + error('Python3 module \'' + module + '\' required by test suite not found') + endif +endforeach + +cdata = configuration_data() +cdata.set_quoted('GETTEXT_PACKAGE', meson.project_name()) +cdata.set_quoted('PACKAGE_VERSION', meson.project_version()) +cdata.set_quoted('VERSION', meson.project_version()) +cdata.set_quoted('SYSCONFDIR', sysconfdir) + +config_h = configure_file( + input: 'config.h.meson', + output: 'config.h', + configuration: cdata +) + +subdir('src') +subdir('data') +subdir('utils') +if get_option('pam') + subdir('pam') +endif +if get_option('gtk_doc') + subdir('doc') +endif +subdir('tests') +subdir('po') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..0b2254e --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,18 @@ +option('pam', + description: 'Build the fprintd PAM module', + type: 'boolean', + value: true) +option('man', + description: 'Generate the man files', + type: 'boolean', + value: true) +option('systemd_system_unit_dir', + description: 'Directory for systemd service files', + type: 'string') +option('dbus_service_dir', + description: 'Directory for dbus service files', + type: 'string') +option('gtk_doc', + type: 'boolean', + value: false, + description: 'Use gtk-doc to build documentation') diff --git a/pam/meson.build b/pam/meson.build new file mode 100644 index 0000000..6a342b0 --- /dev/null +++ b/pam/meson.build @@ -0,0 +1,27 @@ +mapfile = files('pam_fprintd.ver') +pam_modules_dir = '/' + get_option('libdir') / 'security' + +pam_fprintd = shared_module('pam_fprintd', + name_prefix: '', + include_directories: [ + include_directories('..'), + ], + sources: [ + 'pam_fprintd.c', + 'fingerprint-strings.h', + ], + dependencies: [ + libsystemd_dep, + pam_dep, + ], + c_args: [ + '-DLOCALEDIR="@0@"'.format(localedir), + ], + link_args: [ + '-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0]), + '-Wl,--unresolved-symbols=report-all', + ], + link_depends: mapfile, + install: true, + install_dir: pam_modules_dir, +) diff --git a/pam/pam_fprintd.ver b/pam/pam_fprintd.ver new file mode 100644 index 0000000..a8d3722 --- /dev/null +++ b/pam/pam_fprintd.ver @@ -0,0 +1,6 @@ +{ +global: + pam_*; +local: + *; +}; diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 0000000..e9b77d7 --- /dev/null +++ b/po/meson.build @@ -0,0 +1 @@ +i18n.gettext(meson.project_name(), preset: 'glib') diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..4be29ff --- /dev/null +++ b/src/meson.build @@ -0,0 +1,81 @@ +fprintd_marshal = gnome.genmarshal('fprintd-marshal', + prefix: 'fprintd_marshal', + sources: 'fprintd-marshal.list', + valist_marshallers: true, +) + +bash = find_program('bash') +dbus_binding_tool = find_program('dbus-binding-tool') +dbus_interfaces = ['Manager', 'Device'] +dbus_interfaces_files = [] +dbus_server_glue_sources = [] + +foreach interface_name: dbus_interfaces + interface = interface_name.to_lower() + interface_file = interface + '.xml' + glue_name = interface + '-dbus-glue.h' + dbus_server_glue_sources += custom_target(glue_name, + input: interface_file, + output: glue_name, + command: [ + dbus_binding_tool, + '--prefix=fprint_' + interface, + '--mode=glib-server', + '--output=@OUTPUT@', + '@INPUT@', + ]) + + dbus_interfaces_files += custom_target('dbus_interface_' + interface, + input: interface_file, + output: 'net.reactivated.Fprint.@0@.xml'.format(interface_name), + command: ['cp', '@INPUT@', '@OUTPUT@'], + install: true, + install_dir: dbus_interfaces_dir, + ) +endforeach + +fprintd_deps = declare_dependency( + include_directories: [ + include_directories('..'), + ], + dependencies: [ + dbus_glib_dep, + glib_dep, + gio_dep, + gmodule_dep, + libfprint_dep, + polkit_gobject_dep, + ], + compile_args: [ + '-DG_LOG_DOMAIN="@0@"'.format(meson.project_name()), + '-DLOCALEDIR="@0@"'.format(localedir), + '-DPLUGINDIR="@0@"'.format(fprintd_plugindir), + ], +) + +libfprintd_private = static_library('fprintd-private', + sources: [ + 'device.c', + 'fprintd.h', + 'manager.c', + dbus_server_glue_sources, + fprintd_marshal, + ], + dependencies: fprintd_deps, + gnu_symbol_visibility: 'hidden', +) + +fprintd = executable('fprintd', + sources: [ + 'file_storage.c', + 'file_storage.h', + 'fprintd.h', + 'main.c', + 'storage.h', + ], + dependencies: fprintd_deps, + link_with: libfprintd_private, + gnu_symbol_visibility: 'hidden', + install: true, + install_dir: fprintd_installdir, +) diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 0000000..e2c6b57 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,46 @@ +tests = [ + 'fprintd', + 'test_fprintd_utils', +] + +foreach t: tests + test(t, + python3, + args: meson.current_source_dir() / t + '.py', + suite: ['daemon'], + depends: [ + fprintd, + fprintd_utils, + ], + env: [ + 'G_DEBUG=fatal-criticals', + 'FPRINT_BUILD_DIR=' + meson.build_root() / 'src', + 'TOPSRCDIR=' + meson.source_root(), + ], + ) +endforeach + +add_test_setup('default_setup', + is_default: true, + env: [ + 'G_SLICE=always-malloc', + 'MALLOC_CHECK_=2', + 'MALLOC_PERTURB_=55', + ], +) + +if find_program('valgrind', required: false).found() + glib_share = glib_dep.get_pkgconfig_variable('prefix') / 'share' / glib_dep.name() + glib_suppressions = glib_share + '/valgrind/glib.supp' + add_test_setup('valgrind', + env: [ + 'G_SLICE=always-malloc', + 'VALGRIND=' + glib_suppressions, + ], + timeout_multiplier: 5 + ) +endif + +if get_option('pam') + subdir('pam') +endif diff --git a/tests/pam/meson.build b/tests/pam/meson.build new file mode 100644 index 0000000..adba341 --- /dev/null +++ b/tests/pam/meson.build @@ -0,0 +1,26 @@ +subdir('services') + +tests = [ + 'test_pam_fprintd', +] + +foreach t: tests + test(t, + python3, + args: meson.current_source_dir() / t + '.py', + suite: ['PAM'], + depends: [ + pam_fprintd, + pam_service_file, + ], + env: [ + 'TOPBUILDDIR=' + meson.build_root(), + 'TOPSRCDIR=' + meson.source_root(), + 'LD_PRELOAD=libpam_wrapper.so', + 'PAM_WRAPPER=1', + 'PAM_WRAPPER_SERVICE_DIR=' + meson.current_build_dir() / 'services', + 'G_DEBUG=fatal-warnings', + ], + timeout: 60, + ) +endforeach diff --git a/tests/pam/services/meson.build b/tests/pam/services/meson.build new file mode 100644 index 0000000..b9e66e1 --- /dev/null +++ b/tests/pam/services/meson.build @@ -0,0 +1,13 @@ +# Meson doesn't allow to have configure_file's as targets we depend on... Meh! +pam_service_file = custom_target('pam_test_service_file', + output: 'null', + command: 'true', + depends: pam_fprintd, + depend_files: configure_file( + input: 'fprintd-pam-test.in', + output: 'fprintd-pam-test', + configuration: configuration_data({ + 'FPRINTDPAMPATH': pam_fprintd.full_path(), + }), + ), +) diff --git a/tests/pam/test_pam_fprintd.py b/tests/pam/test_pam_fprintd.py index fe160d1..99383a2 100755 --- a/tests/pam/test_pam_fprintd.py +++ b/tests/pam/test_pam_fprintd.py @@ -163,7 +163,7 @@ class TestPamFprintd(dbusmock.DBusTestCase): if __name__ == '__main__': if 'PAM_WRAPPER_SERVICE_DIR' not in os.environ: - print('Cannot run test without environment set correctly, run "make check" instead') + print('Cannot run test without environment set correctly, run "meson test" instead') sys.exit(1) # set stream to sys.stderr to get debug output unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2)) diff --git a/utils/meson.build b/utils/meson.build new file mode 100644 index 0000000..bbdc234 --- /dev/null +++ b/utils/meson.build @@ -0,0 +1,67 @@ +dbus_client_glue_sources = [] + +foreach interface_name: dbus_interfaces + interface = interface_name.to_lower() + interface_file = meson.source_root() / 'src' / interface + '.xml' + glue_name = interface + '-dbus-glue.h' + dbus_client_glue_sources += custom_target(glue_name, + input: interface_file, + output: glue_name, + command: [ + dbus_binding_tool, + '--prefix=fprint_' + interface, + '--mode=glib-client', + '--output=@OUTPUT@', + '@INPUT@', + ]) +endforeach + +utils_marshal = custom_target('utils_marshal', + depends: fprintd_marshal, + input: fprintd_marshal, + output: ['marshal.c', 'marshal.h'], + command: [bash, '-c', + 'cp @INPUT0@ @OUTPUT0@;' + + 'cp @INPUT1@ @OUTPUT1@;' + + 'sed s/fprintd-//g -i ' + meson.current_build_dir() / 'marshal*.{h,c}'] +) + +libfprintd_utils_dep = declare_dependency( + include_directories: [ + include_directories('../pam'), + ], + dependencies: [ + glib_dep, + dbus_glib_dep, + ], + sources: [ + utils_marshal, + dbus_client_glue_sources, + ], + link_with: static_library('fprintd_utils', + sources: [ + dbus_client_glue_sources, + utils_marshal, + ], + dependencies: [ + glib_dep, + ] + ), +) + +utils = [ + 'delete', + 'enroll', + 'list', + 'verify', +] + +fprintd_utils = [] + +foreach util: utils + fprintd_utils += executable('fprintd-' + util, + sources: util + '.c', + dependencies: libfprintd_utils_dep, + install: true, + ) +endforeach