如何在nixos中覆盖单个程序包的编译标志?

mus*_*tze 5 package compiler-optimization nixos nix cflags

CFLAGS在NixOS / Nix环境中,如何为单个软件包覆盖编译标志(如中所示)?

这是我现在所拥有的:

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));
Run Code Online (Sandbox Code Playgroud)

在我configuration.nix,虽然这失败了

error: attribute ‘phaseNames’ missing
Run Code Online (Sandbox Code Playgroud)

Pet*_*ons 5

这是一个使用自定义编译器标志构建(并运行)GNU hello 副本的工作示例:

nix-shell -p 'hello.overrideDerivation (old: { NIX_CFLAGS_COMPILE = "-Ofoo"; })' --run "hello --version"
Run Code Online (Sandbox Code Playgroud)

如果您想说服自己这是否真的有效,请尝试将不存在的标志传递给编译器,例如-Ofoo,并验证构建是否按预期失败。

有关该overrideDerivation功能(和类似替代方案)的更多信息,请参见 Nixpkgs 手册,网址为http://nixos.org/nixpkgs/manual/index.html#sec-pkg-overrideDerivation


mus*_*tze 4

我设法编写了一个函数,可以将其应用于我想要使用自定义标志进行编译的包:

  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}";
    });
Run Code Online (Sandbox Code Playgroud)

该函数采用一个包和一个字符串列表(它们是标志),并使用现有包构建一个新包,但带有附加的编译器标志。

为了方便起见,我编写了另一组辅助函数:

  optimizeForThisHost = pkg:
    optimizeWithFlags pkg [ "-O3" "-march=native" "-fPIC" ];

  withDebuggingCompiled = pkg:
    optimizeWithFlags pkg [ "-DDEBUG" ];
Run Code Online (Sandbox Code Playgroud)

现在,我可以覆盖包(此处muttdmenu):

  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 ];
    });
Run Code Online (Sandbox Code Playgroud)

上面utilsutils = pkgs: import ./util.nix { pkgs = pkgs; };文件util.nix返回一个函数,该函数吐出一组函数。