{"id":13647670,"url":"https://github.com/cargo2nix/cargo2nix","last_synced_at":"2025-05-15T16:02:41.030Z","repository":{"id":37933355,"uuid":"186339009","full_name":"cargo2nix/cargo2nix","owner":"cargo2nix","description":"Granular builds of Rust projects for Nix","archived":false,"fork":false,"pushed_at":"2025-04-12T20:50:58.000Z","size":1764,"stargazers_count":418,"open_issues_count":70,"forks_count":83,"subscribers_count":12,"default_branch":"release-0.11.0","last_synced_at":"2025-05-14T13:56:31.535Z","etag":null,"topics":["cargo","nix","nix-overlay","nixos","nixpkgs","rust"],"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/cargo2nix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"positron-solutions"}},"created_at":"2019-05-13T03:27:27.000Z","updated_at":"2025-05-13T02:16:42.000Z","dependencies_parsed_at":"2023-02-15T03:01:52.511Z","dependency_job_id":"25c38ad8-0f4b-4eac-a7b1-fdf0124a07df","html_url":"https://github.com/cargo2nix/cargo2nix","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cargo2nix%2Fcargo2nix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cargo2nix%2Fcargo2nix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cargo2nix%2Fcargo2nix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cargo2nix%2Fcargo2nix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cargo2nix","download_url":"https://codeload.github.com/cargo2nix/cargo2nix/tar.gz/refs/heads/release-0.11.0","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254374398,"owners_count":22060609,"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","nix","nix-overlay","nixos","nixpkgs","rust"],"created_at":"2024-08-02T01:03:42.002Z","updated_at":"2025-05-15T16:02:40.990Z","avatar_url":"https://github.com/cargo2nix.png","language":"Nix","funding_links":["https://github.com/sponsors/positron-solutions"],"categories":["Nix","Programming Languages"],"sub_categories":["Rust"],"readme":"# cargo2nix\n\n[![darwin \u0026 linux CI](https://github.com/cargo2nix/cargo2nix/actions/workflows/ci.yml/badge.svg)](https://github.com/cargo2nix/cargo2nix/actions/?workflow=CI)\n[![flakes supported](https://img.shields.io/badge/flake-supported-green)](https://nixos.wiki/wiki/Flakes)\n[![latest release](https://img.shields.io/github/v/tag/cargo2nix/cargo2nix?color=%23009922\u0026label=release)](https://github.com/cargo2nix/cargo2nix/releases)\n\nBring [Nix](https://nixos.org/nix) dependency management to your Rust project!\n\n- **Development Shell** - knowing all the dependencies means easy creation of\n  complete shells.  Run `nix develop` or `direnv allow` in this repo and see!\n- **Caching** - CI \u0026 CD pipelines move faster when purity guarantees allow\n  skipping more work!\n- **Reproducibility** - Pure builds.  Access to all of\n  [nixpkgs](https://github.com/NixOS/nixpkgs) for repeatable environment setup\n  across multiple distributions and platforms\n\n## Run it now!\n\nWith [nix](https://nixos.org/nix) (with flake support) installed, generate a\n`Cargo.nix` for your project:\n\n```bash\n# Use nix to get cargo2nix \u0026 rust toolchain on your path\nnix develop github:cargo2nix/cargo2nix#bootstrap\n\n# In directory with Cargo.toml \u0026 Cargo.lock files (cargo generate-lockfile)\ncargo2nix\n\n# Or skip the shell and run it directly\nnix run github:cargo2nix/cargo2nix\n\n# You'll need this in version control\ngit add Cargo.nix\n```\n\n### Use what you generated!\n\nTo consume your new `Cargo.nix`, write a nix expression like that found in the\n[hello world](./examples/1-hello-world/flake.nix) example.\n\nA bare minimum flake.nix:\n\n```nix\n{\n  inputs = {\n    cargo2nix.url = \"github:cargo2nix/cargo2nix/release-0.11.0\";\n    flake-utils.follows = \"cargo2nix/flake-utils\";\n    nixpkgs.follows = \"cargo2nix/nixpkgs\";\n  };\n\n  outputs = inputs: with inputs;\n    flake-utils.lib.eachDefaultSystem (system:\n      let\n        pkgs = import nixpkgs {\n          inherit system;\n          overlays = [cargo2nix.overlays.default];\n        };\n\n        rustPkgs = pkgs.rustBuilder.makePackageSet {\n          rustVersion = \"1.75.0\";\n          packageFun = import ./Cargo.nix;\n        };\n\n      in rec {\n        packages = {\n          # replace hello-world with your package name\n          hello-world = (rustPkgs.workspace.hello-world {});\n          default = packages.hello-world;\n        };\n      }\n    );\n}\n```\n\nFor a more complete project with CI \u0026 CD mostly ready to go, check out\n[Unixsocks][unixsocks] or cargo2nix's own [CI workflow.](./.github/workflows/ci.yml)\n\n[unixsocks]: https://github.com/positron-solutions/unixsocks\n\n#### Build with nix\n\n```shell\n# these must be in version control!\ngit add flake.nix Cargo.nix\n\nnix build\n...\n...\n...\n./result-bin/bin/hello\nhello world!\n```\n\nCheck out our series of [example projects](./examples) which showcase how to use\n`cargo2nix` in more detail.\n\n### Development environment\n\nIn this repo, simply use `nix develop` or `direnv allow`.  Even if you are on\na bare NixOS system or fresh OSX environment with no dependencies or toolchains\ninstalled, you will have everything you need to run `cargo build`.  See the\n`devShell` attribute in `flake.nix` to see how to prepare this kind of shell.\n\nThe `workspaceShell` function, created by [`makePackagSet`](#Arguments), accepts\nall the same options as the nix [`mkShell`] function.\n\n[`mkShell`]: https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell\n\n### Maintaining your project\n\nIn your flake, you can choose your cargo2nix version by changing the URL.\n\n| Flake URL                                 |                            Result                            |\n|-------------------------------------------|:------------------------------------------------------------:|\n| github:cargo2nix/cargo2nix/               | latest release (check repo's default branch, release-0.11.0) |\n| github:cargo2nix/cargo2nix/release-0.11.0 |                    use a specific release                    |\n| github:cargo2nix/cargo2nix/unstable       |                    latest features \u0026 fixes                   |\n\nOnly use unstable for developing with the latest features.  PR's against old\nreleases can be accepted but no active support will be done.  **The default\nbranch for this repo is updated whenever a new release tag is made.**  Only\nspecific release branches are \"stable.\"\n\nUpdate your flake lock with the latest or a specific version of cargo2nix:\n\n```shell\nnix flake lock --update-input cargo2nix\nnix flake lock --update-input cargo2nix --override-input cargo2nix github:cargo2nix/cargo2nix/?rev=d45481420482fa7d9b0a62836555e24ec07d93be\n```\n\nIf you need newer versions of Rust or the flake-utils inputs, just specify them\nusing URL instead of follows.\n\n### Arguments to `makePackageSet`\n\nThe `makePackageSet` function from [the\noverlay](./overlay/make-package-set/user-facing.nix) accepts arguments that\nadjust how the workspace is built.  Only the `packageFun` argument is required.\nCargo2nix's own [flake.nix](./flake.nix) has more information.\n\n- `rustVersion` - is either a version string or YYYY-MM-DD date-string\n- `rustChannel` - `\"nightly\"` `\"beta\"` `\"stable\"`\n- `rustProfile` - `\"default\"` or `\"minimal\"` usually\n- `extraRustComponents` - `[\"clippy\" \"miri\"]` etc\n\n- `workspaceSrc` - override where the source is supplied relative to the\n  Cargo.nix\n- `rootFeatures` - a list of `foo/feature` strings for workspace crate features\n- `packageOverrides` - control over the individual crate overrides used to make\n  them compatible on some platforms, for example to tweak C lib consumption\n\n- `target` - setting an explicit target, useful when cross compiling to obtain a\n  specific Rust target that doesn't align with the nixpkgs target\n\n#### Contents of Package Set\n\n`rustPkgs` contains all crates in the dependency graph and some extra\nconveniences for development.  The workspace crates are also exposed via a\nworkspace attribute.\n\n`rustPkgs.\u003cregistry\u003e.\u003ccrate\u003e.\u003cversion\u003e` is an example of a crate **function**\npath.  Calling the function results in a completed derivation, which can be used\nas a flake output.  They support all the normal behaviors such as `override` and\n`overrideAttrs`.  See [mkCrate.nix](./overlay/mkcrate.nix) for the full set of\narguments the crate function supports.\n\n`rustPkgs.workspace.\u003ccrate\u003e` are usually the packages you will use.  The other\npaths look like:\n\n`rustPkgs.\"registry+https://github.com/rust-lang/crates.io-index\".openssl.\"0.10.30\"`\n\n`rustPkgs.workspaceShell` is a derivation using Nix's standard `mkShell`,\nembellished with information we learned from the dependencies and their\noverrides, enabling vanilla `cargo build` to work in a `nix develop` shell.\n\n#### Overrides\n\n_This is for finished derivations, not for dependencies.  Keep reading below for\nusing `makeOverride` in the dependency tree._\n\n`workspaceShell` and crates both support [`override`](o) and\n[`overrideAttrs`](oa) like normal Nix derivations.  This allows you to customize\nthe workspace shell or a build step in your workspace crate very easily.  See\n`nix show-derivation` and `nix show-derivation #devShell` for more information.\n\n[o]: https://nixos.org/manual/nixpkgs/stable/#sec-pkg-override\n[oa]: https://nixos.org/manual/nixpkgs/stable/#sec-pkg-overrideAttrs\n\n#### More Control\n\nYou can make overrides to packages in the dependency tree.  See examples in\n[overrides.nix](./overlay/overrides.nix).  Overriding the `buildPhase` etc is\npossible for a single crate without modifying `mkcrate.nix` in cargo2nix\ndirectly.  The output of `nix show-derivation` can be valuable when determining\nwhat the current output result is.\n\n**The most important function in cargo2nix source is mkcrate.nix** because it's\nhow we store information in dependents and replay them back when\nbuilding dependents.  It is vital for building crates in isolation.\n\n## Newer Rust versions\n\nIn order to use the latest Rust versions you may need to include\n[rust-overlay](https://github.com/oxalica/rust-overlay) directly in your flake\nlike so:\n\n```nix\n{\n  inputs = {\n    rust-overlay.url = \"github:oxalica/rust-overlay/stable\";\n    cargo2nix = {\n      url = \"github:cargo2nix/cargo2nix/release-0.11.0\";\n      inputs.rust-overlay.follows = \"rust-overlay\";\n    };\n  };\n}\n```\n\nTo use a Rust version that was released after you added the rust-overlay input\nyou will need to run `nix flake update rust-overlay` to get the latest\nrust-overlay version.\n\n## How it works\n\n- The `cargo2nix` utility reads the Rust workspace configuration and\n  `Cargo.lock` and generates nix expressions that encode some of the feature,\n  platform, and target logic into a `Cargo.nix`\n\n- The cargo2nix [Nixpkgs](https://github.com/NixOS/nixpkgs) [overlay](./overlay)\n  consumes the `Cargo.nix`, feeding it what you pass to `makePackageSet` to\n  provide workspace outputs you can expose in your nix flake\n\n- Because we know all of the dependencies, it's easy to create a shell from those\n  dependencies as environment setup using the `workspaceShell` function and\n  exposing the result in the `devShell` flake output\n\n### Building crates isolated from each other\n\nJust like regular `cargo` builds, the Nix dependencies form a [DAG][DAG], but\npurity means we only expose essential information to dependencies and manually\ninvoke `cargo`.  Communication from dependencies to dependents is handled by\nwriting some extra outputs and then reading those outputs inside the next\ndependent build.\n\nThere's two broad categories of information that need to be transmitted when\nhand-building crates in isolation:\n\n- **Global information**\n\n  - target such as `x86_64-unknown-linux-gnu`\n  - cargo actions such as `build` or `test`\n  - features which turn on optional dependencies \u0026 downstream features via logic\n    in the [`Cargo.nix`](./Cargo.nix) expressions\n\n  This information is known before any of the crates are built.  It's used at\n  evaluation time to decide what will be built. See `nix show-derivation` results.\n\n- **Propagated information**\n\n  Each dependency writes information such as linker flags alongside its rlib and\n  other outputs.  When the dependent is going to consume the dependency, it\n  reads this information back.\n\nDerivations are evaluated in Nix with global information available.  During the\nbuild, rlibs and dependency information are propagated back up the DAG.  Each\nderivation's build shell combines the linking, features, target, and other\ninformation.  You can see how it's used in\n[`mkcrate.nix`](./overlay/mkcrate.nix)\n\n[DAG]: https://en.wikipedia.org/wiki/Directed_acyclic_graph\n\n### Limitations implied by purity\n\nEvaluation of nix derivations doesn't require building anything.  If you want to\nbuild a specific variant of a crate in a workspace with Nix, we would have to\nknow this when building all of its dependencies.  This means certain behavior to\nswitch features and optional dependencies on or off depends on what _else_ is\nbeing built.  By default `cargo2nix` will build crates as if all other crates in\nthe workspace _might_ be build.  This can be somewhat controlled with the\n`rootFeatures` argument.  (see `rootFeatures` in [Cargo.nix](./Cargo.nix)).\nThis actually improves caching but may rarely result in a long build for an\nunneeded dependency (which your workspace should put behind a non-default\ntop-level feature).  Cargo isn't any better at this aspect of caching vs\nrebuilding.\n\n## Common issues\n\n1. Flakes require `flake.nix` and `Cargo.nix` to be in version control.  `git\n   add flake.nix Cargo.nix` etc.  Remember to keep them up to date!  Before\n   building the examples, you will usually need to update their pin of\n   cargo2nix: `nix flake lock --update-input cargo2nix` or nix may complain\n   about paths.\n\n1. Old versions of the `cargo2nix.overlay` usually cannot consume newer versions\n   of the `Cargo.nix` that an updated cargo2nix will produce.  Update your\n   inputs with `nix flake lock --update-input cargo2nix` or `nix build\n   --update-input cargo2nix`\n\n1. When building `sys` crates, `build.rs` scripts may themselves attempt to\n   provide native dependencies that could be missing. See the\n   `overlay/overrides.nix` for patterns of common solutions for fixing up\n   specific deps.\n\n   To provide your own override, pass a modified `packageOverrides` to\n   `pkgs.rustBuilder.makePackageSet`:\n\n   ```nix\n     rustPkgs = pkgs.rustBuilder.makePackageSet {\n       # ... required arguments not shown\n\n       # Use the existing all list of overrides and append your override\n       packageOverrides = pkgs: pkgs.rustBuilder.overrides.all ++ [\n\n         # parentheses disambiguate each makeOverride call as a single list element\n         (pkgs.rustBuilder.rustLib.makeOverride {\n             name = \"fantasy-zlib-sys\";\n             overrideAttrs = drv: {\n               propagatedBuildInputs = drv.propagatedBuildInputs or [ ] ++ [\n                 pkgs.zlib.dev\n               ];\n             };\n         })\n       ];\n     };\n   ```\n\n1. Each derivation function in `rustBuilder.makePackageSet` has it's outputs\n   created within [mkcrate.nix](./overlay/mkcrate.nix), using some bash\n   functions in [mkcrate-utils.sh](./overlay/mkcrate-utils.sh).  We try not to\n   copy more than necessary to the outputs, but this also means sometimes\n   skipping a necessary file.  Each derivation is [multiple output], using `bin`\n   and `out`.  The default output is `bin` and should contain just what's\n   necessary at runtime, possibly linked to other files in the Nix store.  This\n   output is for installation into a Nix profile or shell.  The `out` output\n   contains all of this and extra information necessary for dependents to\n   consume the crate, usually linking information, which will collide if you\n   attempt to install several such derivations.\n\n   [multiple output]: https://nixos.org/manual/nixpkgs/stable/#chap-multiple-output\n\n1. Non-deterministic rustc or linker behavior can lead to binary-incompatible\n   crates.  Nix cannot protect from non-determinism, only impurity.  Override\n   your builds with `preferLocalBuild = true;` `allowSubstitutes = false;` for\n   the affected package.  This has been seen more often because of\n   non-deterministic macros.  See #184 for more information.\n\n1. Nixpkgs is a rolling release, and that means breakages occur but you have\n   many potential successful versions to choose from.  View the [CI logs] and\n   check the `flake.lock` for rev information from recent successes.  Update to\n   a specific input version with:\n\n   ```shell\n    nix flake lock --override-input nixpkgs github:nixpgks/nixpkgs?rev=a284564b7f75ac4db73607db02076e8da9d42c9d\n   ```\n\n   [CI logs]: https://github.com/cargo2nix/cargo2nix/actions/?workflow=CI\n\n1. Toml parsing / conversion issues `Error: Cannot convert data to TOML (Invalid\n   type \u003cclass 'NoneType'\u003e)`\n\n   `jq` and `remarshal` are used to read \u0026 modify toml files in some\n   cases. Lines of the form: ```[key.\"cfg(foo = \\\"a\\\", bar = \\\"b\\\"))\".path]```\n   could produce breakage when `jq` output was fed back to `remarshal`. There\n   are workarounds in place to catch many cases. See #149 for more information\n   and report any newly found breakage until a total solution is in place.\n\n1. Git dependencies and crates from alternative Cargo registries rely on\n   `builtins.fetchGit` to support fetching from private Git repositories. This\n   means that such dependencies cannot be evaluated with `restrict-eval`\n   applied.\n\n   Also, if your Git dependency is tied to a Git branch, e.g. `master`, and you\n   would like to force it to update on upstream changes, you should append\n   `--option tarball-ttl 0` to your `nix-build` command.\n\n## Declarative build debugging shell\n\nYou can load a nix shell for any crate derivation in the dependency tree. This\nis the same environment the `cargo2nix` overlay will build them in.\n\nTo do this, first find the `.drv` for your dependency by using, for example,\n`nix show-derivation | grep colorify`\n\n```bash\nnix show-derivation | rg -o \"/nix.*crate.*colorify.*drv\"\nnix/store/whi3jprrpzlnvic9fsn5f69sddazp5sb-colorify-0.2.3.tar.gz\n\n# ignore environment to remove your shell's impurities\nnix develop --ignore-environment nix/store/whi3jprrpzlnvic9fsn5f69sddazp5sb-colorify-0.2.3.tar.gz\n\n# the environment is now as it is when nix builds the package\necho $src\nnix/store/whi3jprrpzlnvic9fsn5f69sddazp5sb-colorify-0.2.3.tar.gz\n\n# If you are working on a dependency and need the source (or a fresh copy) you\n# can unpack the $src variable. Through nix stdenv, tar is available in pure\n# shells\nmkdir debug\ncp $src debug\ncd debug\ntar -xzfv whi3jprrpzlnvic9fsn5f69sddazp5sb-colorify-0.2.3.tar.gz\ncd \u003cunpacked source\u003e\n```\n\nYou will need to override your `Cargo.toml` and `Cargo.lock` in this shell, so\nmake sure that you have them backed up if your are directly using your clone of\nyour project instead of unpacking fresh sources like above.\n\nNow you just need to run the `$configurePhase` and `$buildPhase` steps in order.\nYou can find additional phases that may exist in overrides by running `env |\ngrep Phase`\n\n```bash\necho $configurePhase\n# runHook preConfigure runHook configureCargo runHook postConfigure\n\nrunHook preConfigure # usually does nothing\nrunHook findCrate\nrunHook configureCargo\nrunHook postConfigure # usually does nothing\n\necho $buildPhase\n# runHook overrideCargoManifest runHook setBuildEnv runHook runCargo\n\nrunHook overrideCargoManifest  # This overrides your .cargo folder, e.g. for setting cross-compilers\nrunHook setBuildEnv  # This sets up linker flags for the `rustc` invocations\nrunHook runCargo\n```\n\nIf `runCargo` succeeds, you will have a completed output ready for the (usually)\nless interesting `$installPhase`. If there's a problem, inspecting the `env` or\nreading the generated `Cargo.lock` etc should yield clues.  If you've unpacked a\nfresh source and are using the `--ignore-environment` switch, everything is\nidentical to how the overlay builds the crate, cutting out guess work.\n\n## Contributing\n\nSee [Contributing](./CONTRIBUTING.md) for potentially more information.\n\n1. Fork this repository into the personal GitHub account\n2. Select the appropriate branch, release-\u003cversion\u003e for stable changes, unstable\n   for breaking changes\n3. Make changes on the personal fork\n4. Make a Pull Request against this repository\n5. **Allow maintainers to make changes to your pull request** (there's a checkbox)\n6. Once the pull request has been approved, you will be thanked and observe your\n   changes applied with authorship preserved (if we remember)\n\n## Credits\n\nThe design for the Nix overlay is inspired by the excellent work done by James\nKay, which is described [here][blog-1] and [here][blog-2]. His source is\navailable [here][mkRustCrate]. This work would have been impossible without\nthese fantastic write-ups. Special thanks to James Kay!\n\n[blog-1]: https://www.hadean.com/blog/managing-rust-dependencies-with-nix-part-i\n[blog-2]: https://www.hadean.com/blog/managing-rust-dependencies-with-nix-part-ii\n[mkRustCrate]: https://github.com/Twey/mkRustCrate\n\n## License\n\n`cargo2nix` is free and open source software distributed under the terms of the\n[MIT License](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcargo2nix%2Fcargo2nix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcargo2nix%2Fcargo2nix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcargo2nix%2Fcargo2nix/lists"}