crate2nix
crate2nix copied to clipboard
Respect cargo profiles / enable debug info in release mode
I'm trying to get my workspace to compile with debug info in release mode.
My Cargo.toml has the following:
[profile.release]
debug = 1
however that seems to be ignored when using crate2nix.
Solving
The documentation of buildRustCrate suggests that extraRustcOpts can be used (source code), however transposing it to crate2nix doesn't work:
buildRustCrateForPkgs = pkgs: pkgs.buildRustCrate.override {
extraRustcOpts = "-C debuginfo=1";
};
yields the following error:
error: function 'anonymous lambda' called with unexpected argument 'extraRustcOpts'
at /nix/store/zaza7mgggz4m5h6z18kajabf4wciaj47-source/pkgs/build-support/rust/build-rust-crate/default.nix:7:1
That is because extraRustOpts can't be specified at a global level:
https://github.com/NixOS/nixpkgs/blob/30d044f8235dbd03675bef6e2b59e1c8a94e2c51/pkgs/build-support/rust/build-rust-crate/default.nix#L7
It can only be specified at a crate level:
https://github.com/NixOS/nixpkgs/blob/30d044f8235dbd03675bef6e2b59e1c8a94e2c51/pkgs/build-support/rust/build-rust-crate/default.nix#L180
=> It looks like in order to be able to respect cargo profiles, or at least give an interface that allows users to easily override rust flags at the buildRustCrateForPkgs level, one would need to PR something into nixpkgs so that one can propagate arguments from there.
It looks like as a workaround, one may override the crates one by one through the defaultCrateOverrides mechanism, but that requires re-mentioning every crate in there.
It seems that this may also be a first step towards ~fixing #338.
Current workaround:
{ pkgs, lib, cargoNix }:
let
defaultOrOverrides = pkgs.defaultCrateOverrides;
# Enable debuginfo on all known crates. Unfortunately this has to be overridden on a per-crate basis,
# and we can only do this by looking up crates list from cargoNix.internal.
# The fact this is so complex is tracked by https://github.com/nix-community/crate2nix/issues/345
withDebugInfo = defaultOrOverrides // (
builtins.listToAttrs
(builtins.map
(crate:
let
crateName = crate.crateName;
defaultOverride = defaultOrOverrides.${crateName} or (crate: { });
in
{
name = crateName;
value = crate: (
let defaultOverrideApplied = defaultOverride crate;
in
defaultOverrideApplied // {
extraRustcOpts = (defaultOverrideApplied.extraRustcOpts or [ ]) ++ [ "-C debuginfo=1" ];
extraRustcOptsForBuildRs = (defaultOverrideApplied.extraRustcOptsForBuildRs or [ ]) ++ [ "-C debuginfo=1" ];
}
);
}
)
(builtins.attrValues cargoNix.internal.crates))
);
in
withDebugInfo
note the use of .internal to get the list of all crates, that we can then build the crateOverrides with.