Nix Cookbook: Difference between revisions
imported>Dustinlacewell m Removed superfluous line in "Creating Periodic Services" |
imported>Infinisil Add tutorial on how to wrap derivations |
||
| Line 38: | Line 38: | ||
}; | }; | ||
} | } | ||
</syntaxHighlight> | |||
== Wrapping packages == | |||
If you need to wrap a binary of a package (or a non-binary), there are a few ways of doing it. The simplest of which is just creating a new binary that calls the old one: | |||
<syntaxHighlight lang="nix"> | |||
pkgs.writeScriptBin "hello" '' | |||
#!${pkgs.stdenv.shell} | |||
# Call hello with a traditional greeting | |||
exec ${pkgs.hello}/bin/hello -t | |||
'' | |||
</syntaxHighlight> | |||
The disadvantage of this way is that it doesn't propagate man pages and other paths from the old derivation. There are multiple ways of solving that: | |||
<syntaxHighlight lang="nix"> | |||
let | |||
wrapped = pkgs.writeScriptBin "hello" '' | |||
#!${pkgs.stdenv.shell} | |||
exec ${pkgs.hello}/bin/hello -t | |||
''; | |||
in | |||
pkgs.symlinkJoin { | |||
name = "hello"; | |||
paths = [ | |||
wrapped | |||
pkgs.hello | |||
]; | |||
} | |||
</syntaxHighlight> | |||
Similarly the following works too: | |||
<syntaxHighlight lang="nix"> | |||
pkgs.symlinkJoin { | |||
name = "hello"; | |||
paths = [ pkgs.hello ]; | |||
buildInputs = [ pkgs.makeWrapper ]; | |||
postBuild = '' | |||
wrapProgram $out/bin/hello \ | |||
--add-flags "-t" | |||
''; | |||
} | |||
</syntaxHighlight> | |||
If you prefer not to have every file symlinked and have a cleaner result, the following is also possible: | |||
<syntaxHighlight lang="nix"> | |||
pkgs.runCommand "hello" { | |||
buildInputs = [ pkgs.makeWrapper ]; | |||
} '' | |||
mkdir $out | |||
# Link every top-level folder from pkgs.hello to our new target | |||
ln -s ${pkgs.hello}/* $out | |||
# Except the bin folder | |||
rm $out/bin | |||
mkdir $out/bin | |||
# We create the bin folder ourselves and link every binary in it | |||
ln -s ${pkgs.hello}/bin/* $out/bin | |||
# Except the hello binary | |||
rm $out/bin/hello | |||
# Because we create this ourself, by creating a wrapper | |||
makeWrapper ${pkgs.hello}/bin/hello $out/bin/hello \ | |||
--add-flags "-t" | |||
'' | |||
</syntaxHighlight> | |||
And lastly, there is the possibility of wrapping things right inside the derivation you want to wrap, this is however discouraged and impractical in most cases, as it requires recompilation of it: | |||
<syntaxHighlight lang="nix"> | |||
pkgs.hello.overrideAttrs (oldAttrs: { | |||
buildInputs = oldAttrs.buildInputs or [] ++ [ pkgs.makeWrapper ]; | |||
postInstall = oldAttrs.postInstall or "" + '' | |||
wrapProgram $out/bin/hello \ | |||
--add-flags "-t" | |||
''; | |||
}) | |||
</syntaxHighlight> | </syntaxHighlight> | ||