buildRustCrate: Support versioned crate renames
This commit is contained in:
parent
5f9af254a5
commit
bb660fe228
2 changed files with 99 additions and 4 deletions
|
@ -13,14 +13,30 @@ let
|
|||
then "macos"
|
||||
else stdenv.hostPlatform.parsed.kernel.name;
|
||||
|
||||
# Create rustc arguments to link against the given list of dependencies and
|
||||
# renames
|
||||
# Create rustc arguments to link against the given list of dependencies
|
||||
# and renames.
|
||||
#
|
||||
# See docs for crateRenames below.
|
||||
mkRustcDepArgs = dependencies: crateRenames:
|
||||
lib.concatMapStringsSep " " (dep:
|
||||
let
|
||||
extern = lib.replaceStrings ["-"] ["_"] dep.libName;
|
||||
normalizeName = lib.replaceStrings ["-"] ["_"];
|
||||
extern = normalizeName dep.libName;
|
||||
# Find a choice that matches in name and optionally version.
|
||||
findMatchOrUseExtern = choices:
|
||||
lib.findFirst (choice:
|
||||
(!(choice ? version)
|
||||
|| choice.version == dep.version or ""))
|
||||
{ rename = extern; }
|
||||
choices;
|
||||
name = if lib.hasAttr dep.crateName crateRenames then
|
||||
lib.strings.replaceStrings ["-"] ["_"] crateRenames.${dep.crateName}
|
||||
let choices = crateRenames.${dep.crateName};
|
||||
in
|
||||
normalizeName (
|
||||
if builtins.isList choices
|
||||
then (findMatchOrUseExtern choices).rename
|
||||
else choices
|
||||
)
|
||||
else
|
||||
extern;
|
||||
in (if lib.any (x: x == "lib" || x == "rlib") dep.crateType then
|
||||
|
@ -92,12 +108,45 @@ in
|
|||
#
|
||||
# Example:
|
||||
#
|
||||
# `crateRenames` supports two formats.
|
||||
#
|
||||
# The simple version is an attrset that maps the
|
||||
# `crateName`s of the dependencies to their alternative
|
||||
# names.
|
||||
#
|
||||
# ```nix
|
||||
# {
|
||||
# my_crate_name = "my_alternative_name";
|
||||
# # ...
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# The extended version is also keyed by the `crateName`s but allows
|
||||
# different names for different crate versions:
|
||||
#
|
||||
# ```nix
|
||||
# {
|
||||
# my_crate_name = [
|
||||
# { version = "1.2.3"; rename = "my_alternative_name01"; }
|
||||
# { version = "3.2.3"; rename = "my_alternative_name03"; }
|
||||
# ]
|
||||
# # ...
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# This roughly corresponds to the following snippet in Cargo.toml:
|
||||
#
|
||||
# ```toml
|
||||
# [dependencies]
|
||||
# my_alternative_name01 = { package = "my_crate_name", version = "0.1" }
|
||||
# my_alternative_name03 = { package = "my_crate_name", version = "0.3" }
|
||||
# ```
|
||||
#
|
||||
# Dependencies which use the lib target name as extern name, do not need
|
||||
# to be specified in the crateRenames, even if their crate name differs.
|
||||
#
|
||||
# Including multiple versions of a crate is very popular during
|
||||
# ecosystem transitions, e.g. from futures 0.1 to futures 0.3.
|
||||
, crateRenames
|
||||
# A list of extra options to pass to rustc.
|
||||
#
|
||||
|
@ -172,6 +221,7 @@ stdenv.mkDerivation (rec {
|
|||
|
||||
src = crate.src or (fetchCrate { inherit (crate) crateName version sha256; });
|
||||
name = "rust_${crate.crateName}-${crate.version}${lib.optionalString buildTests_ "-test"}";
|
||||
version = crate.version;
|
||||
depsBuildBuild = [ rust stdenv.cc cargo jq ];
|
||||
buildInputs = (crate.buildInputs or []) ++ buildInputs_;
|
||||
dependencies = map lib.getLib dependencies_;
|
||||
|
|
|
@ -197,6 +197,51 @@ let
|
|||
dependencies = [ (mkCrate { crateName = "foo"; libName = "foolib"; src = mkLib "src/lib.rs"; }) ];
|
||||
crateRenames = { "foo" = "foo_renamed"; };
|
||||
};
|
||||
crateBinRenameMultiVersion = let
|
||||
crateWithVersion = version: mkCrate {
|
||||
crateName = "my_lib";
|
||||
inherit version;
|
||||
src = mkFile "src/lib.rs" ''
|
||||
pub const version: &str = "${version}";
|
||||
'';
|
||||
};
|
||||
depCrate01 = crateWithVersion "0.1.2";
|
||||
depCrate02 = crateWithVersion "0.2.1";
|
||||
in {
|
||||
crateName = "my_bin";
|
||||
src = symlinkJoin {
|
||||
name = "my_bin_src";
|
||||
paths = [
|
||||
(mkFile "src/main.rs" ''
|
||||
#[test]
|
||||
fn my_lib_01() { assert_eq!(lib01::version, "0.1.2"); }
|
||||
|
||||
#[test]
|
||||
fn my_lib_02() { assert_eq!(lib02::version, "0.2.1"); }
|
||||
|
||||
fn main() { }
|
||||
'')
|
||||
];
|
||||
};
|
||||
dependencies = [ depCrate01 depCrate02 ];
|
||||
crateRenames = {
|
||||
"my_lib" = [
|
||||
{
|
||||
version = "0.1.2";
|
||||
rename = "lib01";
|
||||
}
|
||||
{
|
||||
version = "0.2.1";
|
||||
rename = "lib02";
|
||||
}
|
||||
];
|
||||
};
|
||||
buildTests = true;
|
||||
expectedTestOutputs = [
|
||||
"test my_lib_01 ... ok"
|
||||
"test my_lib_02 ... ok"
|
||||
];
|
||||
};
|
||||
rustLibTestsDefault = {
|
||||
src = mkTestFile "src/lib.rs" "baz";
|
||||
buildTests = true;
|
||||
|
|
Loading…
Reference in a new issue