In my NixOS machine, I can use nix-env to query about the ghc package in two ways:
One is nix-env -f '<nixpkgs>' -qaP ghc which results in the output
ghc ghc-8.6.5
Another is nix-env -qaP ghc which results in the output
nixpkgs.ghc ghc-8.6.5
For the second case, I would like to understand why the active Nix expression has a nixpkgs root attribute.
The contents of the ~/.nix-defexpr folder and several subfolders are the following:
How is the active Nix expression assembled from the contents of ~/.nix-defexpr? Why there isn't a channels root attribute? Does the name of the nixpkgs root attribute derive from the name of the nixpkgs folder, or is it derived from the contents of the folder, perhaps from something declared in the default.nix file?
The Nix manual has some info on how .nix-defexpr is assembled:
The Nix expressions in this directory are combined into a single set,
with each file as an attribute that has the name of the file.
It doesn't mention what happens if the contents are themselves directories, though. But I found this GitHub issue that explains things a little more:
If a directory is a valid expression (i.e. has default.nix) its expression will be added to the set, otherwise it will be traversed
recursively.
Names of intermediate directories are completely ignored (i.e. do not take any part in attrpaths).
manifest.nix is recursively ignored.
So, there isn't a channels root attribute because the folder doesn't have a default.nix expression.
Ok. Then, as an experiment, I created a folder .nix-defexpr/foo with a file default.nix with contents { zzz = 4; } inside. When I execute nix-env --install -A foo.zzz I get:
error: expression does not evaluate to a derivation (or a set or list of those)
Which means that it actually found the path! The problem is that 4 is not a derivation.
But what if I create another folder .nix-defexpr/whatever and put a copy of the folder foo there? Won't there be some kind of name collision? Yes, there is:
8f792ff4f96a:~# nix-env --install -A foo.zzz
warning: name collision in input Nix expressions, skipping '/root/.nix-defexpr/whatever/foo'
Related
For some background, my specific use case is actually in Rules Python's compile_pip_requirements rule. I do not want to use the default caching location for pip packages, so I am passing args to pip through compile_pip_requirements via:
compile_pip_requirements(
...
extra_args = [
"--allow-unsafe",
"--cache-dir",
"/tmp/pip-compile",
],
...)
I can easily hardcode the tmp dir there, but I would like to specifically use the same directory that Bazel uses to cache everything else, without making any magic assumptions about where that cache dir is.
I have tried to use $(bazel info | grep output_base | awk '{print $2}') but Bazel appears to only accept its own Make Variables within a variable expression, not to mention that this does not feel like a safe option anyway.
I have also tangled a bit with those make variables (most promisingly, $(location //foo)), but it seems this only returns the location of a given module relative to WORKSPACE.
Thanks!
A NixOS user, I am studying the Nix Pills. They frequently reference ~/.nix-profile/etc/profile.d/nix.sh as a means of "entering the Nix environment". E.g. quoting from chapter 5:
I remind you how to enter the Nix environment: source
~/.nix-profile/etc/profile.d/nix.sh
However, my NixOS machine does not even have a ~/.nix-profile/etc directory, let alone a ~/.nix-profile/etc/profile.d/nix.sh file. My questions:
Why might my machine not have ~/.nix-profile/etc?
Is there an ordinary way to generate ~/.nix-profile/etc/profile.d/nix.sh?
Is there straightforward alternative way to "enter the Nix environment" in NixOS?
I do not yet have answers to (1) and (2), but do have an answer to (3). That is:
$ nix repl
works to enter the nix environment.
According to the official documentation, profile could be automatically generated when you've switched to it by command:
$ nix-env --switch-profile /nix/var/nix/profiles/default
So, you should try this command and it should create missed files and directories.
Here is the text copied from official doc:
You generally wouldn’t have /nix/var/nix/profiles/some-profile/bin in your PATH. Rather, there is a symlink ~/.nix-profile that points to your current profile. This means that you should put ~/.nix-profile/bin in your PATH (and indeed, that’s what the initialisation script /nix/etc/profile.d/nix.sh does). This makes it easier to switch to a different profile. You can do that using the command nix-env --switch-profile:
$ nix-env --switch-profile /nix/var/nix/profiles/my-profile
$ nix-env --switch-profile /nix/var/nix/profiles/default
These commands switch to the my-profile and default profile, respectively. If the profile doesn’t exist, it will be created automatically. You should be careful about storing a profile in another location than the profiles directory, since otherwise it might not be used as a root of the garbage collector.
I notice that descriptions of various nixos commands refer to something called the "active Nix expression". For example, the man page for nix-env includes:
--file / -f path
Specifies the Nix expression (designated below as the active Nix expression) used by the --install, --upgrade, and --query
--available operations to obtain derivations. The default is ~/.nix-defexpr.
What is this "active Nix expression"? Where is it defined? Is it simply what is written in /etc/nixos/configuration.nix ordinarily or instead what was defined by nix-shell otherwise?
This is the file from which the Nix expression in which any attribute specified with -A is evaluated. (Absent -A, that content is expected to directly be a derivation).
Let's say you have a mydir/default.nix file that evaluates to an attrset with keys foo, bar, and baz, each of which maps to a derivation as a value.
In this case, running nix-env -f mydir -iA foo will load mydir/default.nix, evaluate foo in the context of that loaded code, run any associated build steps, and add that software to your active environment.
nix-build ... --no-out-link gives a path in the Nix store.
Is it possible to find out that path without actually building the expression ?
Is it possible to find out the dependencies and the planned build operations without building the expression ?
How could I find the answer myself ?
The Nix manual, "Building and testing" section refers to nix-build documentation, which in the last "Description" paragraph mentions it is a combination of nix-instantiate and nix-store -r.
nix-instantiate does not build. It only calculates the plan, in the form of a derivation and its closure:
$ nix-instantiate '<nixpkgs>' -A hello
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
/nix/store/20bc2g6gfn44p9wk98s30pm346pmz0x9-hello-2.10.drv
However, I prefer to use nix repl to explore Nix expressions:
$ nix repl '<nixpkgs>'
Loading '<nixpkgs>'...
Added 8623 variables.
nix-repl> hello.outPath
"/nix/store/nic2bl8ry6vfyxr9717983d5b2l4sn1c-hello-2.10"
Its tab completion is very helpful when exploring expressions.
man nix-store has the answer, and in particular the --query section.
To know the output path:
nix-store -q --outputs $(nix-instanciate default.nix)
To know the build-time dependencies:
nix-store -qR --include-outputs $(nix-instanciate default.nix)
As for a build plan, the closer I get is to use the --tree flag.
Note that nix-shell exposes a $out variable too, so another possible solution to the first bullet point would be:
nix-shell --pure --run 'echo $out' some-file.nix
I have a nix expression file (.nix) and a shell script builder, specified like:
stdenv.mkDerivation rec {
name = "my-env";
builder = './my-builder.sh';
...
./my-builder.sh: No such file or directory when I run nix-build ./my-env.nix; the nix expression file and builder scripts are sitting side-by-side in my home directory.
My intent is to use this nix expression file to prepare an environment using nix-build and then to actually quickly run the environment whenever I want to use it (using nix-shell).
EDIT: I just noticed that nix-shell ./ my-env.nix works fine; so far I'm not actually building anything, so I should probably just omit the builder.
EDIT#2:
My concrete example is the following:
This line puts both the nix expression and the builder in the same directory. This other line uses nix-shell to prepare the environment, but I assume a similar nix-build command could be used (especially if one wanted to install a custom package as part of the environment, but maybe that is not very idiomatic in Nix)
Solution
Quotes around the builder's path were apparently a no-no. I ended up having other issues, and pieced this together to eventually get the thing to run:
builder = builtins.toFile "builder.sh" ''
source $stdenv/setup
mkdir -p $out
echo "" > $out/Done
echo "Done setting up Scala environment."
'';
Try putting a semicolon at the end of the line and removing the single quotes:
builder = ./my-builder.sh;
Then double-check to make sure my-builder.sh is in the same directory as the .nix file where you wrote that.