project('qdl', 'c', default_options : ['warning_level=2', 'optimization=2'], license: 'BSD-3-Clause', meson_version: '>=0.56.0' ) # Use 64-bit file offsets everywhere. This must be consistent across every # translation unit: off_t appears in shared types (e.g. struct firehose_op) # and in the qdl_file_seek() ABI, so a per-file definition would give # mismatched struct layouts on 32-bit builds. add_project_arguments('-D_FILE_OFFSET_BITS=64', language : 'c') # Determine version env_v = get_option('VERSION') if env_v != '' ver = env_v else git = find_program('git', required: false) git_v = 'unknown-version' if git.found() git_check_ver = run_command(git, 'describe', '--dirty', '--always', '--tags', check: false).stdout().strip() git_v = git_check_ver != '' ? git_check_ver : git_v endif ver = git_v endif # Dependencies libusb_dep = dependency('libusb-1.0') libxml_dep = dependency('libxml-2.0') libzip_dep = dependency('libzip', required: get_option('zip-container')) help2man = find_program('help2man', required: false) cmocka_dep = dependency('cmocka', required: get_option('tests')) # Public API headers live in include/, implementation headers in src/. # '.' adds the top-level build dir, where configure_file generates # version.h, so targets in subdirs (e.g. tests/) resolve it too. inc = include_directories('include', 'src', '.') # Windows-specific link flags ws2_dep = [] setupapi_dep = [] if host_machine.system() == 'windows' ws2_dep = meson.get_compiler('c').find_library('ws2_32', required : false) # SetupAPI / cfgmgr32 are needed by the QUD backend to enumerate Qualcomm # COM ports exposed by the official QDLoader 9008 driver. setupapi_dep = [ meson.get_compiler('c').find_library('setupapi', required : false), meson.get_compiler('c').find_library('cfgmgr32', required : false), ] endif common_dep = [libusb_dep, libxml_dep, ws2_dep, setupapi_dep] compile_view_deps = [libusb_dep, libxml_dep] # Zip container support is optional; the src subdirectory swaps the # libzip-backed sources for no-zip stubs when it is disabled. if libzip_dep.found() common_dep += libzip_dep compile_view_deps += libzip_dep endif # Compile-only view of common_dep (includes + cflags, no link args). # Used on executables so their own sources see the headers, while link # args propagate exactly once through the static library below, avoiding # duplicate "-l..." entries on the link line. common_compile_dep = [] foreach d : compile_view_deps common_compile_dep += d.partial_dependency(compile_args: true, includes: true) endforeach # --- version header generation --- conf = configuration_data() conf.set('version', ver) version_h = configure_file( input: 'include/version.h.in', output: 'version.h', configuration: conf ) # Source lists (common_sources, qdl_sources and the per-test source # vars) are declared next to the sources. subdir('src') shared_lib = static_library('qdl_common', common_sources, dependencies: common_dep, include_directories: inc, ) # --- qdl executable --- qdl_exe = executable('qdl', sources : qdl_sources + [version_h], link_with: shared_lib, dependencies : common_compile_dep, include_directories : inc, install : true ) # --- optional nbdkit plugin --- # nbdkit dlopens plugins, so there is no library to link against; the plugin # just needs and compiles all non-main sources into a shared # module named exactly "nbdkit-qdl-plugin.so". nbdkit_dep = dependency('nbdkit', required: get_option('nbdkit')) if nbdkit_dep.found() shared_module('nbdkit-qdl-plugin', sources : nbdkit_plugin_src + lib_sources + common_sources + [version_h], dependencies : common_dep + [nbdkit_dep], include_directories : inc, name_prefix : '', install : true, install_dir : get_option('libdir') / 'nbdkit' / 'plugins', ) endif # --- tests --- subdir('tests') # --- checkpatch targets --- check_script = join_paths(meson.project_source_root(), 'scripts', 'checkpatch_wrapper.sh') foreach checkpatchparam : ['download-checkpatch', 'check', 'check-cached', 'check-range'] run_target(checkpatchparam, command: ['bash', '-lc', check_script + ' ' + checkpatchparam] ) endforeach # --- markdown lint target --- markdown_script = join_paths(meson.project_source_root(), 'scripts', 'markdownlint_wrapper.sh') run_target('markdown-lint', command: ['bash', '-lc', markdown_script + ' check'] ) # --- man generation --- if help2man.found() # Test if we can run the built executable (might fail in cross-compilation) can_run_exe = not meson.is_cross_build() if can_run_exe manpage_targets = [] foreach prog : [ ['qdl', qdl_exe, 'Qualcomm Download'], ] manpage_targets += custom_target(prog[0] + '.1', input: prog[1], output: prog[0] + '.1', command: [help2man, '-N', '-n', prog[2], prog[1].full_path()], capture: true, install: true, install_dir: get_option('mandir') / 'man1') endforeach # Replicate the "manpages" phony target. alias_target requires at # least one dependency, so it is only declared when we have actually # produced manpage targets above. alias_target('manpages', manpage_targets) endif endif