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:

[package.metadata.nix]
build = true
runtimeLibs = [ ... ]
buildInputs = [
    "wayland",
    ...
]
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:

[package.metadata.nix.crateOverrides.depName]
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:

[package.metadata.nix.crateOverrides.wayland-sys]
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" }
configuring
Running cd .
Building build.rs (wayland-sys)
Running rustc --crate-name build_script_build build.rs --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.', build.rs:10:47
stack backtrace:
   0: rust_begin_unwind
             at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/panicking.rs:107:14
   2: core::result::unwrap_failed
             at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/core/src/result.rs:1613:5
   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 https://github.com/jonringer/nix-template/blob/4d852a1f72b5a8c0d79b8e6b7d5809c66414c12d/nix/nix-template.nix

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.

For completeness (I know this is an old issue, but I just spent too long on this and I found the answer here): even if your dep is only needed at build time, if you want pkg-config to find it, you need to make sure pkg-config has run and modified the env before cargo starts. Thus e.g. openssl is a runtime dep from the POV of the nix building process, even though it’s a build time dep from the POV of a normal cargo build (which vendors the lib rather than link against it).

Sure this is obvious when you have more experience with nix, but maybe the penny will drop for someone else too.

2 Likes