How to deal with conflicting packages?

I’ve been trying to set up my environment to work with rust. I followed a similar path to here: installed rustup with nix-env, and ended up with cargo run answering with:

error: linker ` cc ` not found

I figured things would get better if I installed gcc in my user profile, just to try (i know, use nix-shell instead). So I tried nix-env -iA nixos.gcc which replied:

installing 'gcc-wrapper-9.3.0'
building '/nix/store/4v0073lgw6yql2j3bcza5glqfcl5cf0x-user-environment.drv'...
error: packages '/nix/store/8pbwywcj6vbswz7xmy2dh716x8blgh8w-gcc-wrapper-9.3.0/bin/ld.gold' and '/nix/store/5sj06x18pd8an12ndl65hlwmp8afnrwa-binutils-wrapper-2.31.1/bin/ld.gold' have the same priority 10; use 'nix-env --set-flag priority NUMBER INSTALLED_PKGNAME' to change the priority of one of the conflicting packages (0 being the highest priority)

To continue my quick and dirty attempt to try and make things work, I tried setting the priority of something to some number… but I’m unable to find a valid package name to set the flag:

> nix-env --set-flag priority 5 nixos.gcc-wrapper
error: selector 'nixos.gcc-wrapper' matches no derivations

(I tried all sorts of variants of derivation “names”: gcc, nixos.gcc, gcc-wrapper, gcc-wrapper-9.3.0, I admit that I don’t really know what I’m doing anymore)

I have two question:

  1. How do you set a priority?
  2. How do you properly handle conflicting packages? Is the conflict a mere result of trying to put stuff in my user profile with nix-env inappropriately, and would it never happen if I were to do things in a nix-er way?

The end of the story is that I created a shell.nix with buildInput = [pkgs.rustup pkgs.gcc] and everything works. I don’t know if that’s the best way to go, but I want to use rustup rather than a pure nix way because I feel like it’ll ease interactions with other rust developers not using nix.

1 Like

Maybe this would work?

$ nix-env -iE 'with import <nixpkgs> {}; hiPrio gcc'

This is what it gives:

> nix-env -iE 'with import <nixpkgs> {}; hiPrio gcc'
error: attempt to call something which is not a function but a set, at undefined position

That was probably a dumb idea from my side. Would you be willing to switch to a declarative package management for your user environment? That allows some more fine-grained control over priorities.

For starters I recommend option 2) buildEnv.

Thanks, I’ll have a look at the buildEnv option. For the moment, I put all the packages I need in ~/default.nix and install them with nix-env -f ~ -ir. It somewhat looks like the approach 1), but I’m not sure. Will buildEnv help with conflicting packages?

I couldn’t find much documentation on buildEnv. What does it do?

buildEnv is what is used to build e.g. the system path in NixOS (the stuff you put in environment.systemPackages). To deal with conflicting packages you can assign priorities as I attempted to for nix-env with

{ pkgs ? import <nixpkgs> {} }:
with pkgs;
buildEnv {
  name = "user-env";
  paths = [
    nix # needed on non-NixOS
    rustup
    (hiPrio gcc)
  ];
}

I’m taking some time to look at that again. Can you elaborate on why you recommend buildEnv, especially over the attrset one? I’m trying to understand the differences