-
-
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
Reintroducing mkRustCrate #31150
Closed
Closed
Reintroducing mkRustCrate #31150
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
a20704c
Reintroducing mkRustCrate
P-E-Meunier 7979239
mkRustCrate in all-packages.nix
P-E-Meunier 2d85124
Handling packages that don't have a "build=" in their Cargo.toml
P-E-Meunier 00e93d5
Correction after review
P-E-Meunier 4b5aa82
Handling build dependencies for the latest generate-nix-pkg
P-E-Meunier 08046ce
Adding the tool "carnix", compiled with rust-utils.nix
P-E-Meunier 6088db3
Replacing fetchzip with fetchcrate
P-E-Meunier 235a48e
Carnix 0.4.1
P-E-Meunier 6846126
Factorise regular expression
P-E-Meunier 1917e32
Correction after reviews
P-E-Meunier 655f44a
Carnix 0.4.3 (including calls to buildRustCrate instead of mkRustCrate)
P-E-Meunier cf4ec94
Documenting buildRustCrate
P-E-Meunier a694f61
Adding myself in maintainers
P-E-Meunier d0a68ff
Run `cargo build` again after adding dependencies
P-E-Meunier ca81cad
Carnix 0.4.4
P-E-Meunier b4c5585
Carnix 0.4.5 + dependencies on sqlite and pkgconfig
P-E-Meunier 4ce91ee
Replacing a rm $(find) with find | xargs rm
P-E-Meunier 1f338c1
Carnix 0.4.6, which can now compile workspaces
P-E-Meunier 4121d59
Overriding the Rust compiler now works.
P-E-Meunier 428f66a
Carnix 0.4.7, updated for the latest Rust nightly
P-E-Meunier 01645cf
rust-utils.nix: using the generic extension for shared objects (darwi…
P-E-Meunier 2d2490a
Carnix 0.4.8, removing constants verbose and release (now overridable…
P-E-Meunier 0387786
mkRustCrate Move rust libraries into a /rlibs dir
FlorentBecker 6ffd5b4
mkRustCrate: correct transitive dependencies
FlorentBecker 7b212b8
Replacing bash ifs with optionalString
P-E-Meunier f7bed04
runHook
P-E-Meunier 95ed173
Merge branch 'mkRustCrate' of github.com:FlorentBecker/nixpkgs into m…
P-E-Meunier 099e713
BuildInputs overrides
P-E-Meunier 68b7867
Add CARGO_PKG_VERSION_* variables
P-E-Meunier 50b984f
Merging FlorentBecker's recent refactoring
P-E-Meunier 993d376
defaultCrateOverrides without { pkgs } argument
P-E-Meunier a99ef12
Crate name cannot contain '-'
P-E-Meunier 7e6e3b5
Fixing the names of binaries containing a -
P-E-Meunier c82be14
Carnix 0.4.9
P-E-Meunier ea0cf4b
Correct SHA256 for carnix
P-E-Meunier 4c788cc
Carnix 0.4.10
P-E-Meunier 240fc52
Updates after the latest review
P-E-Meunier 0e8ef4b
Fixing a typo
P-E-Meunier 5555123
Carnix 0.4.13
P-E-Meunier 457f9f5
Fixing the "[ integer" error when building binaries
P-E-Meunier c21a241
Documentation with examples that compile
P-E-Meunier 59d16ef
Carnix 0.4.14
P-E-Meunier 7d7fe21
Carnix src was wrong
P-E-Meunier fc84be3
Carnix 0.5, including a new way to resolve features
P-E-Meunier 1cd1fca
Explain argument forwarding
P-E-Meunier cd0f359
rename rust-utils to build-rust-crate
Mic92 bf70097
rename defaultCrateOverrides to default-crate-overrides
Mic92 f84ad34
doc/rust: update documentation to reflect latest carnix
Mic92 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,7 @@ For daily builds (beta and nightly) use either rustup from | |
nixpkgs or use the [Rust nightlies | ||
overlay](#using-the-rust-nightlies-overlay). | ||
|
||
## Packaging Rust applications | ||
## Compiling Rust applications with Cargo | ||
|
||
Rust applications are packaged by using the `buildRustPackage` helper from `rustPlatform`: | ||
|
||
|
@@ -57,6 +57,167 @@ checksum can be then take from the failed build. | |
To install crates with nix there is also an experimental project called | ||
[nixcrates](https://github.com/fractalide/nixcrates). | ||
|
||
## Compiling Rust crates using Nix instead of Cargo | ||
|
||
When run, `cargo build` produces a file called `Cargo.lock`, | ||
containing pinned versions of all dependencies. Nixpkgs contains a | ||
tool called `carnix` (`nix-env -iA nixos.carnix`), which can be used | ||
to turn a `Cargo.lock` into a Nix expression. | ||
|
||
That Nix expression calls `rustc` directly (hence bypassing Cargo), | ||
and can be used to compile a crate and all its dependencies. Here is | ||
an example for a minimal `hello` crate: | ||
|
||
|
||
$ cargo new hello | ||
$ cd hello | ||
$ cargo build | ||
Compiling hello v0.1.0 (file:///tmp/hello) | ||
Finished dev [unoptimized + debuginfo] target(s) in 0.20 secs | ||
$ carnix -o hello.nix --src ./. Cargo.lock --standalone | ||
$ nix-build hello.nix | ||
|
||
Now, the file produced by the call to `carnix`, called `hello.nix`, looks like: | ||
|
||
``` | ||
with import <nixpkgs> {}; | ||
let kernel = buildPlatform.parsed.kernel.name; | ||
# ... (content skipped) | ||
hello_0_1_0_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate { | ||
crateName = "hello"; | ||
version = "0.1.0"; | ||
authors = [ "Authorname <user@example.com>" ]; | ||
src = ./.; | ||
inherit dependencies buildDependencies features; | ||
}; | ||
in | ||
rec { | ||
hello_0_1_0 = hello_0_1_0_ rec {}; | ||
} | ||
``` | ||
|
||
In particular, note that the argument given as `--src` is copied | ||
verbatim to the source. If we look at a more complicated | ||
dependencies, for instance by adding a single line `libc="*"` to our | ||
`Cargo.toml`, we first need to run `cargo build` to update the | ||
`Cargo.lock`. Then, `carnix` needs to be run again, and produces the | ||
following nix file: | ||
|
||
``` | ||
with import <nixpkgs> {}; | ||
let kernel = buildPlatform.parsed.kernel.name; | ||
# ... (content skipped) | ||
hello_0_1_0_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate { | ||
crateName = "hello"; | ||
version = "0.1.0"; | ||
authors = [ "Jörg Thalheim <joerg@thalheim.io>" ]; | ||
src = ./.; | ||
inherit dependencies buildDependencies features; | ||
}; | ||
libc_0_2_34_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate { | ||
crateName = "libc"; | ||
version = "0.2.34"; | ||
authors = [ "The Rust Project Developers" ]; | ||
sha256 = "11jmqdxmv0ka10ay0l8nzx0nl7s2lc3dbrnh1mgbr2grzwdyxi2s"; | ||
inherit dependencies buildDependencies features; | ||
}; | ||
in | ||
rec { | ||
hello_0_1_0 = hello_0_1_0_ rec { | ||
dependencies = [ libc_0_2_34 ]; | ||
}; | ||
libc_0_2_34_features."default".from_hello_0_1_0__default = true; | ||
libc_0_2_34 = libc_0_2_34_ rec { | ||
features = mkFeatures libc_0_2_34_features; | ||
}; | ||
libc_0_2_34_features."use_std".self_default = hasDefault libc_0_2_34_features; | ||
} | ||
``` | ||
|
||
Here, the `libc` crate has no `src` attribute, so `buildRustCrate` | ||
will fetch it from [crates.io](https://crates.io). A `sha256` | ||
attribute is still needed for Nix purity. | ||
|
||
Some crates require external libraries. For crates from | ||
[crates.io](https://crates.io), such libraries can be specified in | ||
`defaultCrateOverrides` package in nixpkgs itself. | ||
|
||
Starting from that file, one can add more overrides, to add features | ||
or build inputs by overriding the hello crate in a seperate file. | ||
|
||
``` | ||
with import <nixpkgs> {}; | ||
(import ./hello.nix).hello_0_1_0.override { | ||
crateOverrides = defaultCrateOverrides // { | ||
hello = attrs: { buildInputs = [ openssl ]; }; | ||
}; | ||
} | ||
``` | ||
|
||
Here, `crateOverrides` is expected to be a attribute set, where the | ||
key is the crate name without version number and the value a function. | ||
The function gets all attributes passed to `buildRustCrate` as first | ||
argument and returns a set that contains all attribute that should be | ||
overwritten. | ||
|
||
For more complicated cases, such as when parts of the crate's | ||
derivation depend on the the crate's version, the `attrs` argument of | ||
the override above can be read, as in the following example, which | ||
patches the derivation: | ||
|
||
``` | ||
with import <nixpkgs> {}; | ||
(import ./hello.nix).hello_0_1_0.override { | ||
crateOverrides = defaultCrateOverrides // { | ||
hello = attrs: lib.optionalAttrs (lib.versionAtLeast attrs.version "1.0") { | ||
postPatch = '' | ||
substituteInPlace lib/zoneinfo.rs \ | ||
--replace "/usr/share/zoneinfo" "${tzdata}/share/zoneinfo" | ||
''; | ||
}; | ||
}; | ||
} | ||
``` | ||
|
||
Another situation is when we want to override a nested | ||
dependency. This actually works in the exact same way, since the | ||
`crateOverrides` parameter is forwarded to the crate's | ||
dependencies. For instance, to override the build inputs for crate | ||
`libc` in the example above, where `libc` is a dependency of the main | ||
crate, we could do: | ||
|
||
``` | ||
with import <nixpkgs> {}; | ||
(import hello.nix).hello_0_1_0.override { | ||
crateOverrides = defaultCrateOverrides // { | ||
libc = attrs: { buildInputs = []; }; | ||
}; | ||
} | ||
``` | ||
|
||
Three more parameters can be overridden: | ||
|
||
- The version of rustc used to compile the crate: | ||
|
||
``` | ||
hello_0_1_0.override { rust = pkgs.rust; }; | ||
``` | ||
|
||
- Whether to build in release mode or debug mode (release mode by | ||
default): | ||
|
||
``` | ||
hello_0_1_0.override { release = false; }; | ||
``` | ||
|
||
- Whether to print the commands sent to rustc when building | ||
(equivalent to `--verbose` in cargo: | ||
|
||
``` | ||
hello_0_1_0.override { verbose = false; }; | ||
``` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where should users go to find the full collection of attrs that can be passed? |
||
|
||
|
||
## Using the Rust nightlies overlay | ||
|
||
Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 is a reminder to update all
with import <nixpkgs>{};
in the docs with the final preamble selected for carnix.