self-references
when a package's store path appears inside its own output.
when a package's store path appears inside its own output.
the reference scanner finds store path hashes in output files. it has no special case for the output path itself. packages that embed their own store path in their output are common. nix records this as a self-reference.
it looks like a chicken-and-egg problem. to embed a path in the output, you need to know the path. but the path is derived from the output...
except it isn't. store paths are derived from derivation inputs, before the build runs. nix computes $out at derivation evaluation time and passes it to the builder as an environment variable. the builder knows exactly where its output will live before writing a single byte.
nixpkgs generates wrappers around a lot of executables. the wrapper is a shell script that injects flags, sets environment variables, or points the program at its own data files. it lives at $out/bin/foo and its job is to call the real binary at $out/bin/.foo-wrapped, which means it needs to know its own store path to get there.
the same thing happens with compiled binaries that ship shared libraries alongside them. the binary's RPATH ends up pointing at $out/lib:
$ patchelf --print-rpath /nix/store/abc123...-mypkg-1.0/bin/mypkg
/nix/store/abc123...-mypkg-1.0/lib
or Python wrappers that add their own site-packages to PYTHONPATH. whatever the mechanism, $out gets written into a file, and the scanner picks it up.
a self-reference does not prevent garbage collection. gc walks from roots. if nothing reachable from a root points at this package, it gets collected. a path that only references itself is just as unreachable as one with no references at all.
cycles work the same way. if A references B and B references A, both get collected once nothing outside points to either of them.
$ nix-store -q --references /nix/store/xhp149abalfmj232yjhgbqaw281ba8np-curl-8.18.0 \
| grep xhp149ab
/nix/store/xhp149abalfmj232yjhgbqaw281ba8np-curl-8.18.0
self-references show up like any other reference in --references and nix path-info --json. they are not special-cased or filtered out.