Home Explore Blog CI



nixpkgs

22th chunk of `doc/stdenv/stdenv.chapter.md`
7beb22810ab59f638a18339526368087ba74485b673e176d000000010000119f
and the environment contains `bash=/nix/store/bmwp0q28cf21...-bash-3.2-p39` and `coreutils=/nix/store/68afga4khv0w...-coreutils-6.12`, but does not contain the variable `foo`, then the output will be

```bash
#! /nix/store/bmwp0q28cf21...-bash-3.2-p39/bin/sh
PATH=/nix/store/68afga4khv0w...-coreutils-6.12/bin
echo @foo@
```

That is, no substitution is performed for undefined variables.

Environment variables that start with an uppercase letter or an underscore are filtered out, to prevent global variables (like `HOME`) or private variables (like `__ETC_PROFILE_DONE`) from accidentally getting substituted. The variables also have to be valid bash "names", as defined in the bash manpage (alphanumeric or `_`, must not start with a number).

### `substituteAllInPlace` \<file\> {#fun-substituteAllInPlace}

Like `substituteAll`, but performs the substitutions in place on the file \<file\>.

### `stripHash` \<path\> {#fun-stripHash}

Strips the directory and hash part of a store path, outputting the name part to `stdout`. For example:

```bash
# prints coreutils-8.24
stripHash "/nix/store/9s9r019176g7cvn2nvcw41gsp862y6b4-coreutils-8.24"
```

If you wish to store the result in another variable, then the following idiom may be useful:

```bash
name="/nix/store/9s9r019176g7cvn2nvcw41gsp862y6b4-coreutils-8.24"
someVar=$(stripHash $name)
```

### `wrapProgram` \<executable\> \<makeWrapperArgs\> {#fun-wrapProgram}

Convenience function for `makeWrapper` that replaces `<executable>` with a wrapper that executes the original program. It takes all the same arguments as `makeWrapper`, except for `--inherit-argv0` (used by the `makeBinaryWrapper` implementation) and `--argv0` (used by both `makeWrapper` and `makeBinaryWrapper` wrapper implementations).

If you will apply it multiple times, it will overwrite the wrapper file and you will end up with double wrapping, which should be avoided.

### `prependToVar` \<variableName\> \<elements...\> {#fun-prependToVar}

Prepend elements to a variable.

Example:

```shellSession
$ configureFlags="--disable-static"
$ prependToVar configureFlags --disable-dependency-tracking --enable-foo
$ echo $configureFlags
--disable-dependency-tracking --enable-foo --disable-static
```

### `appendToVar` \<variableName\> \<elements...\> {#fun-appendToVar}

Append elements to a variable.

Example:

```shellSession
$ configureFlags="--disable-static"
$ appendToVar configureFlags --disable-dependency-tracking --enable-foo
$ echo $configureFlags
--disable-static --disable-dependency-tracking --enable-foo
```

## Package setup hooks {#ssec-setup-hooks}

Nix itself considers a build-time dependency as merely something that should previously be built and accessible at build time—packages themselves are on their own to perform any additional setup. In most cases, that is fine, and the downstream derivation can deal with its own dependencies. But for a few common tasks, that would result in almost every package doing the same sort of setup work—depending not on the package itself, but entirely on which dependencies were used.

In order to alleviate this burden, the setup hook mechanism was written, where any package can include a shell script that \[by convention rather than enforcement by Nix\], any downstream reverse-dependency will source as part of its build process. That allows the downstream dependency to merely specify its dependencies, and lets those dependencies effectively initialize themselves. No boilerplate mirroring the list of dependencies is needed.

The setup hook mechanism is a bit of a sledgehammer though: a powerful feature with a broad and indiscriminate area of effect. The combination of its power and implicit use may be expedient, but isn’t without costs. Nix itself is unchanged, but the spirit of added dependencies being effect-free is violated even if the latter isn’t. For example, if a derivation path is mentioned more than once, Nix itself doesn’t care and makes sure the dependency derivation is already built just the same—depending is just needing something to exist, and needing is idempotent. However, a dependency specified twice will have its setup hook run twice, and that could easily change the build environment (though a well-written setup hook will therefore strive to be idempotent so this is in fact not observable). More broadly, setup hooks are anti-modular in that multiple dependencies, whether the same or different, should not interfere and yet their setup hooks may well do so.

Title: Nix Functions: Path Manipulation, Program Wrapping, and Variable Modification
Summary
This section outlines Nix functions focused on path manipulation, program wrapping, and variable modification. It covers `stripHash` for extracting the name part of a store path, `wrapProgram` for creating wrappers around executables, `prependToVar` and `appendToVar` for modifying variable values. Additionally, it describes the concept of package setup hooks, which are shell scripts included by packages to perform additional setup and initialization for downstream reverse-dependencies during the build process.