about summary refs log tree commit diff
path: root/nixpkgs/doc/languages-frameworks/rust.section.md
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2019-01-07 02:18:36 +0000
committerAlyssa Ross <hi@alyssa.is>2019-01-07 02:18:47 +0000
commit36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2 (patch)
treeb3faaf573407b32aa645237a4d16b82778a39a92 /nixpkgs/doc/languages-frameworks/rust.section.md
parent4e31070265257dc67d120c27e0f75c2344fdfa9a (diff)
parentabf060725d7614bd3b9f96764262dfbc2f9c2199 (diff)
downloadnixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.gz
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.bz2
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.lz
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.xz
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.zst
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.zip
Add 'nixpkgs/' from commit 'abf060725d7614bd3b9f96764262dfbc2f9c2199'
git-subtree-dir: nixpkgs
git-subtree-mainline: 4e31070265257dc67d120c27e0f75c2344fdfa9a
git-subtree-split: abf060725d7614bd3b9f96764262dfbc2f9c2199
Diffstat (limited to 'nixpkgs/doc/languages-frameworks/rust.section.md')
-rw-r--r--nixpkgs/doc/languages-frameworks/rust.section.md395
1 files changed, 395 insertions, 0 deletions
diff --git a/nixpkgs/doc/languages-frameworks/rust.section.md b/nixpkgs/doc/languages-frameworks/rust.section.md
new file mode 100644
index 000000000000..4549bbd1686b
--- /dev/null
+++ b/nixpkgs/doc/languages-frameworks/rust.section.md
@@ -0,0 +1,395 @@
+---
+title: Rust
+author: Matthias Beyer
+date: 2017-03-05
+---
+
+# User's Guide to the Rust Infrastructure
+
+To install the rust compiler and cargo put
+
+```
+rustc
+cargo
+```
+
+into the `environment.systemPackages` or bring them into
+scope with `nix-shell -p rustc cargo`.
+
+> If you are using NixOS and you want to use rust without a nix expression you
+> probably want to add the following in your `configuration.nix` to build
+> crates with C dependencies.
+>
+>     environment.systemPackages = [binutils gcc gnumake openssl pkgconfig]
+
+For daily builds (beta and nightly) use either rustup from
+nixpkgs or use the [Rust nightlies
+overlay](#using-the-rust-nightlies-overlay).
+
+## Compiling Rust applications with Cargo
+
+Rust applications are packaged by using the `buildRustPackage` helper from `rustPlatform`:
+
+```
+rustPlatform.buildRustPackage rec {
+  name = "ripgrep-${version}";
+  version = "0.4.0";
+
+  src = fetchFromGitHub {
+    owner = "BurntSushi";
+    repo = "ripgrep";
+    rev = "${version}";
+    sha256 = "0y5d1n6hkw85jb3rblcxqas2fp82h3nghssa4xqrhqnz25l799pj";
+  };
+
+  cargoSha256 = "0q68qyl2h6i0qsz82z840myxlnjay8p1w5z7hfyr8fqp7wgwa9cx";
+
+  meta = with stdenv.lib; {
+    description = "A fast line-oriented regex search tool, similar to ag and ack";
+    homepage = https://github.com/BurntSushi/ripgrep;
+    license = licenses.unlicense;
+    maintainers = [ maintainers.tailhook ];
+    platforms = platforms.all;
+  };
+}
+```
+
+`buildRustPackage` requires a `cargoSha256` attribute which is computed over
+all crate sources of this package. Currently it is obtained by inserting a
+fake checksum into the expression and building the package once. The correct
+checksum can be then take from the failed build.
+
+When the `Cargo.lock`, provided by upstream, is not in sync with the
+`Cargo.toml`, it is possible to use `cargoPatches` to update it. All patches
+added in `cargoPatches` will also be prepended to the patches in `patches` at
+build-time.
+
+## Compiling Rust crates using Nix instead of Cargo
+
+### Simple operation
+
+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 -A hello_0_1_0
+
+Now, the file produced by the call to `carnix`, called `hello.nix`, looks like:
+
+```
+# Generated by carnix 0.6.5: carnix -o hello.nix --src ./. Cargo.lock --standalone
+{ lib, stdenv, buildRustCrate, fetchgit }:
+let kernel = stdenv.buildPlatform.parsed.kernel.name;
+    # ... (content skipped)
+in
+rec {
+  hello = f: hello_0_1_0 { features = hello_0_1_0_features { hello_0_1_0 = f; }; };
+  hello_0_1_0_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
+    crateName = "hello";
+    version = "0.1.0";
+    authors = [ "pe@pijul.org <pe@pijul.org>" ];
+    src = ./.;
+    inherit dependencies buildDependencies features;
+  };
+  hello_0_1_0 = { features?(hello_0_1_0_features {}) }: hello_0_1_0_ {};
+  hello_0_1_0_features = f: updateFeatures f (rec {
+        hello_0_1_0.default = (f.hello_0_1_0.default or true);
+    }) [ ];
+}
+```
+
+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:
+
+```
+# Generated by carnix 0.6.5: carnix -o hello.nix --src ./. Cargo.lock --standalone
+{ lib, stdenv, buildRustCrate, fetchgit }:
+let kernel = stdenv.buildPlatform.parsed.kernel.name;
+    # ... (content skipped)
+in
+rec {
+  hello = f: hello_0_1_0 { features = hello_0_1_0_features { hello_0_1_0 = f; }; };
+  hello_0_1_0_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
+    crateName = "hello";
+    version = "0.1.0";
+    authors = [ "pe@pijul.org <pe@pijul.org>" ];
+    src = ./.;
+    inherit dependencies buildDependencies features;
+  };
+  libc_0_2_36_ = { dependencies?[], buildDependencies?[], features?[] }: buildRustCrate {
+    crateName = "libc";
+    version = "0.2.36";
+    authors = [ "The Rust Project Developers" ];
+    sha256 = "01633h4yfqm0s302fm0dlba469bx8y6cs4nqc8bqrmjqxfxn515l";
+    inherit dependencies buildDependencies features;
+  };
+  hello_0_1_0 = { features?(hello_0_1_0_features {}) }: hello_0_1_0_ {
+    dependencies = mapFeatures features ([ libc_0_2_36 ]);
+  };
+  hello_0_1_0_features = f: updateFeatures f (rec {
+    hello_0_1_0.default = (f.hello_0_1_0.default or true);
+    libc_0_2_36.default = true;
+  }) [ libc_0_2_36_features ];
+  libc_0_2_36 = { features?(libc_0_2_36_features {}) }: libc_0_2_36_ {
+    features = mkFeatures (features.libc_0_2_36 or {});
+  };
+  libc_0_2_36_features = f: updateFeatures f (rec {
+    libc_0_2_36.default = (f.libc_0_2_36.default or true);
+    libc_0_2_36.use_std =
+      (f.libc_0_2_36.use_std or false) ||
+      (f.libc_0_2_36.default or false) ||
+      (libc_0_2_36.default or false);
+  }) [];
+}
+```
+
+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.
+
+### Handling external dependencies
+
+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 {}).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 {}).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 {}).override {
+  crateOverrides = defaultCrateOverrides // {
+    libc = attrs: { buildInputs = []; };
+  };
+}
+```
+
+### Options and phases configuration
+
+Actually, the overrides introduced in the previous section are more
+general. A number of other parameters can be overridden:
+
+- The version of rustc used to compile the crate:
+
+  ```
+  (hello {}).override { rust = pkgs.rust; };
+  ```
+
+- Whether to build in release mode or debug mode (release mode by
+  default):
+
+  ```
+  (hello {}).override { release = false; };
+  ```
+
+- Whether to print the commands sent to rustc when building
+  (equivalent to `--verbose` in cargo:
+
+  ```
+  (hello {}).override { verbose = false; };
+  ```
+
+- Extra arguments to be passed to `rustc`:
+
+  ```
+  (hello {}).override { extraRustcOpts = "-Z debuginfo=2"; };
+  ```
+
+- Phases, just like in any other derivation, can be specified using
+  the following attributes: `preUnpack`, `postUnpack`, `prePatch`,
+  `patches`, `postPatch`, `preConfigure` (in the case of a Rust crate,
+  this is run before calling the "build" script), `postConfigure`
+  (after the "build" script),`preBuild`, `postBuild`, `preInstall` and
+  `postInstall`. As an example, here is how to create a new module
+  before running the build script:
+
+  ```
+  (hello {}).override {
+    preConfigure = ''
+       echo "pub const PATH=\"${hi.out}\";" >> src/path.rs"
+    '';
+  };
+  ```
+
+### Features
+
+One can also supply features switches. For example, if we want to
+compile `diesel_cli` only with the `postgres` feature, and no default
+features, we would write:
+
+```
+(callPackage ./diesel.nix {}).diesel {
+  default = false;
+  postgres = true;
+}
+```
+
+Where `diesel.nix` is the file generated by Carnix, as explained above.
+
+
+## Setting Up `nix-shell`
+Oftentimes you want to develop code from within `nix-shell`. Unfortunately
+`buildRustCrate` does not support common `nix-shell` operations directly
+(see [this issue](https://github.com/NixOS/nixpkgs/issues/37945))
+so we will use `stdenv.mkDerivation` instead.
+
+Using the example `hello` project above, we want to do the following:
+- Have access to `cargo` and `rustc`
+- Have the `openssl` library available to a crate through it's _normal_
+  compilation mechanism (`pkg-config`).
+
+A typical `shell.nix` might look like:
+
+```
+with import <nixpkgs> {};
+
+stdenv.mkDerivation {
+  name = "rust-env";
+  buildInputs = [
+    rustc cargo
+
+    # Example Additional Dependencies
+    pkgconfig openssl
+  ];
+
+  # Set Environment Variables
+  RUST_BACKTRACE = 1;
+}
+```
+
+You should now be able to run the following:
+```
+$ nix-shell --pure
+$ cargo build
+$ cargo test
+```
+
+### Controlling Rust Version Inside `nix-shell`
+To control your rust version (i.e. use nightly) from within `shell.nix` (or
+other nix expressions) you can use the following `shell.nix`
+
+```
+# Latest Nightly
+with import <nixpkgs> {};
+let src = fetchFromGitHub {
+      owner = "mozilla";
+      repo = "nixpkgs-mozilla";
+      # commit from: 2018-03-27
+      rev = "2945b0b6b2fd19e7d23bac695afd65e320efcebe";
+      sha256 = "034m1dryrzh2lmjvk3c0krgip652dql46w5yfwpvh7gavd3iypyw";
+   };
+in
+with import "${src.out}/rust-overlay.nix" pkgs pkgs;
+stdenv.mkDerivation {
+  name = "rust-env";
+  buildInputs = [
+    # Note: to use use stable, just replace `nightly` with `stable`
+    latest.rustChannels.nightly.rust
+
+    # Add some extra dependencies from `pkgs`
+    pkgconfig openssl
+  ];
+
+  # Set Environment Variables
+  RUST_BACKTRACE = 1;
+}
+```
+
+Now run:
+```
+$ rustc --version
+rustc 1.26.0-nightly (188e693b3 2018-03-26)
+```
+
+To see that you are using nightly.
+
+
+## Using the Rust nightlies overlay
+
+Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope.
+This overlay can _also_ be used to install recent unstable or stable versions
+of Rust, if desired.
+
+To use this overlay, clone
+[nixpkgs-mozilla](https://github.com/mozilla/nixpkgs-mozilla),
+and create a symbolic link to the file
+[rust-overlay.nix](https://github.com/mozilla/nixpkgs-mozilla/blob/master/rust-overlay.nix)
+in the `~/.config/nixpkgs/overlays` directory.
+
+    $ git clone https://github.com/mozilla/nixpkgs-mozilla.git
+    $ mkdir -p ~/.config/nixpkgs/overlays
+    $ ln -s $(pwd)/nixpkgs-mozilla/rust-overlay.nix ~/.config/nixpkgs/overlays/rust-overlay.nix
+
+The latest version can be installed with the following command:
+
+    $ nix-env -Ai nixos.latest.rustChannels.stable.rust
+
+Or using the attribute with nix-shell:
+
+    $ nix-shell -p nixos.latest.rustChannels.stable.rust
+
+To install the beta or nightly channel, "stable" should be substituted by
+"nightly" or "beta", or
+use the function provided by this overlay to pull a version based on a
+build date.
+
+The overlay automatically updates itself as it uses the same source as
+[rustup](https://www.rustup.rs/).