project( 'nix-store', 'cpp', version : files('.version'), default_options : [ 'cpp_std=c++23', # TODO(Qyriad): increase the warning level 'warning_level=1', 'errorlogs=true', # Please print logs for tests that fail 'localstatedir=/nix/var', ], meson_version : '>= 1.1', license : 'LGPL-2.1-or-later', ) cxx = meson.get_compiler('cpp') subdir('nix-meson-build-support/deps-lists') configdata_pub = configuration_data() configdata_priv = configuration_data() # TODO rename, because it will conflict with downstream projects configdata_priv.set_quoted('PACKAGE_VERSION', meson.project_version()) subdir('nix-meson-build-support/default-system-cpu') # Used in public header. configdata_pub.set_quoted( 'NIX_LOCAL_SYSTEM', nix_system_cpu + '-' + host_machine.system(), description : 'This is the system name Nix expects for local running instance of Nix.\n\n' + 'See the "system" setting for additional details', ) deps_private_maybe_subproject = [] deps_public_maybe_subproject = [ dependency('nix-util'), ] subdir('nix-meson-build-support/subprojects') run_command( 'ln', '-s', meson.project_build_root() / '__nothing_link_target', meson.project_build_root() / '__nothing_symlink', # native doesn't allow dangling symlinks, which the tests require env : {'MSYS' : 'winsymlinks:lnk'}, check : true, ) can_link_symlink = run_command( 'ln', meson.project_build_root() / '__nothing_symlink', meson.project_build_root() / '__nothing_hardlink', check : false, ).returncode() == 0 run_command( 'rm', '-f', meson.project_build_root() / '__nothing_symlink', meson.project_build_root() / '__nothing_hardlink', check : true, ) summary('can hardlink to symlink', can_link_symlink, bool_yn : true) configdata_priv.set('CAN_LINK_SYMLINK', can_link_symlink.to_int()) # Check for each of these functions, and create a define like `#define HAVE_LCHOWN 1`. check_funcs = [ # Optionally used for canonicalising files from the build 'lchown', 'posix_fallocate', 'statvfs', ] foreach funcspec : check_funcs define_name = 'HAVE_' + funcspec.underscorify().to_upper() define_value = cxx.has_function(funcspec).to_int() configdata_priv.set(define_name, define_value) endforeach has_acl_support = cxx.has_header('sys/xattr.h') \ and cxx.has_function('llistxattr') \ and cxx.has_function('lremovexattr') # Used in public header. Affects ABI! configdata_pub.set( 'NIX_SUPPORT_ACL', has_acl_support.to_int(), description : 'FIXME: It\'s a bit peculiar that this needs to be exposed. The reason is that that it effects whether the settings struct in a header has a particular field. This is also odd, because it means when there is no ACL support one will just get an "unknown setting" warning from their configuration.', ) if host_machine.system() == 'darwin' sandbox = cxx.find_library('sandbox') deps_other += [ sandbox ] endif if host_machine.system() == 'windows' wsock32 = cxx.find_library('wsock32') deps_other += [ wsock32 ] endif subdir('nix-meson-build-support/libatomic') boost = dependency( 'boost', modules : [ 'container', # Shouldn't list, because can header-only, and Meson currently looks for libs #'regex', 'url', ], include_type : 'system', ) # boost is a public dependency, but not a pkg-config dependency unfortunately, so we # put in `deps_other`. deps_other += boost curl = dependency('libcurl', 'curl') deps_private += curl # seccomp only makes sense on Linux is_linux = host_machine.system() == 'linux' seccomp_required = get_option('seccomp-sandboxing') if not is_linux and seccomp_required.enabled() warning('Force-enabling seccomp on non-Linux does not make sense') endif seccomp = dependency( 'libseccomp', 'seccomp', required : seccomp_required, version : '>=2.5.5', ) if is_linux and not seccomp.found() warning( 'Sandbox security is reduced because libseccomp has not been found! Please provide libseccomp if it supports your CPU architecture.', ) endif configdata_priv.set('HAVE_SECCOMP', seccomp.found().to_int()) deps_private += seccomp nlohmann_json = dependency('nlohmann_json', version : '>= 3.9') deps_public += nlohmann_json sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19') deps_private += sqlite # AWS C++ SDK has bad pkg-config. See # https://github.com/aws/aws-sdk-cpp/issues/2673 for details. aws_s3 = dependency('aws-cpp-sdk-s3', required : false) # The S3 store definitions in the header will be hidden based on this variables. configdata_pub.set('NIX_WITH_S3_SUPPORT', aws_s3.found().to_int()) if aws_s3.found() aws_s3 = declare_dependency( include_directories : include_directories(aws_s3.get_variable('includedir')), link_args : [ '-L' + aws_s3.get_variable('libdir'), '-laws-cpp-sdk-transfer', '-laws-cpp-sdk-s3', '-laws-cpp-sdk-identity-management', '-laws-cpp-sdk-cognito-identity', '-laws-cpp-sdk-sts', '-laws-cpp-sdk-core', '-laws-crt-cpp', ], ).as_system('system') endif deps_other += aws_s3 subdir('nix-meson-build-support/generate-header') generated_headers = [] foreach header : [ 'schema.sql', 'ca-specific-schema.sql', ] generated_headers += gen_header.process(header) endforeach busybox = find_program(get_option('sandbox-shell'), required : false) configdata_priv.set( 'HAVE_EMBEDDED_SANDBOX_SHELL', get_option('embedded-sandbox-shell').to_int(), ) if get_option('embedded-sandbox-shell') configdata_priv.set_quoted('SANDBOX_SHELL', '__embedded_sandbox_shell__') elif busybox.found() configdata_priv.set_quoted('SANDBOX_SHELL', busybox.full_path()) endif if get_option('embedded-sandbox-shell') hexdump = find_program('hexdump', native : true) embedded_sandbox_shell_gen = custom_target( 'embedded-sandbox-shell.gen.hh', command : [ hexdump, '-v', '-e', '1/1 "0x%x," "\n"' ], input : busybox.full_path(), output : 'embedded-sandbox-shell.gen.hh', capture : true, feed : true, ) generated_headers += embedded_sandbox_shell_gen endif fs = import('fs') prefix = get_option('prefix') # For each of these paths, assume that it is relative to the prefix unless # it is already an absolute path (which is the default for store-dir, localstatedir, and log-dir). path_opts = [ # Meson built-ins. 'datadir', 'mandir', 'libdir', 'includedir', 'libexecdir', # Homecooked Nix directories. 'store-dir', 'localstatedir', 'log-dir', ] # For your grepping pleasure, this loop sets the following variables that aren't mentioned # literally above: # store_dir # localstatedir # log_dir # profile_dir foreach optname : path_opts varname = optname.replace('-', '_') path = get_option(optname) if fs.is_absolute(path) set_variable(varname, path) else set_variable(varname, prefix / path) endif endforeach # sysconfdir doesn't get anything installed to directly, and is only used to # tell Nix where to look for nix.conf, so it doesn't get appended to prefix. sysconfdir = get_option('sysconfdir') if not fs.is_absolute(sysconfdir) sysconfdir = '/' / sysconfdir endif # Aside from prefix itself, each of these was made into an absolute path # by joining it with prefix, unless it was already an absolute path # (which is the default for store-dir, localstatedir, and log-dir). configdata_priv.set_quoted('NIX_PREFIX', prefix) configdata_priv.set_quoted('NIX_STORE_DIR', store_dir) configdata_priv.set_quoted('NIX_DATA_DIR', datadir) configdata_priv.set_quoted('NIX_STATE_DIR', localstatedir / 'nix') configdata_priv.set_quoted('NIX_LOG_DIR', log_dir) configdata_priv.set_quoted('NIX_CONF_DIR', sysconfdir / 'nix') configdata_priv.set_quoted('NIX_MAN_DIR', mandir) lsof = find_program('lsof', required : false) configdata_priv.set_quoted( 'LSOF', lsof.found() ? lsof.full_path() # Just look up on the PATH : 'lsof', ) config_priv_h = configure_file( configuration : configdata_priv, output : 'store-config-private.hh', ) subdir('nix-meson-build-support/common') sources = files( 'binary-cache-store.cc', 'build-result.cc', 'build/derivation-building-goal.cc', 'build/derivation-check.cc', 'build/derivation-env-desugar.cc', 'build/derivation-goal.cc', 'build/derivation-trampoline-goal.cc', 'build/drv-output-substitution-goal.cc', 'build/entry-points.cc', 'build/goal.cc', 'build/substitution-goal.cc', 'build/worker.cc', 'builtins/buildenv.cc', 'builtins/fetchurl.cc', 'builtins/unpack-channel.cc', 'common-protocol.cc', 'common-ssh-store-config.cc', 'content-address.cc', 'daemon.cc', 'derivation-options.cc', 'derivations.cc', 'derived-path-map.cc', 'derived-path.cc', 'downstream-placeholder.cc', 'dummy-store.cc', 'export-import.cc', 'filetransfer.cc', 'gc.cc', 'globals.cc', 'http-binary-cache-store.cc', 'indirect-root-store.cc', 'keys.cc', 'legacy-ssh-store.cc', 'local-binary-cache-store.cc', 'local-fs-store.cc', 'local-overlay-store.cc', 'local-store.cc', 'log-store.cc', 'machines.cc', 'make-content-addressed.cc', 'misc.cc', 'names.cc', 'nar-accessor.cc', 'nar-info-disk-cache.cc', 'nar-info.cc', 'optimise-store.cc', 'outputs-spec.cc', 'parsed-derivations.cc', 'path-info.cc', 'path-references.cc', 'path-with-outputs.cc', 'path.cc', 'pathlocks.cc', 'posix-fs-canonicalise.cc', 'profiles.cc', 'realisation.cc', 'references.cc', 'remote-fs-accessor.cc', 'remote-store.cc', 'restricted-store.cc', 's3-binary-cache-store.cc', 's3.cc', 'serve-protocol-connection.cc', 'serve-protocol.cc', 'sqlite.cc', 'ssh-store.cc', 'ssh.cc', 'store-api.cc', 'store-dir-config.cc', 'store-reference.cc', 'store-registration.cc', 'uds-remote-store.cc', 'worker-protocol-connection.cc', 'worker-protocol.cc', ) subdir('include/nix/store') if host_machine.system() == 'linux' subdir('linux') endif if host_machine.system() == 'windows' subdir('windows') else subdir('unix') endif subdir('nix-meson-build-support/export-all-symbols') subdir('nix-meson-build-support/windows-version') this_library = library( 'nixstore', generated_headers, sources, config_priv_h, soversion : nix_soversion, dependencies : deps_public + deps_private + deps_other, include_directories : include_dirs, link_args : linker_export_flags, prelink : true, # For C++ static initializers install : true, cpp_pch : do_pch ? [ 'pch/precompiled-headers.hh' ] : [], ) install_headers(headers, subdir : 'nix/store', preserve_path : true) libraries_private = [] extra_pkg_config_variables = { 'storedir' : get_option('store-dir'), } # Working around https://github.com/mesonbuild/meson/issues/13584 if host_machine.system() != 'darwin' extra_pkg_config_variables += { 'localstatedir' : get_option('localstatedir'), } endif subdir('nix-meson-build-support/export')