Over the course of reading the Nix manual, reading the Nixpkgs manual, reading the Nix Pills, and performing my own experiments, I have accumulated quite a few “open questions.”
I leave them at the bottom of each post, and they help ease my mind: writing them down allows me to forget them. They are not lurking in the darker corners of my brain, distracting me as I try to go about my day. They will be there for me when I need them, and that is a calming thought.
Now, I’m not done learning Nix. But I have read all of the official documentation, at this point, and it is time to enter into a new chapter of my Nix journey: I am leaving the warm embrace of the manuals, and setting off on my own. And what better place to start by going through my open questions?
All 160 of them.
That’s a lot! But I have written a lot of blog posts. That’s only 4 questions per post, on average, which actually feels a little low to me.
And besides, it’s not really 160 open questions. I expect that I know the answer to most of them, by now. And lots of them are subjective “why is Nix like this”-type questions that I don’t actually need to answer.
So… let’s see if I’m right? Be back soon.
Soon:
Okay, so I went through every single question, and:
- I know the answer to 66 of them.
- I think I know the answer to 11 more, but I want to follow up on something about them.
- 26 are bad questions: either they’re subjective or they don’t have answers or their answers are not actually satisfying in any way.
- Which leaves 57 questions that I don’t know the answer to.
Okay. That’s not… too bad…
But I certainly have my work cut out for me. Let’s start with the easy stuff:
Answers I feel pretty good about
- What is the difference between a “derivation” and a “store derivation”?
- “Store derivation” refers to a
.drv
file, “derivation” is a fuzzy word that could mean any of like three different things.
- “Store derivation” refers to a
- How does a derivation turn into a “result” or an “output path”? When does a derivation “produce” something?
- The primitive operation is
nix-store --realise
, but many other commands realize derivations:nix-build
,nix-env
,nix-shell
, etc.
- The primitive operation is
- How do I configure the location of the Nix binary cache (or other “substituters,” if I recall the terminology correctly)?
- The
substituters
key innix.conf
. See Part 9: Learning to share.
- The
- What/why is
nix-shell '<nixpkgs>' --attr pan
?<nixpkgs>
is a file path that evaluates to a function of no arguments that returns an attribute set;--attr
selects a specific attribute within that attribute set. That gives you a derivation, andnix-shell
plops you into a shell with the build-time dependencies of that derivation.
- What is
NIX_PATH
?- This is a variable kinda like
PATH
, colon-separated directories that are searched to resolve<foo>
expressions, but it can also contain named elements:nixpkgs=/path/to/the/thing
.
- This is a variable kinda like
- What does the weird comment mean about “appending channels” to
NIX_PATH
?- It really does append them, weirdly, even if they’re already present. See Part 35: How to give back.
- What is
~/.nix-defexpr
?- Explained in Part 5: Basic package management. Only relevant to
nix-env
andnix-channel
, as far as I can tell.
- Explained in Part 5: Basic package management. Only relevant to
- What is
~/.nix-profile
?- Symlink to the current user environment built by
nix-env
.
- Symlink to the current user environment built by
- What is
~/.nix-channels
?- Tiny text file listing channel names and URLs. Used by
nix-channel
commands.
- Tiny text file listing channel names and URLs. Used by
- Why does
nix-env -qa git
print the same line three times?-
Package names are dumb and broken. I’m really seeing:
$ nix-env -qa git --json | jq keys [ "nixpkgs.git", "nixpkgs.git-doc", "nixpkgs.gitFull" ]
-
- Why doesn’t
nix-env -qa
behave like a search?- It takes a regex.
- How do I search for packages by name using
nix-env
?- Use a regex.
- Why does
nix-shell
download so many packages? What are they for?- It downloads the packages in the standard environment, usually – it’s entirely dependent on the packages you invoke it with.
- Why does every invocation of
nix-env
take 30 seconds before it does anything?- Package names are dumb and broken.
- How do I collect garbage without making my next invocation of
nix-shell -p hello
redownload all the stuff it needs to be a shell?- I wrote a whole post about this: Part 37: Saving your shell.
- Why does the manual explicitly call out upgrading Nix? Will it not be upgraded through “normal” means? Do I have to upgrade it separately?
- No. It’s the same as any other package. Note that there is also
nix upgrade-nix
, which does not do what you think it does, or what you want it to do.
- No. It’s the same as any other package. Note that there is also
- Why is
~/.nix-defexpr
not just a symlink tonixpkgs
?- Because you might have multiple channels.
- Why does Nix call what seem to be associative arrays, or records, or something “sets”?
- The term “set” is just shorthand for “attribute set.”
- Does
nix-env -iA nixpkgs.hello
actually do anything ifhello
is already installed?- Not if it’s the same derivation; but it will replace it if not.
- Where is the Nix configuration file?
~/.config/nix/config.nix
- What are “outputs” (as in
keep-outputs
)? - What does
keep-derivations
do? I’m still not really clear on the term “derivations”. - What is a
manifest.nix
?- See Part 38: Nix pills.
- What does the function
mkDerivation
actually do? What does it “return”? What side effects does it have? - Why does Nix call maps “sets”?
- Duplicate; see above.
- Are paths a first-class type in Nix?
- Yes.
- What is a hook?
- Do I have to
source $stdenv/setup
? If so, why?- Nope! But it’s pretty handy, and saves a lot of work.
- When are the side effects of
fetchurl
actually executed?fetchurl
evaluates to a derivation, so whenever that derivation is “realized” (built).
- What exactly does
callPackage
call functions with?- The Nixpkgs “fixpoint” set, i.e., the thing that
import <nixpkgs> {}
returns.
- The Nixpkgs “fixpoint” set, i.e., the thing that
- Why does
import /Users/ian/src/nixpkgs
give me a function back?- So you can pass optional arguments like
system
orconfig
to customize Nixpkgs.
- So you can pass optional arguments like
- How do I make my own
ianpkgs
withoutimport
ing things from the “main”nixpkgs
? What would a minimaldefault.nix
look like?- The Nix Pills series does a pretty good job of walking through a derivation from actual scratch.
- How do I find my platform identifier without building Nix from scratch?
builtins.currentSystem
- If
builder
is a derivation that produces multiple files, what binary does it run?- The
builder
technically can be a derivation, but it’s coerced to a path, so thebuilder
would have to evaluate to a single file. If it evaluates to a directory, you have to specify the path to the executable you want.
- The
- Are paths actually a different type at runtime, or are they really strings?
- They really are different, and are more complicated than just strings, due to the file-filtering stuff.
- Why does
$stdenv/setup
require one of$dev
or$out
to exist?- Covered in Part 29: Derivations in detail.
- How can I explicitly register a runtime dependency?
- You can’t, at least in the way that I was thinking when I asked the question. This is only possible by putting a reference to the dependency in the output path.
- Does
toString
have the same behavior as Nix’s stringification of derivation attributes?-
Yes; it just looks at the
outPath
attribute:nix-repl> builtins.toString { outPath = "hi"; } "hi"
-
- What is a pure/impure shell?
- What is
manifest.nix
?- Duplicate; see above.
- What’s the difference between a package and a derivation?
- This is a fuzzy, difficult question to answer. A derivation is like the “recipe” to produce a package, or a “description” of the package. Or sometimes it’s used to refer to the package itself. The terminology is vague and confusing, as far as I can tell.
- How can I ask Nix to show me runtime dependencies of an output?
nix-store --query --references
ornix-store --query --requisites
, for the reqursive version. Note that Nix doesn’t really have a concept of a “runtime” reference, though, and this will include build-time dependencies in the case that you havepropagatedBuildInputs
.
- Are runtime dependencies known per-derivation, or per-output?
- Per-output.
- How can I inspect / pretty print a store derivation?
nix show-derivation
- What’s the difference between
nix-store --dump
andnix-store --export
?--dump
gives you the contents of the store path;--export
gives you the contents of the store path plus the relevant database entries.
- What does
nix-env -i /nix/store/store-path
do?- I mean, it does the thing you expect; it’s just undocumented.
- How do I (locally) “fork” a derivation?
- Overrides and overlays. See Part 25: Overriding for a description of the process, or Part 39: How to install Python for an example.
- How can I evaluate an option to see its current/default value?
nix show-config
- What the hell does
keep-outputs
do?- Duplicate; see above.
- What happens if two packages produce outputs with the same name? Like what if I install
/nix/store/foo-1.0/bin/foo
and/nix/store/bar-1.0/bin/foo
– what ends up in~/.nix-profile/bin/foo
?meta.priority
disambiguates; see Part 39: How to install Python.
- Why is
nix-env -u
trying to upgrade mypython3
to some weird alpha version?- I wrote a whole post about this. See Part 39: How to install Python.
- How do I print all output paths of a derivation?
nix show-derivation
, ornix-store --query --outputs
.
- What is
derivation.override
? A method?- Yeah, essentially, in the let-over-lambda sense. The Nix Pills series walks through the implementation.
- How do I use
derivation.override
?- Explained in Part 25: Overriding.
- Why is there
buildEnv
– a function – in the top-level of Nixpkgs, when I learned before thatnix-env
required all top-level things to be derivations?- It’s more complicated than that; ⌘F
recurseIntoAttrs
in Part 26: An infinite list of functions.
- It’s more complicated than that; ⌘F
- What is “the fixed-point used by Nixpkgs”? What does that mean? Why is that term never defined or explained?
- Nix Pills does explain the term; but yeah, basically this is referring to the giant attribute that the function that is Nixpkgs returns, after applying user overrides and overlays and such.
- Why does the repl print the
drvPath
instead of theoutputPath
?- It actually instantiates the derivation and puts it in your store.
- What’s the point of
.drv
files?- Provides useful query operations, and gives a pretty clean separation between instantiation and realization.
- How do I add a
shell.nix
file to mygcroots
?- Kind of a duplicate; I wrote a whole post about this: Part 37: Saving your shell.
- Why does the
fixupPhase
move doc directories around?-
Okay, so basically: this is because of the default behavior of
man
, when you don’t specify an explicitMANPATH
.Here is my
MANPATH
:$ manpath | tr ':' '\n' /usr/local/share/man /usr/share/man /Library/Apple/usr/share/man /Users/ian/.nix-profile/share/man /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/share/man /Library/Developer/CommandLineTools/usr/share/man
Where does that come from? Wellllll… it’s enormously complicated. The answer to that question will not fit in this blog post. But you can see that
/Users/ian/.nix-profile/share/man
is in there, but/Users/ian/.nix-profile/man
is not, so it makes sense to movefoo-1.0/man
tofoo-1.0/share/man
.1 That way when you install such a package, you will be able to runman foo
and everything will work okay.But why would the
foo
derivation createfoo-1.0/man
in the first place? Why wouldn’t it createfoo-1.0/share/man
directly?Well, it might. But it might not: Nixpkgs is a big place, and packages a lot of software, not all of which is going to put
man
pages in the same place. So it makes sense to impose some consistency on the universe of packages after the fact, in a way that does not require modifying anymake
rules or anything. See that footnote above1 for an explanation of whyshare/man
is preferable toman
.
-
- Why does
nix repl
keep printing errors about unfree packages when I just ask it to evaluate the top-levelpkgs
expression?- Because evaluating derivations at the repl actually instantiates the derivations and puts them in your store.
- Does Nix not explicitly distinguish between runtime and build-time dependencies?
- Nope! Nixpkgs does, but Nix itself has a very simple data model. See Part 37: Saving your shell.
- If I use an override or an overlay or whatever, does that only affect
nix-env
? Or does that affect any Nix command?- This is a Nixpkgs thing, so it will affect anything that imports
<nixpkgs>
.
- This is a Nixpkgs thing, so it will affect anything that imports
- How can I see the hash for a git repository, ala
nix-prefetch-url
?- Requires an external command like
nix-prefetch-github
; see Part 35: How to give back.
- Requires an external command like
- How does Nix calculate the set of references for an output?
- The algorithm is explained in the Nix Pills series; see Part 38: Nix Pills.
- Can I have a dependency that only shows up in
nix-shell
, without being a build-time dependency of my derivation?- No; this doesn’t make sense. All
nix-shell
does is re-create the environment of a derivation, which includes all build-time dependencies.
- No; this doesn’t make sense. All
Answers that I kinda basically get, but maybe should look into it further
-
What is the Nix database, and what is stored there?
- This probably deserves a post of its own, but basically it stores metadata about paths in the store, like what other paths they reference, and whether or not they’re valid. But it also stores info about derivation outputs, and I don’t really understand the purpose of that.
-
When I get a binary cached package, do I still download and keep all the build-time dependencies?
-
I assume the answer is “no,” because it’s not necessary. But I don’t know if
keep-outputs = true
changes this answer. I don’t expect it to, but let’s check empirically.$ nix show-derivation nixpkgs.hello | jq '.[] |= { outputs, inputSrcs, inputDrvs }'
{ "/nix/store/mic03kwmyphr3pd9l0rrq28cf60b215s-hello-2.10.drv": { "outputs": { "out": { "path": "/nix/store/qwn4c03x5s1ydajfbqwdv236qkajpa4j-hello-2.10" } }, "inputSrcs": [ "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh" ], "inputDrvs": { "/nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv": [ "out" ], "/nix/store/apghmhf48v3d381nagi9sa86fprvsl6c-bash-4.4-p23.drv": [ "out" ], "/nix/store/kfkii8d3rkwa1x7icr90bn8gbb6g8pzi-stdenv-darwin.drv": [ "out" ] } } }
So one “build time dependency” of
hello
is the output calledout
produced by the derivation/nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv
. In other words, the hello source code.I think I can instantiate that derivation all by itself, to see the output path? I’m assuming it’s the
src
attribute…$ nix-instantiate '<nixpkgs>' -A hello.src warning: you did not specify '--add-root'; the result might be removed by the garbage collector /nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv
Yep! And now I can find the output:
$ nix show-derivation /nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv | jq '.[] |= .outputs'
{ "/nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv": { "out": { "path": "/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz", "hashAlgo": "sha256", "hash": "31e066137a962676e89f69d1b65382de95a7ef7d914b8cb956f41ea72e0f516b" } } }
Er, I also could have just done:
$ nix-store --query --outputs /nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv /nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz
Anyway. So the question is: when I install
hello
, will I also download the path/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz
? What about the/nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv
?I don’t know the answer. I would be very surprised if it downloads
hello-2.10.tar.gz
, because that’s completely unnecessary. But I do expect it to puthello-2.10.tar.gz.drv
in the store, because that’s a reference of thehello-2.10.drv
file, and Nix doesn’t want a path in the store that is “incomplete” – that is missing some of its references.Let’s see if I’m right?
$ nix-collect-garbage finding garbage collector roots... removing stale temporary roots file '/nix/var/nix/temproots/94738' removing stale temporary roots file '/nix/var/nix/temproots/94712' deleting garbage... deleting '/nix/store/mic03kwmyphr3pd9l0rrq28cf60b215s-hello-2.10.drv' deleting '/nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv' deleting '/nix/store/trash' deleting unused links... note: currently hard linking saves 0.00 MiB 2 store paths deleted, 0.00 MiB freed
Alright. Moment of truth:
$ nix-env -iA nixpkgs.hello installing 'hello-2.10' these paths will be fetched (0.02 MiB download, 0.07 MiB unpacked): /nix/store/qwn4c03x5s1ydajfbqwdv236qkajpa4j-hello-2.10 copying path '/nix/store/qwn4c03x5s1ydajfbqwdv236qkajpa4j-hello-2.10' from 'https://cache.nixos.org'... building '/nix/store/76wq9wqpszy173w5f4dn6fnv76lbsdwc-user-environment.drv'... created 1040 symlinks in user environment
Okay. So we only fetched one path… but that’s expected. Because we’re able to produce the
.drv
files locally, from the definitions in Nixpkgs. And indeed, we did create the.drv
:$ ls /nix/store/mic03kwmyphr3pd9l0rrq28cf60b215s-hello-2.10.drv /nix/store/mic03kwmyphr3pd9l0rrq28cf60b215s-hello-2.10.drv
As well as its references:
$ ls /nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv /nix/store/94ckk990hrnzjbk2062acmwxajpg64gf-hello-2.10.tar.gz.drv
But we did not create the output:
$ ls /nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz ls: cannot access '/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz': No such file or directory
Okay. So it works the way I expected.
-
-
Do “substitutes” live in the Nix database or not?
-
Just, like, empirically… no? This is an unusually false claim for the manual to make, though, and I couldn’t tell you where substituters do live, so I should look into a little bit. Like, it’s probably cached locally, right?
I look it up, and find that substitutes are cached in
~/.cache/nix
:$ sqlite3 ~/.cache/nix/binary-cache-v6.sqlite .schema
CREATE TABLE BinaryCaches ( id integer primary key autoincrement not null, url text unique not null, timestamp integer not null, storeDir text not null, wantMassQuery integer not null, priority integer not null ); CREATE TABLE sqlite_sequence(name,seq); CREATE TABLE NARs ( cache integer not null, hashPart text not null, namePart text, url text, compression text, fileHash text, fileSize integer, narHash text, narSize integer, refs text, deriver text, sigs text, ca text, timestamp integer not null, present integer not null, primary key (cache, hashPart), foreign key (cache) references BinaryCaches(id) on delete cascade ); CREATE TABLE LastPurge ( dummy text primary key, value integer );
They’re still called
BinaryCaches
, but those are our substitutes.
-
-
What is the “type” of a derivation?
- It’s an attribute set containing the attribute
{ type = "derivation"; }
, but it’s also… more than that?
- It’s an attribute set containing the attribute
-
How does
nix-env --set-flag
work?- I assume this just alters the
manifest.nix
, andnix-env
commands know to parsemanifest.nix
before building the environment.
- I assume this just alters the
-
How can I make
nix-shell
usezsh
?- I think just ignoring
--rcfile
will get me there… it is weirdly convoluted and annoying, though. This deserves its own post.
- I think just ignoring
-
Is there a better way to see outdated packages?
- I explain my answer in “Part 22: Declarative environment”, but I don’t know if there is a general answer.
-
Are derivations sets or not? Why do they print differently? What makes them different or special or magical?
- Sort of a duplicate;
{ type = "derivation"; }
is all it takes to make them print differently innix repl
.
- Sort of a duplicate;
-
Can I install my macOS GUI apps with Nix?
-
I think I could, but I can’t think of any reason why I would want to. Basically all macOS GUI apps use something like Sparkle to update themselves, so it’s not like they’d stay in sync anyway. I should check on Emacs, though.
Let’s see… we’ve got
nixpkgs.emacs
andnixpkgs.emacsMacport
.sd nix info emacsMacport
tells me:This is the “Mac port” addition to GNU Emacs 26. This provides a native GUI support for Mac OS X 10.6 - 10.12. Note that Emacs 23 and later already contain the official GUI support via the NS (Cocoa) port for Mac OS X 10.4 and later. So if it is good enough for you, then you don’t need to try this.
Hmm. Is
emacs
good enough for me? Let’s try it and see…Oooh wow. Performance is noticeably terrible. Like, just redraws are visibly slow. Let’s try the
emacsMacport
…Huh! Running
emacs
now opens a terminal instance of Emacs. That’s kinda funny. Not really what I was going for, but sure. So uhhh…$ open ~/.nix-profile/Applications/Emacs.app No application knows how to open file:///Users/ian/.nix-profile/Applications/Emacs.app/ (Error Domain=NSOSStatusErrorDomain Code=-10814 "kLSApplicationNotFoundErr: E.g. no application claims the file" UserInfo={_LSLine=1479, _LSFunction=runEvaluator}).
Hmm. I open it via Finder, and now it launches normally when I use
open
too. Weird. Something about that… made it realize it was an app? I have no idea. Anyway, it seems to work great. Performance feels only the normal amount of sluggish. I will probably gripe in the future if this turns out not to work right for some reason.
-
-
Does Nix install all build-time dependencies of a package?
- Duplicate; see above.
-
Is Hydra responsible for populating https://cache.nixos.org?
-
I thought I knew the answer when I asked this – I thought it was obviously “yes” – but I have no idea how to check this.
This is surprisingly hard to answer. I google furiously. I search through the NixOS organization on GitHub. I come up with no answers.
I can find comments on the NixOS Discourse that confirm this; that make this claim. But nothing authoritative. Not that I don’t believe those comments, just… why isn’t this vital feature described in the Hydra README or manual or something?
Hmm. Let’s look through the Hydra source.
I find
S3Backup.pm
, which seems to be uploading build results to a configurable S3 bucket. But that file has barely changed over the last eight years. I think this is some random other thing.Hmm.
Searching through IRC logs returns tons of references to Hydra populating the binary cache.
So the code must be there. I just can’t find it using GitHub search. Time to clone, and get real search…
Okay, I think it’s this bit. I sort of don’t bother to read the whole thing. I have lost the will to care about this any more.
It’s strange to me that this is just known… and even I assumed this was the case. But I can’t find it actually written down anywhere.
It’s probably stated somewhere really obvious, and I’m just overlooking it? I don’t know.
-
Bad questions
-
What are the
nix
equivalents ofnix-env
,nix-build
, andnix-instantiate
?-
My overall impression is that the
nix
binary, at least right now, has a couple of really useful commands (nix search
,nix repl
) and a couple of pretty-useful commands (nix show-config
,nix show-derivation
) and then dozens of random little utility things that you’ll never need that should be hidden behind some subcommand but aren’t.There are actually 31 subcommands of the
nix
binary. There is no hierarchy to these commands; nothing that makes them browseable. Some examples:to-base16 convert a hash to base-16 representation to-base32 convert a hash to base-32 representation to-base64 convert a hash to base-64 representation to-sri convert a hash to SRI representation
These commands exist at the same level as, say,
nix repl
, despite one of those things being vastly more commonplace.I quickly gave up on trying to use
nix
, or looking fornix
-equivalents of commands. I stopped wanting that: I stopped caring about thenix
command, a few chapters into the manual. It proved that it was not the usability overhaul I was hoping for, and I embraced the “old-style”nix-foo
commands.So while there is a
nix build
command, I haven’t used it: I tried it once, but it didn’t work as well asnix-build
, so now I am soured to it forever. I know there’s no equivalent ofnix-env
, and I would be very surprised if there’s anix-instantiate
equivalent.
-
-
What is the
nix
equivalent ofnix-store -qR
to print out the closure of a store path?- I don’t know, but again, I don’t really care: I expect there isn’t one. Maybe
nix path-info
can do this, but if so it isn’t documented.
- I don’t know, but again, I don’t really care: I expect there isn’t one. Maybe
-
What are the
nix
equivalents ofnix-store --dump
andnix-store --restore
, for working with NARs?- I don’t know, and I don’t really care.
-
Why is there no
man nix
?- Because there isn’t?
-
Why did
nix-env -i hello
tell me it “created 40 symlinks in user environment”?- I get what this means now, but I think the message is useless and confusing. This is basically a debug-level log message.
-
How do I install commands using
nix
instead ofnix-env
?- I don’t.
-
Why does
nix run
need thenixpkgs
qualifier whennix-shell
doesn’t?- It’s pretty much a complete mystery to me what commands will accept what arguments.
nix-env
takes package names, except when it doesn’t;nix-shell -p
evaluates arbitrary Nix expressions with thenixpkgs
entry on yourNIX_PATH
in scope, butnix-shell
takes a path – a Nix path, not a file path – and on and on. So I don’t know. Because every command is a special snowflake.
- It’s pretty much a complete mystery to me what commands will accept what arguments.
-
Why is there an
--upgrade
command if--install
will upgrade packages?- This is dumb and
--upgrade
is dumb and you should never use it.
- This is dumb and
-
How do I pretty print Nix files?
- As far as I can tell, there is no built-in way to do this. I managed to do this with a third-party tool called
nixpkgs.nixfmt
, but it wants to reformat files in-place, which is not very useful.
- As far as I can tell, there is no built-in way to do this. I managed to do this with a third-party tool called
-
Why do hashes appear at the beginning of store paths instead of the end?
- I dunno, because whatever? This seems natural to me, despite it making tab-completion harder.
-
What are the sizes of integral and floating point numbers?
- According to
builtins.valueSize
, they are both 64-bits, but I don’t know if that’s just because it’s the native size. I don’t actually care at all, though: if this ever matters to me, something has gone horribly wrong.
- According to
-
Why does
mkDerivation
pass throughargs
literally?- I would call this a bug, but in practice you don’t ever pass positional arguments to your builder, you just pass environment variables, so it doesn’t really matter.
-
What is the use case for
nix-env --set
?- Don’t know; don’t care.
-
Why can’t I say
nix-env -eA nixpkgs.hello
? Why do I need to use the “symbolic name”?- Ehhh yeah I mean because package names are dumb and the user environment doesn’t remember the path you used to install packages.
-
How do I pretty print Nix expressions?
- Duplicate; see above.
-
Why don’t I have
man
pages forcoreutils
?-
Requires
coreutils-full
; this is probably a disk space thing? I found it extremely confusing, but whatever.A comment in the derivation seems to support this:
$ grep man1 -B1 -A5 ~/src/nixpkgs/pkgs/tools/misc/coreutils/default.nix
postInstall = optionalString (stdenv.hostPlatform != stdenv.buildPlatform && !minimal) '' rm $out/share/man/man1/* cp ${buildPackages.coreutils-full}/share/man/man1/* $out/share/man/man1 '' # du: 8.7 M locale + 0.4 M man pages + optionalString minimal '' rm -r "$out/share" '';
(
minimal = false
incoreutils-full
.)
-
-
Why do I have to explicitly install
info
pages forcoreutils
?- Because no one wants
info
pages. I only asked this because I couldn’t find theman
pages, but then I did, so this question doesn’t really matter.
- Because no one wants
-
Why doesn’t
overrideAttrs
just transform a set into a new set?- Slight convenience with relatively low cost?
-
Why doesn’t
nix-collect-garbage --dry-run
do the thing I expect?- I dunno, because it would be more work?
-
What derivation attributes are special enough that
nix repl
prints them out?- Looking back on this question, I just misread the output of a
repl
session (⌘FrecurseForDerivations
). It seems to only print outdrvPath
.
- Looking back on this question, I just misread the output of a
-
Why is
prefer-remote-fetch
kebab-cased?- There are lots of functions like this in Nixpkgs. I don’t know, but I’m guessing because the files are kebab-cased, and fixing these would cause a lot of breakage.
-
Is it safe to get rid of
locateDominatingFile
(and other unusedlib
functions)?- Ehh, maybe; I don’t really care.
-
Why is
lib.misc
not calledlib.deprecated
?- I can safely assume backwards compatibility with a historical accident.
-
Why is
lib.trivial
not calledlib.misc
?- I can safely assume backwards compatibility with a historical accident.
-
Do we need
fetchFromSavannah
here?- I think the answer is no, but, like, also, who cares.
-
Why does the repl instantiate
.drv
files and put them into the actual store?- Like many “why” questions, I doubt I’ll get a real answer here, and don’t really care enough to try to track it down.
Questions without answers, even in this day and age
- What does it mean to compose a package?
- What is
NIX_PROFILES
? - What are all those
/nix/store/...user-environment/share/nix/*.nix
files? - Why does the default install give me
https://nixos.org/channels/nixpkgs-unstable
which 302s tohttps://channels.nixos.org/nixpkgs-unstable
? - Why is the store object in
~/.nix-defexpr
also called auser-environment
? - Can I put a space in a Nix package name?
- How do “special” paths like
stdenv-darwin
wind up in the store / stay in the store? Are those part of thenix
package? - Why is there a Commander Keen game in nixpkgs? How is that allowed?
- I’ll leave this one as an exercise for the reader. It’s easy to look into; I looked into it; I have no further questions. Everything checks out.
- What is
$hostOffset
in a setup hook? - How do I actually find the logs I want in
/nix/var/log/nix
? - How do extended file system attributes work in Nix?
- Why doesn’t
fetchGit
return a fixed-output derivation? - What is
builtins.placeholder
? - What is “context”?
- What do the
unsafe
functions do? - What is
scopedImport
? - Is there any difference between
nix-build
andnix build
? - What’s up with that weird array situation?
- What’s the “user environment build script”
- Why does
nix eval
need its argument to be in parentheses? - Why doesn’t
nix-store --read-log
work? - What does
allow-import-from-derivation
do? - How can I set up my own “hashed mirror?”
- How should I install my login shell with Nix?
- How do I
--keep-failed
withnix build
?- I think maybe
nix log
has something to say here?
- I think maybe
- What’s the difference between
nix build
andnix-build
?- Duplicate.
- What is the not terribly gross way to run
nix-shell -p
with a package from a custom channel (i.e. without renaming it to"nixpkgs"
)? - Can I run Nix tests after
nix-build
without doing a full rebuild fromnix-shell
? - In the case that I have multiple substituters configured, how can I see which substituters have certain packages?
- How do I see what (package × architecture) pairs are supposed to be cached in the official cache?
- How do I quickly “go to definition” of a package?
- What on earth is
builtins.placeholder
for?- Duplicate.
- How can I use
overrideAttrs
to remove an attribute? - How do I print the contents of a derivation without setting the
type
to something else? - What’s up with
lib.strings.addContextFrom
? - What’s with
fix'
and the__unfix__
attribute? Should I care about this? - What is
hydra-eval-jobs
? - Where is
lib.warn
defined? - What… on earth… is all of this platform arithmetic? What do these numbers mean? Why– what is happening here?
- Why does the
substituteAll
builder need to callpreInstall
/postInstall
? - Is it true that “Environment variables are then substituted in it using
substituteAll
”? Is Python doing that explicitly unnecessarily, or are the docs wrong? - Why is there a
stdenv.targetPlatform
? What does that mean? - How can I get
ldd
on my macOS box? - Why did Nix try to install Xcode to build
hello
for macOS? - Why is
install_name
an intrinsic property of a.dylib
file? - What does it mean to “have a builder for the
system
” ofrunCommandLocal
? - Does
allowSubstitues = false
disable substitutes for all dependencies of a derivation as well? - What is
runtimeShell
, and when should I prefer it over$SHELL
? - How can I
nix search
throughnixpkgs.nodePackages
?- Oddly, I can search through
nixpkgs.ocamlPackages
…
- Oddly, I can search through
- How am I supposed to use e.g.
bower2nix
while iterating on a package fromnix-shell
? - What the heck is up with the Node.js stuff?
- How do
hashed-mirrors
work? - Why does Nix… disable TLS when fetching sources? What?
- How do I enable the sandbox for a single build?
- Is there anything Nix-specific about NAR files?
So… now what? Do I go through and try to answer every single one of these?
No. Of course not. This post has taken way too long already. None of these questions are really pressing, and I can find the answers in my own time, as I do more real Nix things. I already closed like 65% of my open questions in this post; I can leave the rest for later.
-
You might be wondering: why is that in there?
Basically, without an explicit
MANPATH
,man
is going to look through elements in yourPATH
, and try to find a “nearby”man/
directory for each entry. If it finds one, it adds it to theMANPATH
.A concrete example: if you have
/foo/bar/baz/bin
on yourPATH
, it’s going to look for../share/man
– i.e.,/foo/bar/baz/share/man
. If it finds it, it adds it to the manual search path. And then it stops.If it doesn’t find
../share/man
, it will then look for../man
. So if you only had a~/.nix-profile/man
directory and no~/.nix-profile/share/man
directory, thenman
would work as expected. But if you then grew a~/.nix-profile/share/man
directory,man
would no longer be able to find the~/.nix-profile/man
directory, because everyPATH
entry only gets a single correspondingMANPATH
entry.This behavior is not documented anywhere, at least in the
man
that macOS ships. The most it has to say about it is:[…] for each directory in the command search path (we’ll call it a “command directory”) for which you do not have a
MANPATH_MAP
statement,man
automatically looks for a manual page directory “nearby” namely as a subdirectory in the command directory itself or in the parent directory of the command directory.You can disable the automatic “nearby” searches by including a
NOAUTOPATH
statement in/private/etc/man.conf
.That says nothing about the
../share/man
behavior, which is the salient thing here. But you can check the implementation of thefind_man_subdir
function inmanpath.c
, if you want a better answer.That is hilarious, isn’t it? I find running
man man
very funny, and the fact that it doesn’t actually document the one bit of behavior I’m curious about even funnier. Computers are great.Out of curiosity: does GNU
man
fare better?I run
nix-shell -p man-db
to check. Experimenting withmanpath
reveals that it will add both../share/man
and../man
if they exist, unlike macOS’sman
. But neitherman man
norman manpath
has any information about why this is or where those values come from, and even theman.conf
file shipped doesn’t include a note about it (my/etc/man.conf
at least hints at this behavior, by telling you how to disable it).In fact the only reference to this behavior that I can find is a comment in the source: see
get_manpath_from_path
inmanp.c
.Anyway this is the longest footnote I have ever written how are you doing. ↩︎