Either set the substitute
option to false
in nix.conf
(the default is true
) or use --option substitute false
when invoking a Nix command.
nix-env --options substitute false -i hello
nix-shell --options substitute false -p hello
Might not be the droids you are looking for
As Robert Hensing (comment, chat), Henri Menke (comment), and Vladimír Čunát (comment) pointed out, this may not be the thing that you are really after.
To elaborate: I have been using the most basic Nix features confidently, but got to a point where I need to maintain and deploy a custom fork of a large application written in C, which is quite intimidating at the outset.
Tried to attack the problem the simplest way to just fetch my fork and re-build it with the new source, so I boiled it down to this question. Although, I suspect that the right direction for me is something along the lines of Nixpkgs/Create and debug packages in the NixOS Wiki.
Only re-build the package itself
Vladimír Čunát commented that "disabling substitutes makes you rebuild everything that's missing locally, even though I suspect that people asking such a question often only want to rebuild the specified package itself."
(This is probably achieved with nix-build
or "just" overriding the original package but could be wrong. The latter is mention (maybe demonstrated even?) in the NixOS wiki article Development environment with nix-shell
but haven't been able to read it thoroughly yet.)
Test for reproducibility
One might arrive to formulating this same question if they want to make sure that subsequent builds are deterministic. As Henri Menke comments, one should use nix-build --check
for that.
The --check
option is easy to miss; it's not documented in man nix-build
or at nix-build
in the Nix manual, but at nix-store --realize
because (as man nix-build
explains it):
nix-build
is essentially a wrapper around nix-instantiate
(to
translate a high-level Nix expression to a low-level store derivation)
and nix-store --realise
(to build the store derivation) [and so] all
options not listed here are passed to nix-store --realise
, except
for --arg
and --attr
/ -A
which are passed to nix-instantiate
.
See detailed examples in the Nix manual at 18.1. Spot-Checking Build Determinism and the next section right after it.
The relevant parts for the substitute
configuration option under the nix.conf
section from the Nix manual:
Name
nix.conf
— Nix configuration file
Description
Nix reads settings from two configuration files:
The system-wide configuration file sysconfdir/nix/nix.conf
(i.e. /etc/nix/nix.conf
on most systems), or $NIX_CONF_DIR/nix.conf
if NIX_CONF_DIR
is set.
The user configuration file $XDG_CONFIG_HOME/nix/nix.conf
, or ~/.config/nix/nix.conf
if XDG_CONFIG_HOME
is not set.
You can override settings on the command line using the --option
flag,
e.g. --option keep-outputs false
.
The following settings are currently available:
[..]
substitute
If set to true (default), Nix will use binary substitutes if available. This option can be disabled to force building from source.
(Formerly known as use-binary-caches
.)
Notes
Setting substitute
to false
(either with --options
or in nix.conf
) won't recompile the package if the command issue multiple times. That is, hello
above would be compiled from source the first time, and then it will access the already present store path if the command issued again.
This is where it gets fuzzy: it is clear that no recompilation takes place because unless the package's Nix build expression doesn't change, the store output hash won't change either, making the next compilation output equivalent to the previous one, hence the action would be superfluous.
So if one would do some light hacking on a package, and just wanted to try it out locally (e.g., with nix-shell
) then one would have to use -I nixpkgs=a/local/nixpkgs/dir
to pick up those changes - and eventually do a recompilation? Or should one use nix-build
?
See also question How to nix-build
again a built store path?