mirror of
https://github.com/ipetkov/crane.git
synced 2024-11-22 23:17:15 +03:00
Add buildPackage
for building and installing cargo packages
This commit is contained in:
parent
47316bfe5b
commit
f69c8a4c44
53
lib/buildPackage.nix
Normal file
53
lib/buildPackage.nix
Normal file
@ -0,0 +1,53 @@
|
||||
{ buildWithCargo
|
||||
, installFromCargoBuildLogHook
|
||||
}:
|
||||
|
||||
{ cargoBuildCommand ? "cargo build --workspace --release"
|
||||
, cargoExtraArgs ? ""
|
||||
, ...
|
||||
}@args:
|
||||
# NB: we use overrideAttrs here so that our extra additions here do not end up
|
||||
# invalidating any deps builds by being inherited. For example, we probably don't
|
||||
# care about installing bins/libs from the deps only build, so there's no point to
|
||||
# trying to build it with the install scripts in its build environment.
|
||||
(buildWithCargo args).overrideAttrs (old: {
|
||||
# Don't copy target dir by default since we are going to be installing bins/libs
|
||||
doCopyTargetToOutput = args.doCopyTargetToOutput or false;
|
||||
|
||||
buildPhase = args.buildPhase or ''
|
||||
runHook preBuild
|
||||
${args.buildPhaseCargoCommand or ''
|
||||
cargoBuildLog=$(mktemp cargoBuildLogXXXX.json)
|
||||
${cargoBuildCommand} --message-format json-render-diagnostics ${cargoExtraArgs} >"$cargoBuildLog"
|
||||
''}
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = args.installPhase or ''
|
||||
runHook preInstall
|
||||
${args.installPhaseCargoCommand or ''
|
||||
if [ -n "$cargoBuildLog" -a -f "$cargoBuildLog" ]; then
|
||||
installFromCargoBuildLog "$out" "$cargoBuildLog"
|
||||
else
|
||||
echo '
|
||||
$cargoBuildLog is either undefined or does not point to a valid file location!
|
||||
By default `buildPackage` will capture cargo'"'"'s output and use it to determine which binaries
|
||||
should be installed (instead of just guessing based on what is present in cargo'"'"'s target directory).
|
||||
If you are overriding the derivation with a custom build step, you have two options:
|
||||
1. override `installPhaseCargoCommand` with the appropriate installation steps
|
||||
2. ensure that cargo'"'"'s build log is captured in a file and point $cargoBuildLog at it
|
||||
At a minimum, the latter option can be achieved with running:
|
||||
cargoBuildLog=$(mktemp cargoBuildLogXXXX.json)
|
||||
cargo build --message-format json-render-diagnostics >"$cargoBuildLog"
|
||||
'
|
||||
|
||||
false
|
||||
fi
|
||||
''}
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [
|
||||
installFromCargoBuildLogHook
|
||||
];
|
||||
})
|
@ -48,9 +48,6 @@ mkCargoDerivation (args // {
|
||||
# This can be inferred automatically if the `src` root has a Cargo.lock file.
|
||||
cargoVendorDir = args.cargoVendorDir or (vendorCargoDepsFromArgs args);
|
||||
|
||||
# Don't copy target dir by default since we are going to be installing bins/libs
|
||||
doCopyTargetToOutput = args.doCopyTargetToOutput or false;
|
||||
|
||||
nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
|
||||
installFromCargoArtifactsHook
|
||||
];
|
||||
|
@ -13,6 +13,7 @@ lib.makeScope newScope (self:
|
||||
inherit fromTOML toTOML;
|
||||
|
||||
buildDepsOnly = callPackage ./buildDepsOnly.nix { };
|
||||
buildPackage = callPackage ./buildPackage.nix { };
|
||||
buildWithCargo = callPackage ./buildWithCargo.nix { };
|
||||
cleanCargoToml = callPackage ./cleanCargoToml.nix { };
|
||||
crateNameFromCargoToml = callPackage ./crateNameFromCargoToml.nix { };
|
||||
|
@ -1,4 +1,6 @@
|
||||
{ makeSetupHook
|
||||
{ cargo
|
||||
, makeSetupHook
|
||||
, jq
|
||||
, rsync
|
||||
, zstd
|
||||
}:
|
||||
@ -35,6 +37,15 @@
|
||||
name = "installFromCargoArtifactsHook";
|
||||
} ./installFromCargoArtifactsHook.sh;
|
||||
|
||||
installFromCargoBuildLogHook = makeSetupHook
|
||||
{
|
||||
name = "installFromCargoBuildLogHook";
|
||||
substitutions = {
|
||||
cargo = "${cargo}/bin/cargo";
|
||||
jq = "${jq}/bin/jq";
|
||||
};
|
||||
} ./installFromCargoBuildLogHook.sh;
|
||||
|
||||
remapSourcePathPrefixHook = makeSetupHook
|
||||
{
|
||||
name = "remapSourcePathPrefixHook";
|
||||
|
42
pkgs/installFromCargoBuildLogHook.sh
Normal file
42
pkgs/installFromCargoBuildLogHook.sh
Normal file
@ -0,0 +1,42 @@
|
||||
function installFromCargoBuildLog() (
|
||||
local dest=${1:-${out}}
|
||||
local log=${2:-${cargoBuildLog:?not defined}}
|
||||
|
||||
if ! [ -f "${log}" ]; then
|
||||
echo unable to install, cargo build log does not exist at: ${log}
|
||||
false
|
||||
fi
|
||||
|
||||
echo searching for bins/libs to install from cargo build log at ${log}
|
||||
|
||||
local select_non_test='select(.reason == "compiler-artifact" and .profile.test == false)'
|
||||
local select_bins="${select_non_test} | .executable | select(.!= null)"
|
||||
local select_lib_files="${select_non_test}"'
|
||||
| select(.target.kind | contains(["staticlib"]) or contains(["cdylib"]))
|
||||
| .filenames[]
|
||||
| select(endswith(".rlib") | not)
|
||||
'
|
||||
|
||||
function installArtifacts() {
|
||||
local loc=${1?:missing}
|
||||
mkdir -p "${loc}"
|
||||
|
||||
while IFS= read -r to_install; do
|
||||
echo installing ${to_install}
|
||||
cp "${to_install}" "${loc}"
|
||||
done
|
||||
|
||||
rmdir --ignore-fail-on-non-empty "${loc}"
|
||||
}
|
||||
|
||||
@jq@ -r <"${log}" "${select_bins}" | installArtifacts "${dest}/bin"
|
||||
|
||||
@cargo@ metadata --format-version 1 | @jq@ '.workspace_members[]' | (
|
||||
while IFS= read -r ws_member; do
|
||||
local select_member_libs="select(.package_id == ${ws_member}) | ${select_lib_files}"
|
||||
@jq@ -r <"${log}" "${select_member_libs}" | installArtifacts "${dest}/lib"
|
||||
done
|
||||
)
|
||||
|
||||
echo searching for bins/libs complete!
|
||||
)
|
@ -45,8 +45,26 @@ pkgs.lib.makeScope myLib.newScope (self:
|
||||
src = ./various-targets;
|
||||
};
|
||||
|
||||
simple = myLib.buildWithCargo {
|
||||
doCopyTargetToOutput = false;
|
||||
manyLibs = myLib.buildPackage {
|
||||
src = ./with-libs;
|
||||
pname = "my-libs";
|
||||
version = "0.0.1";
|
||||
cargoArtifacts = null;
|
||||
};
|
||||
|
||||
manyLibsInstalledAsExpected = pkgs.runCommand "manyLibsInstalledAsExpected" { } ''
|
||||
cat >expected <<EOF
|
||||
liball_types.a
|
||||
liball_types.so
|
||||
libonly_cdylib.so
|
||||
libonly_staticlib.a
|
||||
EOF
|
||||
|
||||
diff ./expected <(ls -1 ${self.manyLibs}/lib)
|
||||
touch $out
|
||||
'';
|
||||
|
||||
simple = myLib.buildPackage {
|
||||
src = ./simple;
|
||||
};
|
||||
|
||||
@ -58,8 +76,7 @@ pkgs.lib.makeScope myLib.newScope (self:
|
||||
|
||||
smokeOverlappingTargets =
|
||||
let
|
||||
overlappingTargets = myLib.buildWithCargo {
|
||||
doCopyTargetToOutput = false;
|
||||
overlappingTargets = myLib.buildPackage {
|
||||
src = ./overlapping-targets;
|
||||
};
|
||||
in
|
||||
|
28
tests/with-libs/Cargo.lock
generated
Normal file
28
tests/with-libs/Cargo.lock
generated
Normal file
@ -0,0 +1,28 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "all-types"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"some-dep",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "only-cdylib"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"some-dep",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "only-staticlib"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"some-dep",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "some-dep"
|
||||
version = "0.1.0"
|
7
tests/with-libs/Cargo.toml
Normal file
7
tests/with-libs/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"only-cdylib",
|
||||
"only-staticlib",
|
||||
"all-types",
|
||||
]
|
||||
exclude = ["some-dep"]
|
15
tests/with-libs/all-types/Cargo.toml
Normal file
15
tests/with-libs/all-types/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "all-types"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
some-dep = { path = "../some-dep" }
|
||||
|
||||
[lib]
|
||||
crate-type = [
|
||||
"cdylib",
|
||||
"rlib",
|
||||
"staticlib",
|
||||
]
|
||||
|
4
tests/with-libs/all-types/src/lib.rs
Normal file
4
tests/with-libs/all-types/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#[no_mangle]
|
||||
pub fn bar(a: i32) -> i32 {
|
||||
some_dep::foo(a) * a
|
||||
}
|
13
tests/with-libs/only-cdylib/Cargo.toml
Normal file
13
tests/with-libs/only-cdylib/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "only-cdylib"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
some-dep = { path = "../some-dep" }
|
||||
|
||||
[lib]
|
||||
crate-type = [
|
||||
"cdylib",
|
||||
]
|
||||
|
4
tests/with-libs/only-cdylib/src/lib.rs
Normal file
4
tests/with-libs/only-cdylib/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#[no_mangle]
|
||||
pub fn bar(a: i32) -> i32 {
|
||||
some_dep::foo(a) * a
|
||||
}
|
13
tests/with-libs/only-staticlib/Cargo.toml
Normal file
13
tests/with-libs/only-staticlib/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "only-staticlib"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
some-dep = { path = "../some-dep" }
|
||||
|
||||
[lib]
|
||||
crate-type = [
|
||||
"staticlib",
|
||||
]
|
||||
|
4
tests/with-libs/only-staticlib/src/lib.rs
Normal file
4
tests/with-libs/only-staticlib/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#[no_mangle]
|
||||
pub fn bar(a: i32) -> i32 {
|
||||
some_dep::foo(a) * a
|
||||
}
|
7
tests/with-libs/some-dep/Cargo.lock
generated
Normal file
7
tests/with-libs/some-dep/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "some-dep"
|
||||
version = "0.1.0"
|
11
tests/with-libs/some-dep/Cargo.toml
Normal file
11
tests/with-libs/some-dep/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "some-dep"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = [
|
||||
"cdylib",
|
||||
"rlib",
|
||||
"staticlib",
|
||||
]
|
4
tests/with-libs/some-dep/src/lib.rs
Normal file
4
tests/with-libs/some-dep/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#[no_mangle]
|
||||
pub fn foo(a: i32) -> i32 {
|
||||
a + 42
|
||||
}
|
Loading…
Reference in New Issue
Block a user