mirror of
https://github.com/nix-community/naersk
synced 2025-02-17 03:38:24 +00:00
Add support for prebuilt dependencies
This commit is contained in:
parent
9787ccbeee
commit
4022afd8b9
6 changed files with 150 additions and 118 deletions
97
build.nix
97
build.nix
|
@ -1,10 +1,10 @@
|
|||
src:
|
||||
{ #| What command to run during the build phase
|
||||
cargoBuild ? "cargo build --frozen --$CARGO_BUILD_PROFILE -j $NIX_BUILD_CORES"
|
||||
cargoBuild ? "cargo build --$CARGO_BUILD_PROFILE -j $NIX_BUILD_CORES"
|
||||
, #| What command to run during the test phase
|
||||
cargoTest ? "cargo test --$CARGO_BUILD_PROFILE"
|
||||
, doCheck ? true
|
||||
, name ? null
|
||||
, name
|
||||
, rustc
|
||||
, cargo
|
||||
, override ? null
|
||||
|
@ -24,12 +24,10 @@ src:
|
|||
, symlinkJoin
|
||||
, runCommand
|
||||
, remarshal
|
||||
, crateDependencies
|
||||
, cratePaths
|
||||
}:
|
||||
|
||||
with
|
||||
{ libb = import ./lib.nix { inherit lib writeText runCommand remarshal; };
|
||||
};
|
||||
|
||||
with
|
||||
{ builtinz =
|
||||
builtins //
|
||||
|
@ -37,49 +35,23 @@ with
|
|||
{ inherit writeText remarshal runCommand ; };
|
||||
};
|
||||
|
||||
with
|
||||
{ cargolock =
|
||||
if isNull cargolockPath then
|
||||
builtinz.readTOML "${src}/Cargo.lock"
|
||||
else
|
||||
builtinz.readTOML cargolockPath;
|
||||
cargotoml =
|
||||
if isNull cargotomlPath then
|
||||
builtinz.readTOML "${src}/Cargo.toml"
|
||||
else
|
||||
builtinz.readTOML cargotomlPath;
|
||||
};
|
||||
|
||||
with rec
|
||||
{
|
||||
drv = stdenv.mkDerivation
|
||||
{ inherit src doCheck nativeBuildInputs cargolockPath cargotomlPath;
|
||||
{ inherit
|
||||
src
|
||||
doCheck
|
||||
nativeBuildInputs
|
||||
cargolockPath
|
||||
cargotomlPath
|
||||
cratePaths
|
||||
name;
|
||||
|
||||
CARGO_BUILD_PROFILE = if release then "release" else "debug";
|
||||
|
||||
# The list of paths to Cargo.tomls. If this is a workspace, the paths
|
||||
# are the members. Otherwise, there is a single path, ".".
|
||||
cratePaths =
|
||||
with rec
|
||||
{ workspaceMembers = cargotoml.workspace.members or null;
|
||||
};
|
||||
|
||||
if isNull workspaceMembers then "."
|
||||
else lib.concatStringsSep "\n" workspaceMembers;
|
||||
|
||||
# Otherwise specifying CMake as a dep breaks the build
|
||||
dontUseCmakeConfigure = true;
|
||||
|
||||
name =
|
||||
if ! isNull name then
|
||||
name
|
||||
else if lib.length crateNames == 0 then
|
||||
abort "No crate names"
|
||||
else if lib.length crateNames == 1 then
|
||||
lib.head crateNames
|
||||
else
|
||||
lib.head crateNames + "-et-al";
|
||||
|
||||
buildInputs =
|
||||
[ cargo
|
||||
|
||||
|
@ -89,9 +61,8 @@ with rec
|
|||
# needed for "cc"
|
||||
llvmPackages.stdenv.cc
|
||||
|
||||
# needed for "cc"
|
||||
# needed at various steps in the build
|
||||
jq
|
||||
|
||||
rsync
|
||||
] ++ (stdenv.lib.optionals stdenv.isDarwin
|
||||
[ darwin.Security
|
||||
|
@ -129,7 +100,7 @@ with rec
|
|||
|
||||
mkdir -p target
|
||||
|
||||
cat ${writeText "deps" (builtins.toJSON builtDependencies)} |\
|
||||
cat ${builtinz.writeJSON "deps" builtDependencies} |\
|
||||
jq -r '.[]' |\
|
||||
while IFS= read -r dep
|
||||
do
|
||||
|
@ -180,7 +151,7 @@ with rec
|
|||
# "--$CARGO_BUILD_PROFILE" like we do with "cargo build" and "cargo
|
||||
# test"
|
||||
install_arg=""
|
||||
if "$CARGO_BUILD_PROFILE" == "debug"
|
||||
if [ "$CARGO_BUILD_PROFILE" == "debug" ]
|
||||
then
|
||||
install_arg="--debug"
|
||||
fi
|
||||
|
@ -189,7 +160,11 @@ with rec
|
|||
for p in "$cratePaths"; do
|
||||
# XXX: we don't quote install_arg to avoid passing an empty arg
|
||||
# to cargo
|
||||
cargo install --path $p $install_arg --bins --root $out ||\
|
||||
cargo install \
|
||||
--path $p \
|
||||
$install_arg \
|
||||
--bins \
|
||||
--root $out ||\
|
||||
echo "WARNING: Member wasn't installed: $p"
|
||||
done
|
||||
|
||||
|
@ -222,36 +197,16 @@ with rec
|
|||
echo '{"package":"${sha256}","files":{}}' > $out/${name}-${version}/.cargo-checksum.json
|
||||
'';
|
||||
|
||||
# creates a forest of symlinks of all the dependencies XXX: this is very
|
||||
# basic and means that we have very little incrementality; e.g. when
|
||||
# anything changes all the deps will be rebuilt. The rustc compiler is
|
||||
# pretty fast so this is not too bad. In the future we'll want to pre-build
|
||||
# the crates and give cargo a pre-populated ./target directory.
|
||||
mkSnapshotForest =
|
||||
symlinkJoin
|
||||
{ name = "crates-io";
|
||||
paths = map (v: unpackCrate v.name v.version v.sha256)
|
||||
(libb.mkVersions cargolock);
|
||||
};
|
||||
|
||||
# All the Cargo.tomls, including the top-level one
|
||||
cargotomls =
|
||||
with rec
|
||||
{ workspaceMembers = cargotoml.workspace.members or [];
|
||||
};
|
||||
|
||||
[cargotoml] ++ (
|
||||
map (member: (builtinz.readTOML "${src}/${member}/Cargo.toml"))
|
||||
workspaceMembers);
|
||||
|
||||
crateNames = builtins.filter (pname: ! isNull pname) (
|
||||
map (ctoml: ctoml.package.name or null) cargotomls);
|
||||
|
||||
cargoconfig = builtinz.writeTOML
|
||||
{ source =
|
||||
{ crates-io = { replace-with = "nix-sources"; } ;
|
||||
nix-sources =
|
||||
{ directory = mkSnapshotForest; };
|
||||
{ directory = symlinkJoin
|
||||
{ name = "crates-io";
|
||||
paths = map (v: unpackCrate v.name v.version v.sha256)
|
||||
crateDependencies;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
-of json \
|
||||
-o $out
|
||||
''));
|
||||
|
||||
writeTOML = attrs: runCommand "write-toml"
|
||||
{ buildInputs = [ remarshal ]; }
|
||||
''
|
||||
|
@ -24,4 +25,7 @@
|
|||
-of toml \
|
||||
-o $out
|
||||
'';
|
||||
|
||||
writeJSON = name: attrs: writeText name
|
||||
(builtins.toJSON attrs);
|
||||
}
|
||||
|
|
141
default.nix
141
default.nix
|
@ -15,50 +15,117 @@
|
|||
with
|
||||
{ libb = import ./lib.nix { inherit lib writeText runCommand remarshal; }; };
|
||||
|
||||
with
|
||||
{ defaultBuildAttrs =
|
||||
{ inherit
|
||||
llvmPackages
|
||||
jq
|
||||
runCommand
|
||||
lib
|
||||
darwin
|
||||
writeText
|
||||
stdenv
|
||||
rsync
|
||||
remarshal
|
||||
symlinkJoin
|
||||
cargo
|
||||
rustc;
|
||||
};
|
||||
};
|
||||
|
||||
with
|
||||
{ builtinz =
|
||||
builtins //
|
||||
import ./builtins.nix
|
||||
{ inherit writeText remarshal runCommand ; };
|
||||
};
|
||||
|
||||
# Crate building
|
||||
with rec
|
||||
{
|
||||
commonAttrs = src: attrs: rec
|
||||
{ cargolockPath = attrs.cargolockPath or null;
|
||||
cargotomlPath = attrs.cargotomlPath or null;
|
||||
cargolock =
|
||||
if isNull cargolockPath then
|
||||
builtinz.readTOML "${src}/Cargo.lock"
|
||||
else
|
||||
builtinz.readTOML cargolockPath;
|
||||
cargotoml =
|
||||
if isNull cargotomlPath then
|
||||
builtinz.readTOML "${src}/Cargo.toml"
|
||||
else
|
||||
builtinz.readTOML cargotomlPath;
|
||||
# The list of paths to Cargo.tomls. If this is a workspace, the paths
|
||||
# are the members. Otherwise, there is a single path, ".".
|
||||
cratePaths =
|
||||
with rec
|
||||
{ workspaceMembers = cargotoml.workspace.members or null;
|
||||
};
|
||||
|
||||
if isNull workspaceMembers then "."
|
||||
else lib.concatStringsSep "\n" workspaceMembers;
|
||||
crateDependencies = libb.mkVersions cargolock;
|
||||
directDependencies = lib.filter
|
||||
(v:
|
||||
lib.elem v.name (builtins.attrNames cargotoml.dependencies) ||
|
||||
(builtins.hasAttr "dev-dependencies" cargotoml &&
|
||||
lib.elem v.name (builtins.attrNames cargotoml.dev-dependencies)
|
||||
)
|
||||
)
|
||||
(libb.mkVersions cargolock);
|
||||
};
|
||||
buildPackage = src: attrs:
|
||||
with (commonAttrs src attrs);
|
||||
import ./build.nix src
|
||||
( { inherit
|
||||
llvmPackages
|
||||
jq
|
||||
runCommand
|
||||
lib
|
||||
darwin
|
||||
writeText
|
||||
stdenv
|
||||
rsync
|
||||
remarshal
|
||||
symlinkJoin
|
||||
cargo
|
||||
rustc;
|
||||
} // attrs
|
||||
( defaultBuildAttrs //
|
||||
{ name = "foo"; # TODO: infer from toml
|
||||
inherit cratePaths crateDependencies;
|
||||
} //
|
||||
attrs
|
||||
);
|
||||
|
||||
# XXX: not quite working yet
|
||||
# buildPackageIncremental = cargolock: name: version: src: attrs:
|
||||
# with rec
|
||||
# { buildDependency = depName: depVersion:
|
||||
# # Really this should be 'buildPackageIncremental' but that makes
|
||||
# # Nix segfault
|
||||
# buildPackage (libb.dummySrc depName depVersion)
|
||||
# { cargoBuild = "cargo build --$CARGO_BUILD_PROFILE -p ${depName}:${depVersion} -j $NIX_BUILD_CORES";
|
||||
# inherit (attrs) cargo;
|
||||
# cargotomlPath = libb.writeTOML (libb.cargotomlFor depName depVersion);
|
||||
# cargolockPath = libb.writeTOML (
|
||||
# libb.cargolockFor cargolock depName depVersion
|
||||
# );
|
||||
# doCheck = false;
|
||||
# };
|
||||
# };
|
||||
# buildPackage src (attrs //
|
||||
# {
|
||||
# builtDependencies = map (x: buildDependency x.name x.version)
|
||||
# (libb.directDependencies cargolock name version) ;
|
||||
# }
|
||||
# );
|
||||
|
||||
buildPackageIncremental = src: attrs:
|
||||
with (commonAttrs src attrs);
|
||||
with
|
||||
{ buildDepsScript = writeText "prebuild-script"
|
||||
''
|
||||
cat ${builtinz.writeJSON "crates" directDependencies} |\
|
||||
jq -r \
|
||||
--arg cbp $CARGO_BUILD_PROFILE \
|
||||
--arg nbc $NIX_BUILD_CORES \
|
||||
'.[] | "cargo build --\($cbp) -j \($nbc) -p \(.name):\(.version)"' |\
|
||||
while IFS= read -r c
|
||||
do
|
||||
echo "Running build command $c"
|
||||
$c
|
||||
done
|
||||
'';
|
||||
};
|
||||
buildPackage src
|
||||
(attrs //
|
||||
{ builtDependencies = [
|
||||
(
|
||||
buildPackage libb.dummySrc
|
||||
(attrs //
|
||||
{ cargoBuild = "source ${buildDepsScript}";
|
||||
doCheck = false;
|
||||
cargolockPath = builtinz.writeTOML cargolock;
|
||||
cargotomlPath = builtinz.writeTOML
|
||||
(
|
||||
{ package = { name = "dummy"; version = "0.0.0"; };
|
||||
dependencies = cargotoml.dependencies;
|
||||
} //
|
||||
(lib.optionalAttrs
|
||||
(builtins.hasAttr "dev-dependencies" cargotoml)
|
||||
{ inherit (cargotoml) dev-dependencies; }
|
||||
)
|
||||
)
|
||||
;
|
||||
})
|
||||
)
|
||||
];
|
||||
});
|
||||
};
|
||||
|
||||
{ inherit buildPackage buildPackageIncremental crates;
|
||||
|
|
5
lib.nix
5
lib.nix
|
@ -79,7 +79,7 @@ rec
|
|||
};
|
||||
|
||||
# A very minimal 'src' which makes cargo happy nonetheless
|
||||
dummySrc = name: version: runCommand "dummy-${name}-${version}" {}
|
||||
dummySrc = runCommand "dummy-src" {}
|
||||
''
|
||||
mkdir -p $out/src
|
||||
touch $out/src/main.rs
|
||||
|
@ -118,4 +118,7 @@ rec
|
|||
parseDependency' = str:
|
||||
with { components = lib.splitString " " str; };
|
||||
{ name = lib.elemAt components 0; version = lib.elemAt components 1; };
|
||||
|
||||
allRemoteDependencies = cargolock:
|
||||
[];
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
"homepage": "https://doc.rust-lang.org/cargo",
|
||||
"owner": "nmattia",
|
||||
"repo": "cargo",
|
||||
"rev": "87d48b01ed21b0c90ce081273cd7a0eb70673342",
|
||||
"sha256": "1v68v40px7p7w6wmbvls6x3my3jyvl5m22ll9bz3vfwwdv5r4fcq",
|
||||
"rev": "979904e092b39bb6aafe62a3ff3d994d3d8b6247",
|
||||
"sha256": "078hhwii2qhdsm179xl249p0c2445yiyl5dv48kvx2372mc0g2gd",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/nmattia/cargo/archive/87d48b01ed21b0c90ce081273cd7a0eb70673342.tar.gz",
|
||||
"url": "https://github.com/nmattia/cargo/archive/979904e092b39bb6aafe62a3ff3d994d3d8b6247.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"lorri": {
|
||||
|
|
15
test.nix
15
test.nix
|
@ -77,14 +77,21 @@ rec
|
|||
# Error: Cannot parse as TOML (<string>(92, 14): msg)
|
||||
#rust = naersk.buildPackage sources.rust {};
|
||||
|
||||
rustlings = naersk.buildPackage sources.rustlings {};
|
||||
rustlings = naersk.buildPackageIncremental sources.rustlings {};
|
||||
|
||||
simple-dep = naersk.buildPackage ./test/simple-dep {};
|
||||
simple-dep = naersk.buildPackageIncremental
|
||||
(pkgs.lib.cleanSource ./test/simple-dep)
|
||||
{ inherit cargo; };
|
||||
|
||||
# TODO: figure out why 'cargo install' rebuilds some deps
|
||||
cargo =
|
||||
with rec
|
||||
{ cargoSrc = sources.cargo ;
|
||||
cargoCargoToml = builtinz.readTOML "${cargoSrc}/Cargo.toml";
|
||||
|
||||
# XXX: this works around some hack that breaks the build. For more info
|
||||
# on the hack, see
|
||||
# https://github.com/rust-lang/rust/blob/b43eb4235ac43c822d903ad26ed806f34cc1a14a/Cargo.toml#L63-L65
|
||||
cargoCargoToml' = cargoCargoToml //
|
||||
{ dependencies = pkgs.lib.filterAttrs (k: _:
|
||||
k != "rustc-workspace-hack")
|
||||
|
@ -100,10 +107,6 @@ rec
|
|||
# Tests fail, although cargo seems to operate normally
|
||||
doCheck = false;
|
||||
|
||||
# cannot pass in --frozen because cargo fails (unsure why).
|
||||
# Nonetheless, cargo doesn't try to hit the network, so we're fine.
|
||||
cargoBuild = "cargo build --release -j $NIX_BUILD_CORES";
|
||||
|
||||
override = oldAttrs:
|
||||
{ buildInputs = oldAttrs.buildInputs ++
|
||||
[ pkgs.pkgconfig
|
||||
|
|
Loading…
Add table
Reference in a new issue