Merge pull request #10973 from NixOS/meson-libexpr

Meson build for libexpr libflake, external C API, unit tests
This commit is contained in:
Robert Hensing 2024-07-05 20:27:12 +02:00 committed by GitHub
commit ddff76f667
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
101 changed files with 2446 additions and 810 deletions

View file

@ -0,0 +1,36 @@
# 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.
#
# N.B. This concept is mostly unrelated to our own concept of a public
# (stable) API, for consumption outside of the Nix repository.
# `libnixutil` is an unstable C++ library, whose public interface is
# likewise unstable. `libutilc` conversely is a hopefully-soon stable
# C library, whose public interface --- including public but not private
# dependencies --- will also likewise soon be stable.
#
# N.B. For distributions that care about "ABI" stability and not just
# "API" stability, the private dependencies also matter as they can
# potentially affect the public ABI.
deps_public = [ ]
# These are subproject deps (type == "internal"). They are other
# packages in `/src` in this repo. The private vs public distinction is
# the same as above.
deps_private_subproject = [ ]
deps_public_subproject = [ ]
# These are dependencencies without pkg-config files. Ideally they are
# just private, but they may also be public (e.g. boost).
deps_other = [ ]

View file

@ -0,0 +1,13 @@
add_project_arguments(
'-Wno-deprecated-declarations',
'-Wimplicit-fallthrough',
'-Werror=switch',
'-Werror=switch-enum',
'-Werror=unused-result',
'-Wdeprecated-copy',
'-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
# at ~1% overhead in `nix search`.
#
language : 'cpp',
)

View file

@ -0,0 +1,11 @@
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
# Windows DLLs are stricter about symbol visibility than Unix shared
# objects --- see https://gcc.gnu.org/wiki/Visibility for details.
# This is a temporary sledgehammer to export everything like on Unix,
# and not detail with this yet.
#
# TODO do not do this, and instead do fine-grained export annotations.
linker_export_flags = ['-Wl,--export-all-symbols']
else
linker_export_flags = []
endif

View file

@ -0,0 +1,30 @@
requires_private = []
foreach dep : deps_private_subproject
requires_private += dep.name()
endforeach
requires_private += deps_private
requires_public = []
foreach dep : deps_public_subproject
requires_public += dep.name()
endforeach
requires_public += deps_public
import('pkgconfig').generate(
this_library,
filebase : meson.project_name(),
name : 'Nix',
description : 'Nix Package Manager',
subdirs : ['nix'],
extra_cflags : ['-std=c++2a'],
requires : requires_public,
requires_private : requires_private,
libraries_private : libraries_private,
)
meson.override_dependency(meson.project_name(), declare_dependency(
include_directories : include_dirs,
link_with : this_library,
compile_args : ['-std=c++2a'],
dependencies : deps_public_subproject + deps_public,
))

View file

@ -0,0 +1,19 @@
foreach maybe_subproject_dep : deps_private_maybe_subproject
if maybe_subproject_dep.type_name() == 'internal'
deps_private_subproject += maybe_subproject_dep
# subproject sadly no good for pkg-config module
deps_other += maybe_subproject_dep
else
deps_private += maybe_subproject_dep
endif
endforeach
foreach maybe_subproject_dep : deps_public_maybe_subproject
if maybe_subproject_dep.type_name() == 'internal'
deps_public_subproject += maybe_subproject_dep
# subproject sadly no good for pkg-config module
deps_other += maybe_subproject_dep
else
deps_public += maybe_subproject_dep
endif
endforeach

View file

@ -0,0 +1,6 @@
# 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

View file

