grapevine/nix/pkgs/default/default.nix
Benjamin Lee 8f24ac1f27
do default-feature unification in nix
Some of the features affect nix dependencies, so we need to have a
full feature list available when constructing the nix derivation. This
incidentally fixes the bug where we weren't enabling jemalloc on rocksdb
in CI/devshells, because jemalloc is now a default feature. It does not
fix the more general class of that issue, where CI is performing an
`--all-features` build in a nix devshell built for default-features.

I am now passing `--no-default-features` to cargo, and having it use our
unified feature list rather than duplicating the unification inside cargo.
2024-05-30 21:19:08 -07:00

121 lines
3.2 KiB
Nix

# Dependencies (keep sorted)
{ craneLib
, inputs
, jq
, lib
, pkgsBuildHost
, rocksdb
, rust
, rust-jemalloc-sys
, stdenv
# Options (keep sorted)
, default-features ? true
, features ? []
, profile ? "release"
}:
let
# We perform default-feature unification in nix, because some of the dependencies
# on the nix side depend on feature values.
allDefaultFeatures =
(lib.importTOML "${inputs.self}/Cargo.toml").features.default;
features' = lib.unique
(features ++ lib.optionals default-features allDefaultFeatures);
featureEnabled = feature : builtins.elem feature features';
# This derivation will set the JEMALLOC_OVERRIDE variable, causing the
# tikv-jemalloc-sys crate to use the nixpkgs jemalloc instead of building it's
# own. In order for this to work, we need to set flags on the build that match
# whatever flags tikv-jemalloc-sys was going to use. These are dependent on
# which features we enable in tikv-jemalloc-sys.
rust-jemalloc-sys' = (rust-jemalloc-sys.override {
# tikv-jemalloc-sys/unprefixed_malloc_on_supported_platforms feature
unprefixed = true;
});
buildDepsOnlyEnv =
let
rocksdb' = rocksdb.override {
jemalloc = rust-jemalloc-sys';
enableJemalloc = featureEnabled "jemalloc";
};
in
{
NIX_OUTPATH_USED_AS_RANDOM_SEED = "randomseed";
CARGO_PROFILE = profile;
ROCKSDB_INCLUDE_DIR = "${rocksdb'}/include";
ROCKSDB_LIB_DIR = "${rocksdb'}/lib";
}
//
(import ./cross-compilation-env.nix {
# Keep sorted
inherit
lib
pkgsBuildHost
rust
stdenv;
});
buildPackageEnv = {
GRAPEVINE_VERSION_EXTRA = inputs.self.shortRev or inputs.self.dirtyShortRev;
} // buildDepsOnlyEnv;
commonAttrs = {
inherit
(craneLib.crateNameFromCargoToml {
cargoToml = "${inputs.self}/Cargo.toml";
})
pname
version;
src = let filter = inputs.nix-filter.lib; in filter {
root = inputs.self;
# Keep sorted
include = [
"Cargo.lock"
"Cargo.toml"
"src"
];
};
buildInputs = lib.optional (featureEnabled "jemalloc") rust-jemalloc-sys';
nativeBuildInputs = [
# bindgen needs the build platform's libclang. Apparently due to "splicing
# weirdness", pkgs.rustPlatform.bindgenHook on its own doesn't quite do the
# right thing here.
pkgsBuildHost.rustPlatform.bindgenHook
# We don't actually depend on `jq`, but crane's `buildPackage` does, but
# its `buildDepsOnly` doesn't. This causes those two derivations to have
# differing values for `NIX_CFLAGS_COMPILE`, which contributes to spurious
# rebuilds of bindgen and its depedents.
jq
];
};
in
craneLib.buildPackage ( commonAttrs // {
cargoArtifacts = craneLib.buildDepsOnly (commonAttrs // {
env = buildDepsOnlyEnv;
});
cargoExtraArgs = "--locked --no-default-features "
+ lib.optionalString
(features' != [])
"--features " + (builtins.concatStringsSep "," features');
# This is redundant with CI
doCheck = false;
env = buildPackageEnv;
passthru = {
env = buildPackageEnv;
};
meta.mainProgram = commonAttrs.pname;
})