{"id":13584066,"url":"https://github.com/nix-community/naersk","last_synced_at":"2025-05-16T12:06:07.758Z","repository":{"id":38007085,"uuid":"191750015","full_name":"nix-community/naersk","owner":"nix-community","description":"Build Rust projects in Nix - no configuration, no code generation, no IFD, sandbox friendly.","archived":false,"fork":false,"pushed_at":"2024-07-23T09:37:40.000Z","size":386,"stargazers_count":730,"open_issues_count":49,"forks_count":87,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-10-29T17:12:45.654Z","etag":null,"topics":["cargo","crates","nix","rust-lang"],"latest_commit_sha":null,"homepage":"","language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nix-community.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"nix-community"}},"created_at":"2019-06-13T11:27:21.000Z","updated_at":"2024-10-28T15:37:21.000Z","dependencies_parsed_at":"2024-08-04T00:14:08.951Z","dependency_job_id":null,"html_url":"https://github.com/nix-community/naersk","commit_stats":{"total_commits":304,"total_committers":49,"mean_commits":6.204081632653061,"dds":0.493421052631579,"last_synced_commit":"3fb418eaf352498f6b6c30592e3beb63df42ef11"},"previous_names":["nmattia/naersk"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nix-community%2Fnaersk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nix-community%2Fnaersk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nix-community%2Fnaersk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nix-community%2Fnaersk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nix-community","download_url":"https://codeload.github.com/nix-community/naersk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246255750,"owners_count":20748121,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cargo","crates","nix","rust-lang"],"created_at":"2024-08-01T15:03:59.367Z","updated_at":"2025-04-02T05:06:43.806Z","avatar_url":"https://github.com/nix-community.png","language":"Nix","funding_links":["https://opencollective.com/nix-community"],"categories":["Nix","Programming Languages"],"sub_categories":["Rust"],"readme":"# Naersk\n\n[![GitHub Actions](https://img.shields.io/github/checks-status/nix-community/naersk/master)](https://github.com/nix-community/naersk/actions)\n\nBuild Rust projects with ease!\n\n- [Introduction](#introduction)\n- [Setup](#setup)\n- [Usage](#usage)\n- [Examples](#examples)\n- [Tips \u0026 Tricks](#tips--tricks)\n\nStatus: project's working!\n\n## Introduction\n\nNaersk is a [Nix](https://nixos.org/explore.html) library for building Rust\nprojects - basically, you write:\n\n```\nnaersk.buildPackage {\n  src = ./.; # Wherever your Cargo.lock and the rest of your source code are\n}\n```\n\n... and that turns your code into a Nix derivation which you can, for instance,\ninclude in your system:\n\n```\nenvironment.systemPackages = [\n  (naersk.buildPackage {\n    src = ./my-cool-app;\n  })\n];\n\n# (see below for more complete examples)\n```\n\nUnder the hood, `buildPackage` parses `Cargo.lock`, downloads all dependencies,\nand compiles your application, fully utilizing Nix's sandboxing and caching\nabilities; so, with a pinch of salt, Naersk is `cargo build`, but inside Nix!\n\nIf you're using Hydra, you can rely on Naersk as well because it doesn't use\nIFD - all the parsing happens directly inside Nix code.\n\n## Setup\n\n### Using Flakes\n\n```shell\n$ nix flake init -t github:nix-community/naersk\n$ nix flake lock\n```\n\nAlternatively, store this as `flake.nix` in your repository:\n\n```nix\n{\n  inputs = {\n    flake-utils.url = \"github:numtide/flake-utils\";\n    naersk.url = \"github:nix-community/naersk\";\n    nixpkgs.url = \"github:NixOS/nixpkgs/nixpkgs-unstable\";\n  };\n\n  outputs = { self, flake-utils, naersk, nixpkgs }:\n    flake-utils.lib.eachDefaultSystem (system:\n      let\n        pkgs = (import nixpkgs) {\n          inherit system;\n        };\n\n        naersk' = pkgs.callPackage naersk {};\n\n      in rec {\n        # For `nix build` \u0026 `nix run`:\n        defaultPackage = naersk'.buildPackage {\n          src = ./.;\n        };\n\n        # For `nix develop` (optional, can be skipped):\n        devShell = pkgs.mkShell {\n          nativeBuildInputs = with pkgs; [ rustc cargo ];\n        };\n      }\n    );\n}\n```\n\nThis assumes `flake.nix` is created next to `Cargo.toml` \u0026 `Cargo.lock` - if\nthat's not the case for you, adjust `./.` in `naersk'.buildPackage`.\n\nNote that Naersk by default ignores the `rust-toolchain` file, using whatever\nRust compiler version is present in `nixpkgs`.\n\nIf you have a custom `rust-toolchain` file, you can make Naersk use it this way:\n\n```nix\n{\n  inputs = {\n    flake-utils.url = \"github:numtide/flake-utils\";\n    naersk.url = \"github:nix-community/naersk\";\n\n    nixpkgs-mozilla = {\n      url = \"github:mozilla/nixpkgs-mozilla\";\n      flake = false;\n    };\n  };\n\n  outputs = { self, flake-utils, naersk, nixpkgs, nixpkgs-mozilla }:\n    flake-utils.lib.eachDefaultSystem (system:\n      let\n        pkgs = (import nixpkgs) {\n          inherit system;\n\n          overlays = [\n            (import nixpkgs-mozilla)\n          ];\n        };\n\n        toolchain = (pkgs.rustChannelOf {\n          rustToolchain = ./rust-toolchain;\n          sha256 = \"\";\n          #        ^ After you run `nix build`, replace this with the actual\n          #          hash from the error message\n        }).rust;\n\n        naersk' = pkgs.callPackage naersk {\n          cargo = toolchain;\n          rustc = toolchain;\n        };\n\n      in rec {\n        # For `nix build` \u0026 `nix run`:\n        defaultPackage = naersk'.buildPackage {\n          src = ./.;\n        };\n\n        # For `nix develop` (optional, can be skipped):\n        devShell = pkgs.mkShell {\n          nativeBuildInputs = [ toolchain ];\n        };\n      }\n    );\n}\n```\n\n### Using Niv\n\n```shell\n$ niv init\n$ niv add nix-community/naersk\n```\n\n... and then create `default.nix` with:\n\n```nix\nlet\n  pkgs = import \u003cnixpkgs\u003e {};\n  sources = import ./nix/sources.nix;\n  naersk = pkgs.callPackage sources.naersk {};\n\nin\n  naersk.buildPackage ./.\n```\n\nThis assumes `default.nix` is created next to `Cargo.toml` \u0026 `Cargo.lock` - if\nthat's not the case for you, adjust `./.` in `naersk.buildPackage`.\n\nNote that Naersk by default ignores the `rust-toolchain` file, using whatever\nRust compiler version is present in `nixpkgs`.\n\nIf you have a custom `rust-toolchain` file, you can make Naersk use it this way:\n\n```shell\n$ niv add mozilla/nixpkgs-mozilla\n```\n\n... and then:\n\n```nix\nlet\n  sources = import ./nix/sources.nix;\n  nixpkgs-mozilla = import sources.nixpkgs-mozilla;\n\n  pkgs = import sources.nixpkgs {\n    overlays = [\n      nixpkgs-mozilla\n    ];\n  };\n\n  toolchain = (pkgs.rustChannelOf {\n    rustToolchain = ./rust-toolchain;\n    sha256 = \"\";\n    #        ^ After you run `nix-build`, replace this with the actual\n    #          hash from the error message\n  }).rust;\n\n  naersk = pkgs.callPackage sources.naersk {\n    cargo = toolchain;\n    rustc = toolchain;\n  };\n\nin\n  naersk.buildPackage ./.\n```\n\n## Usage\n\nNaersk provides a function called `buildPackage` that takes an attribute set\ndescribing your application's directory, its dependencies etc. - in general, the\nusage is:\n\n```nix\nnaersk.buildPackage {\n  # Assuming there's `Cargo.toml` right in this directory:\n  src = ./.;\n\n  someOption = \"yass\";\n  someOtherOption = false;\n  CARGO_ENVIRONMENTAL_VARIABLE = \"test\";\n}\n```\n\nSome of the options (described below) are used by Naersk to affect the building\nprocess, rest is passed-through into `mkDerivation`.\n\nNote that you shouldn't call `overrideAttrs` on a derivation built by Naersk\n(see the [note on `overrideAttrs`](#note-on-overrideattrs) below).\n\n### `buildPackage`'s parameters\n\n| Attribute | Description |\n| - | - |\n| `name` | The name of the derivation. |\n| `version` | The version of the derivation. |\n| `src` | Used by `naersk` as source input to the derivation. When `root` is not set, `src` is also used to discover the `Cargo.toml` and `Cargo.lock`. |\n| `root` | Used by `naersk` to read the `Cargo.toml` and `Cargo.lock` files. May be different from `src`. When `src` is not set, `root` is (indirectly) used as `src`. |\n| `gitAllRefs` | Whether to fetch all refs while fetching Git dependencies. Useful if the wanted revision isn't in the default branch. Requires Nix 2.4+. Default: `false` |\n| `gitSubmodules` | Whether to fetch submodules while fetching Git dependencies. Requires Nix 2.4+. Default: `false` |\n| `additionalCargoLock` | Additional cargo lock used to specify crates required for build |\n| `cratesDownloadUrl` | Url for downloading crates from an alternative source Default: `\"https://crates.io\"` |\n| `cargoBuild` | The command to use for the build. The argument must be a function modifying the default value. \u003cbr/\u003e Default: `''cargo $cargo_options build $cargo_build_options \u003e\u003e $cargo_build_output_json''` |\n| `cargoBuildOptions` | Options passed to cargo build, i.e. `cargo build \u003cOPTS\u003e`. These options can be accessed during the build through the environment variable `cargo_build_options`. \u003cbr/\u003e Note: naersk relies on the `--out-dir out` option and the `--message-format` option. The `$cargo_message_format` variable is set based on the cargo version.\u003cbr/\u003e Note: these values are not (shell) escaped, meaning that you can use environment variables but must be careful when introducing e.g. spaces. \u003cbr/\u003e The argument must be a function modifying the default value. \u003cbr/\u003e Default: `[ \"$cargo_release\" ''-j \"$NIX_BUILD_CORES\"'' \"--message-format=$cargo_message_format\" ]` |\n| `remapPathPrefix` | When `true`, rustc remaps the (`/nix/store`) source paths to `/sources` to reduce the number of dependencies in the closure. Default: `true` |\n| `cargoTestCommands` | The commands to run in the `checkPhase`. Do not forget to set [`doCheck`](https://nixos.org/nixpkgs/manual/#ssec-check-phase). The argument must be a function modifying the default value. \u003cbr/\u003e Default: `[ ''cargo $cargo_options test $cargo_test_options'' ]` |\n| `cargoTestOptions` | Options passed to cargo test, i.e. `cargo test \u003cOPTS\u003e`. These options can be accessed during the build through the environment variable `cargo_test_options`. \u003cbr/\u003e Note: these values are not (shell) escaped, meaning that you can use environment variables but must be careful when introducing e.g. spaces. \u003cbr/\u003e The argument must be a function modifying the default value. \u003cbr/\u003e Default: `[ \"$cargo_release\" ''-j \"$NIX_BUILD_CORES\"'' ]` |\n| `cargoClippyOptions` | Options passed to cargo clippy, i.e. `cargo clippy -- \u003cOPTS\u003e`. These options can be accessed during the build through the environment variable `cargo_clippy_options`. \u003cbr /\u003e Note: these values are not (shell) escaped, meaning that you can use environment variables but must be careful when introducing e.g. spaces. \u003cbr/\u003e The argument must be a function modifying the default value. \u003cbr/\u003e Default: `[ \"-D warnings\" ]` |\n| `cargoFmtOptions` | Options passed to cargo fmt, i.e. `cargo fmt -- \u003cOPTS\u003e`. These options can be accessed during the build through the environment variable `cargo_fmt_options`. \u003cbr /\u003e Note: these values are not (shell) escaped, meaning that you can use environment variables but must be careful when introducing e.g. spaces. \u003cbr/\u003e The argument must be a function modifying the default value. \u003cbr/\u003e Default: `[ \"--check\" ]` |\n| `nativeBuildInputs` | Extra `nativeBuildInputs` to all derivations. Default: `[]` |\n| `buildInputs` | Extra `buildInputs` to all derivations. Default: `[]` |\n| `cargoOptions` | Options passed to all cargo commands, i.e. `cargo \u003cOPTS\u003e ...`. These options can be accessed during the build through the environment variable `cargo_options`. \u003cbr/\u003e Note: these values are not (shell) escaped, meaning that you can use environment variables but must be careful when introducing e.g. spaces. \u003cbr/\u003e The argument must be a function modifying the default value. \u003cbr/\u003e Default: `[ ]` |\n| `doDoc` | When true, `cargo doc` is run and a new output `doc` is generated. Default: `false` |\n| `cargoDocCommands` | The commands to run in the `docPhase`. Do not forget to set `doDoc`. The argument must be a function modifying the default value. \u003cbr/\u003e Default: `[ ''cargo $cargo_options doc $cargo_doc_options'' ]` |\n| `cargoDocOptions` | Options passed to cargo doc, i.e. `cargo doc \u003cOPTS\u003e`. These options can be accessed during the build through the environment variable `cargo_doc_options`. \u003cbr/\u003e Note: these values are not (shell) escaped, meaning that you can use environment variables but must be careful when introducing e.g. spaces. \u003cbr/\u003e The argument must be a function modifying the default value. \u003cbr/\u003e Default: `[ \"--offline\" \"$cargo_release\" ''-j \"$NIX_BUILD_CORES\"'' ]` |\n| `release` | When true, all cargo builds are run with `--release`. The environment variable `cargo_release` is set to `--release` iff this option is set. Default: `true` |\n| `override` | An override for all derivations involved in the build. Default: `(x: x)` |\n| `overrideMain` | An override for the top-level (last, main) derivation. If both `override` and `overrideMain` are specified, _both_ will be applied to the top-level derivation. Default: `(x: x)` |\n| `singleStep` | When true, no intermediary (dependency-only) build is run. Enabling `singleStep` greatly reduces the incrementality of the builds. Default: `false` |\n| `copyBins` | When true, the resulting binaries are copied to `$out/bin`. \u003cbr/\u003e Note: this relies on cargo's `--message-format` argument, set in the default `cargoBuildOptions`. Default: `true` |\n| `copyLibs` | When true, the resulting binaries are copied to `$out/lib`. \u003cbr/\u003e Note: this relies on cargo's `--message-format` argument, set in the default `cargoBuildOptions`. Default: `false` |\n| `copyBinsFilter` | A [`jq`](https://stedolan.github.io/jq) filter for selecting which build artifacts to release. This is run on cargo's [`--message-format`](https://doc.rust-lang.org/cargo/reference/external-tools.html#json-messages) JSON output. \u003cbr/\u003e The value is written to the `cargo_bins_jq_filter` variable. Default: `''select(.reason == \"compiler-artifact\" and .executable != null and .profile.test == false)''` |\n| `copyLibsFilter` | A [`jq`](https://stedolan.github.io/jq) filter for selecting which build artifacts to release. This is run on cargo's [`--message-format`](https://doc.rust-lang.org/cargo/reference/external-tools.html#json-messages) JSON output. \u003cbr/\u003e The value is written to the `cargo_libs_jq_filter` variable. Default: `''select(.reason == \"compiler-artifact\" and ((.target.kind | contains([\"staticlib\"])) or (.target.kind | contains([\"cdylib\"]))) and .filenames != null and .profile.test == false)''` Default: `''select(.reason == \"compiler-artifact\" and ((.target.kind | contains([\"staticlib\"])) or (.target.kind | contains([\"cdylib\"]))) and .filenames != null and .profile.test == false)''` |\n| `copyDocsToSeparateOutput` | When true, the documentation is generated in a different output, `doc`. Default: `true` |\n| `doDocFail` | When true, the build fails if the documentation step fails; otherwise the failure is ignored. Default: `false` |\n| `removeReferencesToSrcFromDocs` | When true, references to the nix store are removed from the generated documentation. Default: `true` |\n| `compressTarget` | When true, the build output of intermediary builds is compressed with [`Zstandard`](https://facebook.github.io/zstd/). This reduces the size of closures. Default: `true` |\n| `copyTarget` | When true, the `target/` directory is copied to `$out`. Default: `false` |\n| `postInstall` | Optional hook to run after the compilation is done; inside this script, `$out/bin` contains compiled Rust binaries. Useful if your application needs e.g. custom environment variables, in which case you can simply run `wrapProgram $out/bin/your-app-name` in here. Default: `false` |\n| `usePureFromTOML` | Whether to use the `fromTOML` built-in or not. When set to `false` the python package `remarshal` is used instead (in a derivation) and the JSON output is read with `builtins.fromJSON`. This is a workaround for old versions of Nix. May be used safely from Nix 2.3 onwards where all bugs in `builtins.fromTOML` seem to have been fixed. Default: `true` |\n| `mode` | What to do when building the derivation. Either `build`, `check`, `test`, `fmt` or `clippy`. \u003cbr/\u003e When set to something other than `build`, no binaries are generated. Default: `\"build\"` |\n| `autoCrateSpecificOverrides` | Whether to automatically apply crate-specific overrides, mainly additional `buildInputs` for dependencies. \u003cbr /\u003e For example, if you use the `openssl` crate, `pkgs.pkg-config` and `pkgs.openssl` are automatically added as buildInputs. Default: `true` |\n\n\n### Note on `overrideAttrs`\n\nWhen you call `buildPackage`, Naersk internally builds two derivations: one that\ncompiles all of your application's dependencies and then another one that\ncompiles just your application.\n\nIt's done this way to improve compilation speed when you build your program for\nthe second time etc., because then if only your application's code has changed\n(and `Cargo.toml` \u0026 `Cargo.lock` stayed the same), Naersk doesn't have to\nrebuild your dependencies.\n\nThis mechanism has a shortcoming, though - in particular, you shouldn't use\n`overrideAttrs` to inject something into the build environment:\n\n```nix\n{ pkgs, naersk, ... }:\n\nlet\n  app = naersk.buildPackage {\n    src = ./.;\n  };\n\nin\napp.overrideAttrs (p: {\n  buildInputs = p.buildInputs + [ pkgs.cmake ];\n  SOME_ENV_VAR = \"yes\";\n})\n```\n\n... because that will inject it only into the app-derivation, leaving it\ninaccessible for your dependencies to use.\n\nInstead, you should pass the parameters directly into the `buildPackage`\ninvocation:\n\n```nix\n{ pkgs, naersk, ... }:\n\nnaersk.buildPackage {\n  src = ./.;\n  buildInputs = [ pkgs.cmake ];\n  SOME_ENV_VAR = \"yes\";\n}\n```\n\n... or use `override`, if the names conflict with something already reserved by\nNaersk:\n\n```nix\n{ pkgs, naersk, ... }:\n\nnaersk.buildPackage {\n  src = ./.;\n\n  override = p: {\n    # ...\n  };\n}\n```\n\n... or, if you really have to call `overrideAttrs` on the final derivation, you\nshould disable the incremental-compilation mechanism:\n\n```nix\n{ pkgs, naersk, ... }:\n\nlet\n  app = naersk.buildPackage {\n    src = ./.;\n    singleStep = true; # here\n  };\n\nin\napp.overrideAttrs (p: {\n  buildInputs = p.buildInputs + [ pkgs.cmake ];\n})\n```\n\n(it's just an optimization so there's no harm in disabling it, Naersk should\nproduce the same binary anyway.)\n\n## Examples\n\nSee: [./examples](./examples).\n\n## Tips \u0026 Tricks\n\n### Building a particular example\n\nIf you want to build only a particular example, use:\n\n```nix\nnaersk.buildPackage {\n  pname = \"your-example-name\";\n  src = ./.;\n\n  overrideMain = old: {\n    preConfigure = ''\n      cargo_build_options=\"$cargo_build_options --example your-example-name\"\n    '';\n  };\n}\n```\n\n### Using CMake\n\nIf your application uses CMake, the build process might fail, saying:\n\n```\nCMake Error: The current CMakeCache.txt directory ... is different than the directory ... where CMakeCache.txt was created.\n```\n\nYou can fix this problem by removing stale `CMakeCache.txt` files before the\nbuild:\n\n```nix\nnaersk.buildPackage {\n  # ...\n\n  preBuild = ''\n    find \\\n        -name CMakeCache.txt \\\n        -exec rm {} \\;\n  '';\n}\n```\n\n([context](https://github.com/nix-community/naersk/pull/288))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnix-community%2Fnaersk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnix-community%2Fnaersk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnix-community%2Fnaersk/lists"}