-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
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
cargo-vendor: Build from source using carnix #33980
Conversation
cc @P-E-Meunier |
@@ -332,6 +332,9 @@ stdenv.mkDerivation rec { | |||
libName = if crate ? libName then crate.libName else crate.crateName; | |||
libPath = if crate ? libPath then crate.libPath else ""; | |||
|
|||
# TODO: the documentation suggests this works, is this necessary? | |||
preBuild = if lib.hasAttr "preBuild" crate then crate.preBuild else ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to rethink, how crateOverrides
are applied here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally it should work the same way as defaultGemConfig
: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/ruby-modules/bundled-common/default.nix#L38
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we would need to pass all arguments to the function defined by cratesOverrides
before passing it to the underlying stdenv.mkDerivation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remember correctly, my intention was to allow the user to override the derivation with standard Nix functions, but having multiple ways of doing this is not too bad. Wouldn't it look better with an inherit of multiple attributes instead of this extra line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want this to configure the build of one of cargo-vendor's dependencies: libgit2-sys. I don't see how to use the standard Nix functions in this case. If I use overrideAttrs
, I can produce a derivation for the libgit2-sys that will build but it wouldn't be used as a dependency, since the dependencies are assembled by carnix as part of a rec
attribute map. If this were configurable like the overall package set, then it would be possible.
Even if it were possible to change the dependency using the standard methods, it seems like this is what crateOverrides
are for. Any package using libgit2-sys requires this configuration, so crateOverrides should be able to specify more build attributes. I can do the fairly simple thing of mkDerivation ({ ... } // crate)
, (removing things already processed) or I can whitelist particular attributes, or even make an extra attribute in crateOverrides for this purpose. Which one would you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mkDerivation ({ ... } // crate)
sounds like what I would expect from crateOverrides
.
And we definitely need access to the patch phase in crateOverrides
.
inherit (darwin.apple_sdk.frameworks) CoreFoundation; | ||
in | ||
|
||
(callPackage ./cargo-vendor.nix {}).cargo_vendor_0_1_13.override { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can indeed be used in this way, but the intention is to gather all possible crateOverrides in pkgs/build-support/rust/default-crate-overrides.nix instead. The goal is that other users of the same packages won't have to do this again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mechanism is indented for overrides outside of nixpkgs.
Cool! Thanks for trying carnix out. |
Removes a binary bootstrap, and enables cargo-vendor on aarch64.
Yay, I've tested this successfully builds firefox on aarch64. I had to add this:
or similar. |
There's an interesting quirk to this package. As far as I can tell, it's only used to produce fixed output derivations which are typically present in the cache. Removing the assertion failure was sufficient to build (and run!) firefox on aarch64, (though apparently I had |
buildInputs_ = buildInputs; | ||
in | ||
stdenv.mkDerivation rec { | ||
stdenv.mkDerivation (rec { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the following can be also simplified then:
- buildInputs = [ rust ncurses ] ++ (crate.buildInputs or []) ++ buildInputs_;
+ buildInputs = [ rust ncurses ] ++ buildInputs_;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As is, I don't think this is possible. If the crateOverrides
includes buildInputs
, that will merged on top of the attribute passed set to mkDerivation
then the rust and ncurses inputs will be lost. We could rename the attribute in crate overrides to be extraBuildInputs
to be less surprising, or use a different composition that lets crateOverrides
read more of the context it's updating, so it can explicitly append or replace the value as appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot about that. You are right.
Ah, good point, indeed it's used for fixed-output derivations. But forcing a |
"buildDependencies" "dependencies" "features" | ||
"crateName" "version" "build" "authors" "colors" | ||
]; | ||
extraDerivationAttrs = lib.filterAttrs (n: v: ! lib.elem n processedAttrs) crate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather then filtering I would make an assertion
to make debugging easier, in case somebody tries to set them.
Or is there any use case for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The intent here was to remove only the attributes that had a special interpretation in the body below. All of these are valid to set. Re-reading, I think I could simplify colors, build, libName and libPath.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I see that. But users might try to override them in cratesOverrides
and wonder why the override has no effect for these special attributes. And assertion would make this an runtime error instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When users set these fields in crateOverrides
, the overrides become part of crate
, and will have some meaning in the body. They're not being silently ignored. I agree it's potentially confusing that setting crateBin
doesn't pass through without being transformed, or that features
is renamed and transformed to crateFeatures
, but they do make it through in some expression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. Then we it should be kept this way.
Apart from my last comment, this pull request is then good to go. |
Not sure if this helps here, but there is a source tarball for cargo vendor on the release page that has all the dependencies vendored in. It's called: The tarball is generated on every release automatically by CI. See alexcrichton/cargo-vendor#51 for more details. |
This would work too. But the advantage of carnix is that we can also replace our bootstrap cargo binary and build cargo directly from source instead. |
@GrahamcOfBorg build cargo-vendor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failure for system: x86_64-linux
error: attribute ‘cargo-vendor’ in selection path ‘cargo-vendor’ not found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failure for system: aarch64-linux
error: attribute 'cargo-vendor' in selection path 'cargo-vendor' not found
@LnL7 could you test this pr on darwin sometime? |
@GrahamcOfBorg build rust.cargo-vendor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failure for system: x86_64-linux
error: attribute ‘cargo-vendor’ in selection path ‘rust.cargo-vendor’ not found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failure for system: aarch64-linux
error: attribute 'cargo-vendor' in selection path 'rust.cargo-vendor' not found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failure for system: x86_64-darwin
error: attribute 'cargo-vendor' in selection path 'cargo-vendor' not found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failure for system: x86_64-darwin
error: attribute 'cargo-vendor' in selection path 'rust.cargo-vendor' not found
Motivation for this change
Build cargo-vendor from source #32254
So I can try to build firefox on aarch64.
Things done
build-use-sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)I had a go at building
cargo-vendor
using carnix and buildRustCrate. There are a few awkward things here I'd like to tidy, flagged with "TODO" in the source.crateOverrides
in the documentation suggests that you can override any attribute, with an example forpostPatch
, but mypreBuild
hook was ignored. I very crudely added it, but I don't know how it should work.The inference for the source file for a
[[bin]]
section in aCargo.toml
file doesn't seem to match cargo. I couldn't find it in the documentation, but the tests suggest that the expected location forfoo
issrc/bin/foo.rs
, while acceptingsrc/main.rs
with a warning. However inbuildRustCrate
, onlysrc/main.rs
is checked.cargo-vendor
itself needs to emit a binary calledcargo-vendor
to be acargo
subcommand, but it defaults tocargo_vendor
.The
src
attribute for the main target is not optional when usingcarnix
, defaulting to./.
. The crate we're buildingcargo-vendor
, is in crates.io, and could be fetched with the same logic as the rest of the dependencies. What's preferred here?