cp foo $out/bin
runHook postInstall
'';
}
```
(Note the use of `''`-style string literals, which are very convenient for large multi-line script fragments because they don’t need escaping of `"` and `\`, and because indentation is intelligently removed.)
There are many other attributes to customise the build. These are listed in [](#ssec-stdenv-attributes).
While the standard environment provides a generic builder, you can still supply your own build script:
```nix
stdenv.mkDerivation {
pname = "libfoo";
version = "1.2.3";
# ...
builder = ./builder.sh;
}
```
where `stdenv` sets up the environment automatically (e.g. by resetting `PATH` and populating it from build inputs). If you want, you can use `stdenv`’s generic builder:
```bash
buildPhase() {
echo "... this is my custom build phase ..."
gcc foo.c -o foo
}
installPhase() {
mkdir -p $out/bin
cp foo $out/bin
}
genericBuild
```
### Building a `stdenv` package in `nix-shell` {#sec-building-stdenv-package-in-nix-shell}
To build a `stdenv` package in a [`nix-shell`](https://nixos.org/manual/nix/unstable/command-ref/nix-shell.html), enter a shell, find the [phases](#sec-stdenv-phases) you wish to build, then invoke `genericBuild` manually:
Go to an empty directory, invoke `nix-shell` with the desired package, and from inside the shell, set the output variables to a writable directory:
```bash
cd "$(mktemp -d)"
nix-shell '<nixpkgs>' -A some_package
export out=$(pwd)/out
```
Next, invoke the desired parts of the build.
First, run the phases that generate a working copy of the sources, which will change directory to the sources for you:
```bash
phases="${prePhases[*]:-} unpackPhase patchPhase" genericBuild
```
Then, run more phases up until the failure is reached.
If the failure is in the build or check phase, the following phases would be required:
```bash
phases="${preConfigurePhases[*]:-} configurePhase ${preBuildPhases[*]:-} buildPhase checkPhase" genericBuild
```
Use this command to run all install phases:
```bash
phases="${preInstallPhases[*]:-} installPhase ${preFixupPhases[*]:-} fixupPhase installCheckPhase" genericBuild
```
Single phase can be re-run as many times as necessary to examine the failure like so:
```bash
phases="buildPhase" genericBuild
```
To modify a [phase](#sec-stdenv-phases), first print it with
```bash
echo "$buildPhase"
```
Or, if that is empty, for instance, if it is using a function:
```bash
type buildPhase
```
then change it in a text editor, and paste it back to the terminal.
::: {.note}
This method may have some inconsistencies in environment variables and behaviour compared to a normal build within the [Nix build sandbox](https://nixos.org/manual/nix/unstable/language/derivations#builder-execution).
The following is a non-exhaustive list of such differences:
- `TMP`, `TMPDIR`, and similar variables likely point to non-empty directories that the build might conflict with files in.
- Output store paths are not writable, so the variables for outputs need to be overridden to writable paths.
- Other environment variables may be inconsistent with a `nix-build` either due to `nix-shell`'s initialization script or due to the use of `nix-shell` without the `--pure` option.
If the build fails differently inside the shell than in the sandbox, consider using [`breakpointHook`](#breakpointhook) and invoking `nix-build` instead.
The [`--keep-failed`](https://nixos.org/manual/nix/unstable/command-ref/conf-file#opt--keep-failed) option for `nix-build` may also be useful to examine the build directory of a failed build.
:::
## Tools provided by `stdenv` {#sec-tools-of-stdenv}
The standard environment provides the following packages:
- The GNU C Compiler, configured with C and C++ support.
- GNU coreutils (contains a few dozen standard Unix commands).
- GNU findutils (contains `find`).
- GNU diffutils (contains `diff`, `cmp`).
- GNU `sed`.
- GNU `grep`.
- GNU `awk`.
- GNU `tar`.
- `gzip`, `bzip2` and `xz`.
- GNU Make.