@ -122,7 +122,6 @@ Run `make` with [`-e` / `--environment-overrides`](https://www.gnu.org/software/
The docs can take a while to build, so you may want to disable this for local development. The docs can take a while to build, so you may want to disable this for local development.
- `ENABLE_FUNCTIONAL_TESTS=yes` to enable building the functional tests. - `ENABLE_FUNCTIONAL_TESTS=yes` to enable building the functional tests.
- `ENABLE_UNIT_TESTS=yes` to enable building the unit tests.
- `OPTIMIZE=1` to enable optimizations. - `OPTIMIZE=1` to enable optimizations.
- `libraries=libutil programs=` to only build a specific library. - `libraries=libutil programs=` to only build a specific library.

View file

@ -59,15 +59,15 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
> … > …
> ``` > ```
The tests for each Nix library (`libnixexpr`, `libnixstore`, etc..) live inside a directory `tests/unit/${library_name_without-nix}`. The tests for each Nix library (`libnixexpr`, `libnixstore`, etc..) live inside a directory `src/${library_name_without-nix}-test`.
Given an interface (header) and implementation pair in the original library, say, `src/libexpr/value/context.{hh,cc}`, we write tests for it in `tests/unit/libexpr/tests/value/context.cc`, and (possibly) declare/define additional interfaces for testing purposes in `tests/unit/libexpr-support/tests/value/context.{hh,cc}`. Given an interface (header) and implementation pair in the original library, say, `src/libexpr/value/context.{hh,cc}`, we write tests for it in `src/nix-expr-tests/value/context.cc`, and (possibly) declare/define additional interfaces for testing purposes in `src/nix-expr-test-support/tests/value/context.{hh,cc}`.
Data for unit tests is stored in a `data` subdir of the directory for each unit test executable. Data for unit tests is stored in a `data` subdir of the directory for each unit test executable.
For example, `libnixstore` code is in `src/libstore`, and its test data is in `tests/unit/libstore/data`. For example, `libnixstore` code is in `src/libstore`, and its test data is in `src/nix-store-tests/data`.
The path to the `tests/unit/data` directory is passed to the unit test executable with the environment variable `_NIX_TEST_UNIT_DATA`. The path to the `src/${library_name_without-nix}-test/data` directory is passed to the unit test executable with the environment variable `_NIX_TEST_UNIT_DATA`.
Note that each executable only gets the data for its tests. Note that each executable only gets the data for its tests.
The unit test libraries are in `tests/unit/${library_name_without-nix}-lib`. The unit test libraries are in `src/${library_name_without-nix}-test-support`.
All headers are in a `tests` subdirectory so they are included with `#include "tests/"`. All headers are in a `tests` subdirectory so they are included with `#include "tests/"`.
The use of all these separate directories for the unit tests might seem inconvenient, as for example the tests are not "right next to" the part of the code they are testing. The use of all these separate directories for the unit tests might seem inconvenient, as for example the tests are not "right next to" the part of the code they are testing.
@ -76,8 +76,25 @@ there is no risk of any build-system wildcards for the library accidentally pick
### Running tests ### Running tests
You can run the whole testsuite with `make check`, or the tests for a specific component with `make libfoo-tests_RUN`. You can run the whole testsuite with `meson test` from the Meson build directory, or the tests for a specific component with `meson test nix-store-tests`.
Finer-grained filtering is also possible using the [--gtest_filter](https://google.github.io/googletest/advanced.html#running-a-subset-of-the-tests) command-line option, or the `GTEST_FILTER` environment variable, e.g. `GTEST_FILTER='ErrorTraceTest.*' make check`. A environment variables that Google Test accepts are also worth knowing:
1. [`GTEST_FILTER`](https://google.github.io/googletest/advanced.html#running-a-subset-of-the-tests)
This is used for finer-grained filtering of which tests to run.
2. [`GTEST_BRIEF`](https://google.github.io/googletest/advanced.html#suppressing-test-passes)
This is used to avoid logging passing tests.
Putting the two together, one might run
```bash
GTEST_BREIF=1 GTEST_FILTER='ErrorTraceTest.*' meson test nix-expr-tests -v
```
for short but comprensive output.
### Characterisation testing { #characaterisation-testing-unit } ### Characterisation testing { #characaterisation-testing-unit }
@ -86,7 +103,7 @@ See [functional characterisation testing](#characterisation-testing-functional)
Like with the functional characterisation, `_NIX_TEST_ACCEPT=1` is also used. Like with the functional characterisation, `_NIX_TEST_ACCEPT=1` is also used.
For example: For example:
```shell-session ```shell-session
$ _NIX_TEST_ACCEPT=1 make libstore-tests_RUN $ _NIX_TEST_ACCEPT=1 meson test nix-store-tests -v
... ...
[ SKIPPED ] WorkerProtoTest.string_read [ SKIPPED ] WorkerProtoTest.string_read
[ SKIPPED ] WorkerProtoTest.string_write [ SKIPPED ] WorkerProtoTest.string_write

View file

@ -145,9 +145,7 @@
nix = final.nixComponents.nix; nix = final.nixComponents.nix;
nix_noTests = final.nix.override { nix_noTests = final.nix.override {
doCheck = false;
doInstallCheck = false; doInstallCheck = false;
installUnitTests = false;
}; };
# See https://github.com/NixOS/nixpkgs/pull/214409 # See https://github.com/NixOS/nixpkgs/pull/214409
@ -304,8 +302,8 @@
env = { env = {
# Needed for Meson to find Boost. # Needed for Meson to find Boost.
# https://github.com/NixOS/nixpkgs/issues/86131. # https://github.com/NixOS/nixpkgs/issues/86131.
BOOST_INCLUDEDIR = "${lib.getDev pkgs.boost}/include"; BOOST_INCLUDEDIR = "${lib.getDev pkgs.nixDependencies.boost}/include";
BOOST_LIBRARYDIR = "${lib.getLib pkgs.boost}/lib"; BOOST_LIBRARYDIR = "${lib.getLib pkgs.nixDependencies.boost}/lib";
# For `make format`, to work without installing pre-commit # For `make format`, to work without installing pre-commit
_NIX_PRE_COMMIT_HOOKS_CONFIG = _NIX_PRE_COMMIT_HOOKS_CONFIG =
"${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" modular.pre-commit.settings.rawConfig}"; "${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" modular.pre-commit.settings.rawConfig}";
@ -326,6 +324,7 @@
++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs ++ pkgs.nixComponents.nix-internal-api-docs.nativeBuildInputs
++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs ++ pkgs.nixComponents.nix-external-api-docs.nativeBuildInputs
++ [ ++ [
pkgs.buildPackages.cmake
modular.pre-commit.settings.package modular.pre-commit.settings.package
(pkgs.writeScriptBin "pre-commit-hooks-install" (pkgs.writeScriptBin "pre-commit-hooks-install"
modular.pre-commit.settings.installationScript) modular.pre-commit.settings.installationScript)
@ -336,6 +335,10 @@
++ lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) pkgs.buildPackages.clang-tools; ++ lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform) pkgs.buildPackages.clang-tools;
buildInputs = attrs.buildInputs or [] buildInputs = attrs.buildInputs or []
++ [
pkgs.gtest
pkgs.rapidcheck
]
++ lib.optional havePerl pkgs.perl ++ lib.optional havePerl pkgs.perl
; ;
}); });

View file

@ -9,13 +9,27 @@ project('nix-dev-shell', 'cpp',
subproject('libutil') subproject('libutil')
subproject('libstore') subproject('libstore')
subproject('libfetchers') subproject('libfetchers')
subproject('perl') subproject('libexpr')
subproject('libflake')
# Docs
subproject('internal-api-docs') subproject('internal-api-docs')
subproject('external-api-docs') subproject('external-api-docs')
# C wrappers # C wrappers
subproject('libutil-c') subproject('libutil-c')
subproject('libstore-c')
subproject('libexpr-c')
# Language Bindings
subproject('perl')
# Testing # Testing
subproject('libutil-test-support') subproject('nix-util-test-support')
subproject('libutil-test') subproject('nix-util-tests')
subproject('nix-store-test-support')
subproject('nix-store-tests')
subproject('nix-fetchers-tests')
subproject('nix-expr-test-support')
subproject('nix-expr-tests')
subproject('nix-flake-tests')

View file

@ -4,7 +4,7 @@
# remove file extension. # remove file extension.
test_name=$(echo -n "${test?must be defined by caller (test runner)}" | sed \ test_name=$(echo -n "${test?must be defined by caller (test runner)}" | sed \
-e "s|^tests/unit/[^/]*/data/||" \ -e "s|^src/[^/]*-test/data/||" \
-e "s|^tests/functional/||" \ -e "s|^tests/functional/||" \
-e "s|\.sh$||" \ -e "s|\.sh$||" \
) )

View file

@ -33,7 +33,7 @@
, rapidcheck , rapidcheck
, sqlite , sqlite
, toml11 , toml11
, util-linux , unixtools
, xz , xz
, busybox-sandbox-shell ? null , busybox-sandbox-shell ? null
@ -175,7 +175,7 @@ in {
(fileset.difference ./src ./src/perl) (fileset.difference ./src ./src/perl)
./COPYING ./COPYING
./scripts/local.mk ./scripts/local.mk
] ++ lib.optionals buildUnitTests [ ] ++ lib.optionals enableManual [
./doc/manual ./doc/manual
] ++ lib.optionals buildUnitTests [ ] ++ lib.optionals buildUnitTests [
./tests/unit ./tests/unit
@ -213,11 +213,10 @@ in {
man # for testing `nix-* --help` man # for testing `nix-* --help`
] ++ lib.optionals (doInstallCheck || enableManual) [ ] ++ lib.optionals (doInstallCheck || enableManual) [
jq # Also for custom mdBook preprocessor. jq # Also for custom mdBook preprocessor.
] ++ lib.optional stdenv.hostPlatform.isLinux util-linux ] ++ lib.optional stdenv.hostPlatform.isStatic unixtools.hexdump
; ;
buildInputs = lib.optionals doBuild [ buildInputs = lib.optionals doBuild [
boost
brotli brotli
bzip2 bzip2
curl curl
@ -226,10 +225,7 @@ in {
libsodium libsodium
openssl openssl
sqlite sqlite
(toml11.overrideAttrs (old: { toml11
# TODO change in Nixpkgs, Windows works fine.
meta.platforms = lib.platforms.all;
}))
xz xz
({ inherit readline editline; }.${readlineFlavor}) ({ inherit readline editline; }.${readlineFlavor})
] ++ lib.optionals enableMarkdown [ ] ++ lib.optionals enableMarkdown [
@ -248,34 +244,13 @@ in {
; ;
propagatedBuildInputs = [ propagatedBuildInputs = [
boost
nlohmann_json nlohmann_json
] ++ lib.optional enableGC boehmgc; ] ++ lib.optional enableGC boehmgc;
dontBuild = !attrs.doBuild; dontBuild = !attrs.doBuild;
doCheck = attrs.doCheck; doCheck = attrs.doCheck;
disallowedReferences = [ boost ];
preConfigure = lib.optionalString (doBuild && ! stdenv.hostPlatform.isStatic) (
''
# Copy libboost_context so we don't get all of Boost in our closure.
# https://github.com/NixOS/nixpkgs/issues/45462
mkdir -p $out/lib
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
rm -f $out/lib/*.a
'' + lib.optionalString stdenv.hostPlatform.isLinux ''
chmod u+w $out/lib/*.so.*
patchelf --set-rpath $out/lib:${stdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.*
'' + lib.optionalString stdenv.hostPlatform.isDarwin ''
for LIB in $out/lib/*.dylib; do
chmod u+w $LIB
install_name_tool -id $LIB $LIB
install_name_tool -delete_rpath ${boost}/lib/ $LIB || true
done
install_name_tool -change ${boost}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib
''
);
configureFlags = [ configureFlags = [
(lib.enableFeature doBuild "build") (lib.enableFeature doBuild "build")
(lib.enableFeature buildUnitTests "unit-tests") (lib.enableFeature buildUnitTests "unit-tests")
@ -322,11 +297,6 @@ in {
lib.optionalString stdenv.hostPlatform.isStatic '' lib.optionalString stdenv.hostPlatform.isStatic ''
mkdir -p $out/nix-support mkdir -p $out/nix-support
echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products
'' + lib.optionalString stdenv.isDarwin ''
install_name_tool \
-change ${boost}/lib/libboost_context.dylib \
$out/lib/libboost_context.dylib \
$out/lib/libnixutil.dylib
'' ''
) + lib.optionalString enableManual '' ) + lib.optionalString enableManual ''
mkdir -p ''${!outputDoc}/nix-support mkdir -p ''${!outputDoc}/nix-support

View file

@ -8,21 +8,28 @@ in
nix = callPackage ../package.nix { }; nix = callPackage ../package.nix { };
nix-util = callPackage ../src/libutil/package.nix { }; nix-util = callPackage ../src/libutil/package.nix { };
nix-util-test-support = callPackage ../tests/unit/libutil-support/package.nix { };
nix-util-test = callPackage ../tests/unit/libutil/package.nix { };
nix-util-c = callPackage ../src/libutil-c/package.nix { }; nix-util-c = callPackage ../src/libutil-c/package.nix { };
nix-util-test-support = callPackage ../tests/unit/libutil-support/package.nix { };
nix-util-tests = callPackage ../tests/unit/libutil/package.nix { };
nix-store = callPackage ../src/libstore/package.nix { }; nix-store = callPackage ../src/libstore/package.nix { };
nix-store-c = callPackage ../src/libstore-c/package.nix { };
nix-store-test-support = callPackage ../tests/unit/libstore-support/package.nix { };
nix-store-tests = callPackage ../tests/unit/libstore/package.nix { };
nix-fetchers = callPackage ../src/libfetchers/package.nix { }; nix-fetchers = callPackage ../src/libfetchers/package.nix { };
nix-fetchers-tests = callPackage ../tests/unit/libfetchers/package.nix { };
nix-perl-bindings = callPackage ../src/perl/package.nix { }; nix-expr = callPackage ../src/libexpr/package.nix { };
nix-expr-c = callPackage ../src/libexpr-c/package.nix { };
nix-expr-test-support = callPackage ../tests/unit/libexpr-support/package.nix { };
nix-expr-tests = callPackage ../tests/unit/libexpr/package.nix { };
nix-flake = callPackage ../src/libflake/package.nix { };
nix-flake-tests = callPackage ../tests/unit/libflake/package.nix { };
nix-internal-api-docs = callPackage ../src/internal-api-docs/package.nix { }; nix-internal-api-docs = callPackage ../src/internal-api-docs/package.nix { };
nix-external-api-docs = callPackage ../src/external-api-docs/package.nix { }; nix-external-api-docs = callPackage ../src/external-api-docs/package.nix { };
nix-perl-bindings = callPackage ../src/perl/package.nix { };
} }

View file

@ -10,6 +10,7 @@
stdenv, stdenv,
versionSuffix, versionSuffix,
}: }:
let let
inherit (pkgs) lib; inherit (pkgs) lib;
@ -52,6 +53,19 @@ scope: {
enableLargeConfig = true; enableLargeConfig = true;
}; };
# TODO Hack until https://github.com/NixOS/nixpkgs/issues/45462 is fixed.
boost = (pkgs.boost.override {
extraB2Args = [
"--with-container"
"--with-context"
"--with-coroutine"
];
}).overrideAttrs (old: {
# Need to remove `--with-*` to use `--with-libraries=...`
buildPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.buildPhase;
installPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.installPhase;
});
libgit2 = pkgs.libgit2.overrideAttrs (attrs: { libgit2 = pkgs.libgit2.overrideAttrs (attrs: {
src = inputs.libgit2; src = inputs.libgit2;
version = inputs.libgit2.lastModifiedDate; version = inputs.libgit2.lastModifiedDate;
@ -83,5 +97,11 @@ scope: {
''; '';
}); });
# TODO change in Nixpkgs, Windows works fine. First commit of
# https://github.com/NixOS/nixpkgs/pull/322977 backported will fix.
toml11 = pkgs.toml11.overrideAttrs (old: {
meta.platforms = lib.platforms.all;
});
mkMesonDerivation = f: stdenv.mkDerivation (lib.extends localSourceLayer f); mkMesonDerivation = f: stdenv.mkDerivation (lib.extends localSourceLayer f);
} }

View file

@ -38,9 +38,19 @@ let
"nix-util" "nix-util"
"nix-util-c" "nix-util-c"
"nix-util-test-support" "nix-util-test-support"
"nix-util-test" "nix-util-tests"
"nix-store" "nix-store"
"nix-store-c"
"nix-store-test-support"
"nix-store-tests"
"nix-fetchers" "nix-fetchers"
"nix-fetchers-tests"
"nix-expr"
"nix-expr-c"
"nix-expr-test-support"
"nix-expr-tests"
"nix-flake"
"nix-flake-tests"
]; ];
in in
{ {

View file

@ -38,27 +38,27 @@ GENERATE_LATEX = NO
# so they can expand variables despite configure variables. # so they can expand variables despite configure variables.
INPUT = \ INPUT = \
@src@/src/libcmd \ @src@/libcmd \
@src@/src/libexpr \ @src@/libexpr \
@src@/src/libexpr/flake \ @src@/libexpr/flake \
@src@/tests/unit/libexpr \ @src@/nix-expr-tests \
@src@/tests/unit/libexpr/value \ @src@/nix-expr-tests/value \
@src@/tests/unit/libexpr/test \ @src@/nix-expr-test-support/test \
@src@/tests/unit/libexpr/test/value \ @src@/nix-expr-test-support/test/value \
@src@/src/libexpr/value \ @src@/libexpr/value \
@src@/src/libfetchers \ @src@/libfetchers \
@src@/src/libmain \ @src@/libmain \
@src@/src/libstore \ @src@/libstore \
@src@/src/libstore/build \ @src@/libstore/build \
@src@/src/libstore/builtins \ @src@/libstore/builtins \
@src@/tests/unit/libstore \ @src@/nix-store-tests \
@src@/tests/unit/libstore/test \ @src@/nix-store-test-support/test \
@src@/src/libutil \ @src@/libutil \
@src@/tests/unit/libutil \ @src@/nix-util-tests \
@src@/tests/unit/libutil/test \ @src@/nix-util-test-support/test \
@src@/src/nix \ @src@/nix \
@src@/src/nix-env \ @src@/nix-env \
@src@/src/nix-store @src@/nix-store
# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names # If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
# in the source code. If set to NO, only conditional compilation will be # in the source code. If set to NO, only conditional compilation will be

View file

@ -12,7 +12,7 @@ doxygen_cfg = configure_file(
configuration : { configuration : {
'PROJECT_NUMBER': meson.project_version(), 'PROJECT_NUMBER': meson.project_version(),
'OUTPUT_DIRECTORY' : meson.current_build_dir(), 'OUTPUT_DIRECTORY' : meson.current_build_dir(),
'src' : fs.parent(fs.parent(meson.project_source_root())), 'src' : fs.parent(fs.parent(meson.project_source_root())) / 'src',
}, },
) )

View file

@ -28,7 +28,6 @@ stdenv.mkDerivation (finalAttrs: {
# Source is not compiled, but still must be available for Doxygen # Source is not compiled, but still must be available for Doxygen
# to gather comments. # to gather comments.
(cpp ../.) (cpp ../.)
(cpp ../../tests/unit)
]; ];
}; };

View file

@ -0,0 +1 @@
../../build-utils-meson

View file

@ -1,7 +1,6 @@
#include "network-proxy.hh" #include "network-proxy.hh"
#include <algorithm> #include <algorithm>
#include <boost/algorithm/string.hpp>
#include "environment-variables.hh" #include "environment-variables.hh"
@ -13,7 +12,10 @@ static StringSet getAllVariables()
{ {
StringSet variables = lowercaseVariables; StringSet variables = lowercaseVariables;
for (const auto & variable : lowercaseVariables) { for (const auto & variable : lowercaseVariables) {
variables.insert(boost::to_upper_copy(variable)); std::string upperVariable;
std::transform(
variable.begin(), variable.end(), upperVariable.begin(), [](unsigned char c) { return std::toupper(c); });
variables.insert(std::move(upperVariable));
} }
return variables; return variables;
} }

1
src/libexpr-c/.version Symbolic link
View file

@ -0,0 +1 @@
../../.version

View file

@ -0,0 +1 @@
../../build-utils-meson

91
src/libexpr-c/meson.build Normal file
View file

@ -0,0 +1,91 @@
project('nix-expr-c', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
configdata = configuration_data()
deps_private_maybe_subproject = [
dependency('nix-util'),
dependency('nix-store'),
dependency('nix-expr'),
]
deps_public_maybe_subproject = [
dependency('nix-util-c'),
dependency('nix-store-c'),
]
subdir('build-utils-meson/subprojects')
# TODO rename, because it will conflict with downstream projects
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
config_h = configure_file(
configuration : configdata,
output : 'config-expr.h',
)
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.
# From C++ libraries, only for internals
'-include', 'config-util.hh',
'-include', 'config-store.hh',
'-include', 'config-expr.hh',
# From C libraries, for our public, installed headers too
'-include', 'config-util.h',
'-include', 'config-store.h',
'-include', 'config-expr.h',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'nix_api_expr.cc',
'nix_api_external.cc',
'nix_api_value.cc',
)
include_dirs = [include_directories('.')]
headers = [config_h] + files(
'nix_api_expr.h',
'nix_api_external.h',
'nix_api_value.h',
)
# TODO move this header to libexpr, maybe don't use it in tests?
headers += files('nix_api_expr_internal.h')
subdir('build-utils-meson/export-all-symbols')
this_library = library(
'nixexprc',
sources,
dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs,
link_args: linker_export_flags,
prelink : true, # For C++ static initializers
install : true,
)
install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = []
subdir('build-utils-meson/export')

80
src/libexpr-c/package.nix Normal file
View file

@ -0,0 +1,80 @@
{ lib
, stdenv
, mkMesonDerivation
, meson
, ninja
, pkg-config
, nix-store-c
, nix-expr
# Configuration Options
, versionSuffix ? ""
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-expr-c";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
(fileset.fileFilter (file: file.hasExt "h") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
propagatedBuildInputs = [
nix-store-c
nix-expr
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../.version
'';
mesonFlags = [
];
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

1
src/libexpr/.version Symbolic link
View file

@ -0,0 +1 @@
../../.version

View file

@ -0,0 +1 @@
../../build-utils-meson

View file

@ -293,7 +293,7 @@ EvalState::EvalState(
)} )}
, callFlakeInternal{internalFS->addFile( , callFlakeInternal{internalFS->addFile(
CanonPath("call-flake.nix"), CanonPath("call-flake.nix"),
#include "flake/call-flake.nix.gen.hh" #include "call-flake.nix.gen.hh"
)} )}
, store(store) , store(store)
, buildStore(buildStore ? buildStore : store) , buildStore(buildStore ? buildStore : store)

View file

@ -47,4 +47,4 @@ $(foreach i, $(wildcard src/libexpr/value/*.hh), \
$(d)/primops.cc: $(d)/imported-drv-to-derivation.nix.gen.hh $(d)/primops.cc: $(d)/imported-drv-to-derivation.nix.gen.hh
$(d)/eval.cc: $(d)/primops/derivation.nix.gen.hh $(d)/fetchurl.nix.gen.hh $(d)/flake/call-flake.nix.gen.hh $(d)/eval.cc: $(d)/primops/derivation.nix.gen.hh $(d)/fetchurl.nix.gen.hh $(d)/call-flake.nix.gen.hh

204
src/libexpr/meson.build Normal file
View file

@ -0,0 +1,204 @@
project('nix-expr', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
configdata = configuration_data()
deps_private_maybe_subproject = [
]
deps_public_maybe_subproject = [
dependency('nix-util'),
dependency('nix-store'),
dependency('nix-fetchers'),
]
subdir('build-utils-meson/subprojects')
subdir('build-utils-meson/threads')
boost = dependency(
'boost',
modules : ['container', 'context'],
)
# boost is a public dependency, but not a pkg-config dependency unfortunately, so we
# put in `deps_other`.
deps_other += boost
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
deps_public += nlohmann_json
bdw_gc = dependency('bdw-gc', required : get_option('gc'))
if bdw_gc.found()
deps_public += bdw_gc
foreach funcspec : [
'pthread_attr_get_np',
'pthread_getattr_np',
]
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
define_value = cxx.has_function(funcspec).to_int()
configdata.set(define_name, define_value)
endforeach
configdata.set('GC_THREADS', 1)
endif
configdata.set('HAVE_BOEHMGC', bdw_gc.found().to_int())
toml11 = dependency('toml11', version : '>=3.7.0', method : 'cmake')
deps_other += toml11
config_h = configure_file(
configuration : configdata,
output : 'config-expr.hh',
)
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-util.hh',
'-include', 'config-store.hh',
# '-include', 'config-fetchers.h',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
parser_tab = custom_target(
input : 'parser.y',
output : [
'parser-tab.cc',
'parser-tab.hh',
],
command : [
'bison',
'-v',
'-o',
'@OUTPUT0@',
'@INPUT@',
'-d',
],
# NOTE(Qyriad): Meson doesn't support installing only part of a custom target, so we add
# an install script below which removes parser-tab.cc.
install : true,
install_dir : get_option('includedir') / 'nix',
)
lexer_tab = custom_target(
input : [
'lexer.l',
parser_tab,
],
output : [
'lexer-tab.cc',
'lexer-tab.hh',
],
command : [
'flex',
'--outfile',
'@OUTPUT0@',
'--header-file=' + '@OUTPUT1@',
'@INPUT0@',
],
# NOTE(Qyriad): Meson doesn't support installing only part of a custom target, so we add
# an install script below which removes lexer-tab.cc.
install : true,
install_dir : get_option('includedir') / 'nix',
)
generated_headers = []
foreach header : [
'imported-drv-to-derivation.nix',
'fetchurl.nix',
'call-flake.nix',
]
generated_headers += custom_target(
command : [ 'bash', '-c', '{ echo \'R"__NIX_STR(\' && cat @INPUT@ && echo \')__NIX_STR"\'; } > "$1"', '_ignored_argv0', '@OUTPUT@' ],
input : header,
output : '@PLAINNAME@.gen.hh',
)
endforeach
sources = files(
'attr-path.cc',
'attr-set.cc',
'eval-cache.cc',
'eval-error.cc',
'eval-gc.cc',
'eval-settings.cc',
'eval.cc',
'function-trace.cc',
'get-drvs.cc',
'json-to-value.cc',
'nixexpr.cc',
'paths.cc',
'primops.cc',
'print-ambiguous.cc',
'print.cc',
'search-path.cc',
'value-to-json.cc',
'value-to-xml.cc',
'value/context.cc',
)
include_dirs = [include_directories('.')]
headers = [config_h] + files(
'attr-path.hh',
'attr-set.hh',
'eval-cache.hh',
'eval-error.hh',
'eval-gc.hh',
'eval-inline.hh',
'eval-settings.hh',
'eval.hh',
'function-trace.hh',
'gc-small-vector.hh',
'get-drvs.hh',
'json-to-value.hh',
'nixexpr.hh',
'parser-state.hh',
'pos-idx.hh',
'pos-table.hh',
'primops.hh',
'print-ambiguous.hh',
'print-options.hh',
'print.hh',
'repl-exit-status.hh',
'search-path.hh',
'symbol-table.hh',
'value-to-json.hh',
'value-to-xml.hh',
'value.hh',
'value/context.hh',
)
subdir('primops')
this_library = library(
'nixexpr',
sources,
parser_tab,
lexer_tab,
generated_headers,
dependencies : deps_public + deps_private + deps_other,
prelink : true, # For C++ static initializers
install : true,
)
install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = []
subdir('build-utils-meson/export')

View file

@ -0,0 +1,3 @@
option('gc', type : 'feature',
description : 'enable garbage collection in the Nix expression evaluator (requires Boehm GC)',
)

119
src/libexpr/package.nix Normal file
View file

@ -0,0 +1,119 @@
{ lib
, stdenv
, mkMesonDerivation
, releaseTools
, meson
, ninja
, pkg-config
, bison
, flex
, cmake # for resolving toml11 dep
, nix-util
, nix-store
, nix-fetchers
, boost
, boehmgc
, nlohmann_json
, toml11
# Configuration Options
, versionSuffix ? ""
# Whether to use garbage collection for the Nix language evaluator.
#
# If it is disabled, we just leak memory, but this is not as bad as it
# sounds so long as evaluation just takes places within short-lived
# processes. (When the process exits, the memory is reclaimed; it is
# only leaked *within* the process.)
#
# Temporarily disabled on Windows because the `GC_throw_bad_alloc`
# symbol is missing during linking.
, enableGC ? !stdenv.hostPlatform.isWindows
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-expr";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build
./meson.options
./primops/meson.build
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
./lexer.l
./parser.y
(fileset.fileFilter (file: file.hasExt "nix") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
bison
flex
cmake
];
buildInputs = [
toml11
];
propagatedBuildInputs = [
nix-util
nix-store
nix-fetchers
boost
nlohmann_json
] ++ lib.optional enableGC boehmgc;
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../.version
'';
mesonFlags = [
(lib.mesonEnable "gc" enableGC)
];
env = {
# Needed for Meson to find Boost.
# https://github.com/NixOS/nixpkgs/issues/86131.
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
} // lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

View file

@ -1,4 +1,4 @@
#include "libfetchers/attrs.hh" #include "attrs.hh"
#include "primops.hh" #include "primops.hh"
#include "eval-inline.hh" #include "eval-inline.hh"
#include "eval-settings.hh" #include "eval-settings.hh"

View file

@ -0,0 +1,17 @@
foreach header : [
'derivation.nix',
]
generated_headers += custom_target(
command : [ 'bash', '-c', '{ echo \'R"__NIX_STR(\' && cat @INPUT@ && echo \')__NIX_STR"\'; } > "$1"', '_ignored_argv0', '@OUTPUT@' ],
input : header,
output : '@PLAINNAME@.gen.hh',
)
endforeach
sources += files(
'context.cc',
'fetchClosure.cc',
'fetchMercurial.cc',
'fetchTree.cc',
'fromTOML.cc',
)

View file

@ -0,0 +1 @@
../../build-utils-meson

View file

@ -14,62 +14,35 @@ project('nix-fetchers', 'cpp',
cxx = meson.get_compiler('cpp') cxx = meson.get_compiler('cpp')
# See note in ../nix-util/meson.build subdir('build-utils-meson/deps-lists')
deps_private = [ ]
# See note in ../nix-util/meson.build
deps_public = [ ]
# See note in ../nix-util/meson.build
deps_other = [ ]
configdata = configuration_data() configdata = configuration_data()
nix_util = dependency('nix-util') deps_private_maybe_subproject = [
if nix_util.type_name() == 'internal' ]
# subproject sadly no good for pkg-config module deps_public_maybe_subproject = [
deps_other += nix_util dependency('nix-util'),
else dependency('nix-store'),
deps_public += nix_util ]
endif subdir('build-utils-meson/subprojects')
nix_store = dependency('nix-store')
if nix_store.type_name() == 'internal'
# subproject sadly no good for pkg-config module
deps_other += nix_store
else
deps_public += nix_store
endif
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9') nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
deps_public += nlohmann_json deps_public += nlohmann_json
libgit2 = dependency('libgit2') libgit2 = dependency('libgit2')
deps_public += libgit2 deps_private += libgit2
add_project_arguments( add_project_arguments(
# TODO(Qyriad): Yes this is how the autoconf+Make system did it. # TODO(Qyriad): Yes this is how the autoconf+Make system did it.
# It would be nice for our headers to be idempotent instead. # It would be nice for our headers to be idempotent instead.
'-include', 'config-util.h', '-include', 'config-util.hh',
'-include', 'config-store.h', '-include', 'config-store.hh',
# '-include', 'config-fetchers.h', # '-include', 'config-fetchers.h',
'-Wno-deprecated-declarations',
'-Wimplicit-fallthrough',
'-Werror=switch',
'-Werror=switch-enum',
'-Werror=unused-result',
'-Wdeprecated-copy',
'-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
# at ~1% overhead in `nix search`.
#
# FIXME: remove when we get meson 1.4.0 which will default this to on for us:
# https://mesonbuild.com/Release-notes-for-1-4-0.html#ndebug-setting-now-controls-c-stdlib-assertions
'-D_GLIBCXX_ASSERTIONS=1',
language : 'cpp', language : 'cpp',
) )
subdir('build-utils-meson/diagnostics')
sources = files( sources = files(
'attrs.cc', 'attrs.cc',
'cache.cc', 'cache.cc',
@ -89,6 +62,8 @@ sources = files(
'tarball.cc', 'tarball.cc',
) )
include_dirs = [include_directories('.')]
headers = files( headers = files(
'attrs.hh', 'attrs.hh',
'cache.hh', 'cache.hh',
@ -107,36 +82,12 @@ this_library = library(
'nixfetchers', 'nixfetchers',
sources, sources,
dependencies : deps_public + deps_private + deps_other, dependencies : deps_public + deps_private + deps_other,
prelink : true, # For C++ static initializers
install : true, install : true,
) )
install_headers(headers, subdir : 'nix', preserve_path : true) install_headers(headers, subdir : 'nix', preserve_path : true)
requires = [] libraries_private = []
if nix_util.type_name() == 'internal'
# `requires` cannot contain declared dependencies (from the
# subproject), so we need to do this manually
requires += 'nix-util'
endif
if nix_store.type_name() == 'internal'
requires += 'nix-store'
endif
requires += deps_public
import('pkgconfig').generate( subdir('build-utils-meson/export')
this_library,
filebase : meson.project_name(),
name : 'Nix',
description : 'Nix Package Manager',
subdirs : ['nix'],
extra_cflags : ['-std=c++2a'],
requires : requires,
requires_private : deps_private,
)
meson.override_dependency(meson.project_name(), declare_dependency(
include_directories : include_directories('.'),
link_with : this_library,
compile_args : ['-std=c++2a'],
dependencies : [nix_util, nix_store],
))

View file

@ -1,5 +1,6 @@
{ lib { lib
, stdenv , stdenv
, mkMesonDerivation
, releaseTools , releaseTools
, meson , meson
@ -15,40 +16,28 @@
# Configuration Options # Configuration Options
, versionSuffix ? "" , versionSuffix ? ""
# Check test coverage of Nix. Probably want to use with with at least
# one of `doCheck` or `doInstallCheck` enabled.
, withCoverageChecks ? false
}: }:
let let
inherit (lib) fileset; inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix; version = lib.fileContents ./.version + versionSuffix;
mkDerivation =
if withCoverageChecks
then
# TODO support `finalAttrs` args function in
# `releaseTools.coverageAnalysis`.
argsFun:
releaseTools.coverageAnalysis (let args = argsFun args; in args)
else stdenv.mkDerivation;
in in
mkDerivation (finalAttrs: { mkMesonDerivation (finalAttrs: {
pname = "nix-fetchers"; pname = "nix-fetchers";
inherit version; inherit version;
src = fileset.toSource { workDir = ./.;
root = ./.;
fileset = fileset.unions [ fileset = fileset.unions [
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build ./meson.build
(fileset.fileFilter (file: file.hasExt "cc") ./.) (fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.) (fileset.fileFilter (file: file.hasExt "hh") ./.)
]; ];
};
outputs = [ "out" "dev" ]; outputs = [ "out" "dev" ];
@ -69,9 +58,11 @@ mkDerivation (finalAttrs: {
]; ];
preConfigure = preConfigure =
# "Inline" .version so its not a symlink, and includes the suffix # "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
'' ''
echo ${version} > .version chmod u+w ./.version
echo ${version} > ../../.version
''; '';
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) { env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
@ -80,16 +71,11 @@ mkDerivation (finalAttrs: {
enableParallelBuilding = true; enableParallelBuilding = true;
postInstall =
# Remove absolute path to boost libs
''
'';
separateDebugInfo = !stdenv.hostPlatform.isStatic; separateDebugInfo = !stdenv.hostPlatform.isStatic;
# TODO `releaseTools.coverageAnalysis` in Nixpkgs needs to be updated # TODO `releaseTools.coverageAnalysis` in Nixpkgs needs to be updated
# to work with `strictDeps`. # to work with `strictDeps`.
strictDeps = !withCoverageChecks; strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie"; hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
@ -97,8 +83,4 @@ mkDerivation (finalAttrs: {
platforms = lib.platforms.unix ++ lib.platforms.windows; platforms = lib.platforms.unix ++ lib.platforms.windows;
}; };
} // lib.optionalAttrs withCoverageChecks {
lcovFilter = [ "*-tab.*" ];
hardeningDisable = ["fortify"];
}) })

1
src/libflake/.version Symbolic link
View file

@ -0,0 +1 @@
../../.version

View file

@ -0,0 +1 @@
../../build-utils-meson

75
src/libflake/meson.build Normal file
View file

@ -0,0 +1,75 @@
project('nix-flake', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
]
deps_public_maybe_subproject = [
dependency('nix-util'),
dependency('nix-store'),
dependency('nix-fetchers'),
dependency('nix-expr'),
]
subdir('build-utils-meson/subprojects')
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
deps_public += nlohmann_json
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-util.hh',
'-include', 'config-store.hh',
# '-include', 'config-fetchers.h',
'-include', 'config-expr.hh',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'flake-settings.cc',
'flake/config.cc',
'flake/flake.cc',
'flake/flakeref.cc',
'flake/url-name.cc',
'flake/lockfile.cc',
)
include_dirs = [include_directories('.')]
headers = files(
'flake-settings.hh',
'flake/flake.hh',
'flake/flakeref.hh',
'flake/lockfile.hh',
'flake/url-name.hh',
)
this_library = library(
'nixflake',
sources,
dependencies : deps_public + deps_private + deps_other,
prelink : true, # For C++ static initializers
install : true,
)
install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = []
subdir('build-utils-meson/export')

86
src/libflake/package.nix Normal file
View file

@ -0,0 +1,86 @@
{ lib
, stdenv
, mkMesonDerivation
, releaseTools
, meson
, ninja
, pkg-config
, nix-util
, nix-store
, nix-fetchers
, nix-expr
, nlohmann_json
, libgit2
, man
# Configuration Options
, versionSuffix ? ""
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-flake";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
propagatedBuildInputs = [
nix-store
nix-util
nix-fetchers
nix-expr
nlohmann_json
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../.version
'';
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
# TODO `releaseTools.coverageAnalysis` in Nixpkgs needs to be updated
# to work with `strictDeps`.
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

View file

@ -0,0 +1 @@
../../build-utils-meson

1
src/libstore-c/.version Symbolic link
View file

@ -0,0 +1 @@
../../.version

View file

@ -0,0 +1 @@
../../build-utils-meson

View file

@ -0,0 +1,83 @@
project('nix-store-c', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
configdata = configuration_data()
deps_private_maybe_subproject = [
dependency('nix-util'),
dependency('nix-store'),
]
deps_public_maybe_subproject = [
dependency('nix-util-c'),
]
subdir('build-utils-meson/subprojects')
# TODO rename, because it will conflict with downstream projects
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
config_h = configure_file(
configuration : configdata,
output : 'config-store.h',
)
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.
# From C++ libraries, only for internals
'-include', 'config-util.hh',
'-include', 'config-store.hh',
# From C libraries, for our public, installed headers too
'-include', 'config-util.h',
'-include', 'config-store.h',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'nix_api_store.cc',
)
include_dirs = [include_directories('.')]
headers = [config_h] + files(
'nix_api_store.h',
)
# TODO don't install this once tests don't use it and/or move the header into `libstore`, non-`c`
headers += files('nix_api_store_internal.h')
subdir('build-utils-meson/export-all-symbols')
this_library = library(
'nixstorec',
sources,
dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs,
link_args: linker_export_flags,
prelink : true, # For C++ static initializers
install : true,
)
install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = []
subdir('build-utils-meson/export')

View file

@ -0,0 +1,81 @@
{ lib
, stdenv
, mkMesonDerivation
, releaseTools
, meson
, ninja
, pkg-config
, nix-util-c
, nix-store
# Configuration Options
, versionSuffix ? ""
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-store-c";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
(fileset.fileFilter (file: file.hasExt "h") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
propagatedBuildInputs = [
nix-util-c
nix-store
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../.version
'';
mesonFlags = [
];
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

View file

@ -0,0 +1 @@
../../build-utils-meson

View file

@ -14,14 +14,7 @@ project('nix-store', 'cpp',
cxx = meson.get_compiler('cpp') cxx = meson.get_compiler('cpp')
# See note in ../nix-util/meson.build subdir('build-utils-meson/deps-lists')
deps_private = [ ]
# See note in ../nix-util/meson.build
deps_public = [ ]
# See note in ../nix-util/meson.build
deps_other = [ ]
configdata = configuration_data() configdata = configuration_data()
@ -30,13 +23,12 @@ configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
configdata.set_quoted('SYSTEM', host_machine.system()) configdata.set_quoted('SYSTEM', host_machine.system())
nix_util = dependency('nix-util') deps_private_maybe_subproject = [
if nix_util.type_name() == 'internal' ]
# subproject sadly no good for pkg-config module deps_public_maybe_subproject = [
deps_other += nix_util dependency('nix-util'),
else ]
deps_public += nix_util subdir('build-utils-meson/subprojects')
endif
run_command('ln', '-s', run_command('ln', '-s',
meson.project_build_root() / '__nothing_link_target', meson.project_build_root() / '__nothing_link_target',
@ -75,12 +67,7 @@ has_acl_support = cxx.has_header('sys/xattr.h') \
and cxx.has_function('lremovexattr') and cxx.has_function('lremovexattr')
configdata.set('HAVE_ACL_SUPPORT', has_acl_support.to_int()) configdata.set('HAVE_ACL_SUPPORT', has_acl_support.to_int())
# This is only conditional to work around subdir('build-utils-meson/threads')
# 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
boost = dependency( boost = dependency(
'boost', 'boost',
@ -112,27 +99,28 @@ deps_public += nlohmann_json
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19') sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19')
deps_private += sqlite deps_private += sqlite
enable_embedded_sandbox_shell = get_option('embedded-sandbox-shell')
if enable_embedded_sandbox_shell
# This one goes in config.h
# The path to busybox is passed as a -D flag when compiling this_library.
# Idk why, ask the old buildsystem.
configdata.set('HAVE_EMBEDDED_SANDBOX_SHELL', 1)
endif
generated_headers = [] generated_headers = []
foreach header : [ 'schema.sql', 'ca-specific-schema.sql' ] foreach header : [
'schema.sql',
'ca-specific-schema.sql',
]
generated_headers += custom_target( generated_headers += custom_target(
command : [ 'bash', '-c', '{ echo \'R"__NIX_STR(\' && cat @INPUT@ && echo \')__NIX_STR"\'; } > "$1"', '_ignored_argv0', '@OUTPUT@' ], command : [ 'bash', '-c', '{ echo \'R"__NIX_STR(\' && cat @INPUT@ && echo \')__NIX_STR"\'; } > "$1"', '_ignored_argv0', '@OUTPUT@' ],
input : header, input : header,
output : '@PLAINNAME@.gen.hh', output : '@PLAINNAME@.gen.hh',
install : true, install : true,
install_dir : get_option('includedir') / 'nix' install_dir : get_option('includedir') / 'nix',
) )
endforeach endforeach
if enable_embedded_sandbox_shell busybox = find_program(get_option('sandbox-shell'), required : false)
if get_option('embedded-sandbox-shell')
# This one goes in config.h
# The path to busybox is passed as a -D flag when compiling this_library.
# This solution is inherited from the old make buildsystem
# TODO: do this differently?
configdata.set('HAVE_EMBEDDED_SANDBOX_SHELL', 1)
hexdump = find_program('hexdump', native : true) hexdump = find_program('hexdump', native : true)
embedded_sandbox_shell_gen = custom_target( embedded_sandbox_shell_gen = custom_target(
'embedded-sandbox-shell.gen.hh', 'embedded-sandbox-shell.gen.hh',
@ -152,30 +140,19 @@ endif
config_h = configure_file( config_h = configure_file(
configuration : configdata, configuration : configdata,
output : 'config-store.h', output : 'config-store.hh',
) )
add_project_arguments( add_project_arguments(
# TODO(Qyriad): Yes this is how the autoconf+Make system did it. # TODO(Qyriad): Yes this is how the autoconf+Make system did it.
# It would be nice for our headers to be idempotent instead. # It would be nice for our headers to be idempotent instead.
'-include', 'config-util.h', '-include', 'config-util.hh',
'-include', 'config-store.h', '-include', 'config-store.hh',
'-Wno-deprecated-declarations',
'-Wimplicit-fallthrough',
'-Werror=switch',
'-Werror=switch-enum',
'-Werror=unused-result',
'-Wdeprecated-copy',
'-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
# at ~1% overhead in `nix search`.
#
# FIXME: remove when we get meson 1.4.0 which will default this to on for us:
# https://mesonbuild.com/Release-notes-for-1-4-0.html#ndebug-setting-now-controls-c-stdlib-assertions
'-D_GLIBCXX_ASSERTIONS=1',
language : 'cpp', language : 'cpp',
) )
subdir('build-utils-meson/diagnostics')
sources = files( sources = files(
'binary-cache-store.cc', 'binary-cache-store.cc',
'build-result.cc', 'build-result.cc',
@ -392,11 +369,15 @@ cpp_str_defines += {
'LSOF': lsof_path 'LSOF': lsof_path
} }
#if busybox.found() if get_option('embedded-sandbox-shell')
cpp_str_defines += { cpp_str_defines += {
# 'SANDBOX_SHELL': busybox.full_path() 'SANDBOX_SHELL': '__embedded_sandbox_shell__'
} }
#endif elif busybox.found()
cpp_str_defines += {
'SANDBOX_SHELL': busybox.full_path()
}
endif
cpp_args = [] cpp_args = []
@ -406,12 +387,7 @@ foreach name, value : cpp_str_defines
] ]
endforeach endforeach
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows' subdir('build-utils-meson/export-all-symbols')
# See note in `../nix-util/meson.build`
linker_export_flags = ['-Wl,--export-all-symbols']
else
linker_export_flags = []
endif
this_library = library( this_library = library(
'nixstore', 'nixstore',
@ -421,34 +397,12 @@ this_library = library(
include_directories : include_dirs, include_directories : include_dirs,
cpp_args : cpp_args, cpp_args : cpp_args,
link_args: linker_export_flags, link_args: linker_export_flags,
prelink : true, # For C++ static initializers
install : true, install : true,
) )
install_headers(headers, subdir : 'nix', preserve_path : true) install_headers(headers, subdir : 'nix', preserve_path : true)
requires = [] libraries_private = []
if nix_util.type_name() == 'internal'
# `requires` cannot contain declared dependencies (from the
# subproject), so we need to do this manually
requires += 'nix-util'
endif
requires += deps_public
import('pkgconfig').generate( subdir('build-utils-meson/export')
this_library,
filebase : meson.project_name(),
name : 'Nix',
description : 'Nix Package Manager',
subdirs : ['nix'],
extra_cflags : ['-std=c++2a'],
requires : requires,
requires_private : deps_private,
libraries_private : ['-lboost_container'],
)
meson.override_dependency(meson.project_name(), declare_dependency(
include_directories : include_dirs,
link_with : this_library,
compile_args : ['-std=c++2a'],
dependencies : [nix_util],
))

View file

@ -1,10 +1,12 @@
{ lib { lib
, stdenv , stdenv
, mkMesonDerivation
, releaseTools , releaseTools
, meson , meson
, ninja , ninja
, pkg-config , pkg-config
, unixtools
, nix-util , nix-util
, boost , boost
@ -20,36 +22,25 @@
, versionSuffix ? "" , versionSuffix ? ""
# Check test coverage of Nix. Probably want to use with at least , embeddedSandboxShell ? stdenv.hostPlatform.isStatic
# one of `doCheck` or `doInstallCheck` enabled.
, withCoverageChecks ? false
# Avoid setting things that would interfere with a functioning devShell
, forDevShell ? false
}: }:
let let
inherit (lib) fileset; inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix; version = lib.fileContents ./.version + versionSuffix;
mkDerivation =
if withCoverageChecks
then
# TODO support `finalAttrs` args function in
# `releaseTools.coverageAnalysis`.
argsFun:
releaseTools.coverageAnalysis (let args = argsFun args; in args)
else stdenv.mkDerivation;
in in
mkDerivation (finalAttrs: { mkMesonDerivation (finalAttrs: {
pname = "nix-store"; pname = "nix-store";
inherit version; inherit version;
src = fileset.toSource { workDir = ./.;
root = ./.;
fileset = fileset.unions [ fileset = fileset.unions [
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build ./meson.build
./meson.options ./meson.options
./linux/meson.build ./linux/meson.build
@ -61,7 +52,6 @@ mkDerivation (finalAttrs: {
(fileset.fileFilter (file: file.hasExt "md") ./.) (fileset.fileFilter (file: file.hasExt "md") ./.)
(fileset.fileFilter (file: file.hasExt "sql") ./.) (fileset.fileFilter (file: file.hasExt "sql") ./.)
]; ];
};
outputs = [ "out" "dev" ]; outputs = [ "out" "dev" ];
@ -69,7 +59,7 @@ mkDerivation (finalAttrs: {
meson meson
ninja ninja
pkg-config pkg-config
]; ] ++ lib.optional embeddedSandboxShell unixtools.hexdump;
buildInputs = [ buildInputs = [
boost boost
@ -89,17 +79,17 @@ mkDerivation (finalAttrs: {
nlohmann_json nlohmann_json
]; ];
disallowedReferences = [ boost ];
preConfigure = preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix # "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
'' ''
echo ${version} > .version chmod u+w ./.version
echo ${version} > ../../.version
''; '';
mesonFlags = [ mesonFlags = [
(lib.mesonEnable "seccomp-sandboxing" stdenv.hostPlatform.isLinux) (lib.mesonEnable "seccomp-sandboxing" stdenv.hostPlatform.isLinux)
(lib.mesonBool "embedded-sandbox-shell" stdenv.hostPlatform.isStatic) (lib.mesonBool "embedded-sandbox-shell" embeddedSandboxShell)
] ++ lib.optionals stdenv.hostPlatform.isLinux [ ] ++ lib.optionals stdenv.hostPlatform.isLinux [
(lib.mesonOption "sandbox-shell" "${busybox-sandbox-shell}/bin/busybox") (lib.mesonOption "sandbox-shell" "${busybox-sandbox-shell}/bin/busybox")
]; ];
@ -115,18 +105,9 @@ mkDerivation (finalAttrs: {
enableParallelBuilding = true; enableParallelBuilding = true;
postInstall =
# 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-store.pc" -e 's, ${lib.getLib boost}[^ ]*,,g'
'';
separateDebugInfo = !stdenv.hostPlatform.isStatic; separateDebugInfo = !stdenv.hostPlatform.isStatic;
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564 strictDeps = true;
strictDeps = !withCoverageChecks;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie"; hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
@ -134,8 +115,4 @@ mkDerivation (finalAttrs: {
platforms = lib.platforms.unix ++ lib.platforms.windows; platforms = lib.platforms.unix ++ lib.platforms.windows;
}; };
} // lib.optionalAttrs withCoverageChecks {
lcovFilter = [ "*/boost/*" "*-tab.*" ];
hardeningDisable = [ "fortify" ];
}) })

View file

@ -0,0 +1 @@
../../build-utils-meson

View file

@ -14,68 +14,16 @@ project('nix-util-c', 'cpp',
cxx = meson.get_compiler('cpp') cxx = meson.get_compiler('cpp')
# See note in ../nix-util/meson.build subdir('build-utils-meson/deps-lists')
deps_private = [ ]
# See note in ../nix-util/meson.build
deps_public = [ ]
# See note in ../nix-util/meson.build
deps_other = [ ]
configdata = configuration_data() configdata = configuration_data()
add_project_arguments( deps_private_maybe_subproject = [
# TODO(Qyriad): Yes this is how the autoconf+Make system did it. dependency('nix-util'),
# It would be nice for our headers to be idempotent instead. ]
'-include', 'config-util.h', deps_public_maybe_subproject = [
# '-include', 'config-store.h', ]
'-Wno-deprecated-declarations', subdir('build-utils-meson/subprojects')
'-Wimplicit-fallthrough',
'-Werror=switch',
'-Werror=switch-enum',
'-Werror=unused-result',
'-Wdeprecated-copy',
'-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
# at ~1% overhead in `nix search`.
#
# FIXME: remove when we get meson 1.4.0 which will default this to on for us:
# https://mesonbuild.com/Release-notes-for-1-4-0.html#ndebug-setting-now-controls-c-stdlib-assertions
'-D_GLIBCXX_ASSERTIONS=1',
language : 'cpp',
)
sources = files(
'nix_api_util.cc',
)
include_dirs = [include_directories('.')]
headers = files(
'nix_api_util.h',
'nix_api_util_internal.h',
)
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
# Windows DLLs are stricter about symbol visibility than Unix shared
# objects --- see https://gcc.gnu.org/wiki/Visibility for details.
# This is a temporary sledgehammer to export everything like on Unix,
# and not detail with this yet.
#
# TODO do not do this, and instead do fine-grained export annotations.
linker_export_flags = ['-Wl,--export-all-symbols']
else
linker_export_flags = []
endif
nix_util = dependency('nix-util')
if nix_util.type_name() == 'internal'
# subproject sadly no good for pkg-config module
deps_other += nix_util
else
deps_public += nix_util
endif
# TODO rename, because it will conflict with downstream projects # TODO rename, because it will conflict with downstream projects
configdata.set_quoted('PACKAGE_VERSION', meson.project_version()) configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
@ -85,12 +33,42 @@ config_h = configure_file(
output : 'config-util.h', output : 'config-util.h',
) )
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.
# From C++ libraries, only for internals
'-include', 'config-util.hh',
# From C libraries, for our public, installed headers too
'-include', 'config-util.h',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'nix_api_util.cc',
)
include_dirs = [include_directories('.')]
headers = [config_h] + files(
'nix_api_util.h',
)
# TODO don't install this once tests don't use it.
headers += files('nix_api_util_internal.h')
subdir('build-utils-meson/export-all-symbols')
this_library = library( this_library = library(
'nixutilc', 'nixutilc',
sources, sources,
dependencies : deps_public + deps_private + deps_other, dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs, include_directories : include_dirs,
link_args: linker_export_flags, link_args: linker_export_flags,
prelink : true, # For C++ static initializers
install : true, install : true,
) )
@ -98,21 +76,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = [] libraries_private = []
import('pkgconfig').generate( subdir('build-utils-meson/export')
this_library,
filebase : meson.project_name(),
name : 'Nix',
description : 'Nix Package Manager',
subdirs : ['nix'],
extra_cflags : ['-std=c++2a'],
requires : deps_public,
requires_private : deps_private,
libraries_private : libraries_private,
)
meson.override_dependency(meson.project_name(), declare_dependency(
include_directories : include_dirs,
link_with : this_library,
compile_args : ['-std=c++2a'],
dependencies : [],
))

View file

@ -1,5 +1,6 @@
{ lib { lib
, stdenv , stdenv
, mkMesonDerivation
, releaseTools , releaseTools
, meson , meson
@ -11,41 +12,30 @@
# Configuration Options # Configuration Options
, versionSuffix ? "" , versionSuffix ? ""
# Check test coverage of Nix. Probably want to use with at least
# one of `doCheck` or `doInstallCheck` enabled.
, withCoverageChecks ? false
}: }:
let let
inherit (lib) fileset; inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix; version = lib.fileContents ./.version + versionSuffix;
mkDerivation =
if withCoverageChecks
then
# TODO support `finalAttrs` args function in
# `releaseTools.coverageAnalysis`.
argsFun:
releaseTools.coverageAnalysis (let args = argsFun args; in args)
else stdenv.mkDerivation;
in in
mkDerivation (finalAttrs: { mkMesonDerivation (finalAttrs: {
pname = "nix-util-c"; pname = "nix-util-c";
inherit version; inherit version;
src = fileset.toSource { workDir = ./.;
root = ./.;
fileset = fileset.unions [ fileset = fileset.unions [
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build ./meson.build
./meson.options ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.) (fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.) (fileset.fileFilter (file: file.hasExt "hh") ./.)
(fileset.fileFilter (file: file.hasExt "h") ./.) (fileset.fileFilter (file: file.hasExt "h") ./.)
]; ];
};
outputs = [ "out" "dev" ]; outputs = [ "out" "dev" ];
@ -55,19 +45,16 @@ mkDerivation (finalAttrs: {
pkg-config pkg-config
]; ];
buildInputs = [
nix-util
]
;
propagatedBuildInputs = [ propagatedBuildInputs = [
nix-util nix-util
]; ];
preConfigure = preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix # "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
'' ''
echo ${version} > .version chmod u+w ./.version
echo ${version} > ../../.version
''; '';
mesonFlags = [ mesonFlags = [
@ -81,8 +68,7 @@ mkDerivation (finalAttrs: {
separateDebugInfo = !stdenv.hostPlatform.isStatic; separateDebugInfo = !stdenv.hostPlatform.isStatic;
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564 strictDeps = true;
strictDeps = !withCoverageChecks;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie"; hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
@ -90,8 +76,4 @@ mkDerivation (finalAttrs: {
platforms = lib.platforms.unix ++ lib.platforms.windows; platforms = lib.platforms.unix ++ lib.platforms.windows;
}; };
} // lib.optionalAttrs withCoverageChecks {
lcovFilter = [ "*/boost/*" "*-tab.*" ];
hardeningDisable = [ "fortify" ];
}) })

View file

@ -1 +0,0 @@
../tests/unit/libutil/

View file

@ -1 +0,0 @@
../tests/unit/libutil-support/

View file

@ -0,0 +1 @@
../../build-utils-meson

View file

@ -14,39 +14,16 @@ project('nix-util', 'cpp',
cxx = meson.get_compiler('cpp') cxx = meson.get_compiler('cpp')
# These are private dependencies with pkg-config files. What private subdir('build-utils-meson/deps-lists')
# 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.
#
# N.B. This concept is mostly unrelated to our own concept of a public
# (stable) API, for consumption outside of the Nix repository.
# `libnixutil` is an unstable C++ library, whose public interface is
# likewise unstable. `libutilc` conversely is a hopefully-soon stable
# C library, whose public interface --- including public but not private
# dependencies --- will also likewise soon be stable.
#
# N.B. For distributions that care about "ABI" stablity and not just
# "API" stability, the private dependencies also matter as they can
# potentially affect the public ABI.
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() configdata = configuration_data()
deps_private_maybe_subproject = [
]
deps_public_maybe_subproject = [
]
subdir('build-utils-meson/subprojects')
# Check for each of these functions, and create a define like `#define # 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 # HAVE_LUTIMES 1`. The `#define` is unconditional, 0 for not found and 1
# for found. One therefore uses it with `#if` not `#ifdef`. # for found. One therefore uses it with `#if` not `#ifdef`.
@ -71,12 +48,7 @@ foreach funcspec : check_funcs
configdata.set(define_name, define_value) configdata.set(define_name, define_value)
endforeach endforeach
# This is only conditional to work around subdir('build-utils-meson/threads')
# 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
if host_machine.system() == 'windows' if host_machine.system() == 'windows'
socket = cxx.find_library('ws2_32') socket = cxx.find_library('ws2_32')
@ -132,29 +104,18 @@ deps_public += nlohmann_json
config_h = configure_file( config_h = configure_file(
configuration : configdata, configuration : configdata,
output : 'config-util.h', output : 'config-util.hh',
) )
add_project_arguments( add_project_arguments(
# TODO(Qyriad): Yes this is how the autoconf+Make system did it. # TODO(Qyriad): Yes this is how the autoconf+Make system did it.
# It would be nice for our headers to be idempotent instead. # It would be nice for our headers to be idempotent instead.
'-include', 'config-util.h', '-include', 'config-util.hh',
'-Wno-deprecated-declarations',
'-Wimplicit-fallthrough',
'-Werror=switch',
'-Werror=switch-enum',
'-Werror=unused-result',
'-Wdeprecated-copy',
'-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
# at ~1% overhead in `nix search`.
#
# FIXME: remove when we get meson 1.4.0 which will default this to on for us:
# https://mesonbuild.com/Release-notes-for-1-4-0.html#ndebug-setting-now-controls-c-stdlib-assertions
'-D_GLIBCXX_ASSERTIONS=1',
language : 'cpp', language : 'cpp',
) )
subdir('build-utils-meson/diagnostics')
sources = files( sources = files(
'archive.cc', 'archive.cc',
'args.cc', 'args.cc',
@ -280,17 +241,7 @@ else
subdir('unix') subdir('unix')
endif endif
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows' subdir('build-utils-meson/export-all-symbols')
# Windows DLLs are stricter about symbol visibility than Unix shared
# objects --- see https://gcc.gnu.org/wiki/Visibility for details.
# This is a temporary sledgehammer to export everything like on Unix,
# and not detail with this yet.
#
# TODO do not do this, and instead do fine-grained export annotations.
linker_export_flags = ['-Wl,--export-all-symbols']
else
linker_export_flags = []
endif
this_library = library( this_library = library(
'nixutil', 'nixutil',
@ -298,38 +249,17 @@ this_library = library(
dependencies : deps_public + deps_private + deps_other, dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs, include_directories : include_dirs,
link_args: linker_export_flags, link_args: linker_export_flags,
prelink : true, # For C++ static initializers
install : true, install : true,
) )
install_headers(headers, subdir : 'nix', preserve_path : true) install_headers(headers, subdir : 'nix', preserve_path : true)
# Part of how we copy boost libraries to a separate installation to libraries_private = []
# 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' if host_machine.system() == 'windows'
# `libraries_private` cannot contain ad-hoc dependencies (from # `libraries_private` cannot contain ad-hoc dependencies (from
# `find_library), so we need to do this manually # `find_library), so we need to do this manually
libraries_private += ['-lws2_32'] libraries_private += ['-lws2_32']
endif endif
import('pkgconfig').generate( subdir('build-utils-meson/export')
this_library,
filebase : meson.project_name(),
name : 'Nix',
description : 'Nix Package Manager',
subdirs : ['nix'],
extra_cflags : ['-std=c++2a'],
requires : deps_public,
requires_private : deps_private,
libraries_private : libraries_private,
)
meson.override_dependency(meson.project_name(), declare_dependency(
include_directories : include_dirs,
link_with : this_library,
compile_args : ['-std=c++2a'],
dependencies : [],
))

View file

@ -18,25 +18,12 @@
# Configuration Options # Configuration Options
, versionSuffix ? "" , versionSuffix ? ""
# Check test coverage of Nix. Probably want to use with at least
# one of `doCheck` or `doInstallCheck` enabled.
, withCoverageChecks ? false
}: }:
let let
inherit (lib) fileset; inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix; version = lib.fileContents ./.version + versionSuffix;
mkDerivation =
if withCoverageChecks
then
# TODO support `finalAttrs` args function in
# `releaseTools.coverageAnalysis`.
argsFun:
releaseTools.coverageAnalysis (let args = argsFun args; in args)
else stdenv.mkDerivation;
in in
mkMesonDerivation (finalAttrs: { mkMesonDerivation (finalAttrs: {
@ -45,6 +32,8 @@ mkMesonDerivation (finalAttrs: {
workDir = ./.; workDir = ./.;
fileset = fileset.unions [ fileset = fileset.unions [
../../build-utils-meson
./build-utils-meson
../../.version ../../.version
./.version ./.version
./meson.build ./meson.build
@ -65,7 +54,6 @@ mkMesonDerivation (finalAttrs: {
]; ];
buildInputs = [ buildInputs = [
boost
brotli brotli
libsodium libsodium
openssl openssl
@ -73,37 +61,21 @@ mkMesonDerivation (finalAttrs: {
; ;
propagatedBuildInputs = [ propagatedBuildInputs = [
boost.dev boost
libarchive libarchive
nlohmann_json nlohmann_json
]; ];
disallowedReferences = [ boost ];
preConfigure = preConfigure =
# TODO: change release process to add `pre` in `.version`, remove it before tagging, and restore after. # "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
#
# TODO: change release process to add `pre` in `.version`, remove it
# before tagging, and restore after.
'' ''
chmod u+w ./.version chmod u+w ./.version
echo ${version} > ../../.version echo ${version} > ../../.version
'' '';
# 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
rm -f $out/lib/*.a
'' + lib.optionalString stdenv.hostPlatform.isLinux ''
chmod u+w $out/lib/*.so.*
patchelf --set-rpath $out/lib:${stdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.*
'' + lib.optionalString stdenv.hostPlatform.isDarwin ''
for LIB in $out/lib/*.dylib; do
chmod u+w $LIB
install_name_tool -id $LIB $LIB
install_name_tool -delete_rpath ${boost}/lib/ $LIB || true
done
install_name_tool -change ${boost}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib
''
);
mesonFlags = [ mesonFlags = [
(lib.mesonEnable "cpuid" stdenv.hostPlatform.isx86_64) (lib.mesonEnable "cpuid" stdenv.hostPlatform.isx86_64)
@ -120,24 +92,9 @@ mkMesonDerivation (finalAttrs: {
enableParallelBuilding = true; enableParallelBuilding = true;
postInstall =
# 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'
''
+ lib.optionalString stdenv.isDarwin ''
install_name_tool \
-change ${boost}/lib/libboost_context.dylib \
$out/lib/libboost_context.dylib \
$out/lib/libnixutil.dylib
'';
separateDebugInfo = !stdenv.hostPlatform.isStatic; separateDebugInfo = !stdenv.hostPlatform.isStatic;
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564 strictDeps = true;
strictDeps = !withCoverageChecks;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie"; hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
@ -145,8 +102,4 @@ mkMesonDerivation (finalAttrs: {
platforms = lib.platforms.unix ++ lib.platforms.windows; platforms = lib.platforms.unix ++ lib.platforms.windows;
}; };
} // lib.optionalAttrs withCoverageChecks {
lcovFilter = [ "*/boost/*" "*-tab.*" ];
hardeningDisable = [ "fortify" ];
}) })

1
src/nix-expr-test-support Symbolic link
View file

@ -0,0 +1 @@
../tests/unit/libexpr-support

1
src/nix-expr-tests Symbolic link
View file

@ -0,0 +1 @@
../tests/unit/libexpr

1
src/nix-fetchers-tests Symbolic link
View file

@ -0,0 +1 @@
../tests/unit/libfetchers

1
src/nix-flake-tests Symbolic link
View file

@ -0,0 +1 @@
../tests/unit/libflake

1
src/nix-store-test-support Symbolic link
View file

@ -0,0 +1 @@
../tests/unit/libstore-support

1
src/nix-store-tests Symbolic link
View file

@ -0,0 +1 @@
../tests/unit/libstore

1
src/nix-util-test-support Symbolic link
View file

@ -0,0 +1 @@
../tests/unit/libutil-support

1
src/nix-util-tests Symbolic link
View file

@ -0,0 +1 @@
../tests/unit/libutil

View file

@ -1,5 +1,5 @@
#include "config-util.h" #include "config-util.hh"
#include "config-store.h" #include "config-store.hh"
#include "EXTERN.h" #include "EXTERN.h"
#include "perl.h" #include "perl.h"

View file

@ -43,6 +43,7 @@ nix_perl_store_lib = library(
'Store', 'Store',
sources : nix_perl_store_cc, sources : nix_perl_store_cc,
name_prefix : '', name_prefix : '',
prelink : true, # For C++ static initializers
install : true, install : true,
install_mode : 'rwxr-xr-x', install_mode : 'rwxr-xr-x',
install_dir : join_paths(nix_perl_install_dir, 'auto', 'Nix', 'Store'), install_dir : join_paths(nix_perl_install_dir, 'auto', 'Nix', 'Store'),

View file

@ -6,11 +6,6 @@
, ninja , ninja
, pkg-config , pkg-config
, nix-store , nix-store
, curl
, bzip2
, xz
, boost
, libsodium
, darwin , darwin
, versionSuffix ? "" , versionSuffix ? ""
}: }:
@ -40,18 +35,12 @@ perl.pkgs.toPerlModule (stdenv.mkDerivation (finalAttrs: {
meson meson
ninja ninja
pkg-config pkg-config
perl
]; ];
buildInputs = [ buildInputs = [
nix-store nix-store
curl ];
bzip2
xz
perl
boost
]
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
++ lib.optional stdenv.isDarwin darwin.apple_sdk.frameworks.Security;
# `perlPackages.Test2Harness` is marked broken for Darwin # `perlPackages.Test2Harness` is marked broken for Darwin
doCheck = !stdenv.isDarwin; doCheck = !stdenv.isDarwin;

View file

@ -0,0 +1 @@
../../../.version

View file

@ -0,0 +1 @@
../../../build-utils-meson/

View file

@ -0,0 +1,74 @@
project('nix-expr-test-support', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
]
deps_public_maybe_subproject = [
dependency('nix-util'),
dependency('nix-util-test-support'),
dependency('nix-store'),
dependency('nix-store-test-support'),
dependency('nix-expr'),
]
subdir('build-utils-meson/subprojects')
rapidcheck = dependency('rapidcheck')
deps_public += rapidcheck
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-util.hh',
'-include', 'config-store.hh',
'-include', 'config-expr.hh',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'tests/value/context.cc',
)
include_dirs = [include_directories('.')]
headers = files(
'tests/libexpr.hh',
'tests/nix_api_expr.hh',
'tests/value/context.hh',
)
subdir('build-utils-meson/export-all-symbols')
this_library = library(
'nix-expr-test-support',
sources,
dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs,
# TODO: Remove `-lrapidcheck` when https://github.com/emil-e/rapidcheck/pull/326
# is available. See also ../libutil/build.meson
link_args: linker_export_flags + ['-lrapidcheck'],
prelink : true, # For C++ static initializers
install : true,
)
install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = []
subdir('build-utils-meson/export')

View file

@ -0,0 +1,83 @@
{ lib
, stdenv
, mkMesonDerivation
, releaseTools
, meson
, ninja
, pkg-config
, nix-store-test-support
, nix-expr
, rapidcheck
# Configuration Options
, versionSuffix ? ""
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-util-test-support";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../../build-utils-meson
./build-utils-meson
../../../.version
./.version
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
propagatedBuildInputs = [
nix-store-test-support
nix-expr
rapidcheck
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../../.version
'';
mesonFlags = [
];
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

1
tests/unit/libexpr/.version Symbolic link
View file

@ -0,0 +1 @@
../../../.version

View file

@ -0,0 +1 @@
../../../build-utils-meson/

View file

View file

@ -0,0 +1,90 @@
project('nix-expr-tests', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
dependency('nix-expr'),
dependency('nix-expr-c'),
dependency('nix-expr-test-support'),
]
deps_public_maybe_subproject = [
]
subdir('build-utils-meson/subprojects')
subdir('build-utils-meson/export-all-symbols')
rapidcheck = dependency('rapidcheck')
deps_private += rapidcheck
gtest = dependency('gtest')
deps_private += gtest
gtest = dependency('gmock')
deps_private += gtest
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-util.hh',
'-include', 'config-store.hh',
'-include', 'config-store.hh',
'-include', 'config-util.h',
'-include', 'config-store.h',
'-include', 'config-expr.h',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'derived-path.cc',
'error_traces.cc',
'eval.cc',
'json.cc',
'main.cc',
'nix_api_expr.cc',
'nix_api_external.cc',
'nix_api_value.cc',
'primops.cc',
'search-path.cc',
'trivial.cc',
'value/context.cc',
'value/print.cc',
'value/value.cc',
)
include_dirs = [include_directories('.')]
this_exe = executable(
meson.project_name(),
sources,
dependencies : deps_private_subproject + deps_private + deps_other,
include_directories : include_dirs,
# TODO: -lrapidcheck, see ../libutil-support/build.meson
link_args: linker_export_flags + ['-lrapidcheck'],
install : true,
)
test(
meson.project_name(),
this_exe,
env : {
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
},
protocol : 'gtest',
)

View file

@ -0,0 +1,100 @@
{ lib
, stdenv
, mkMesonDerivation
, releaseTools
, meson
, ninja
, pkg-config
, nix-expr
, nix-expr-c
, nix-expr-test-support
, rapidcheck
, gtest
, runCommand
# Configuration Options
, versionSuffix ? ""
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-expr-tests";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../../build-utils-meson
./build-utils-meson
../../../.version
./.version
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
buildInputs = [
nix-expr
nix-expr-c
nix-expr-test-support
rapidcheck
gtest
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../../.version
'';
mesonFlags = [
];
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
passthru = {
tests = {
run = runCommand "${finalAttrs.pname}-run" {
} ''
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
export _NIX_TEST_UNIT_DATA=${./data}
nix-expr-tests
touch $out
'';
};
};
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

View file

@ -0,0 +1 @@
../../../.version

View file

@ -0,0 +1 @@
../../../build-utils-meson/

View file

@ -0,0 +1,71 @@
project('nix-fetchers-tests', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
dependency('nix-store-test-support'),
dependency('nix-fetchers'),
]
deps_public_maybe_subproject = [
]
subdir('build-utils-meson/subprojects')
subdir('build-utils-meson/export-all-symbols')
rapidcheck = dependency('rapidcheck')
deps_private += rapidcheck
gtest = dependency('gtest', main : true)
deps_private += gtest
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-util.hh',
'-include', 'config-store.hh',
'-include', 'config-store.hh',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'public-key.cc',
)
include_dirs = [include_directories('.')]
this_exe = executable(
meson.project_name(),
sources,
dependencies : deps_private_subproject + deps_private + deps_other,
include_directories : include_dirs,
# TODO: -lrapidcheck, see ../libutil-support/build.meson
link_args: linker_export_flags + ['-lrapidcheck'],
# get main from gtest
install : true,
)
test(
meson.project_name(),
this_exe,
env : {
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
},
protocol : 'gtest',
)

View file

@ -0,0 +1,98 @@
{ lib
, stdenv
, mkMesonDerivation
, releaseTools
, meson
, ninja
, pkg-config
, nix-fetchers
, nix-store-test-support
, rapidcheck
, gtest
, runCommand
# Configuration Options
, versionSuffix ? ""
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-fetchers-tests";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../../build-utils-meson
./build-utils-meson
../../../.version
./.version
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
buildInputs = [
nix-fetchers
nix-store-test-support
rapidcheck
gtest
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../../.version
'';
mesonFlags = [
];
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
passthru = {
tests = {
run = runCommand "${finalAttrs.pname}-run" {
} ''
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
export _NIX_TEST_UNIT_DATA=${./data}
nix-fetchers-tests
touch $out
'';
};
};
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

View file

@ -0,0 +1 @@
../../../.version

View file

@ -0,0 +1 @@
../../../build-utils-meson/

View file

View file

@ -0,0 +1,72 @@
project('nix-flake-tests', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
dependency('nix-expr-test-support'),
dependency('nix-flake'),
]
deps_public_maybe_subproject = [
]
subdir('build-utils-meson/subprojects')
subdir('build-utils-meson/export-all-symbols')
rapidcheck = dependency('rapidcheck')
deps_private += rapidcheck
gtest = dependency('gtest', main : true)
deps_private += gtest
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-util.hh',
'-include', 'config-store.hh',
'-include', 'config-expr.hh',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'flakeref.cc',
'url-name.cc',
)
include_dirs = [include_directories('.')]
this_exe = executable(
meson.project_name(),
sources,
dependencies : deps_private_subproject + deps_private + deps_other,
include_directories : include_dirs,
# TODO: -lrapidcheck, see ../libutil-support/build.meson
link_args: linker_export_flags + ['-lrapidcheck'],
# get main from gtest
install : true,
)
test(
meson.project_name(),
this_exe,
env : {
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
},
protocol : 'gtest',
)

View file

@ -0,0 +1,98 @@
{ lib
, stdenv
, mkMesonDerivation
, releaseTools
, meson
, ninja
, pkg-config
, nix-flake
, nix-expr-test-support
, rapidcheck
, gtest
, runCommand
# Configuration Options
, versionSuffix ? ""
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-flake-tests";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../../build-utils-meson
./build-utils-meson
../../../.version
./.version
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
buildInputs = [
nix-flake
nix-expr-test-support
rapidcheck
gtest
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../../.version
'';
mesonFlags = [
];
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
passthru = {
tests = {
run = runCommand "${finalAttrs.pname}-run" {
} ''
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
export _NIX_TEST_UNIT_DATA=${./data}
nix-flake-tests
touch $out
'';
};
};
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

View file

@ -0,0 +1 @@
../../../.version

View file

@ -0,0 +1 @@
../../../build-utils-meson/

View file

@ -0,0 +1,76 @@
project('nix-store-test-support', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
]
deps_public_maybe_subproject = [
dependency('nix-util'),
dependency('nix-util-test-support'),
dependency('nix-store'),
]
subdir('build-utils-meson/subprojects')
rapidcheck = dependency('rapidcheck')
deps_public += rapidcheck
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-util.hh',
'-include', 'config-store.hh',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'tests/derived-path.cc',
'tests/outputs-spec.cc',
'tests/path.cc',
)
include_dirs = [include_directories('.')]
headers = files(
'tests/derived-path.hh',
'tests/libstore.hh',
'tests/nix_api_store.hh',
'tests/outputs-spec.hh',
'tests/path.hh',
'tests/protocol.hh',
)
subdir('build-utils-meson/export-all-symbols')
this_library = library(
'nix-store-test-support',
sources,
dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs,
# TODO: Remove `-lrapidcheck` when https://github.com/emil-e/rapidcheck/pull/326
# is available. See also ../libutil/build.meson
link_args: linker_export_flags + ['-lrapidcheck'],
prelink : true, # For C++ static initializers
install : true,
)
install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = []
subdir('build-utils-meson/export')

View file

@ -0,0 +1,83 @@
{ lib
, stdenv
, mkMesonDerivation
, releaseTools
, meson
, ninja
, pkg-config
, nix-util-test-support
, nix-store
, rapidcheck
# Configuration Options
, versionSuffix ? ""
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-store-test-support";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../../build-utils-meson
./build-utils-meson
../../../.version
./.version
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
propagatedBuildInputs = [
nix-util-test-support
nix-store
rapidcheck
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../../.version
'';
mesonFlags = [
];
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

View file

@ -0,0 +1 @@
../../../.version

View file

@ -0,0 +1 @@
../../../build-utils-meson/

View file

@ -0,0 +1,95 @@
project('nix-store-tests', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
dependency('nix-store'),
dependency('nix-store-c'),
dependency('nix-store-test-support'),
]
deps_public_maybe_subproject = [
]
subdir('build-utils-meson/subprojects')
subdir('build-utils-meson/export-all-symbols')
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19')
deps_private += sqlite
rapidcheck = dependency('rapidcheck')
deps_private += rapidcheck
gtest = dependency('gtest', main : true)
deps_private += gtest
gtest = dependency('gmock')
deps_private += gtest
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-util.hh',
'-include', 'config-store.hh',
'-include', 'config-util.h',
'-include', 'config-store.h',
language : 'cpp',
)
subdir('build-utils-meson/diagnostics')
sources = files(
'common-protocol.cc',
'content-address.cc',
'derivation-advanced-attrs.cc',
'derivation.cc',
'derived-path.cc',
'downstream-placeholder.cc',
'machines.cc',
'nar-info-disk-cache.cc',
'nar-info.cc',
'nix_api_store.cc',
'outputs-spec.cc',
'path-info.cc',
'path.cc',
'references.cc',
'serve-protocol.cc',
'store-reference.cc',
'worker-protocol.cc',
)
include_dirs = [include_directories('.')]
this_exe = executable(
meson.project_name(),
sources,
dependencies : deps_private_subproject + deps_private + deps_other,
include_directories : include_dirs,
# TODO: -lrapidcheck, see ../libutil-support/build.meson
link_args: linker_export_flags + ['-lrapidcheck'],
# get main from gtest
install : true,
)
test(
meson.project_name(),
this_exe,
env : {
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
},
protocol : 'gtest',
)

View file

@ -0,0 +1,111 @@
{ lib
, stdenv
, mkMesonDerivation
, releaseTools
, meson
, ninja
, pkg-config
, nix-store
, nix-store-c
, nix-store-test-support
, sqlite
, rapidcheck
, gtest
, runCommand
# Configuration Options
, versionSuffix ? ""
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
in
mkMesonDerivation (finalAttrs: {
pname = "nix-store-tests";
inherit version;
workDir = ./.;
fileset = fileset.unions [
../../../build-utils-meson
./build-utils-meson
../../../.version
./.version
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
];
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
buildInputs = [
nix-store
nix-store-c
nix-store-test-support
sqlite
rapidcheck
gtest
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../../.version
'';
mesonFlags = [
];
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
passthru = {
tests = {
run = let
# Some data is shared with the functional tests: they create it,
# we consume it.
data = lib.fileset.toSource {
root = ../..;
fileset = lib.fileset.unions [
./data
../../functional/derivation
];
};
in runCommand "${finalAttrs.pname}-run" {} ''
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
export _NIX_TEST_UNIT_DATA=${data + "/unit/libstore/data"}
nix-store-tests
touch $out
'';
};
};
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
})

View file

@ -0,0 +1 @@
../../../build-utils-meson/

View file

@ -14,32 +14,27 @@ project('nix-util-test-support', 'cpp',
cxx = meson.get_compiler('cpp') cxx = meson.get_compiler('cpp')
# See note in ../nix-util/meson.build subdir('build-utils-meson/deps-lists')
deps_private = [ ]
# See note in ../nix-util/meson.build deps_private_maybe_subproject = [
deps_public = [ ] ]
deps_public_maybe_subproject = [
dependency('nix-util'),
]
subdir('build-utils-meson/subprojects')
# See note in ../nix-util/meson.build rapidcheck = dependency('rapidcheck')
deps_other = [ ] deps_public += rapidcheck
add_project_arguments( add_project_arguments(
'-Wno-deprecated-declarations', # TODO(Qyriad): Yes this is how the autoconf+Make system did it.
'-Wimplicit-fallthrough', # It would be nice for our headers to be idempotent instead.
'-Werror=switch', '-include', 'config-util.hh',
'-Werror=switch-enum',
'-Werror=unused-result',
'-Wdeprecated-copy',
'-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
# at ~1% overhead in `nix search`.
#
# FIXME: remove when we get meson 1.4.0 which will default this to on for us:
# https://mesonbuild.com/Release-notes-for-1-4-0.html#ndebug-setting-now-controls-c-stdlib-assertions
'-D_GLIBCXX_ASSERTIONS=1',
language : 'cpp', language : 'cpp',
) )
subdir('build-utils-meson/diagnostics')
sources = files( sources = files(
'tests/hash.cc', 'tests/hash.cc',
'tests/string_callback.cc', 'tests/string_callback.cc',
@ -54,28 +49,7 @@ headers = files(
'tests/string_callback.hh', 'tests/string_callback.hh',
) )
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows' subdir('build-utils-meson/export-all-symbols')
# Windows DLLs are stricter about symbol visibility than Unix shared
# objects --- see https://gcc.gnu.org/wiki/Visibility for details.
# This is a temporary sledgehammer to export everything like on Unix,
# and not detail with this yet.
#
# TODO do not do this, and instead do fine-grained export annotations.
linker_export_flags = ['-Wl,--export-all-symbols']
else
linker_export_flags = []
endif
nix_util = dependency('nix-util')
if nix_util.type_name() == 'internal'
# subproject sadly no good for pkg-config module
deps_other += nix_util
else
deps_public += nix_util
endif
rapidcheck = dependency('rapidcheck')
deps_public += rapidcheck
this_library = library( this_library = library(
'nix-util-test-support', 'nix-util-test-support',
@ -85,6 +59,7 @@ this_library = library(
# TODO: Remove `-lrapidcheck` when https://github.com/emil-e/rapidcheck/pull/326 # TODO: Remove `-lrapidcheck` when https://github.com/emil-e/rapidcheck/pull/326
# is available. See also ../libutil/build.meson # is available. See also ../libutil/build.meson
link_args: linker_export_flags + ['-lrapidcheck'], link_args: linker_export_flags + ['-lrapidcheck'],
prelink : true, # For C++ static initializers
install : true, install : true,
) )
@ -92,20 +67,4 @@ install_headers(headers, subdir : 'nix', preserve_path : true)
libraries_private = [] libraries_private = []
import('pkgconfig').generate( subdir('build-utils-meson/export')
this_library,
filebase : meson.project_name(),
name : 'Nix',
description : 'Nix Package Manager',
subdirs : ['nix'],
extra_cflags : ['-std=c++2a'],
requires : deps_public,
requires_private : deps_private,
)
meson.override_dependency(meson.project_name(), declare_dependency(
include_directories : include_dirs,
link_with : this_library,
compile_args : ['-std=c++2a'],
dependencies : [],
))

View file

@ -1,5 +1,6 @@
{ lib { lib
, stdenv , stdenv
, mkMesonDerivation
, releaseTools , releaseTools
, meson , meson
@ -13,40 +14,29 @@
# Configuration Options # Configuration Options
, versionSuffix ? "" , versionSuffix ? ""
# Check test coverage of Nix. Probably want to use with at least
# one of `doCheck` or `doInstallCheck` enabled.
, withCoverageChecks ? false
}: }:
let let
inherit (lib) fileset; inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix; version = lib.fileContents ./.version + versionSuffix;
mkDerivation =
if withCoverageChecks
then
# TODO support `finalAttrs` args function in
# `releaseTools.coverageAnalysis`.
argsFun:
releaseTools.coverageAnalysis (let args = argsFun args; in args)
else stdenv.mkDerivation;
in in
mkDerivation (finalAttrs: { mkMesonDerivation (finalAttrs: {
pname = "nix-util-test-support"; pname = "nix-util-test-support";
inherit version; inherit version;
src = fileset.toSource { workDir = ./.;
root = ./.;
fileset = fileset.unions [ fileset = fileset.unions [
../../../build-utils-meson
./build-utils-meson
../../../.version
./.version
./meson.build ./meson.build
# ./meson.options # ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.) (fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.) (fileset.fileFilter (file: file.hasExt "hh") ./.)
]; ];
};
outputs = [ "out" "dev" ]; outputs = [ "out" "dev" ];
@ -56,20 +46,17 @@ mkDerivation (finalAttrs: {
pkg-config pkg-config
]; ];
buildInputs = [
nix-util
rapidcheck
]
;
propagatedBuildInputs = [ propagatedBuildInputs = [
nix-util nix-util
rapidcheck
]; ];
preConfigure = preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix # "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
'' ''
echo ${version} > .version chmod u+w ./.version
echo ${version} > ../../../.version
''; '';
mesonFlags = [ mesonFlags = [
@ -83,8 +70,7 @@ mkDerivation (finalAttrs: {
separateDebugInfo = !stdenv.hostPlatform.isStatic; separateDebugInfo = !stdenv.hostPlatform.isStatic;
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564 strictDeps = true;
strictDeps = !withCoverageChecks;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie"; hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
@ -92,8 +78,4 @@ mkDerivation (finalAttrs: {
platforms = lib.platforms.unix ++ lib.platforms.windows; platforms = lib.platforms.unix ++ lib.platforms.windows;
}; };
} // lib.optionalAttrs withCoverageChecks {
lcovFilter = [ "*/boost/*" "*-tab.*" ];
hardeningDisable = [ "fortify" ];
}) })

View file

@ -1 +0,0 @@
2.24.0

1
tests/unit/libutil/.version Symbolic link
View file

@ -0,0 +1 @@
../../../.version

View file

@ -0,0 +1 @@
../../../build-utils-meson/

Some files were not shown because too many files have changed in this diff Show more