[Nix-dev] $out/ENV?

Marc Weber marco-oweber at gmx.de
Sat Jun 5 03:27:56 CEST 2010


I've been wondering how to support setting env vars natively in Nix* or
how to simplify using some env vars such as

  - RUBYLIB
  - PYTHONPATH ( soon NIX_PYTHON_SITES)
  - PERL5LIB
  - PATH !
  - PKG_CONFIG_PATH
  - ..

What's the problem? Have a look at nixpkgs sources. How often is
toPythonPath being used? Approx 42 times.

My vision:

Add an $out/ENV file to each package. For a python package it could look
like this (OUT = $out).

  addColonSeparatedOnce PATH $out/bin $out/sbin
  addColonSeparatedOnce NIX_PYTHON_SITES $out

for a C package it could look like this:

  addColonSeparatedOnce PATH $out/bin $out/sbin
  spaceThenSuffix NIX_LD_FLAGS "-L $out/lib"
  spaceThenSuffix NIX_CFLAGS_COMPILE "-I $out/include"


setup.sh could contain this code:

  declare -A sourced

  for x in $nativePackages; do
    [ -n "${sourced["$x"]}" ] || {
      . $x/ENV
      sourced["$x"]=1
    }
  done

benefits: A path will never be added twice to a list. If you use
propagatedBuildInputs this can happen easily.



Now we could replace the buildenv.pl script by

  {
    for i in $paths; do
      cat $i/ENV
    done
  } >> $out/ENV

Thus: we don't have to create 10.000 symlinks. we could concatenate all
ENV files. In your .bashrc you could source it and be done.

You can choose whether to source your ENV file only or the system ENV
file as well. In other words: You can merge envs on the fly:

. ~joe/.nix-profile/ENV
. ~marc/.nix-profile/ENV
. ~other-user/.nix-profile/ENV

Benefit: Your user env does no longer differ that much from a build
environment. Eg automake, configure, ruby, python, perl, ... will just
work the way they would in a builder.


For performance reasons you could store items which should be appended
to lists in hashs to avoid duplications and create the env vars at the
end after having sourced all ENV files:


. /nix/store/env-helpers-script
. ~joe/.nix-profile/ENV
. ~marc/.nix-profile/ENV
. ~other-user/.nix-profile/ENV
realiseEnv # hashs -> env vars

drawbacks:
- sourcing ENV can take some time. However the built result could be
  cached. Eg /bin/sh -c '. ENV; export > built-env'
- the shell environment will be bigger because it contains more paths.
  Does this make forks slower because the environment has to be copied?
- you can no longer ask a browser to open pdfs with
  ~/.nix-profile/bin/evince.

The last point shows the benefits of collecting all files within one
environment: the path ~/.nix-profile will not change even when
storepaths do. For the last reason I'd like to keep my user environment.
However having those ENV files in /nix/store/*/ENV could simplify a lot
of things including the ghc wrapper which is looking for packages using
$PATH..

I'm sure having env vars only will cause some trouble.
Nevertheless I'm curious about what you think about this approach.

Marc Weber



More information about the nix-dev mailing list