我使用此default.nix使用nix-build构建我的包,并使用env获取nix-shell

{ pkgs ? import <nixpkgs> {} }:
with pkgs;
with haskellPackages;

let
  myPackage = callPackage ./myPackage.nix {};
in
  if lib.inNixShell then myPackage.env else myPackage

使用myPackage.nix生成的cabal2nix . > myPackage.nix
{ mkDerivation, base, split, stdenv }:
mkDerivation {
  pname = "myPackage";
  version = "0.1.0.0";
  src = ./.;
  isLibrary = false;
  isExecutable = true;
  executableHaskellDepends = [ base split ];
  license = stdenv.lib.licenses.bsd3;
}

这样可以很好地进行构建,但是我想在开发过程中添加开发助手工具。我不想编辑myPackage.nix。我想在编辑cabal2nix时重新运行myPackage.cabal

我尝试使用buildInputsmkDerivation,但似乎没有用。
let
  myPackage = callPackage ./myPackage.nix {};
in
  stdenv.mkDerivation {
    name = myPackage.name;

    buildInputs = [ myPackage hlint hasktags ];
}

除了nix-build停止工作之外,它也将我放入具有myPackage可执行文件但没有myPackage的env的 shell 中。

我知道这是因为ghc在上面的myPackage中存在于default.nix的env中时不可用。

如何将这些工具添加到从env生成的cabal2nix中?

最佳答案

nix-shell命令可构建项目的所有依赖项,并将所有环境变量设置为其各自的派生属性值和源(bash)$stdenv/setup。有关更多详细信息,请参见the Nix manual about nix-shell

因此,在最后一个示例中,如果运行echo $buildInputs,您将看到已构建的软件包作为构建输入。这样行得通,但这不是您想要的。

相反,您需要重用特定于Haskell的环境派生myPackage.env。此nix-shell的虚拟派生具有GHC,该GHC设置为仅发现您的依赖项等。

pkgs.lib.overrideDerivation myPackage.env (old: {
    buildInputs = old.buildInputs ++ [ pkgs.haskellPackages.hlint ];
})

不请自来的建议;)

在我的项目中,为此使用了shell.nix文件。这也让我避免了破坏引用透明性的lib.inNixShell值。

如果您的项目包含多个Haskell程序包,则建议编写一个覆盖图。这将使您的项目更加连贯。
shell.nix
# This imports the project + overlay. The overlay takes care of
# adding `myPackage` to `haskellPackages`, to make it available
# throughout the project.
attrs@{...}:
let pkgs = (import ../nix attrs);

# Adapt myPackage.env
in pkgs.lib.overrideDerivation pkgs.haskellPackages.myPackage.env (old: {
    buildInputs = old.buildInputs ++ [ pkgs.haskellPackages.hlint ];
})

有关覆盖的示例,请参见zimbatm's todomvc-nix

关于haskell - 如何将软件包添加到cabal2nix生成的 `env`中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47729044/

10-12 22:31