How can I override compile flags (as in CFLAGS
) for a single package in NixOS/Nix environments?
Here's what I've got by now:
let
optimizeForThisHost = pkg:
pkgs.lib.overrideDerivation pkg (old: {
exportOptimizations = ''
export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -fPIC -O3 -march=native"
'';
phaseNames = ["exportOptimizations"] ++ old.phaseNames;
});
in
muttWithoutThings = pkgs: (pkgs.mutt.override {
sslSupport = false;
saslSupport = false;
imapSupport = false;
withSidebar = false;
};
});
mutt = pkgs:
(optimizeForThisHost (muttWithoutThings pkgs));
in my configuration.nix
, though this fails with
error: attribute ‘phaseNames’ missing
Here is a working example that builds (and runs) a copy of GNU hello with custom compiler flags:
nix-shell -p 'hello.overrideDerivation (old: { NIX_CFLAGS_COMPILE = "-Ofoo"; })' --run "hello --version"
If you want to convince yourself whether this really works, try passing a non-existent flag to the compiler, like -Ofoo
, and verify that the builds fails as expected.
More information about the overrideDerivation
function (and similar alternatives) can found in the Nixpkgs manual at http://nixos.org/nixpkgs/manual/index.html#sec-pkg-overrideDerivation.
I managed to write a function which I can apply to the packages I want to compile with custom flags:
optimizeWithFlags = pkg: flags:
pkgs.lib.overrideDerivation pkg (old:
let
newflags = pkgs.lib.foldl' (acc: x: "${acc} ${x}") "" flags;
oldflags = if (pkgs.lib.hasAttr "NIX_CFLAGS_COMPILE" old)
then "${old.NIX_CFLAGS_COMPILE}"
else "";
in
{
NIX_CFLAGS_COMPILE = "${oldflags} ${newflags}";
});
This function takes a package and a list of strings (which are the flags) and builds a new package with the existing one, but with the additional compiler flags.
For convenience, I wrote another set of helper functions:
optimizeForThisHost = pkg:
optimizeWithFlags pkg [ "-O3" "-march=native" "-fPIC" ];
withDebuggingCompiled = pkg:
optimizeWithFlags pkg [ "-DDEBUG" ];
Now, I can override packages (here mutt
and dmenu
):
muttWithoutThings = pkgs: (pkgs.mutt.override {
sslSupport = false;
saslSupport = false;
imapSupport = false;
withSidebar = false;
});
mutt = pkgs:
(utils pkgs).withoutConfigureFlag "--enable-debug"
((utils pkgs).optimizeForThisHost (muttWithoutThings pkgs)
);
dmenu = pkgs:
(utils pkgs).optimizeForThisHost
(pkgs.dmenu.override {
patches = [ ./patches/dmenu-fuzzymatch-4.6.diff ];
});
In the above utils
is utils = pkgs: import ./util.nix { pkgs = pkgs; };
and the util.nix
file returns a function which spits out a set of functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With