diff options
author | Peter Kolloch <info@eigenvalue.net> | 2020-04-10 00:55:44 +0200 |
---|---|---|
committer | Peter Kolloch <info@eigenvalue.net> | 2020-04-10 00:55:44 +0200 |
commit | bb660fe2284e16b2bea1710edf4dba0452c6bbc3 (patch) | |
tree | 3bf0f3bc174eeccab2f7c4fe8b00b7beb319e477 /pkgs/build-support/rust/build-rust-crate | |
parent | 5f9af254a5d60bef7dd5b6879e5c71567f0d66e0 (diff) |
buildRustCrate: Support versioned crate renames
Diffstat (limited to 'pkgs/build-support/rust/build-rust-crate')
-rw-r--r-- | pkgs/build-support/rust/build-rust-crate/default.nix | 58 | ||||
-rw-r--r-- | pkgs/build-support/rust/build-rust-crate/test/default.nix | 45 |
2 files changed, 99 insertions, 4 deletions
diff --git a/pkgs/build-support/rust/build-rust-crate/default.nix b/pkgs/build-support/rust/build-rust-crate/default.nix index fdff9edfa739f..d9ed26f1d94a7 100644 --- a/pkgs/build-support/rust/build-rust-crate/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/default.nix @@ -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_; diff --git a/pkgs/build-support/rust/build-rust-crate/test/default.nix b/pkgs/build-support/rust/build-rust-crate/test/default.nix index fba938f623727..4783129bad9a9 100644 --- a/pkgs/build-support/rust/build-rust-crate/test/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/test/default.nix @@ -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; |