forked from lix-project/lix
295 lines
8.4 KiB
Meson
295 lines
8.4 KiB
Meson
|
#
|
||
|
# OUTLINE:
|
||
|
#
|
||
|
# The top-level meson.build file (this file) handles general logic for build options,
|
||
|
# generation of config.h (which is put in the build directory, not the source root
|
||
|
# like the previous, autoconf-based build system did), the mechanism for header
|
||
|
# generation, and the few global C++ compiler arguments that are added to all targets in Lix.
|
||
|
#
|
||
|
# src/meson.build coordinates each of Lix's subcomponents (the lib dirs in ./src),
|
||
|
# which each have their own meson.build. Lix's components depend on each other,
|
||
|
# so each of `src/lib{util,store,fetchers,expr,main,cmd}/meson.build` rely on variables
|
||
|
# set in earlier `meson.build` files. Each of these also defines the install targets for
|
||
|
# their headers.
|
||
|
#
|
||
|
# src/meson.build also collects the miscellaneous source files that are in further subdirectories
|
||
|
# that become part of the final Nix command (things like `src/nix-build/*.cc`).
|
||
|
#
|
||
|
# Finally, src/nix/meson.build defines the Nix command itself, relying on all prior meson files.
|
||
|
|
||
|
project('lix', 'cpp',
|
||
|
version : run_command('bash', '-c', 'echo -n $(cat ./.version)$VERSION_SUFFIX', check : true).stdout().strip(),
|
||
|
default_options : [
|
||
|
'cpp_std=c++20',
|
||
|
# TODO(Qyriad): increase the warning level
|
||
|
'warning_level=1',
|
||
|
'debug=true',
|
||
|
'optimization=2',
|
||
|
],
|
||
|
)
|
||
|
|
||
|
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, state-dir, and log-dir).
|
||
|
path_opts = [
|
||
|
# Meson built-ins.
|
||
|
'datadir',
|
||
|
'sysconfdir',
|
||
|
'bindir',
|
||
|
'mandir',
|
||
|
'libdir',
|
||
|
'includedir',
|
||
|
# Homecooked Lix directories.
|
||
|
'store-dir',
|
||
|
'state-dir',
|
||
|
'log-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
|
||
|
|
||
|
cxx = meson.get_compiler('cpp')
|
||
|
|
||
|
host_system = host_machine.cpu_family() + '-' + host_machine.system()
|
||
|
message('canonical Nix system name:', host_system)
|
||
|
|
||
|
deps = [ ]
|
||
|
configdata = { }
|
||
|
|
||
|
#
|
||
|
# Dependencies
|
||
|
#
|
||
|
|
||
|
boehm = dependency('bdw-gc', required : get_option('gc'))
|
||
|
if boehm.found()
|
||
|
deps += boehm
|
||
|
endif
|
||
|
configdata += {
|
||
|
'HAVE_BOEHMGC': boehm.found().to_int(),
|
||
|
}
|
||
|
|
||
|
boost = dependency('boost', required : true, modules : ['context', 'coroutine', 'container'])
|
||
|
deps += boost
|
||
|
|
||
|
cpuid = dependency('libcpuid', 'cpuid', required : get_option('cpuid'))
|
||
|
configdata += {
|
||
|
'HAVE_LIBCPUID': cpuid.found().to_int(),
|
||
|
}
|
||
|
deps += cpuid
|
||
|
|
||
|
seccomp = dependency('libseccomp', 'seccomp', required : get_option('seccomp-sandboxing'))
|
||
|
configdata += {
|
||
|
'HAVE_SECCOMP': seccomp.found().to_int(),
|
||
|
}
|
||
|
|
||
|
libarchive = dependency('libarchive', required : true)
|
||
|
deps += libarchive
|
||
|
|
||
|
brotli = [
|
||
|
dependency('libbrotlicommon', required : true),
|
||
|
dependency('libbrotlidec', required : true),
|
||
|
dependency('libbrotlienc', required : true),
|
||
|
]
|
||
|
deps += brotli
|
||
|
|
||
|
openssl = dependency('libcrypto', 'openssl', required : true)
|
||
|
deps += openssl
|
||
|
|
||
|
aws_sdk = dependency('aws-cpp-sdk-core', required : true)
|
||
|
if aws_sdk.found()
|
||
|
# The AWS pkg-config adds -std=c++11.
|
||
|
aws_sdk = aws_sdk.partial_dependency(
|
||
|
compile_args : false,
|
||
|
includes : true,
|
||
|
link_args : true,
|
||
|
links : true,
|
||
|
sources : true,
|
||
|
)
|
||
|
deps += aws_sdk
|
||
|
s = aws_sdk.version().split('.')
|
||
|
configdata += {
|
||
|
'AWS_VERSION_MAJOR': s[0].to_int(),
|
||
|
'AWS_VERSION_MINOR': s[1].to_int(),
|
||
|
'AWS_VERSION_PATCH': s[2].to_int(),
|
||
|
}
|
||
|
aws_sdk_transfer = dependency('aws-cpp-sdk-transfer', required : true).partial_dependency(
|
||
|
compile_args : false,
|
||
|
includes : true,
|
||
|
link_args : true,
|
||
|
links : true,
|
||
|
sources : true,
|
||
|
)
|
||
|
endif
|
||
|
|
||
|
aws_s3 = dependency('aws-cpp-sdk-s3', required : true)
|
||
|
if aws_s3.found()
|
||
|
# The AWS pkg-config adds -std=c++11.
|
||
|
aws_s3 = aws_s3.partial_dependency(
|
||
|
compile_args : false,
|
||
|
includes : true,
|
||
|
link_args : true,
|
||
|
links : true,
|
||
|
sources : true,
|
||
|
)
|
||
|
deps += aws_s3
|
||
|
endif
|
||
|
|
||
|
configdata += {
|
||
|
'ENABLE_S3': aws_s3.found().to_int(),
|
||
|
}
|
||
|
|
||
|
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19', required : true)
|
||
|
deps += sqlite
|
||
|
|
||
|
sodium = dependency('libsodium', 'sodium', required : true)
|
||
|
deps += sodium
|
||
|
|
||
|
curl = dependency('libcurl', 'curl', required : true)
|
||
|
deps += curl
|
||
|
|
||
|
editline = dependency('libeditline', 'editline', version : '>=1.14', required : true)
|
||
|
deps += editline
|
||
|
|
||
|
lowdown = dependency('lowdown', version : '>=0.9.0', required : true)
|
||
|
deps += lowdown
|
||
|
|
||
|
rapidcheck = dependency('rapidcheck', required : false)
|
||
|
deps += rapidcheck
|
||
|
|
||
|
gtest = dependency('gtest', required : false)
|
||
|
deps += gtest
|
||
|
|
||
|
#
|
||
|
# Build-time tools
|
||
|
#
|
||
|
bash = find_program('bash')
|
||
|
|
||
|
# Used to workaround https://github.com/mesonbuild/meson/issues/2320 in src/nix/meson.build.
|
||
|
installcmd = find_program('install')
|
||
|
|
||
|
sandbox_shell = get_option('sandbox-shell')
|
||
|
# Consider it required if we're on Linux and the user explicitly specified a non-default value.
|
||
|
sandbox_shell_required = sandbox_shell != 'busybox' and host_machine.system() == 'linux'
|
||
|
# NOTE(Qyriad): package.nix puts busybox in buildInputs for Linux.
|
||
|
# Most builds should not require setting this.
|
||
|
busybox = find_program(sandbox_shell, required : sandbox_shell_required, native : false)
|
||
|
if not busybox.found() and host_machine.system() == 'linux' and sandbox_shell_required
|
||
|
warning('busybox not found and other sandbox shell was specified')
|
||
|
warning('a sandbox shell is recommended on Linux -- configure with -Dsandbox-shell=/path/to/shell to set')
|
||
|
endif
|
||
|
# FIXME(Qyriad): the autoconf system checks that busybox has the "standalone" feature, indicating
|
||
|
# that busybox sh won't run busybox applets as builtins (which would break our sandbox).
|
||
|
|
||
|
lsof = find_program('lsof')
|
||
|
bison = find_program('bison')
|
||
|
flex = find_program('flex')
|
||
|
|
||
|
# This is how Nix does generated headers...
|
||
|
# FIXME(Qyriad): do we really need to use the shell for this?
|
||
|
gen_header = generator(
|
||
|
bash,
|
||
|
arguments : [
|
||
|
'-c',
|
||
|
'echo \'R"__NIX_STR(\' | cat - @INPUT@ && echo \')__NIX_STR"\'',
|
||
|
],
|
||
|
capture : true,
|
||
|
output : '@PLAINNAME@.gen.hh',
|
||
|
)
|
||
|
|
||
|
#
|
||
|
# Configuration
|
||
|
#
|
||
|
|
||
|
run_command('ln', '-s',
|
||
|
meson.project_build_root() / '__nothing_link_target',
|
||
|
meson.project_build_root() / '__nothing_symlink',
|
||
|
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 += { '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 = [
|
||
|
'lchown',
|
||
|
'lutimes',
|
||
|
'pipe2',
|
||
|
'posix_fallocate',
|
||
|
'statvfs',
|
||
|
'strsignal',
|
||
|
'sysconf',
|
||
|
]
|
||
|
foreach funcspec : check_funcs
|
||
|
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
|
||
|
define_value = cxx.has_function(funcspec).to_int()
|
||
|
configdata += {
|
||
|
define_name: define_value,
|
||
|
}
|
||
|
endforeach
|
||
|
|
||
|
# extern "C++" functions can't be checked with the normal mechanism (much less member functions),
|
||
|
# so we have to do this one ourselves.
|
||
|
has_pubsetbuf = cxx.compiles('''
|
||
|
#include <iostream>
|
||
|
using namespace std;
|
||
|
static char buf[1024];
|
||
|
decltype(cerr.rdbuf()->pubsetbuf(buf, sizeof(buf))) _;
|
||
|
''')
|
||
|
summary('have std::basic_streambuf::pubsetbuf', has_pubsetbuf, bool_yn : true)
|
||
|
configdata += {
|
||
|
'HAVE_PUBSETBUF': has_pubsetbuf.to_int(),
|
||
|
}
|
||
|
|
||
|
config_h = configure_file(
|
||
|
configuration : {
|
||
|
'PACKAGE_NAME': '"' + meson.project_name() + '"',
|
||
|
'PACKAGE_VERSION': '"' + meson.project_version() + '"',
|
||
|
'PACKAGE_TARNAME': '"' + meson.project_name() + '"',
|
||
|
'PACKAGE_STRING': '"' + meson.project_name() + ' ' + meson.project_version() + '"',
|
||
|
'HAVE_STRUCT_DIRENT_D_TYPE': 1, # FIXME: actually check this for solaris
|
||
|
'SYSTEM': '"' + host_system + '"',
|
||
|
} + configdata,
|
||
|
output : 'config.h',
|
||
|
)
|
||
|
|
||
|
install_headers(config_h, subdir : 'nix')
|
||
|
|
||
|
add_project_arguments(
|
||
|
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||
|
# It would be nice for our headers to be idempotent instead.
|
||
|
'-include', 'config.h',
|
||
|
'-Wno-deprecated-declarations',
|
||
|
'-Wimplicit-fallthrough',
|
||
|
'-Werror=switch',
|
||
|
'-Werror=switch-enum',
|
||
|
language : 'cpp',
|
||
|
)
|
||
|
|
||
|
add_project_link_arguments(
|
||
|
'-pthread',
|
||
|
# FIXME(Qyriad): autoconf did this only if not Darwin, Solaris, or FreeBSD
|
||
|
# (...so only if Linux?)
|
||
|
'-Wl,--no-copy-dt-needed-entries',
|
||
|
language : 'cpp',
|
||
|
)
|
||
|
|
||
|
subdir('src')
|