Skip to content

Commit

Permalink
Document the nix-util Meson build system more extensively
Browse files Browse the repository at this point in the history
I hope this will make it easier to maintain, and also make it easier for
others to assist with porting the rest of the build system to Meson.
  • Loading branch information
Ericson2314 committed Jun 13, 2024
1 parent 8684e8b commit d3d6e3f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 12 deletions.
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
changelog-d;
default = self.packages.${system}.nix;
} // lib.concatMapAttrs
# We need to "flatten" packages we care about to pass `flake check`.
(pkgName: {}: {
"${pkgName}" = nixpkgsFor.${system}.native.${pkgName};
"${pkgName}-static" = nixpkgsFor.${system}.static.${pkgName};
Expand Down
50 changes: 42 additions & 8 deletions src/libutil/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,44 @@ project('nix-util', 'cpp',

cxx = meson.get_compiler('cpp')

# These are private dependencies with pkg-config files. What private
# means is that the dependencies are used by the library but they are
# *not* used (e.g. `#include`-ed) in any installed header file, and only
# in regular source code (`*.cc`) or private, uninstalled headers. They
# are thus part of the *implementation* of the library, but not its
# *interface*.
#
# See `man pkg-config` for some details.
deps_private = [ ]

# These are public dependencies with pkg-config files. Public is the
# opposite of private: these dependencies are used in installed header
# files. They are part of the interface (and implementation) of the
# library.
deps_public = [ ]

# These are dependencencies without pkg-config files. Ideally they are
# just private, but they may also be public (e.g. boost).
deps_other = [ ]

configdata = configuration_data()

# Check for each of these functions, and create a define like `#define HAVE_LUTIMES 1`.
# Check for each of these functions, and create a define like `#define
# HAVE_LUTIMES 1`. The `#define` is unconditional, 0 for not found and 1
# for found. One therefore uses it with `#if` not `#ifdef`.
check_funcs = [
# Optionally used for changing the mtime of symlinks.
# Optionally used for changing the mtime of symlinks.
'lutimes',
# Optionally used for creating pipes on Unix
'pipe2',
# Optionally used to preallocate files to be large enough before
# writing to them.
'posix_fallocate',
# Optionally used to get more information about processes failing due
# to a signal on Unix.
'strsignal',
# Optionally used to try to close more file descriptors (e.g. before
# forking) on Unix.
'sysconf',
]
foreach funcspec : check_funcs
Expand All @@ -35,8 +60,10 @@ foreach funcspec : check_funcs
configdata.set(define_name, define_value)
endforeach

# Conditional to work around https://github.com/mesonbuild/meson/issues/13293
if host_machine.system() != 'windows' and cxx.get_id() == 'gcc'
# This is only conditional to work around
# https://github.com/mesonbuild/meson/issues/13293. It should be
# unconditional.
if not (host_machine.system() == 'windows' and cxx.get_id() == 'gcc')
deps_private += dependency('threads')
endif

Expand All @@ -53,7 +80,8 @@ boost = dependency(
'boost',
modules : ['context', 'coroutine'],
)
# Actually public, but wrong type of dep for pkg config
# This is public, but not a pkg-config dependency unfortunately, so we
# put in `deps_other`.
deps_other += boost

openssl = dependency(
Expand All @@ -80,8 +108,10 @@ brotli = [
]
deps_private += brotli

# cpuid only makes sense on x86_64
cpuid_required = host_machine.cpu_family() == 'x86_64' ? get_option('cpuid') : false
cpuid_required = get_option('cpuid')
if host_machine.cpu_family() != 'x86_64' and cpuid_required.enabled()
warning('Force-enabling seccomp on non-x86_64 does not make sense')
endif
cpuid = dependency('libcpuid', 'cpuid', required : cpuid_required)
configdata.set('HAVE_LIBCPUID', cpuid.found().to_int())
deps_private += cpuid
Expand Down Expand Up @@ -259,6 +289,11 @@ libutil = library(

install_headers(headers, subdir : 'nix', preserve_path : true)

# Part of how we copy boost libraries to a separate installation to
# reduce closure size. These libraries will be copied to our `$out/bin`,
# and these `-l` flags will pick them up there.
#
# https://github.com/NixOS/nixpkgs/issues/45462
libraries_private = ['-lboost_context', '-lboost_coroutine']
if host_machine.system() == 'windows'
# `libraries_private` cannot contain ad-hoc dependencies (from
Expand All @@ -275,7 +310,6 @@ import('pkgconfig').generate(
extra_cflags : ['-std=c++2a'],
requires : deps_public,
requires_private : deps_private,
# avoid absolute paths, use vendored ones
libraries_private : libraries_private,
)

Expand Down
9 changes: 5 additions & 4 deletions src/libutil/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,8 @@ mkDerivation (finalAttrs: {
''
echo ${version} > .version
''
# Copy libboost_context so we don't get all of Boost in our closure.

# https://github.com/NixOS/nixpkgs/issues/45462
# Copy some boost libraries so we don't get all of Boost in our
# closure. https://github.com/NixOS/nixpkgs/issues/45462
+ lib.optionalString (!stdenv.hostPlatform.isStatic) (''
mkdir -p $out/lib
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
Expand Down Expand Up @@ -115,7 +114,9 @@ mkDerivation (finalAttrs: {
enableParallelBuilding = true;

postInstall =
# Remove absolute path to boost libs
# Remove absolute path to boost libs that ends up in `Libs.private`
# by default, and would clash with out `disallowedReferences`. Part
# of the https://github.com/NixOS/nixpkgs/issues/45462 workaround.
''
sed -i "$out/lib/pkgconfig/nix-util.pc" -e 's, ${lib.getLib boost}[^ ]*,,g'
''
Expand Down
2 changes: 2 additions & 0 deletions src/libutil/unix/file-descriptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ void unix::closeMostFDs(const std::set<int> & exceptions)
#endif

int maxFD = 0;
#if HAVE_SYSCONF
maxFD = sysconf(_SC_OPEN_MAX);
#endif
for (int fd = 0; fd < maxFD; ++fd)
if (!exceptions.count(fd))
close(fd); /* ignore result */
Expand Down

0 comments on commit d3d6e3f

Please sign in to comment.