rizin/meson.build
2026-02-12 03:20:28 +08:00

903 lines
35 KiB
Meson

project('rizin', 'c',
version: 'v0.9.0',
license: 'LGPL-3.0-only',
meson_version: '>=0.57.0',
default_options: [
'buildtype=debugoptimized',
'b_vscrt=from_buildtype',
'warning_level=1',
]
)
py3_exe = import('python').find_installation()
git_exe = find_program('git', required: false)
pkgconfig_mod = import('pkgconfig')
# Python scripts used during the build process
create_tags_rz_py = files('sys/create_tags_rz.py')
syscall_preprocessing_py = files('sys/syscall_preprocessing.py')
check_meson_subproject_py = files('sys/check_meson_subproject.py')
git_exe_repo_py = files('sys/meson_git_wrapper.py')
cmake_package_prefix_dir_py = files('sys/meson_cmake_prefix_dir.py')
is_static_build = get_option('static_runtime')
is_static_libs_only = get_option('default_library') == 'static'
if is_static_build and not is_static_libs_only
error('Cannot use `static_runtime` when libraries are dynamically built. Set `--default-library=static` if you want to build statically.')
endif
# Get rizin version and compute various version parts
rizin_version = meson.project_version().split('v')[1]
rizin_version_split = rizin_version.split('.')
rizin_version_major = rizin_version_split[0].to_int()
rizin_version_minor = rizin_version_split[1].to_int()
rizin_version_patch = rizin_version_split[2].split('-')[0].to_int()
rizin_version_number = 1000000 * rizin_version_major + 1000 * rizin_version_minor + rizin_version_patch
repo = meson.current_source_dir()
rizin_libversion = '@0@.@1@'.format(rizin_version_major, rizin_version_minor)
message('rizin lib version: ' + rizin_libversion)
# system dependencies
cc = meson.get_compiler('c')
cc_native = meson.get_compiler('c', native: true)
platform_deps = []
platform_inc = ['.', 'librz', 'librz/include', 'subprojects/rzheap']
if host_machine.system() == 'windows'
add_project_arguments('-DPSAPI_VERSION=1', language: 'c')
platform_deps = [
cc.find_library('ws2_32'),
cc.find_library('wininet'),
cc.find_library('psapi'),
cc.find_library('dbghelp'),
]
endif
platform_inc = include_directories(platform_inc)
lib_name_suffix = []
lib_name_prefix = []
if is_static_libs_only and cc.get_id() == 'msvc'
# On MSVC meson uses the .a suffix and lib as prefix, but cmake and other
# tools expect a .lib suffix and no prefix
# https://mesonbuild.com/FAQ.html#why-does-building-my-project-with-msvc-output-static-libraries-called-libfooa
lib_name_suffix = 'lib'
lib_name_prefix = ''
endif
if is_static_build
if cc.get_id() == 'msvc'
# Use -Db_vscrt=static_from_buildtype to avoid warnings due to multiple /M options
if get_option('b_vscrt') == 'from_buildtype'
warning('To avoid warnings due to multiple /M options, please also set -Db_vscrt=mt or -Db_vscrt=mtd.')
add_project_arguments('/MT', language: 'c')
endif
else
if cc.has_link_argument('-static')
add_project_link_arguments('-static', language: 'c')
endif
endif
endif
# These two warnings enum compare and conversion are necessary for the Capstone compatibility header.
# Newer compilers will warn about the comparison of different enums (arm64 and aarch64) in the header.
# Hence, we have to disable them for the newer once.
# Older compilers don't have these warnings and should not be included with #pragma
if cc.has_argument('-Wenum-conversion')
add_project_arguments('-DCC_SUPPORTS_W_ENUM_CONVERION', language: ['c', 'cpp'])
endif
if cc.has_argument('-Wenum-compare')
add_project_arguments('-DCC_SUPPORTS_W_ENUM_COMPARE', language: ['c', 'cpp'])
endif
if cc.has_argument('-std=gnu99')
add_project_arguments('-std=gnu99', language: ['c', 'cpp'])
elif cc.has_argument('--std=gnu99')
add_project_arguments('--std=gnu99', language: ['c', 'cpp'])
elif cc.has_argument('-std=c99')
add_project_arguments('-std=c99', language: ['c', 'cpp'])
elif cc.has_argument('--std=c99')
add_project_arguments('--std=c99', language: ['c', 'cpp'])
endif
# Sanitize correct usage of rz_strf()
if cc.has_argument('-Werror=sizeof-pointer-memaccess')
add_project_arguments('-Werror=sizeof-pointer-memaccess', language: ['c', 'cpp'])
endif
if cc.has_argument('-Wimplicit-fallthrough=3')
add_project_arguments('-Wimplicit-fallthrough=3', language: ['c', 'cpp'])
endif
if cc.get_id() == 'clang-cl'
if cc.has_argument('-fcommon')
add_project_arguments('-fcommon', language: 'c')
endif
add_project_arguments('-D__STDC__=1', language: 'c')
add_project_arguments('-D_CRT_DECLARE_NONSTDC_NAMES ', language: 'c')
add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', language: 'c')
add_project_arguments('-D_CRT_NONSTDC_NO_DEPRECATE', language: 'c')
endif
if get_option('default_library') == 'shared'
if cc.has_argument('-fvisibility=hidden')
add_project_arguments('-fvisibility=hidden', language: 'c')
endif
endif
add_project_arguments(['-DRZ_PLUGIN_INCORE=1'], language: 'c')
b_sanitize_opt = get_option('b_sanitize')
if (b_sanitize_opt.contains('address') or b_sanitize_opt.contains('undefined')) and cc.get_id() == 'clang'
add_project_arguments('-shared-libasan', language: 'c')
add_project_link_arguments('-shared-libasan', language: 'c')
add_project_arguments('-shared-libasan', language: 'c', native: true)
add_project_link_arguments('-shared-libasan', language: 'c', native: true)
endif
fs = import('fs')
rizin_prefix = get_option('prefix')
rizin_bindir = get_option('bindir')
rizin_libdir = get_option('libdir')
rizin_cmakedir = rizin_libdir / 'cmake'
rizin_incdir = get_option('includedir') / 'librz'
rizin_datdir = get_option('datadir')
extra_prefix = get_option('extra_prefix')
if host_machine.system() == 'windows'
rizin_prefix = fs.as_posix(rizin_prefix).replace('/', '\\\\')
rizin_bindir = fs.as_posix(rizin_bindir).replace('/', '\\\\')
rizin_libdir = fs.as_posix(rizin_libdir).replace('/', '\\\\')
rizin_cmakedir = fs.as_posix(rizin_cmakedir).replace('/', '\\\\')
rizin_incdir = fs.as_posix(rizin_incdir).replace('/', '\\\\')
rizin_datdir = fs.as_posix(rizin_datdir).replace('/', '\\\\')
rizin_datdir_rz = fs.as_posix(rizin_datdir).replace('/', '\\\\')
else
rizin_datdir_rz = rizin_datdir / 'rizin'
endif
load_dirs = {
'rizin_sdb': rizin_datdir_rz,
'rizin_wwwroot': rizin_datdir_rz / 'www',
'rizin_sigdb': rizin_datdir_rz / 'sigdb',
'rizin_themes': rizin_datdir_rz / 'cons',
'rizin_fortunes': rizin_datdir_rz / 'fortunes',
'rizin_flags': rizin_datdir_rz / 'flag',
'rizin_hud': rizin_datdir_rz / 'hud',
'rizin_plugins': rizin_libdir / 'rizin' / 'plugins',
'rizin_bindings': rizin_libdir / 'rizin-bindings',
}
# Calcualte BINDIR's depth to be able to find the root directory during runtime
# in portable builds
py_cmd = 'import os; from pathlib import Path; print(len(Path(os.path.normpath(r"@0@")).parents) - len(Path(os.path.normpath(r"@1@")).parents))'.format(rizin_prefix / rizin_bindir, rizin_prefix)
py_cmd = run_command(py3_exe, '-c', py_cmd, check: true)
bindir_depth = py_cmd.stdout().strip()
foreach load_dir, default_subdir : load_dirs
val = get_option(load_dir)
if val != ''
set_variable(load_dir, val)
else
val = default_subdir
if host_machine.system() == 'windows'
val = fs.as_posix(val).replace('/', '\\\\')
endif
set_variable(load_dir, val)
endif
endforeach
cmake_package_relative_path = run_command(py3_exe, cmake_package_prefix_dir_py, rizin_prefix, rizin_cmakedir / 'xxx', check: true).stdout().strip()
subproject_clean_error_msg = 'Subprojects are not updated. Please run `git clean -dxff subprojects/` to delete all local subprojects directories. If you want to compile against current subprojects then set option `subprojects_check=false`.'
# handle capstone dependency
capstone_dep = dependency('capstone', version: '>=4.0.2', required: get_option('use_sys_capstone'), static: is_static_build)
if not capstone_dep.found()
capstone_version = get_option('use_capstone_version')
if fs.is_file('subprojects/capstone-' + capstone_version + '.wrap')
r = run_command(py3_exe, check_meson_subproject_py, 'capstone-' + capstone_version, check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
capstone_proj = subproject('capstone-' + capstone_version, default_options: ['default_library=static'])
else
error('Wrong capstone version selected. Please use one of the supported versions.')
endif
capstone_dep = capstone_proj.get_variable('capstone_dep')
else
# Package managers CS version has no meta programming macros for AArch64 -> ARM64 renaming
# (because it is outdated).
# With this define we includeour copy of those macros.
add_project_arguments(['-DUSE_SYS_CAPSTONE'], language: 'c')
endif
# Handle PCRE2
cpu_jit_supported = [ 'aarch64', 'arm', 'mips', 'mips64', 'ppc', 'ppc64', 'riscv32', 'riscv64', 's390x', 'x86', 'x86_64' ]
pcre2_jit_supported = target_machine.cpu_family() in cpu_jit_supported and cc.get_id() != 'tcc' and target_machine.system() != 'darwin'
if pcre2_jit_supported
add_project_arguments(['-DSUPPORTS_PCRE2_JIT'], language: 'c')
endif
pcre2_dep_opt = get_option('use_sys_pcre2')
pcre2_dep = disabler()
sys_pcre2_found = false
if (pcre2_dep_opt.enabled() or pcre2_dep_opt.auto()) and not meson.is_cross_build()
pcre2_deps = []
sys_pcre2_found = true
foreach utf : [8, 16, 32]
pcre2_utf_dep = dependency('libpcre2-@0@'.format(utf), required: false, static: false)
if not pcre2_utf_dep.found()
sys_pcre2_found = false
endif
pcre2_deps += pcre2_utf_dep
endforeach
if sys_pcre2_found
pcre2_dep = declare_dependency(dependencies: pcre2_deps, version: pcre2_deps[0].version())
else
pcre2_dep = cc.find_library('pcre2', required: true, static: true)
endif
else
pcre2_dep = dependency('pcre2', version: '>=10.42', required: true, static: true, allow_fallback: true)
endif
if meson.is_cross_build()
pcre2_native_dep = dependency('pcre2_cross_native', required: true, static: true, native: true)
endif
# handle magic library
sys_magic_opt = get_option('use_sys_magic')
sys_magic = disabler()
if sys_magic_opt.enabled() or sys_magic_opt.auto()
sys_magic = dependency('libmagic', required: false, static: is_static_build)
if not sys_magic.found()
sys_magic = cc.find_library('magic', required: sys_magic_opt, static: is_static_build)
endif
endif
# Handle Zydis library
sys_zydis_opt = get_option('use_sys_zydis')
zydis_dep = disabler()
if sys_zydis_opt.enabled() or sys_zydis_opt.auto()
zydis_dep = dependency('zydis', required: false, static: is_static_build)
if not zydis_dep.found()
zydis_dep = cc.find_library('zydis', required: sys_zydis_opt, static: is_static_build)
endif
endif
if (sys_zydis_opt.auto() and not zydis_dep.found()) or sys_zydis_opt.disabled()
zydis_proj = subproject('zydis', default_options: ['default_library=static'])
zydis_dep = zydis_proj.get_variable('zydis_dep')
add_project_arguments(['-DZYDIS_STATIC_BUILD'], language: 'c')
endif
# handle libmspack library
sys_libmspack_opt = get_option('use_sys_libmspack')
libmspack_dep = disabler()
if sys_libmspack_opt.enabled() or sys_libmspack_opt.auto()
libmspack_dep = dependency('libmspack', required: false, static: is_static_build)
if not libmspack_dep.found()
libmspack_dep = cc.find_library('mspack', required: sys_libmspack_opt, static: is_static_build)
endif
endif
if (sys_libmspack_opt.auto() and not libmspack_dep.found()) or sys_libmspack_opt.disabled()
libmspack_proj = subproject('libmspack', default_options: ['default_library=static'])
libmspack_dep = libmspack_proj.get_variable('libmspack_dep')
endif
# handle xxhash library
r = run_command(py3_exe, check_meson_subproject_py, 'xxhash', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
sys_xxhash_opt = get_option('use_sys_xxhash')
if sys_xxhash_opt.enabled() or sys_xxhash_opt.auto()
xxhash_dep = dependency('libxxhash', required: false, static: is_static_build)
if not xxhash_dep.found()
xxhash_dep = cc.find_library('xxhash', required: sys_xxhash_opt, static: is_static_build)
endif
endif
if (sys_xxhash_opt.auto() and not xxhash_dep.found()) or sys_xxhash_opt.disabled()
xxhash_proj = subproject('xxhash', default_options: ['default_library=static'])
xxhash_dep = xxhash_proj.get_variable('xxhash_dep')
endif
# handle libdemangle
r = run_command(py3_exe, check_meson_subproject_py, 'libdemangle', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
libdemangle_options = [
'default_library=static',
'use_swift_demangler=false',
]
if get_option('use_gpl')
libdemangle_options += 'use_gpl=true'
else
libdemangle_options += 'use_gpl=false'
endif
libdemangle_proj = subproject('libdemangle', default_options: libdemangle_options)
libdemangle_dep = libdemangle_proj.get_variable('libdemangle_dep')
# handle blake3 algo
blake3_dep = dependency('libblake3', required: get_option('use_sys_blake3'), static: is_static_build)
if not blake3_dep.found()
blake3_proj = subproject('blake3', default_options: ['default_library=static', 'werror=false'])
blake3_dep = blake3_proj.get_variable('blake3_dep')
endif
# handle openssl library
sys_openssl = dependency('openssl', required: get_option('use_sys_openssl'), static: is_static_build)
# handle tree-sitter
r = run_command(py3_exe, check_meson_subproject_py, 'tree-sitter', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
tree_sitter_dep = dependency('tree-sitter', required: get_option('use_sys_tree_sitter'), static: is_static_build, fallback: [])
if not tree_sitter_dep.found()
tree_sitter_proj = subproject('tree-sitter', default_options: ['default_library=static'])
tree_sitter_dep = tree_sitter_proj.get_variable('tree_sitter_dep')
meson.override_dependency('tree-sitter', tree_sitter_dep)
endif
# handle rizin-grammar-c
r = run_command(py3_exe, check_meson_subproject_py, 'rizin-grammar-c', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
rizin_grammar_c_proj = subproject('rizin-grammar-c', default_options: ['default_library=static', 'werror=false'])
rizin_grammar_c_dep = rizin_grammar_c_proj.get_variable('rizin_grammar_c_dep')
# override done in rizin-grammar-c subproject
has_debugger = get_option('debugger')
have_ptrace = not ['windows', 'cygwin', 'sunos', 'haiku'].contains(host_machine.system())
use_ptrace_wrap = ['linux'].contains(host_machine.system())
have_ptrace = have_ptrace and has_debugger
use_ptrace_wrap = use_ptrace_wrap and has_debugger
message('HAVE_PTRACE: @0@'.format(have_ptrace))
message('USE_PTRACE_WRAP: @0@'.format(use_ptrace_wrap))
checks_level = get_option('checks_level')
message('RZ_CHECKS_LEVEL: @0@'.format(checks_level))
if checks_level < 0 or checks_level > 3
error('`checks_level` must be between 0 and 3.')
endif
userconf = configuration_data()
ccs = [[cc, userconf, host_machine, false]]
if meson.is_cross_build()
userconf_native = configuration_data()
ccs += [[cc_native, userconf_native, build_machine, true]]
endif
userconfs = []
foreach it : ccs
it_cc = it[0]
it_userconf = it[1]
it_machine = it[2]
it_native = it[3]
# required for linux
it_utl = it_cc.find_library('util', required: false, static: is_static_build)
it_ldl = it_cc.find_library('dl', required: false, static: is_static_build)
it_th = dependency('threads', required: false, static: is_static_build, native: it_native)
have_pthread = it_th.found() and it_machine.system() != 'windows'
if it_machine.system() == 'sunos'
# workaround for Solaris until https://github.com/mesonbuild/meson/issues/4328 is fixed
it_mth = declare_dependency(link_args: '-lm')
else
it_mth = it_cc.find_library('m', required: false, static: is_static_build)
endif
it_lrt = dependency('', required: false, native: it_native)
if not it_cc.has_function('clock_gettime', prefix: '#include <time.h>') and it_cc.has_header_symbol('features.h', '__GLIBC__')
it_lrt = it_cc.find_library('rt', required: true, static: is_static_build)
endif
have_lrt = not ['windows', 'darwin', 'openbsd', 'android', 'haiku'].contains(it_machine.system())
if have_lrt and not it_lrt.found()
it_lrt = it_cc.find_library('rt', required: true, static: is_static_build)
endif
# FreeBSD has backtrace() in libexecinfo
it_lexecinfo = it_cc.find_library('execinfo', required: false)
it_userconf.set('RZ_CHECKS_LEVEL', checks_level)
it_userconf.set10('IS_PORTABLE', get_option('portable'))
it_userconf.set10('HAVE_LIB_MAGIC', sys_magic.found())
it_userconf.set10('USE_LIB_MAGIC', sys_magic.found())
it_userconf.set10('HAVE_LIB_PCRE2', pcre2_dep.found())
it_userconf.set10('USE_LIB_PCRE2', pcre2_dep.found())
it_userconf.set10('HAVE_LIB_XXHASH', xxhash_dep.found())
it_userconf.set10('USE_LIB_XXHASH', xxhash_dep.found())
it_userconf.set10('DEBUGGER', has_debugger)
if extra_prefix != ''
it_userconf.set_quoted('EXTRA_PREFIX', extra_prefix)
else
it_userconf.set10('EXTRA_PREFIX', false)
endif
it_userconf.set('PREFIX', rizin_prefix)
it_userconf.set('BINDIR', rizin_bindir)
it_userconf.set('BINDIR_DEPTH', bindir_depth)
it_userconf.set('LIBDIR', rizin_libdir)
it_userconf.set('INCLUDEDIR', rizin_incdir)
it_userconf.set('DATADIR_RZ', rizin_datdir_rz)
is_ppc = it_machine.cpu_family() == 'ppc' or it_machine.cpu_family() == 'ppc64'
it_userconf.set('DATADIR', rizin_datdir)
it_userconf.set('WWWROOT', rizin_wwwroot)
it_userconf.set('SDB', rizin_sdb)
it_userconf.set('SIGDB', rizin_sigdb)
it_userconf.set('THEMES', rizin_themes)
it_userconf.set('FORTUNES', rizin_fortunes)
it_userconf.set('FLAGS', rizin_flags)
it_userconf.set('HUD', rizin_hud)
it_userconf.set('PLUGINS', rizin_plugins)
it_userconf.set('BINDINGS', rizin_bindings)
it_userconf.set10('HAVE_OPENSSL', sys_openssl.found())
it_userconf.set10('WANT_DYLINK', true)
it_userconf.set10('HAVE_PTRACE', have_ptrace)
it_userconf.set10('USE_PTRACE_WRAP', use_ptrace_wrap)
it_userconf.set10('WITH_GPL', get_option('use_gpl'))
it_userconf.set10('RZ_BUILD_DEBUG', get_option('buildtype').startswith('debug'))
ok = it_cc.has_header_symbol('sys/personality.h', 'ADDR_NO_RANDOMIZE')
it_userconf.set10('HAVE_DECL_ADDR_NO_RANDOMIZE', ok)
ok = it_cc.has_header_symbol('sys/procctl.h', 'PROC_ASLR_CTL')
it_userconf.set10('HAVE_DECL_PROCCTL_ASLR_CTL', ok)
it_userconf.set10('HAVE_THREADS', it_th.found())
it_userconf.set10('HAVE_PTHREAD', have_pthread)
it_userconf.set10('HAVE_LZMA', get_option('use_lzma'))
it_userconf.set10('HAVE_ZLIB', get_option('use_zlib'))
it_userconf.set10('USE_SYS_ZYDIS', zydis_dep.found() and zydis_dep.type_name() != 'internal')
it_userconf.set10('SUPPORTS_PCRE2_JIT', pcre2_jit_supported)
it_userconf.set('N_THREAD_LIMIT', get_option('n_thread_limit'))
if it_machine.system() == 'freebsd' or it_machine.system() == 'dragonfly'
add_project_link_arguments('-Wl,--unresolved-symbols,ignore-in-object-files', language: 'c', native: it_native)
add_project_link_arguments('-Wl,--allow-shlib-undefined', language: 'c', native: it_native)
endif
if it_machine.system() == 'darwin'
# On older Mac OS X versions (at least Lion and older), environ is only available when compiling an executable,
# but we will use is primarily in shared libs. Unfortunately, it_cc.links() only checks for executable compiling,
# so this does not help us.
# But in fact, even the environ(7) man page on macOS 11.6 still claims that environ is not avaliable for
# shared libs (even though it seems to work) and suggests using _NSGetEnviron(), so let's just do this always.
have_environ = false
elif host_machine.system() == 'windows'
code = '#include <stdlib.h>\n\nint main() { char **env = environ; }'
have_environ = cc.links(code, name: 'have environ')
else
code = '#include <unistd.h>\nextern char **environ;\nint main() { char **env = environ; }'
have_environ = it_cc.links(code, name: 'have extern char **environ')
endif
it_userconf.set10('HAVE_ENVIRON', have_environ)
message('HAVE_ENVIRON: @0@'.format(have_environ))
code = '#if __is_target_os(ios)\nint x = 0;\n#endif\nint main() { x++; }'
is_ios = it_cc.links(code, name: 'target is ios')
it_userconf.set10('IS_IOS', is_ios)
message('IS_IOS: @0@'.format(is_ios))
foreach item : [
['arc4random', '#include <stdlib.h>', []],
['arc4random_uniform', '#include <stdlib.h>', []],
['explicit_bzero', '#include <string.h>', []],
['explicit_memset', '#include <string.h>', []],
['clock_nanosleep', '#include <time.h>', []],
['clock_gettime', '#include <time.h>', [it_lrt]],
['sigaction', '#include <signal.h>', []],
['pipe', '#include <unistd.h>', []],
['execv', '#include <unistd.h>', []],
['execve', '#include <unistd.h>', []],
['execvp', '#include <unistd.h>', []],
['execl', '#include <unistd.h>', []],
['system', '#include <stdlib.h>', []],
['realpath', '#include <stdlib.h>', []],
['fork', '#include <unistd.h>', []],
['nice', '#include <unistd.h>', []],
['copyfile', '#include <copyfile.h>', []],
['strlcpy', '#include <string.h>', []],
['strlcat', '#include <string.h>', []],
['strnlen', '#include <string.h>', []],
['shm_open', '#include <sys/mman.h>', [it_lrt]],
['openpty', '', [it_utl]],
['forkpty', '', [it_utl]],
['login_tty', '', [it_utl]],
['pipe2', '#define _GNU_SOURCE\n#include <fcntl.h>\n#include <unistd.h>', []],
# copy_file_range for now disable on freebsd as it s not reliable even for small chunks
['copy_file_range', '#ifdef __linux__\n#define _GNU_SOURCE\n#include <unistd.h>\n#endif', []],
['backtrace', '', [it_lexecinfo]],
['__builtin_bswap16', '', []],
['__builtin_bswap32', '', []],
['__builtin_bswap64', '', []],
['__builtin_clzll', '', []],
['__builtin_ctzll', '', []],
['posix_memalign', '#include <stdlib.h>', []],
['_aligned_malloc', '#include <malloc.h>', []],
]
func = item[0]
ok = it_cc.has_function(func, prefix: item[1], dependencies: item[2])
it_userconf.set10('HAVE_@0@'.format(func.to_upper()), ok)
endforeach
foreach item : [
['linux/ashmem.h', '', []],
['sys/shm.h', '', []],
['sys/ipc.h', '', []],
['sys/mman.h', '', []],
['inttypes.h', '', []],
]
hdr = item[0]
ok = it_cc.has_header(hdr, prefix: item[1], dependencies: item[2])
it_userconf.set10('HAVE_HEADER_@0@'.format(hdr.underscorify().to_upper()), ok)
endforeach
if it_userconf.get('HAVE_PIPE2') == 1
add_project_arguments('-D_GNU_SOURCE', language: ['c', 'cpp'], native: it_native)
endif
userconfs += [[it_userconf, it_lrt, it_utl, it_ldl, it_mth, it_th]]
endforeach
userconf = userconfs[0][0]
lrt = userconfs[0][1]
utl = userconfs[0][2]
ldl = userconfs[0][3]
mth = userconfs[0][4]
th = userconfs[0][5]
if meson.is_cross_build()
userconf_native = userconfs[1][0]
lrt_native = userconfs[1][1]
utl_native = userconfs[1][2]
ldl_native = userconfs[1][3]
mth_native = userconfs[1][4]
th_native = userconfs[1][5]
endif
rz_userconf_h_in = files('librz/include/rz_userconf.h.in')
rz_userconf_h = configure_file(
input: rz_userconf_h_in,
output: 'rz_userconf.h',
configuration: userconf,
install_dir: rizin_incdir
)
packager = get_option('packager')
packager_version = get_option('packager_version')
message('Version Major: @0@0'.format(rizin_version_major))
message('Version Minor: @0@0'.format(rizin_version_minor))
message('Version Patch: @0@0'.format(rizin_version_patch))
versionconf = configuration_data()
versionconf.set('RZ_VERSION_MAJOR', rizin_version_major)
versionconf.set('RZ_VERSION_MINOR', rizin_version_minor)
versionconf.set('RZ_VERSION_PATCH', rizin_version_patch)
versionconf.set('RZ_VERSION_NUMBER', rizin_version_number)
versionconf.set('RZ_VERSION', rizin_version)
if packager_version != ''
versionconf.set_quoted('RZ_PACKAGER_VERSION', packager_version)
if packager != ''
versionconf.set_quoted('RZ_PACKAGER', packager)
endif
endif
rz_version_h = configure_file(
input: 'librz/include/rz_build_version.h.in',
output: 'rz_build_version.h',
configuration: versionconf,
install_dir: rizin_incdir
)
if git_exe.found() and fs.exists('.git')
gittip_file = custom_target('gittip_file',
build_always_stale: true,
build_by_default: true,
output: 'gittip',
command: [py3_exe, git_exe_repo_py, git_exe, repo, '@OUTPUT@', 'rev-parse', 'HEAD'],
install: true,
install_dir: rizin_datdir_rz
)
endif
# handle zlib dependency
zlib_dep = disabler()
if get_option('use_zlib')
r = run_command(py3_exe, check_meson_subproject_py, 'zlib', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
zlib_dep = dependency('zlib', required: get_option('use_sys_zlib'), static: is_static_build)
if not zlib_dep.found()
zlib_proj = subproject('zlib', default_options: ['default_library=static', 'werror=false'])
zlib_dep = zlib_proj.get_variable('zlib_dep')
meson.override_dependency('zlib', zlib_dep)
endif
endif
# handle lz4 dependency
r = run_command(py3_exe, check_meson_subproject_py, 'lz4', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
lz4_dep = dependency('liblz4', required: get_option('use_sys_lz4'), static: is_static_build)
if not lz4_dep.found()
lz4_proj = subproject('lz4', default_options: ['default_library=static'])
lz4_dep = lz4_proj.get_variable('lz4_dep')
endif
# handle lzma dependency
liblzma_dep = disabler()
if get_option('use_lzma')
r = run_command(py3_exe, check_meson_subproject_py, 'lzma', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
liblzma_dep = dependency('liblzma', required: get_option('use_sys_lzma'), static: is_static_build)
if not liblzma_dep.found()
liblzma_proj = subproject('liblzma', default_options: ['default_library=static'])
liblzma_dep = liblzma_proj.get_variable('lzma_dep')
meson.override_dependency('liblzma', liblzma_dep)
endif
endif
# handle softfloat dependency
r = run_command(py3_exe, check_meson_subproject_py, 'softfloat', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
softfloat_dep = dependency('softfloat', required: get_option('use_sys_softfloat'), static: is_static_build)
if not softfloat_dep.found()
softfloat_proj = subproject('softfloat', default_options: ['default_library=static'])
softfloat_dep = softfloat_proj.get_variable('softfloat_dep')
endif
if meson.is_cross_build()
softfloat_cross_native_proj = subproject('softfloat_cross_native', default_options: ['default_library=static', 'cross_native=true'])
softfloat_cross_native_dep = softfloat_cross_native_proj.get_variable('softfloat_dep')
endif
# handle zip dependency
r = run_command(py3_exe, check_meson_subproject_py, 'libzip', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
libzip_dep = dependency('libzip', required: get_option('use_sys_libzip'), static: is_static_build)
if not libzip_dep.found()
libzip_proj = subproject('libzip', default_options: [
'default_library=static',
'werror=false',
'static_runtime=@0@'.format(is_static_build),
'use_sys_openssl=@0@'.format(get_option('use_sys_libzip_openssl')),
])
libzip_dep = libzip_proj.get_variable('libzip_dep')
endif
# handle zstd dependency
r = run_command(py3_exe, check_meson_subproject_py, 'zstd', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
libzstd_dep = dependency('libzstd', required: get_option('use_sys_libzstd'), static: is_static_build, fallback: [])
if not libzstd_dep.found()
zstd_proj = subproject('zstd', default_options: [
'default_library=static',
'static_runtime=@0@'.format(is_static_build),
])
libzstd_dep = zstd_proj.get_variable('libzstd_dep')
meson.override_dependency('zstd', libzstd_dep)
endif
# handle mpc dependency
r = run_command(py3_exe, check_meson_subproject_py, 'mpc', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
mpc_proj = subproject('mpc', default_options: ['default_library=static'])
mpc_dep = mpc_proj.get_variable('mpc_dep')
# handle yxml dependency
r = run_command(py3_exe, check_meson_subproject_py, 'yxml', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
yxml_proj = subproject('yxml', default_options: ['default_library=static'])
yxml_dep = yxml_proj.get_variable('yxml_dep')
use_rpath = false
use_rpath_absolute = false
if host_machine.system() != 'windows' and get_option('default_library') == 'shared'
if get_option('local') == 'enabled'
use_rpath = true
elif get_option('local') == 'absolute'
use_rpath_absolute = true
elif get_option('local') == 'auto' and get_option('prefix') != '/usr'
if host_machine.system() == 'openbsd'
# OpenBSD's $ORIGIN only works in the way we would need it when running an
# executable by its actual path, but not when run through PATH.
# So let's use absolute rpaths there.
use_rpath_absolute = true
else
use_rpath = true
endif
endif
endif
rpath_exe = ''
rpath_lib = ''
rpath_summary = 'disabled'
if use_rpath
# Use bindir depth to create a path to the rootdir from bindir
py_cmd = 'import os; print("../" * @0@)'.format(bindir_depth.to_int())
py_cmd = run_command(py3_exe, '-c', py_cmd, check: true)
path_to_rootdir = py_cmd.stdout().strip()
rpath_exe = '$ORIGIN/' + path_to_rootdir + get_option('libdir')
rpath_lib = '$ORIGIN'
rpath_summary = 'relative'
elif use_rpath_absolute
rpath_exe = get_option('prefix') / get_option('libdir')
rpath_lib = get_option('prefix') / get_option('libdir')
rpath_summary = 'absolute'
endif
# NOTE: this is to workaround an issue on Windows where unit tests don't use
# the right libraries, resulting in tests not being run properly
test_env_common_path = []
build_root = meson.current_build_dir()
if host_machine.system() == 'windows'
test_env_common_path += [
build_root / 'librz' / 'arch',
build_root / 'librz' / 'bin',
build_root / 'librz' / 'config',
build_root / 'librz' / 'cons',
build_root / 'librz' / 'signature',
build_root / 'librz' / 'core',
build_root / 'librz' / 'demangler',
build_root / 'librz' / 'diff',
build_root / 'librz' / 'crypto',
build_root / 'librz' / 'debug',
build_root / 'librz' / 'egg',
build_root / 'librz' / 'flag',
build_root / 'librz' / 'mark',
build_root / 'librz' / 'hash',
build_root / 'librz' / 'io',
build_root / 'librz' / 'lang',
build_root / 'librz' / 'magic',
build_root / 'librz' / 'main',
build_root / 'librz' / 'parse',
build_root / 'librz' / 'reg',
build_root / 'librz' / 'search',
build_root / 'librz' / 'socket',
build_root / 'librz' / 'syscall',
build_root / 'librz' / 'type',
build_root / 'librz' / 'util',
]
endif
subdir('librz')
if get_option('install_sigdb')
r = run_command(py3_exe, check_meson_subproject_py, 'sigdb', check: false)
if r.returncode() == 1 and get_option('subprojects_check')
error(subproject_clean_error_msg)
endif
subproject('sigdb', default_options: ['sigdb_path=@0@'.format(get_option('prefix') / rizin_sigdb)])
endif
cli_option = get_option('cli')
cli_enabled = cli_option.auto() ? not meson.is_subproject() : cli_option.enabled()
if cli_enabled
subdir('binrz')
install_data('doc/hud',
install_dir: rizin_hud,
rename: 'main'
)
endif
subdir('test')
subdir('examples')
install_data(
'doc/fortunes.fun',
'doc/fortunes.tips',
install_dir: rizin_fortunes
)
dist_script = 'sys/meson_dist_script.py'
if meson.version().version_compare('>=0.49.0') and meson.version().version_compare('<0.57.0')
meson.add_dist_script(meson.source_root() / dist_script)
else
meson.add_dist_script(files(dist_script))
endif
summary({
'prefix': rizin_prefix,
'bindir': rizin_bindir,
'libdir': rizin_libdir,
'includedir': rizin_incdir,
'datadir': rizin_datdir,
'wwwroot': rizin_wwwroot,
'sdb': rizin_sdb,
'sigdb': rizin_sigdb,
'themes': rizin_themes,
'fortunes': rizin_fortunes,
'flags': rizin_flags,
'hud': rizin_hud,
'plugins': rizin_plugins,
'bindings': rizin_bindings,
}, section: 'Directories')
summary({
'GPL code': get_option('use_gpl'),
'Install sigdb': get_option('install_sigdb'),
'Debugger enabled': has_debugger,
'Capstone version': capstone_dep.version(),
'PCRE2 version': pcre2_dep.version(),
'PCRE2 JIT': pcre2_jit_supported,
'System magic library': sys_magic.found() and sys_magic.type_name() != 'internal',
'System pcre2 library': pcre2_dep.found() and sys_pcre2_found,
'System xxhash library': xxhash_dep.found() and xxhash_dep.type_name() != 'internal',
'System libmspack library': libmspack_dep.found() and libmspack_dep.type_name() != 'internal',
'System openssl library': sys_openssl.found() and sys_openssl.type_name() != 'internal',
'System capstone library': capstone_dep.found() and capstone_dep.type_name() != 'internal',
'System zydis library': zydis_dep.found() and zydis_dep.type_name() != 'internal',
'System tree-sitter library': tree_sitter_dep.found() and tree_sitter_dep.type_name() != 'internal',
'System lz4 library': lz4_dep.found() and lz4_dep.type_name() != 'internal',
'System lzma library': liblzma_dep.found() and liblzma_dep.type_name() != 'internal',
'System softfloat library': softfloat_dep.found() and softfloat_dep.type_name() != 'internal',
'System zlib library': zlib_dep.found() and zlib_dep.type_name() != 'internal',
'System zstd library': libzstd_dep.found() and libzstd_dep.type_name() != 'internal',
'System zip library': libzip_dep.found() and libzip_dep.type_name() != 'internal',
'System blake3 library': blake3_dep.found() and blake3_dep.type_name() != 'internal',
'Use ptrace-wrap': use_ptrace_wrap,
'Use RPATH': rpath_summary,
}, section: 'Configuration', bool_yn: true)
# output will be slightly degraded if there's only 1 crca_crc hash plugin and/or last hash plugin is a crca_crc plugin
comb_hash_plugins = []
in_crca_loop = false
foreach plugin : hash_plugins.get('list')
if plugin.startswith('crca_crc')
comb_hash_plugins += (in_crca_loop ? '' : 'crca_crc(') + plugin.split('_')[1].split('crc')[1]
in_crca_loop = true
else
if in_crca_loop
# add closing parenthesis to last crca_cec plugin
parenthesized_last = []
foreach item : comb_hash_plugins
if item not in [comb_hash_plugins[-1]]
parenthesized_last += item
endif
endforeach
parenthesized_last += comb_hash_plugins[-1] + ')'
comb_hash_plugins = parenthesized_last
endif
comb_hash_plugins += plugin
in_crca_loop = false
endif
endforeach
summary({
'Arch Plugins': arch_plugins.get('list'),
'Binary Plugins': bin_plugins.get('list'),
'BinXtr Plugins': bin_xtr_plugins.get('list'),
'Core Plugins': core_plugins.get('list'),
'Crypto Plugins': crypto_plugins.get('list'),
'Debug Plugins': debug_plugins.get('list'),
'Egg Plugins': egg_plugins.get('list'),
'IO Plugins': io_plugins.get('list'),
'Lang Plugins': lang_plugins.get('list'),
'Hash Plugins': comb_hash_plugins,
'Demangler Plugins': demangler_plugins.get('list'),
}, section: 'Plugins', list_sep: ', ')