Skip to content

Add support for cross-compilation, with backcompat #160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 43 additions & 28 deletions crate2nix/Cargo.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
, pkgs ? import nixpkgs { config = {}; }
, lib ? pkgs.lib
, stdenv ? pkgs.stdenv
, buildRustCrate ? pkgs.buildRustCrate
, buildRustCrateForPkgs ? if buildRustCrate != null
then lib.warn "`buildRustCrate` is deprecated, use `buildRustCrateForPkgs` instead" (_: buildRustCrate)
else pkgs: pkgs.buildRustCrate
# Deprecated
, buildRustCrate ? null
# This is used as the `crateOverrides` argument for `buildRustCrate`.
, defaultCrateOverrides ? pkgs.defaultCrateOverrides
# The features to enable for the root_crate or the workspace_members.
Expand Down Expand Up @@ -2291,7 +2295,7 @@ rec {
{ packageId
, features ? rootFeatures
, crateOverrides ? defaultCrateOverrides
, buildRustCrateFunc ? null
, buildRustCrateForPkgsFunc ? null
, runTests ? false
, testCrateFlags ? [ ]
, testInputs ? [ ]
Expand All @@ -2305,30 +2309,30 @@ rec {
, testInputs
}:
let
buildRustCrateFuncOverriden =
if buildRustCrateFunc != null
then buildRustCrateFunc
buildRustCrateForPkgsFuncOverriden =
if buildRustCrateForPkgsFunc != null
then buildRustCrateForPkgsFunc
else
(
if crateOverrides == pkgs.defaultCrateOverrides
then buildRustCrate
then buildRustCrateForPkgs
else
buildRustCrate.override {
pkgs: (buildRustCrateForPkgs pkgs).override {
defaultCrateOverrides = crateOverrides;
}
);
builtRustCrates = builtRustCratesWithFeatures {
inherit packageId features;
buildRustCrateFunc = buildRustCrateFuncOverriden;
buildRustCrateForPkgsFunc = buildRustCrateForPkgsFuncOverriden;
runTests = false;
};
builtTestRustCrates = builtRustCratesWithFeatures {
inherit packageId features;
buildRustCrateFunc = buildRustCrateFuncOverriden;
buildRustCrateForPkgsFunc = buildRustCrateForPkgsFuncOverriden;
runTests = true;
};
drv = builtRustCrates.${packageId};
testDrv = builtTestRustCrates.${packageId};
drv = builtRustCrates.crates.${packageId};
testDrv = builtTestRustCrates.crates.${packageId};
derivation =
if runTests then
crateWithTest
Expand All @@ -2343,14 +2347,14 @@ rec {
)
{ inherit features crateOverrides runTests testCrateFlags testInputs; };

/* Returns an attr set with packageId mapped to the result of buildRustCrateFunc
/* Returns an attr set with packageId mapped to the result of buildRustCrateForPkgsFunc
for the corresponding crate.
*/
builtRustCratesWithFeatures =
{ packageId
, features
, crateConfigs ? crates
, buildRustCrateFunc
, buildRustCrateForPkgsFunc
, runTests
, target ? defaultTarget
} @ args:
Expand All @@ -2368,12 +2372,17 @@ rec {
target = target // { test = runTests; };
}
);
buildByPackageId = packageId: buildByPackageIdImpl packageId;

# Memoize built packages so that reappearing packages are only built once.
builtByPackageId =
lib.mapAttrs (packageId: value: buildByPackageId packageId) crateConfigs;
buildByPackageIdImpl = packageId:
builtByPackageIdByPkgs = mkBuiltByPackageIdByPkgs pkgs;
mkBuiltByPackageIdByPkgs = pkgs:
let
self = {
crates = lib.mapAttrs (packageId: value: buildByPackageIdForPkgsImpl self pkgs packageId) crateConfigs;
build = mkBuiltByPackageIdByPkgs pkgs.buildPackages;
};
in
self;
buildByPackageIdForPkgsImpl = self: pkgs: packageId:
let
features = mergedFeatures."${packageId}" or [ ];
crateConfig' = crateConfigs."${packageId}";
Expand All @@ -2385,14 +2394,21 @@ rec {
(crateConfig'.devDependencies or [ ]);
dependencies =
dependencyDerivations {
inherit builtByPackageId features target;
inherit features target;
buildByPackageId = depPackageId:
# proc_macro crates must be compiled for the build architecture
if crateConfigs.${depPackageId}.procMacro or false
then self.build.crates.${depPackageId}
else self.crates.${depPackageId};
dependencies =
(crateConfig.dependencies or [ ])
++ devDependencies;
};
buildDependencies =
dependencyDerivations {
inherit builtByPackageId features target;
inherit features target;
buildByPackageId = depPackageId:
self.build.crates.${depPackageId};
dependencies = crateConfig.buildDependencies or [ ];
};
filterEnabledDependenciesForThis = dependencies: filterEnabledDependencies {
Expand Down Expand Up @@ -2424,13 +2440,13 @@ rec {
dependenciesWithRenames;
versionAndRename = dep:
let
package = builtByPackageId."${dep.packageId}";
package = crateConfigs."${dep.packageId}";
in
{ inherit (dep) rename; version = package.version; };
in
lib.mapAttrs (name: choices: builtins.map versionAndRename choices) grouped;
in
buildRustCrateFunc
buildRustCrateForPkgsFunc pkgs
(
crateConfig // {
src = crateConfig.src or (
Expand All @@ -2449,24 +2465,23 @@ rec {
}
);
in
builtByPackageId;
builtByPackageIdByPkgs;

/* Returns the actual derivations for the given dependencies. */
dependencyDerivations =
{ builtByPackageId
{ buildByPackageId
, features
, dependencies
, target
}:
assert (builtins.isAttrs builtByPackageId);
assert (builtins.isList features);
assert (builtins.isList dependencies);
assert (builtins.isAttrs target);
let
enabledDependencies = filterEnabledDependencies {
inherit dependencies features target;
};
depDerivation = dependency: builtByPackageId.${dependency.packageId};
depDerivation = dependency: buildByPackageId dependency.packageId;
in
map depDerivation enabledDependencies;

Expand All @@ -2489,14 +2504,14 @@ rec {
debug = rec {
# The built tree as passed to buildRustCrate.
buildTree = buildRustCrateWithFeatures {
buildRustCrateFunc = lib.id;
buildRustCrateForPkgsFunc = _: lib.id;
inherit packageId;
};
sanitizedBuildTree = sanitizeForJson buildTree;
dependencyTree = sanitizeForJson
(
buildRustCrateWithFeatures {
buildRustCrateFunc = crate: {
buildRustCrateForPkgsFunc = _: crate: {
"01_crateName" = crate.crateName or false;
"02_features" = crate.features or [ ];
"03_dependencies" = crate.dependencies or [ ];
Expand Down
6 changes: 5 additions & 1 deletion crate2nix/templates/Cargo.nix.tera
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
, pkgs ? import nixpkgs { config = {}; }
, lib ? pkgs.lib
, stdenv ? pkgs.stdenv
, buildRustCrate ? pkgs.buildRustCrate
, buildRustCrateForPkgs ? if buildRustCrate != null
then lib.warn "`buildRustCrate` is deprecated, use `buildRustCrateForPkgs` instead" (_: buildRustCrate)
else pkgs: pkgs.buildRustCrate
# Deprecated
, buildRustCrate ? null
# This is used as the `crateOverrides` argument for `buildRustCrate`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update comment?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! perhaps I was confused whether the comments were describing the thing above or the thing below.

, defaultCrateOverrides ? pkgs.defaultCrateOverrides
# The features to enable for the root_crate or the workspace_members.
Expand Down
68 changes: 41 additions & 27 deletions crate2nix/templates/nix/crate2nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
, lib
, stdenv
, buildRustCrate
, buildRustCrateForPkgs ? if buildRustCrate != null
then lib.warn "`buildRustCrate` is deprecated, use `buildRustCrateForPkgs` instead" (_: buildRustCrate)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really dig this user guidance, thank you 👍

else pkgs: pkgs.buildRustCrate
, defaultCrateOverrides
, strictDeprecation ? true
, crates ? { }
Expand Down Expand Up @@ -162,7 +165,7 @@ rec {
{ packageId
, features ? rootFeatures
, crateOverrides ? defaultCrateOverrides
, buildRustCrateFunc ? null
, buildRustCrateForPkgsFunc ? null
, runTests ? false
, testCrateFlags ? [ ]
, testInputs ? [ ]
Expand All @@ -176,30 +179,30 @@ rec {
, testInputs
}:
let
buildRustCrateFuncOverriden =
if buildRustCrateFunc != null
then buildRustCrateFunc
buildRustCrateForPkgsFuncOverriden =
if buildRustCrateForPkgsFunc != null
then buildRustCrateForPkgsFunc
else
(
if crateOverrides == pkgs.defaultCrateOverrides
then buildRustCrate
then buildRustCrateForPkgs
else
buildRustCrate.override {
pkgs: (buildRustCrateForPkgs pkgs).override {
defaultCrateOverrides = crateOverrides;
}
);
builtRustCrates = builtRustCratesWithFeatures {
inherit packageId features;
buildRustCrateFunc = buildRustCrateFuncOverriden;
buildRustCrateForPkgsFunc = buildRustCrateForPkgsFuncOverriden;
runTests = false;
};
builtTestRustCrates = builtRustCratesWithFeatures {
inherit packageId features;
buildRustCrateFunc = buildRustCrateFuncOverriden;
buildRustCrateForPkgsFunc = buildRustCrateForPkgsFuncOverriden;
runTests = true;
};
drv = builtRustCrates.${packageId};
testDrv = builtTestRustCrates.${packageId};
drv = builtRustCrates.crates.${packageId};
testDrv = builtTestRustCrates.crates.${packageId};
derivation =
if runTests then
crateWithTest
Expand All @@ -214,14 +217,14 @@ rec {
)
{ inherit features crateOverrides runTests testCrateFlags testInputs; };

/* Returns an attr set with packageId mapped to the result of buildRustCrateFunc
/* Returns an attr set with packageId mapped to the result of buildRustCrateForPkgsFunc
for the corresponding crate.
*/
builtRustCratesWithFeatures =
{ packageId
, features
, crateConfigs ? crates
, buildRustCrateFunc
, buildRustCrateForPkgsFunc
, runTests
, target ? defaultTarget
} @ args:
Expand All @@ -239,12 +242,17 @@ rec {
target = target // { test = runTests; };
}
);
buildByPackageId = packageId: buildByPackageIdImpl packageId;

# Memoize built packages so that reappearing packages are only built once.
builtByPackageId =
lib.mapAttrs (packageId: value: buildByPackageId packageId) crateConfigs;
buildByPackageIdImpl = packageId:
builtByPackageIdByPkgs = mkBuiltByPackageIdByPkgs pkgs;
mkBuiltByPackageIdByPkgs = pkgs:
let
self = {
crates = lib.mapAttrs (packageId: value: buildByPackageIdForPkgsImpl self pkgs packageId) crateConfigs;
build = mkBuiltByPackageIdByPkgs pkgs.buildPackages;
};
in
self;
buildByPackageIdForPkgsImpl = self: pkgs: packageId:
let
features = mergedFeatures."${packageId}" or [ ];
crateConfig' = crateConfigs."${packageId}";
Expand All @@ -256,14 +264,21 @@ rec {
(crateConfig'.devDependencies or [ ]);
dependencies =
dependencyDerivations {
inherit builtByPackageId features target;
inherit features target;
buildByPackageId = depPackageId:
# proc_macro crates must be compiled for the build architecture
if crateConfigs.${depPackageId}.procMacro or false
then self.build.crates.${depPackageId}
else self.crates.${depPackageId};
dependencies =
(crateConfig.dependencies or [ ])
++ devDependencies;
};
buildDependencies =
dependencyDerivations {
inherit builtByPackageId features target;
inherit features target;
buildByPackageId = depPackageId:
self.build.crates.${depPackageId};
dependencies = crateConfig.buildDependencies or [ ];
};
filterEnabledDependenciesForThis = dependencies: filterEnabledDependencies {
Expand Down Expand Up @@ -295,13 +310,13 @@ rec {
dependenciesWithRenames;
versionAndRename = dep:
let
package = builtByPackageId."${dep.packageId}";
package = crateConfigs."${dep.packageId}";
in
{ inherit (dep) rename; version = package.version; };
in
lib.mapAttrs (name: choices: builtins.map versionAndRename choices) grouped;
in
buildRustCrateFunc
buildRustCrateForPkgsFunc pkgs
(
crateConfig // {
src = crateConfig.src or (
Expand All @@ -320,24 +335,23 @@ rec {
}
);
in
builtByPackageId;
builtByPackageIdByPkgs;

/* Returns the actual derivations for the given dependencies. */
dependencyDerivations =
{ builtByPackageId
{ buildByPackageId
, features
, dependencies
, target
}:
assert (builtins.isAttrs builtByPackageId);
assert (builtins.isList features);
assert (builtins.isList dependencies);
assert (builtins.isAttrs target);
let
enabledDependencies = filterEnabledDependencies {
inherit dependencies features target;
};
depDerivation = dependency: builtByPackageId.${dependency.packageId};
depDerivation = dependency: buildByPackageId dependency.packageId;
in
map depDerivation enabledDependencies;

Expand All @@ -360,14 +374,14 @@ rec {
debug = rec {
# The built tree as passed to buildRustCrate.
buildTree = buildRustCrateWithFeatures {
buildRustCrateFunc = lib.id;
buildRustCrateForPkgsFunc = _: lib.id;
inherit packageId;
};
sanitizedBuildTree = sanitizeForJson buildTree;
dependencyTree = sanitizeForJson
(
buildRustCrateWithFeatures {
buildRustCrateFunc = crate: {
buildRustCrateForPkgsFunc = _: crate: {
"01_crateName" = crate.crateName or false;
"02_features" = crate.features or [ ];
"03_dependencies" = crate.dependencies or [ ];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ let
];
dependencyDerivations = features: dependencies:
crate2nix.dependencyDerivations {
builtByPackageId = fakeCrates;
buildByPackageId = p: fakeCrates.${p};
target = crate2nix.defaultTarget;
inherit features dependencies;
};
Expand Down
Loading