964 lines
32 KiB
Nix
964 lines
32 KiB
Nix
{
|
|
pkgs,
|
|
pkgsStatic,
|
|
lib,
|
|
stdenv,
|
|
closureInfo,
|
|
runCommand,
|
|
aws-sdk-cpp,
|
|
# If the patched version of Boehm isn't passed, then patch it based off of
|
|
# pkgs.boehmgc. This allows `callPackage`ing this file without needing to
|
|
# to implement behavior that this package flat out doesn't build without
|
|
# anyway, but also allows easily overriding the patch logic.
|
|
boehmgc-nix ? __forDefaults.boehmgc-nix,
|
|
boehmgc,
|
|
buildPackages,
|
|
nlohmann_json,
|
|
build-release-notes ? __forDefaults.build-release-notes,
|
|
boost,
|
|
brotli,
|
|
bzip2,
|
|
callPackage,
|
|
capnproto,
|
|
cmake,
|
|
curl-lix ? __forDefaults.curl-lix,
|
|
fetchpatch2,
|
|
curl,
|
|
doxygen,
|
|
git,
|
|
gtest,
|
|
jq,
|
|
libarchive,
|
|
libcpuid,
|
|
libseccomp,
|
|
libsystemtap,
|
|
lix-clang-tidy ? null,
|
|
llvmPackages,
|
|
lsof,
|
|
lowdown-unsandboxed,
|
|
lowdown,
|
|
mdbook,
|
|
# older nixpkgs only have v1, newer nixpkgs only have v2
|
|
mdbook-linkcheck ? null,
|
|
mdbook-linkcheck2 ? mdbook-linkcheck,
|
|
mercurial,
|
|
meson,
|
|
ninja,
|
|
openssl,
|
|
passt,
|
|
pegtl,
|
|
pkg-config,
|
|
python3,
|
|
rapidcheck,
|
|
removeReferencesTo,
|
|
rustPlatform,
|
|
rustc,
|
|
cargo,
|
|
sqlite,
|
|
systemtap-lix ? __forDefaults.systemtap-lix,
|
|
toml11,
|
|
util-linuxMinimal ? utillinuxMinimal,
|
|
utillinuxMinimal ? null,
|
|
xz,
|
|
zstd,
|
|
yq,
|
|
wrapBintoolsWith,
|
|
|
|
busybox-sandbox-shell,
|
|
bash,
|
|
|
|
pname ? "lix",
|
|
versionSuffix ? "",
|
|
officialRelease ? __forDefaults.versionJson.official_release,
|
|
# Set to true to build the release notes for the next release.
|
|
buildUnreleasedNotes ? true,
|
|
internalApiDocs ? false,
|
|
|
|
# Support garbage collection in the evaluator.
|
|
enableGC ? sanitize == null || !builtins.elem "address" sanitize,
|
|
# List of Meson sanitize options. Accepts values of b_sanitize, e.g.
|
|
# "address", "undefined", "thread".
|
|
# Enabling the "address" sanitizer will disable garbage collection in the evaluator.
|
|
sanitize ? null,
|
|
# include sanitizer libraries in the build closure (mostly for devshells)
|
|
includeSanitizerLibs ? sanitize != null,
|
|
# Turn compiler warnings into errors.
|
|
werror ? false,
|
|
|
|
lintInsteadOfBuild ? false,
|
|
|
|
useLld ? false,
|
|
|
|
# FIXME(jade): figure out if it is possible to support non-linux systems for dtrace probes
|
|
withDtrace ?
|
|
lib.meta.availableOn stdenv.hostPlatform libsystemtap
|
|
&& lib.meta.availableOn stdenv.buildPlatform systemtap-lix,
|
|
|
|
# In CI, we want to make sure both static and dynamic versions of our libraries build.
|
|
# Building them entirely separately is way too expensive for our anemic CI, so we instead
|
|
# ask Meson to `-Ddefault_library=both`. However that also installs both kinds of libraries,
|
|
# which takes up waaaay more space. So we'll delete the installed static libraries in postInstall.
|
|
ciBuildAndDeleteBothLibraries ? !stdenv.hostPlatform.isStatic,
|
|
|
|
# Not a real argument, just the only way to approximate let-binding some
|
|
# stuff for argument defaults.
|
|
__forDefaults ? {
|
|
canRunInstalled = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
|
|
|
|
versionJson = builtins.fromJSON (builtins.readFile ./version.json);
|
|
|
|
boehmgc-nix = (boehmgc.override { enableLargeConfig = true; }).overrideAttrs (oldAttrs: {
|
|
/*
|
|
TODO: Use the `initialMarkStackSize` override when
|
|
https://github.com/NixOS/nixpkgs/pull/439943 hits a stable branch
|
|
|
|
Increase the initial mark stack size to avoid stack
|
|
overflows, since these inhibit parallel marking (see
|
|
GC_mark_some()). To check whether the mark stack is too
|
|
small, run Nix with GC_PRINT_STATS=1 and look for messages
|
|
such as `Mark stack overflow`, `No room to copy back mark
|
|
stack`, and `Grew mark stack to ... frames`.
|
|
*/
|
|
NIX_CFLAGS_COMPILE = (oldAttrs.NIX_CFLAGS_COMPILE or "") + " -DINITIAL_MARK_STACK_SIZE=1048576";
|
|
});
|
|
|
|
curl-lix =
|
|
# curl 8.21.0 /somehow/ breaks Lix unit tests.
|
|
# See https://github.com/NixOS/nixpkgs/issues/534713
|
|
# FIXME remove once fixed
|
|
if lib.versionAtLeast curl.version "8.21" then
|
|
curl.overrideAttrs (
|
|
{
|
|
patches ? [ ],
|
|
...
|
|
}:
|
|
{
|
|
patches = patches ++ [
|
|
# See https://github.com/curl/curl/commit/2a2104f3cff44bb28bb570a093be52bbeeed8f23
|
|
(fetchpatch2 {
|
|
name = "fix-wakeup-consumption-revert.patch";
|
|
url = "https://github.com/curl/curl/commit/2a2104f3cff44bb28bb570a093be52bbeeed8f23.patch";
|
|
hash = "sha256-dkwr1ZaR7XB408JxeIKhuHxJrlwf3J01jL6lnOLXo1I=";
|
|
revert = true;
|
|
})
|
|
];
|
|
}
|
|
)
|
|
else
|
|
# Filter out the version backported in Nixpkgs
|
|
# https://github.com/NixOS/nixpkgs/issues/534713#event-27130052199
|
|
curl.overrideAttrs (prev: {
|
|
patches = lib.filter (patch: !lib.strings.hasSuffix "fix-wakeup-consumption.patch" patch) (
|
|
prev.patches or [ ]
|
|
);
|
|
});
|
|
|
|
# Avoid a bunch of build closure of the tracer, we just need the dtrace
|
|
# generator.
|
|
systemtap-lix = buildPackages.linuxPackages.systemtap.override { withStap = false; };
|
|
|
|
build-release-notes = callPackage ./maintainers/build-release-notes.nix { };
|
|
},
|
|
}:
|
|
|
|
# gcc miscompiles coroutines at least until 13.2, possibly longer
|
|
assert stdenv.cc.isClang;
|
|
|
|
let
|
|
inherit (__forDefaults) canRunInstalled;
|
|
inherit (lib) fileset;
|
|
inherit (stdenv) hostPlatform buildPlatform;
|
|
|
|
version = __forDefaults.versionJson.version + versionSuffix;
|
|
|
|
# This could be the dtrace for macOS, etc, but I have no idea if it is
|
|
# packaged or if it works.
|
|
dtrace-generator = if withDtrace then systemtap-lix else null;
|
|
|
|
# This is for sys/sdt.h
|
|
dtrace-headers = if withDtrace then libsystemtap else null;
|
|
|
|
# FIXME(jade): can be removed once our nixpkgs has https://github.com/NixOS/nixpkgs/pull/435749 (probably 25.11?)
|
|
dontWrapPython =
|
|
drv:
|
|
drv.overridePythonAttrs (old: {
|
|
dontWrapPythonPrograms = true;
|
|
});
|
|
|
|
aws-sdk-cpp-nix =
|
|
if aws-sdk-cpp == null then
|
|
null
|
|
else
|
|
(aws-sdk-cpp.override {
|
|
apis = [
|
|
"s3"
|
|
"transfer"
|
|
];
|
|
customMemoryManagement = false;
|
|
}).overrideAttrs
|
|
{
|
|
# this overrideAttrs is needed to match the configuration of
|
|
# aws-sdk-cpp in nixpkgs' builds of lix so we don't rebuild this in
|
|
# practice
|
|
requiredSystemFeatures = [ ];
|
|
};
|
|
|
|
# Reimplementation of Nixpkgs' Meson cross file, with some additions to make
|
|
# it actually work.
|
|
mesonCrossFile =
|
|
deps:
|
|
runCommand "lix-cross-file.conf"
|
|
{
|
|
input = ''
|
|
[properties]
|
|
# Meson is convinced that if !buildPlatform.canExecute hostPlatform then we cannot
|
|
# build anything at all, which is not at all correct. If we can't execute the host
|
|
# platform, we'll just disable tests and doc gen.
|
|
needs_exe_wrapper = false
|
|
|
|
[binaries]
|
|
# Meson refuses to consider any CMake binary during cross compilation if it's
|
|
# not explicitly specified here, in the cross file.
|
|
# https://github.com/mesonbuild/meson/blob/0ed78cf6fa6d87c0738f67ae43525e661b50a8a2/mesonbuild/cmake/executor.py#L72
|
|
cmake = 'cmake'
|
|
|
|
[project options]
|
|
builtin-dep-closure = @deps@
|
|
'';
|
|
passAsFile = [ "input" ];
|
|
}
|
|
''
|
|
substitute $inputPath $out --replace-fail @deps@ "$(cat ${deps})"
|
|
'';
|
|
|
|
mesonNativeFile =
|
|
deps:
|
|
runCommand "lix-native-file.conf"
|
|
{
|
|
input = ''
|
|
[project options]
|
|
builtin-dep-closure = @deps@
|
|
'';
|
|
passAsFile = [ "input" ];
|
|
}
|
|
''
|
|
substitute $inputPath $out --replace-fail @deps@ "$(cat ${deps})"
|
|
'';
|
|
|
|
# Remove once https://github.com/NixOS/nixpkgs/pull/476848 lands here.
|
|
pyxattrForPython =
|
|
p:
|
|
p.pyxattr.overrideAttrs (old: {
|
|
buildInputs = lib.filter (lib.meta.availableOn stdenv.hostPlatform) old.buildInputs;
|
|
meta.platforms = old.meta.platforms ++ lib.platforms.darwin;
|
|
});
|
|
|
|
inputsForPython = p: [
|
|
p.python-frontmatter
|
|
p.pycapnp
|
|
];
|
|
|
|
checkInputsForPython = p: [
|
|
(dontWrapPython p.pytest)
|
|
p.pytest-xdist
|
|
p.pytest-timeout
|
|
p.tappy
|
|
p.ruff
|
|
p.aiohttp
|
|
p.mistletoe
|
|
(pyxattrForPython p)
|
|
];
|
|
|
|
devShellInputsForPython = p: [
|
|
p.yapf
|
|
p.requests
|
|
p.xdg-base-dirs
|
|
p.packaging
|
|
p.xonsh
|
|
];
|
|
|
|
# The internal API docs need these for the build, but if we're not building
|
|
# Nix itself, then these don't need to be propagated.
|
|
maybePropagatedInputs = lib.optional enableGC boehmgc-nix ++ [ nlohmann_json ];
|
|
|
|
# .gitignore has already been processed, so any changes in it are irrelevant
|
|
# at this point. It is not represented verbatim for test purposes because
|
|
# that would interfere with repo semantics.
|
|
baseFiles = fileset.fileFilter (f: f.name != ".gitignore") ./.;
|
|
|
|
configureFiles = fileset.unions [ ./version.json ];
|
|
|
|
topLevelBuildFiles = fileset.unions ([
|
|
./meson.build
|
|
./meson.options
|
|
./meson
|
|
./scripts/meson.build
|
|
(fileset.fileFilter (f: lib.strings.hasSuffix ".wrap" f.name) ./subprojects)
|
|
./subprojects/aws_sdk
|
|
./tools
|
|
# Required for meson to generate Cargo wraps
|
|
./Cargo.lock
|
|
./Cargo.toml
|
|
./.cargo/config.toml
|
|
]);
|
|
|
|
functionalTestFiles = fileset.unions [
|
|
./tests/functional
|
|
./tests/functional2
|
|
./tests/unit
|
|
(fileset.fileFilter (f: lib.strings.hasPrefix "nix-profile" f.name) ./scripts)
|
|
];
|
|
|
|
# Nixpkgs only provides an lld wrapper if the entire Nixpkgs is instantiated with "linker = lld",
|
|
# but we can just make one ourselves.
|
|
lldBintools = wrapBintoolsWith {
|
|
bintools = llvmPackages.bintools;
|
|
};
|
|
|
|
# Rustc will use `cc` as the linker by default, but we need to link the C++ standard library.
|
|
# However the C++ compiler is not unprefixed `c++` in Nixpkgs when cross compiling.
|
|
# This is a fair amount of logic to encode in a Cargo config.toml, so the most reasonable
|
|
# options are to have meson `configure_file()` a config.toml,
|
|
# or just use these environment variables.
|
|
cxxLinkerFor = stdenv: lib.getExe' stdenv.cc "${stdenv.cc.targetPrefix}c++";
|
|
hostCargoEnvVar = hostPlatform.rust.cargoEnvVarTarget;
|
|
buildCargoEnvVar = buildPlatform.rust.cargoEnvVarTarget;
|
|
|
|
# Environment variables that set Cargo config values.
|
|
cargoConfigEnv = {
|
|
"CARGO_TARGET_${hostCargoEnvVar}_LINKER" = cxxLinkerFor stdenv;
|
|
}
|
|
// lib.optionalAttrs (hostCargoEnvVar != buildCargoEnvVar) {
|
|
"CARGO_TARGET_${buildCargoEnvVar}_LINKER" = cxxLinkerFor buildPackages.clangStdenv;
|
|
};
|
|
in
|
|
assert (lintInsteadOfBuild -> lix-clang-tidy != null);
|
|
stdenv.mkDerivation (finalAttrs: {
|
|
inherit pname version;
|
|
|
|
__structuredAttrs = true;
|
|
|
|
# python3.withPackages does not splice properly, see https://github.com/NixOS/nixpkgs/issues/305858
|
|
lixPythonForBuild = python3.pythonOnBuildForHost.withPackages (
|
|
p:
|
|
lib.concatLists [
|
|
(inputsForPython p)
|
|
(lib.optionals finalAttrs.doCheck (checkInputsForPython p))
|
|
]
|
|
);
|
|
|
|
# precompile the bridge generator since the zngur parser takes so long to build. this way we can
|
|
# cache the generator in ci and for devshells, both of which decrease cycle times by quite a bit
|
|
licxxbridge = rustPlatform.buildRustPackage {
|
|
pname = "licxxbridge";
|
|
version = "0.0.0";
|
|
src = fileset.toSource {
|
|
root = ./.;
|
|
fileset = fileset.unions [
|
|
./Cargo.toml
|
|
./Cargo.lock
|
|
./tools/licxxbridge
|
|
# these are only needed to let cargo parse the manifests at all, they're not used elsewise
|
|
./lix/lix-doc/Cargo.toml
|
|
./lix/lix-doc/src/lib.rs
|
|
./lix/lix-rs/Cargo.toml
|
|
./lix/lix-rs/src/lib.rs
|
|
];
|
|
};
|
|
cargoDeps = rustPlatform.importCargoLock { lockFile = ./Cargo.lock; };
|
|
cargoBuildFlags = [
|
|
"-p"
|
|
"licxxbridge"
|
|
];
|
|
cargoTestFlags = [
|
|
"-p"
|
|
"licxxbridge"
|
|
];
|
|
meta.mainProgram = "licxxbridge";
|
|
};
|
|
|
|
buildTestShell =
|
|
if hostPlatform.isLinux then
|
|
"${pkgsStatic.bash}/bin"
|
|
else if hostPlatform.isDarwin then
|
|
"${bash}/bin"
|
|
else
|
|
null;
|
|
|
|
buildTestEnv =
|
|
if hostPlatform.isLinux then
|
|
lib.makeBinPath [
|
|
pkgsStatic.busybox
|
|
pkgsStatic.acl
|
|
]
|
|
else
|
|
lib.makeBinPath [
|
|
pkgs.darwin.file_cmds
|
|
pkgs.darwin.shell_cmds
|
|
pkgs.darwin.text_cmds
|
|
];
|
|
|
|
src = fileset.toSource {
|
|
root = ./.;
|
|
fileset = fileset.intersection baseFiles (
|
|
fileset.unions (
|
|
[
|
|
configureFiles
|
|
topLevelBuildFiles
|
|
functionalTestFiles
|
|
]
|
|
++ lib.optionals (!finalAttrs.dontBuild || internalApiDocs || lintInsteadOfBuild) [
|
|
./doc
|
|
./lix
|
|
./misc
|
|
./contrib/plugins
|
|
./COPYING
|
|
]
|
|
++ lib.optionals lintInsteadOfBuild [ ./.clang-tidy ]
|
|
)
|
|
);
|
|
};
|
|
|
|
outputs = [
|
|
"out"
|
|
]
|
|
++ lib.optionals (!finalAttrs.dontBuild) [
|
|
"dev"
|
|
"doc"
|
|
];
|
|
|
|
dontBuild = lintInsteadOfBuild;
|
|
|
|
mesonFlags =
|
|
let
|
|
sanitizeOpts = lib.optional (
|
|
sanitize != null
|
|
) "-Db_sanitize=${builtins.concatStringsSep "," sanitize}";
|
|
in
|
|
lib.optionals hostPlatform.isLinux [
|
|
# You'd think meson could just find this in PATH, but busybox is in buildInputs,
|
|
# which don't actually get added to PATH. And buildInputs is correct over
|
|
# nativeBuildInputs since this should be a busybox executable on the host.
|
|
"-Dsandbox-shell=${lib.getExe' busybox-sandbox-shell "busybox"}"
|
|
"-Dpasta-path=${lib.getExe' passt "pasta"}"
|
|
]
|
|
++ lib.optional (
|
|
finalAttrs.buildTestShell != null
|
|
) "-Dbuild-test-shell=${finalAttrs.buildTestShell}"
|
|
++ lib.optional (finalAttrs.buildTestEnv != null) "-Dbuild-test-env=${finalAttrs.buildTestEnv}"
|
|
++ lib.optionals useLld [
|
|
"-Dc_link_args=-fuse-ld=lld"
|
|
"-Dcpp_link_args=-fuse-ld=lld"
|
|
]
|
|
++ lib.optionals hostPlatform.isStatic [
|
|
"-Denable-embedded-sandbox-shell=true"
|
|
"-Denable-contrib-plugins=false"
|
|
"-Db_sanitize=none"
|
|
]
|
|
++ lib.optional ciBuildAndDeleteBothLibraries "-Ddefault_library=both"
|
|
# musl doesn't support fibers, and we can't detect this with meson alone.
|
|
++ lib.optional hostPlatform.isMusl "-Ddisable-fibers=true"
|
|
++ lib.optional (finalAttrs.dontBuild && !lintInsteadOfBuild) "-Denable-build=false"
|
|
++ lib.optional (!finalAttrs.dontBuild) "-Dlicxxbridge=${lib.getExe finalAttrs.licxxbridge}"
|
|
++ lib.optional lintInsteadOfBuild "-Dlix-clang-tidy-checks-path=${lix-clang-tidy}/lib/liblix-clang-tidy.${
|
|
if hostPlatform.isDarwin then "dylib" else "so"
|
|
}"
|
|
++ [
|
|
# mesonConfigurePhase automatically passes -Dauto_features=enabled,
|
|
# so we must explicitly enable or disable features that we are not passing
|
|
# dependencies for.
|
|
(lib.mesonEnable "gc" enableGC)
|
|
(lib.mesonEnable "internal-api-docs" internalApiDocs)
|
|
(lib.mesonEnable "dtrace-probes" withDtrace)
|
|
(lib.mesonBool "enable-tests" (finalAttrs.finalPackage.doCheck || lintInsteadOfBuild))
|
|
(lib.mesonBool "enable-docs" canRunInstalled)
|
|
(lib.mesonBool "werror" werror)
|
|
]
|
|
++ lib.optional (
|
|
hostPlatform != buildPlatform
|
|
) "--cross-file=${mesonCrossFile finalAttrs.builtinDeps}"
|
|
++ lib.optional (
|
|
hostPlatform == buildPlatform
|
|
) "--native-file=${mesonNativeFile finalAttrs.builtinDeps}"
|
|
# Temporary workaround for https://git.lix.systems/lix-project/lix/issues/832
|
|
++ lib.optional (hostPlatform.isDarwin) "-Db_lto=false"
|
|
++ sanitizeOpts;
|
|
|
|
# We only include CMake so that Meson can locate toml11, which only ships CMake dependency metadata.
|
|
dontUseCmakeConfigure = true;
|
|
|
|
# depsBuildBuild is put in PATH before nativeBuildInputs, but clangStdenv.cc's version
|
|
# of clang-tidy doesn't seem to work. Thankfully, if we're linting, we don't need to
|
|
# compile things for the build platform either.
|
|
depsBuildBuild = lib.optionals (!lintInsteadOfBuild) [
|
|
# clangStdenv is spliced but clangStdenv.cc is not:
|
|
# https://github.com/NixOS/nixpkgs/issues/211340
|
|
buildPackages.clangStdenv.cc
|
|
];
|
|
|
|
nativeBuildInputs = [
|
|
rustPlatform.cargoSetupHook
|
|
finalAttrs.lixPythonForBuild
|
|
meson
|
|
ninja
|
|
cmake
|
|
rustc
|
|
cargo
|
|
capnproto
|
|
# Required for libstd++ assertions that leaks inside of the final binary.
|
|
removeReferencesTo
|
|
dtrace-generator
|
|
]
|
|
++ [
|
|
(lib.getBin lowdown-unsandboxed)
|
|
(lib.warnIf
|
|
(
|
|
# if mdbook 0.5 is backported to 25.11
|
|
(lib.trivial.release == "25.11" && lib.versionAtLeast mdbook.version "0.5.0")
|
|
# or 25.11 is EOL
|
|
|| (lib.trivial.oldestSupportedRelease > 2511)
|
|
)
|
|
"Workarounds for mdbook 0.4.x/0.5.x interoperability can be removed as 0.5.0 is in nixpkgs-stable"
|
|
mdbook
|
|
)
|
|
mdbook-linkcheck2
|
|
]
|
|
++ [
|
|
pkg-config
|
|
|
|
# Tests
|
|
git
|
|
mercurial
|
|
jq
|
|
yq
|
|
lsof
|
|
zstd
|
|
# For mTLS tests
|
|
curl-lix
|
|
]
|
|
++ lib.optional useLld lldBintools
|
|
++ lib.optional hostPlatform.isLinux util-linuxMinimal
|
|
++ lib.optional (!officialRelease && buildUnreleasedNotes) build-release-notes
|
|
++ lib.optional internalApiDocs doxygen
|
|
++ lib.optionals lintInsteadOfBuild [
|
|
llvmPackages.libllvm
|
|
# required for a wrapped clang-tidy
|
|
llvmPackages.clang-tools
|
|
# load-bearing order (just as below); the actual stdenv wrapped clang
|
|
# needs to precede the unwrapped clang in PATH such that calling `clang`
|
|
# can compile things.
|
|
stdenv.cc
|
|
# required for run-clang-tidy
|
|
llvmPackages.clang-unwrapped
|
|
];
|
|
|
|
buildInputs = [
|
|
curl-lix
|
|
bzip2
|
|
xz
|
|
brotli
|
|
openssl
|
|
sqlite
|
|
libarchive
|
|
boost
|
|
lowdown
|
|
toml11
|
|
pegtl
|
|
capnproto
|
|
dtrace-headers
|
|
]
|
|
# NOTE(Raito): I'd have expected that the LLVM packaging would inject the
|
|
# libunwind library path directly in the wrappers, but it does inject
|
|
# -lunwind without injecting the library path...
|
|
++ lib.optionals stdenv.hostPlatform.isStatic [ llvmPackages.libunwind ]
|
|
++ lib.optionals hostPlatform.isLinux [
|
|
libseccomp
|
|
passt
|
|
]
|
|
++ lib.optional internalApiDocs rapidcheck
|
|
++ lib.optional hostPlatform.isx86_64 libcpuid
|
|
# There have been issues building these dependencies
|
|
++ lib.optional (hostPlatform.canExecute buildPlatform) aws-sdk-cpp-nix
|
|
++ lib.optionals (finalAttrs.dontBuild) maybePropagatedInputs
|
|
# I am so sorry. This is because checkInputs are required to pass
|
|
# configure, but we don't actually want to *run* the checks here.
|
|
++ lib.optionals lintInsteadOfBuild finalAttrs.checkInputs;
|
|
|
|
checkInputs = [
|
|
gtest
|
|
(rapidcheck.overrideAttrs (old: {
|
|
patches = (old.patches or [ ]) ++ [ ./misc/rapidcheck-gen-hpp.patch ];
|
|
}))
|
|
];
|
|
|
|
propagatedBuildInputs = lib.optionals (!finalAttrs.dontBuild) maybePropagatedInputs;
|
|
|
|
disallowedReferences = [
|
|
boost
|
|
buildPackages.python3
|
|
finalAttrs.lixPythonForBuild
|
|
];
|
|
|
|
# dep closure for builtin builders in meson array form for immediate use
|
|
builtinDeps =
|
|
if hostPlatform.isStatic then
|
|
builtins.toFile "lix-static-dep-closure" "[]"
|
|
else
|
|
runCommand "lix-builtin-dep-closure"
|
|
{
|
|
closure = closureInfo {
|
|
# closureInfo does not work all that well for things like lowdown,
|
|
# where it finds only -out but not -lib. we'll take -out and -lib,
|
|
# ignoring -bin, -man, -dev, etc. and hope that'll be good enough.
|
|
rootPaths = lib.flatten (
|
|
map
|
|
(drv: [
|
|
(drv.out or [ ])
|
|
(drv.lib or [ ])
|
|
])
|
|
(
|
|
lib.subtractLists finalAttrs.disallowedReferences (
|
|
finalAttrs.buildInputs
|
|
++ finalAttrs.propagatedBuildInputs
|
|
# include compiler wrapper as an input to get the sanitizer libraries too
|
|
++ lib.optional includeSanitizerLibs stdenv.cc
|
|
)
|
|
)
|
|
);
|
|
};
|
|
}
|
|
''
|
|
closure=($(cat $closure/store-paths))
|
|
closure="$(printf ", '%s'" "''${closure[@]}")"
|
|
printf "[%s]" "''${closure:2}" >$out
|
|
'';
|
|
|
|
env = {
|
|
# Meson allows referencing a /usr/share/cargo/registry shaped thing for subproject sources.
|
|
# Turns out the Nix-generated Cargo dependencies are named the same as they
|
|
# would be in a Cargo registry cache.
|
|
MESON_PACKAGE_CACHE_DIR = finalAttrs.cargoDeps;
|
|
|
|
VERSION_SUFFIX = versionSuffix;
|
|
}
|
|
# Putting these here means they'll also work in the dev shell.
|
|
// cargoConfigEnv
|
|
// lib.optionalAttrs (finalAttrs.buildTestEnv != null) {
|
|
BUILD_TEST_ENV = finalAttrs.buildTestEnv;
|
|
}
|
|
// lib.optionalAttrs (finalAttrs.buildTestShell != null) {
|
|
BUILD_TEST_SHELL = finalAttrs.buildTestShell;
|
|
}
|
|
// lib.optionalAttrs hostPlatform.isStatic {
|
|
NIX_CFLAGS_COMPILE = " -static";
|
|
}
|
|
// lib.optionalAttrs (hostPlatform.isStatic && stdenv.cc.libcxx == null) {
|
|
# pkgsStatic.clangStdenv.cc does not have the correct libstdc++.
|
|
# It's using pkgsStatic.buildPackages.gcc.cc, whose libstdc++ appears
|
|
# to have object files that were compiled with -fno-pic,
|
|
# (R_X86_64_32, R_X86_64_32S, and R_X86_64_TPOFF32 relocations).
|
|
# pkgsStatic.gcc.cc's libstdc++ has the correct relocations, but idk
|
|
# what the correct `wrapCCWith`/`stdenv.cc.override` incantation is.
|
|
# But just putting that libstdc++ in `-L` seems to make the driver find
|
|
# the right things.
|
|
NIX_CFLAGS_LINK = "-L${lib.getLib pkgsStatic.gcc.cc}/lib";
|
|
};
|
|
|
|
cargoDeps = rustPlatform.importCargoLock { lockFile = ./Cargo.lock; };
|
|
|
|
preConfigure = ''
|
|
# Fix up /usr/bin/env shebangs relied on by the build
|
|
patchShebangs --build tests/ doc/manual/
|
|
'';
|
|
|
|
mesonBuildType = "debugoptimized";
|
|
|
|
installTargets = lib.optional internalApiDocs "internal-api-html";
|
|
|
|
enableParallelBuilding = true;
|
|
|
|
doCheck = canRunInstalled && !lintInsteadOfBuild;
|
|
|
|
mesonCheckFlags = [
|
|
"--suite=check"
|
|
];
|
|
# the tests access localhost.
|
|
__darwinAllowLocalNetworking = true;
|
|
|
|
# Make sure the internal API docs are already built, because mesonInstallPhase
|
|
# won't let us build them there. They would normally be built in buildPhase,
|
|
# but the internal API docs are conventionally built with doBuild = false.
|
|
preInstall =
|
|
(lib.optionalString internalApiDocs ''
|
|
meson ''${mesonBuildFlags:-} compile "$installTargets"
|
|
'')
|
|
# evil, but like above, we do not want to run an actual build phase
|
|
+ lib.optionalString lintInsteadOfBuild ''
|
|
ninja clang-tidy
|
|
'';
|
|
|
|
installPhase = lib.optionalString lintInsteadOfBuild ''
|
|
runHook preInstall
|
|
touch $out
|
|
runHook postInstall
|
|
'';
|
|
|
|
postInstall =
|
|
lib.optionalString (!finalAttrs.dontBuild) ''
|
|
mkdir -p $doc/nix-support
|
|
echo "doc manual $doc/share/doc/nix/manual" >> $doc/nix-support/hydra-build-products
|
|
''
|
|
+ lib.optionalString ciBuildAndDeleteBothLibraries ''
|
|
rm -f $out/lib/liblix{cmd,expr,fetchers,main,store,util}${hostPlatform.extensions.staticLibrary}
|
|
''
|
|
+ lib.optionalString hostPlatform.isStatic ''
|
|
mkdir -p $out/nix-support
|
|
echo "file binary-dist $out/bin/nix" >> $out/nix-support/hydra-build-products
|
|
''
|
|
+ lib.optionalString internalApiDocs ''
|
|
mkdir -p $out/nix-support
|
|
echo "doc internal-api-docs $out/share/doc/nix/internal-api/html" >> "$out/nix-support/hydra-build-products"
|
|
''
|
|
+ lib.optionalString (sanitize == null) ''
|
|
# Drop all references to libstd++ include files due to `__FILE__` leaking in libstd++ assertions.
|
|
# we do NOT want to do this during asan builds because it breaks the test suite! but as we do not
|
|
# actually want to ship asan builds in any reasonable capacity the leak will not matter that much
|
|
find "$out" -type f -exec remove-references-to -t ${stdenv.cc.cc.stdenv.cc.cc} '{}' +
|
|
'';
|
|
|
|
doInstallCheck = finalAttrs.doCheck;
|
|
|
|
mesonInstallCheckFlags = [
|
|
"--suite=installcheck"
|
|
"--max-lines=10000"
|
|
];
|
|
|
|
installCheckPhase = ''
|
|
runHook preInstallCheck
|
|
|
|
(
|
|
unset -v preCheck preCheckHooks postCheck postCheckHooks
|
|
mesonCheckFlags=("''${mesonInstallCheckFlags[@]}")
|
|
mesonCheckPhase
|
|
)
|
|
|
|
runHook postInstallCheck
|
|
'';
|
|
|
|
# NOTE: This is disabled everywhere except Darwin due to Nixpkgs
|
|
# corrupting `.debug_gdb_scripts` segments (which currently aren't used on Darwin)
|
|
separateDebugInfo = !hostPlatform.isStatic && !finalAttrs.dontBuild && hostPlatform.isDarwin;
|
|
|
|
strictDeps = true;
|
|
|
|
# strictoverflow is disabled because we trap on signed overflow instead
|
|
hardeningDisable = [ "strictoverflow" ];
|
|
|
|
meta = {
|
|
mainProgram = "nix";
|
|
platforms = lib.platforms.unix;
|
|
};
|
|
|
|
# Export the patched version of boehmgc.
|
|
# flake.nix exports that into its overlay.
|
|
passthru = {
|
|
inherit (__forDefaults)
|
|
boehmgc-nix
|
|
curl-lix
|
|
build-release-notes
|
|
pegtl
|
|
;
|
|
|
|
# The collection of dependency logic for this derivation is complicated enough that
|
|
# it's easier to parameterize the devShell off an already called package.nix.
|
|
mkDevShell =
|
|
{
|
|
pkgsBuildHost,
|
|
|
|
mkShell,
|
|
|
|
bashInteractive,
|
|
clangbuildanalyzer,
|
|
doxygen,
|
|
glibcLocales,
|
|
just,
|
|
nixfmt,
|
|
skopeo,
|
|
tree,
|
|
|
|
# Lix specific packages
|
|
pre-commit-checks,
|
|
contribNotice,
|
|
check-syscalls,
|
|
|
|
# Rust development tools
|
|
rust-analyzer,
|
|
cargo,
|
|
rustc,
|
|
rustfmt,
|
|
rustPlatform,
|
|
|
|
# debuggers
|
|
gdb,
|
|
rr,
|
|
}:
|
|
let
|
|
glibcFix = lib.optionalAttrs (buildPlatform.isLinux && glibcLocales != null) {
|
|
# Required to make non-NixOS Linux not complain about missing locale files during configure in a dev shell
|
|
LOCALE_ARCHIVE = "${lib.getLib pkgsBuildHost.glibcLocales}/lib/locale/locale-archive";
|
|
};
|
|
|
|
# FIXME: these have to be added twice due to the nix shell using a
|
|
# wrapped python instead of build inputs for its python inputs
|
|
pythonEnv = python3.pythonOnBuildForHost.withPackages (
|
|
p:
|
|
lib.concatLists [
|
|
(inputsForPython p)
|
|
(checkInputsForPython p)
|
|
(devShellInputsForPython p)
|
|
]
|
|
);
|
|
|
|
# pkgs.mkShell uses pkgs.stdenv by default, regardless of inputsFrom.
|
|
actualMkShell = mkShell.override { inherit stdenv; };
|
|
in
|
|
actualMkShell (
|
|
glibcFix
|
|
// {
|
|
|
|
name = "lix-shell-env";
|
|
|
|
# finalPackage is necessary to propagate stuff that is set by mkDerivation itself,
|
|
# like doCheck.
|
|
inputsFrom = [ finalAttrs.finalPackage ];
|
|
|
|
# For Meson to find Boost.
|
|
env = finalAttrs.env;
|
|
|
|
mesonFlags =
|
|
# I guess this is necessary because mesonFlags to mkDerivation doesn't propagate in inputsFrom,
|
|
# which only propagates stuff set in hooks? idk.
|
|
finalAttrs.mesonFlags
|
|
# Clangd breaks when GCC is using precompiled headers, so for the devshell specifically
|
|
# we make precompiled C++ stdlib conditional on using Clang.
|
|
# https://git.lix.systems/lix-project/lix/issues/374
|
|
++ [ (lib.mesonBool "enable-pch-std" stdenv.cc.isClang) ];
|
|
depsBuildBuild = [
|
|
# From a strict deps point-of-view, I'm pretty sure this is literally incorrect.
|
|
# The clang-tidy from clang-tools is for checking source files that are compiled
|
|
# for the host machine.
|
|
# However, we need a clang-tools version of clang-tidy in PATH before
|
|
# clangStdenv.cc, and it seems like all depsBuildBuild things come before
|
|
# "packages" things.
|
|
# I also tried just putting these in `packages` with the correct ordering,
|
|
# but that did not work.
|
|
# I guess the platform offsets really do matter here, even in the devshell.
|
|
buildPackages.llvmPackages.clang-tools
|
|
|
|
# This *has* clang-tidy, but it doesn't (seem to?) work.
|
|
buildPackages.clangStdenv.cc
|
|
];
|
|
|
|
packages =
|
|
lib.optional (stdenv.cc.isClang && hostPlatform == buildPlatform) llvmPackages.clang-tools
|
|
++ [
|
|
# Why are we providing a bashInteractive? Well, when you run
|
|
# `bash` from inside `nix develop`, say, because you are using it
|
|
# via direnv, you will by default get bash (unusable edition).
|
|
bashInteractive
|
|
check-syscalls
|
|
pythonEnv
|
|
# docker image tool
|
|
skopeo
|
|
just
|
|
nixfmt
|
|
# Included above when internalApiDocs is true, but we set that to
|
|
# false intentionally to save dev build time.
|
|
# To build them in a dev shell, you can set -Dinternal-api-docs=enabled when configuring.
|
|
doxygen
|
|
# Load-bearing order. Must come before clang-unwrapped below, but after clang_tools above.
|
|
stdenv.cc
|
|
|
|
# git-clang-format
|
|
llvmPackages.libclang.python
|
|
|
|
# Required for releng scripts
|
|
tree
|
|
]
|
|
++ [
|
|
rust-analyzer
|
|
cargo
|
|
rustc
|
|
rustfmt
|
|
rustPlatform.rustLibSrc
|
|
rustPlatform.rustcSrc
|
|
]
|
|
++ lib.optionals stdenv.cc.isClang [
|
|
# Required for clang-tidy checks.
|
|
llvmPackages.llvm
|
|
llvmPackages.clang-unwrapped.dev
|
|
]
|
|
++ lib.optionals (pre-commit-checks ? enabledPackages) pre-commit-checks.enabledPackages
|
|
++ lib.optional (lib.meta.availableOn buildPlatform clangbuildanalyzer) clangbuildanalyzer
|
|
++ lib.optional (!stdenv.isDarwin) gdb
|
|
++ lib.optional (lib.meta.availableOn buildPlatform rr && hostPlatform == buildPlatform) rr
|
|
++ finalAttrs.checkInputs;
|
|
|
|
shellHook = ''
|
|
# don't re-run the hook in (other) nested nix-shells
|
|
function lixShellHook() {
|
|
# n.b. how the heck does this become -env-env? well, `nix develop` does it:
|
|
# https://git.lix.systems/lix-project/lix/src/commit/7575db522e9008685c4009423398f6900a16bcce/src/nix/develop.cc#L240-L241
|
|
# this is, of course, absurd.
|
|
if [[ $name != lix-shell-env && $name != lix-shell-env-env ]]; then
|
|
return
|
|
fi
|
|
|
|
PATH=$prefix/bin''${PATH:+:''${PATH}}
|
|
unset PYTHONPATH
|
|
export MANPATH=$out/share/man:''${MANPATH:-}
|
|
|
|
# default build dir. lets rust-analyzer find generated code
|
|
export MESON_BUILD_DIR="$PWD/build"
|
|
|
|
# Make bash completion work.
|
|
XDG_DATA_DIRS+=:$out/share
|
|
|
|
if [[ ! -f ./.this-is-lix ]]; then
|
|
echo "Dev shell not started from inside a Lix repo, skipping repo setup" >&2
|
|
return
|
|
fi
|
|
|
|
${lib.optionalString (pre-commit-checks ? shellHook) pre-commit-checks.shellHook}
|
|
# Allow `touch .nocontribmsg` to turn this notice off.
|
|
if ! [[ -f .nocontribmsg ]]; then
|
|
cat ${contribNotice}
|
|
fi
|
|
|
|
# Install the Gerrit commit-msg hook.
|
|
# (git common dir is the main .git, including for worktrees)
|
|
if gitcommondir=$(git rev-parse --git-common-dir 2>/dev/null) && [[ ! -f "$gitcommondir/hooks/commit-msg" ]]; then
|
|
echo 'Installing Gerrit commit-msg hook (adds Change-Id to commit messages)' >&2
|
|
mkdir -p "$gitcommondir/hooks"
|
|
curl -s -Lo "$gitcommondir/hooks/commit-msg" https://gerrit.lix.systems/tools/hooks/commit-msg
|
|
chmod u+x "$gitcommondir/hooks/commit-msg"
|
|
fi
|
|
unset gitcommondir
|
|
}
|
|
|
|
lixShellHook
|
|
'';
|
|
}
|
|
);
|
|
|
|
perl-bindings = pkgs.callPackage ./perl {
|
|
inherit fileset stdenv;
|
|
nix = finalAttrs.finalPackage;
|
|
};
|
|
|
|
binaryTarball = pkgs.callPackage ./nix-support/binary-tarball.nix {
|
|
nix = finalAttrs.finalPackage;
|
|
};
|
|
};
|
|
})
|