Nix and rust - how to use pkgconfig

I’m stuck how to build using flakes and rust. I tried to compile program which as one of dependency has a wayland so when I write:

build = true
runtimeLibs = [ ... ]
buildInputs = [
nativeBuildInputs = [ "pkgconfig" ]

I got error:

error: builder for '/nix/store/c4qshv8zf49pi4y9z7m4a9wrqhnziq6v-devshell-dir.drv' failed with exit code 25;
       last 1 log lines:
       > error: collision between `/nix/store/k6xlv2g261xwvhg6h27h8fzrdxjh66wy-wayland-1.20.0-bin/lib/pkgconfig/wayland-scanner.pc' and `/nix/store/7lpzdf2abg0964pr7lz0l3aw3cf86z2v-wayland-1.20.0-dev/lib/pkgconfig/wayland-scanner.pc'
       For full logs, run 'nix log /nix/store/c4qshv8zf49pi4y9z7m4a9wrqhnziq6v-devshell-dir.drv'.
error: 1 dependencies of derivation '/nix/store/9qjijmdqa0672f8pvfqc67vrgnrh8l31-devshell-env.drv' failed to build

And during nix build it couldn’t find pkgconfig. When I tried to play with overrides I couldn’t get it to work either.

My flakes.nix is:

  inputs = {
    nixCargoIntegration.url = "github:yusdacra/nix-cargo-integration";
    rust-overlay.url = "github:oxalica/rust-overlay";
    nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; 

  outputs = inputs: inputs.nixCargoIntegration.lib.makeOutputs {
    root = ./.;
    buildPlatform = "crate2nix";
1 Like

You should use crateOverrides instead of those attributes. There is a section in nix-cargo-integration manual on that:

nativeBuildInputs = ["pkg-config"]
buildInputs = ["wayland", "wayland-protocols"]

and replace depName with your dependency’s name that needs them.

I would also appreciate if you made an issue on nix-cargo-integration’s repository on your issues :slight_smile:

I added:

buildInputs = [ "wayland", "wayland-protocols" ]
nativeBuildInputs = [ "pkgconfig" ]

But it still fails:

@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking sources
unpacking source archive /nix/store/x165ccc87gli5njrzrpkzkh2z6683dab-wayland-sys-0.29.4.tar.gz
source root is wayland-sys-0.29.4
@nix { "action": "setPhase", "phase": "patchPhase" }
patching sources
@nix { "action": "setPhase", "phase": "configurePhase" }
Running cd .
Building (wayland-sys)
Running rustc --crate-name build_script_build --crate-type bin -C opt-level=3 -C codegen-units=12 --edition 2018 --cfg feature="client" --cfg feature="default" --cfg feature="dlib">
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Could not run `"pkg-config" "--libs" "--cflags" "wayland-client"`
The pkg-config command could not be found.

Most likely, you need to install a pkg-config package for your OS.
Try `apt install pkg-config`, or `yum install pkg-config`,
or `pkg install pkg-config` depending on your distribution.

If you've already installed it, ensure the pkg-config command is one of the
directories in the PATH environment variable.

If you did not expect this build to link to a pre-installed system library,
then check documentation of the wayland-sys crate for an option to
build the library from source, or disable features or dependencies
that require pkg-config.',
stack backtrace:
   0: rust_begin_unwind
             at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/
   1: core::panicking::panic_fmt
             at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/
   2: core::result::unwrap_failed
             at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/
   3: build_script_build::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Using pkg-config doesn’t change things.

For development, I would do something like:

mkShell = {
  name = "rust-env";
  nativeBuildInputs = [ pkg-config ];
  buildInputs = [ wayland ];

The important part is that pkg-config will run a shell hook, and the shell hook will expose the env vars necesarry for pkg-config to work.

For packaging, I would do something like nix-template/nix-template.nix at 4d852a1f72b5a8c0d79b8e6b7d5809c66414c12d · jonringer/nix-template · GitHub

Yeah. If I run nix-shell -p wayland ... 'cargo build' it works. The question is how to use it with flakes…

expose it as outputs.devShell, then you run nix develop instead.

I managed to get it to work (partial) by:

  inputs = {
    nixCargoIntegration.url = "github:yusdacra/nix-cargo-integration";

  outputs = inputs: inputs.nixCargoIntegration.lib.makeOutputs {
    root = ./.;
    buildPlatform = "crate2nix";
    overrides = {
      crateOverrides = common: prev: {
        "wayland-sys" = prev: {
          buildInputs = (prev.buildInputs or []) ++ [common.pkgs.wayland];
          nativeBuildInputs = (prev.nativeBuildInputs or []) ++ [common.pkgs.pkgconfig];

However the devshell fails:

error: builder for '/nix/store/xqs8d45sw9p8is3lmw9ygjr2ss1pl4nq-devshell-dir.drv' failed with exit code 25;
       last 1 log lines:
       > error: collision between `/nix/store/k6xlv2g261xwvhg6h27h8fzrdxjh66wy-wayland-1.20.0-bin/lib/pkgconfig/wayland-scanner.pc' and `/nix/store/7lpzdf2abg0964pr7lz0l3aw3cf86z2v-wayland-1.20.0-dev/lib/pkgconfig/wayland-scanner.pc'
       For full logs, run 'nix log /nix/store/xqs8d45sw9p8is3lmw9ygjr2ss1pl4nq-devshell-dir.drv'.

This shouldn’t exist. looks like wayland is mis-packaged

Thanks. I will create nix bug.

Can you make an issue on nix-cargo-integration repo about the Cargo.toml crate override not working? I’d like to see your full Cargo.toml file, even better if this is public, would be good to see all files.