Merge pull request #84179 from kolloch/build-rust-crate-multi-version-rename
buildRustCrate: Allow version specific dependency renaming + parameter doc
This commit is contained in:
commit
310b5f6c34
@ -13,14 +13,30 @@ let
|
|||||||
then "macos"
|
then "macos"
|
||||||
else stdenv.hostPlatform.parsed.kernel.name;
|
else stdenv.hostPlatform.parsed.kernel.name;
|
||||||
|
|
||||||
# Create rustc arguments to link against the given list of dependencies and
|
# Create rustc arguments to link against the given list of dependencies
|
||||||
# renames
|
# and renames.
|
||||||
|
#
|
||||||
|
# See docs for crateRenames below.
|
||||||
mkRustcDepArgs = dependencies: crateRenames:
|
mkRustcDepArgs = dependencies: crateRenames:
|
||||||
lib.concatMapStringsSep " " (dep:
|
lib.concatMapStringsSep " " (dep:
|
||||||
let
|
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
|
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
|
else
|
||||||
extern;
|
extern;
|
||||||
in (if lib.any (x: x == "lib" || x == "rlib") dep.crateType then
|
in (if lib.any (x: x == "lib" || x == "rlib") dep.crateType then
|
||||||
@ -42,11 +58,128 @@ let
|
|||||||
installCrate = import ./install-crate.nix { inherit stdenv; };
|
installCrate = import ./install-crate.nix { inherit stdenv; };
|
||||||
in
|
in
|
||||||
|
|
||||||
crate_: lib.makeOverridable ({ rust, release, verbose, features, buildInputs, crateOverrides,
|
/* The overridable pkgs.buildRustCrate function.
|
||||||
dependencies, buildDependencies, crateRenames,
|
*
|
||||||
extraRustcOpts, buildTests,
|
* Any unrecognized parameters will be passed as to
|
||||||
preUnpack, postUnpack, prePatch, patches, postPatch,
|
* the underlying stdenv.mkDerivation.
|
||||||
preConfigure, postConfigure, preBuild, postBuild, preInstall, postInstall }:
|
*/
|
||||||
|
crate_: lib.makeOverridable (
|
||||||
|
# The rust compiler to use.
|
||||||
|
#
|
||||||
|
# Default: pkgs.rustc
|
||||||
|
{ rust
|
||||||
|
# Whether to build a release version (`true`) or a debug
|
||||||
|
# version (`false`). Debug versions are faster to build
|
||||||
|
# but might be much slower at runtime.
|
||||||
|
, release
|
||||||
|
# Whether to print rustc invocations etc.
|
||||||
|
#
|
||||||
|
# Example: false
|
||||||
|
# Default: true
|
||||||
|
, verbose
|
||||||
|
# A list of rust/cargo features to enable while building the crate.
|
||||||
|
# Example: [ "std" "async" ]
|
||||||
|
, features
|
||||||
|
# Additional build inputs for building this crate.
|
||||||
|
#
|
||||||
|
# Example: [ pkgs.openssl ]
|
||||||
|
, buildInputs
|
||||||
|
# Allows to override the parameters to buildRustCrate
|
||||||
|
# for any rust dependency in the transitive build tree.
|
||||||
|
#
|
||||||
|
# Default: pkgs.defaultCrateOverrides
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# pkgs.defaultCrateOverrides // {
|
||||||
|
# hello = attrs: { buildInputs = [ openssl ]; };
|
||||||
|
# }
|
||||||
|
, crateOverrides
|
||||||
|
# Rust library dependencies, i.e. other libaries that were built
|
||||||
|
# with buildRustCrate.
|
||||||
|
, dependencies
|
||||||
|
# Rust build dependencies, i.e. other libaries that were built
|
||||||
|
# with buildRustCrate and are used by a build script.
|
||||||
|
, buildDependencies
|
||||||
|
# Specify the "extern" name of a library if it differs from the library target.
|
||||||
|
# See above for an extended explanation.
|
||||||
|
#
|
||||||
|
# Default: no renames.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# Example: [ "-Z debuginfo=2" ]
|
||||||
|
# Default: []
|
||||||
|
, extraRustcOpts
|
||||||
|
# Whether to enable building tests.
|
||||||
|
# Use true to enable.
|
||||||
|
# Default: false
|
||||||
|
, buildTests
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, preUnpack
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, postUnpack
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, prePatch
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, patches
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, postPatch
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, preConfigure
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, postConfigure
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, preBuild
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, postBuild
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, preInstall
|
||||||
|
# Passed to stdenv.mkDerivation.
|
||||||
|
, postInstall
|
||||||
|
}:
|
||||||
|
|
||||||
let crate = crate_ // (lib.attrByPath [ crate_.crateName ] (attr: {}) crateOverrides crate_);
|
let crate = crate_ // (lib.attrByPath [ crate_.crateName ] (attr: {}) crateOverrides crate_);
|
||||||
dependencies_ = dependencies;
|
dependencies_ = dependencies;
|
||||||
@ -88,6 +221,7 @@ stdenv.mkDerivation (rec {
|
|||||||
|
|
||||||
src = crate.src or (fetchCrate { inherit (crate) crateName version sha256; });
|
src = crate.src or (fetchCrate { inherit (crate) crateName version sha256; });
|
||||||
name = "rust_${crate.crateName}-${crate.version}${lib.optionalString buildTests_ "-test"}";
|
name = "rust_${crate.crateName}-${crate.version}${lib.optionalString buildTests_ "-test"}";
|
||||||
|
version = crate.version;
|
||||||
depsBuildBuild = [ rust stdenv.cc cargo jq ];
|
depsBuildBuild = [ rust stdenv.cc cargo jq ];
|
||||||
buildInputs = (crate.buildInputs or []) ++ buildInputs_;
|
buildInputs = (crate.buildInputs or []) ++ buildInputs_;
|
||||||
dependencies = map lib.getLib dependencies_;
|
dependencies = map lib.getLib dependencies_;
|
||||||
|
@ -197,6 +197,51 @@ let
|
|||||||
dependencies = [ (mkCrate { crateName = "foo"; libName = "foolib"; src = mkLib "src/lib.rs"; }) ];
|
dependencies = [ (mkCrate { crateName = "foo"; libName = "foolib"; src = mkLib "src/lib.rs"; }) ];
|
||||||
crateRenames = { "foo" = "foo_renamed"; };
|
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 = {
|
rustLibTestsDefault = {
|
||||||
src = mkTestFile "src/lib.rs" "baz";
|
src = mkTestFile "src/lib.rs" "baz";
|
||||||
buildTests = true;
|
buildTests = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user