NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.51k stars 13.69k forks source link

Referencing a package from config.nix seems to imply a different stdenv #2530

Closed jwiegley closed 9 years ago

jwiegley commented 10 years ago

On Darwin, I've created the following config.nix file:

{ packageOverrides = pkgs: with pkgs; rec {

systemToolsEnv = pkgs.buildEnv {
    name = "systemTools";
    paths = [
      coreutils findutils gnused gnutar httrack iperf mosh mtr multitail
      p7zip parallel pdnsd gnupg pinentry pv rsync silver-searcher socat
      stow watch xz
    ];
  };

}; }

If I install that list of dependencies manually, using:

nix-env -i <paths>

Then everything installs fine. But if I install the buildEnv above with:

nix-env -iA nixpkgs.systemToolsEnv

Then it tries to pull in binutils, gcc-apple-wrapper, and different derivations for bash, coreutils, and several other packages. It seems like it's trying to build these paths using a different stdenv than what gets used by all-packages.nix.

How can I determine the "decision chain" which is leading to it trying to use binutils when installed one way, but not the other?

jwiegley commented 10 years ago

Conversely, how do I reference these packages from all-packages.nix in my config.nix such that it does use the correct stdenv?

jwiegley commented 10 years ago

It works if I define my config.nix like this:

{ pkgs }:

{ packageOverrides = self: with pkgs; rec {

systemToolsEnv = pkgs.buildEnv {
    name = "systemTools";
    paths = [
      coreutils findutils gnused gnutar httrack iperf mosh mtr multitail
      p7zip parallel pdnsd gnupg pinentry pv rsync silver-searcher socat
      stow watch xz
    ];
  };

}; }

I recommend that this be documented on the following page:

https://nixos.org/wiki/Nix_Modifying_Packages#Creating_a_config.nix_File
peti commented 10 years ago

The current pkgs set is an argument to the packagesOverrides function. IMHO, the most idiomatic way to write overrides is:

{
  packageOverrides = pkgs: with pkgs; {
    # do stuff here 
  };
}
jwiegley commented 10 years ago

Yes, but it doesn't work. See above.

peti commented 10 years ago

Well, it works just fine for me! What does env | grep NIX say on your system? And could you please also paste the output from ls -ld ~/.nix-defexpr && ls -la ~/.nix-defexpr?

jwiegley commented 10 years ago
hermes:~ $ env | grep NIX
NIX_CONF_DIR=/Users/johnw/.nix
NIX_PATH=nixpkgs=/Users/johnw/Projects/nixpkgs:/nix/var/nix/profiles/per-user/johnw/channels/nixpkgs:nixpkgs=/Users/johnw/.nix-defexpr/channels/nixpkgs
hermes:~ $ ls -ld ~/.nix-defexpr
drwxr-xr-x 3 johnw staff 102 Apr 24 00:44 /Users/johnw/.nix-defexpr
hermes:~ $ ls -ld ~/.nix-defexpr/*
lrwxr-xr-x 1 johnw staff 24 Apr 23 23:48 /Users/johnw/.nix-defexpr/nixpkgs -> /Users/johnw/src/nixpkgs
peti commented 10 years ago

Are /Users/johnw/Projects/nixpkgs and /Users/johnw/src/nixpkgs the same path on your system? Your NIX_PATH refers to both of them, which doesn't seem right.

peti commented 10 years ago

Does it make any difference if you set

export NIX_PATH=/nix/var/nix/profiles/per-user/johnw/channels/nixpkgs:nixpkgs=/Users/johnw/src/nixpkgs

before running nix-env?

gridaphobe commented 9 years ago

@jwiegley is this still an issue?

peti commented 9 years ago

I believe we found out at some point that there's a difference between pkgs.foo and pkgs.pkgs.foo in the context of packageOverrides = pkgs: { ... }. The name pkgs refers to the package set without overrides applied, and the latter refers to the package set after overrides have been applied. Thus, it's important to distinguish which package set is used to resolve references. In the Haskell package set world, we usually call these two sets self and super.

After figuring all this out, I re-wrote my ~/.nixpkgs/config.nix file to read:

{
  packageOverrides = super: let self = super.pkgs; in {
    ...
  };
}

Now, I can override a package like so:

rWrapper = super.rWrapper.override {
  packages = with self.rPackages; [ assertthat ];
};