使用 nix 构建简单的 haskell 库

Build simple haskell library using nix

我对 Nix 感兴趣有一段时间了,我想我最终会尝试用它来开始一个新的 haskell 项目。

我从目录结构开始

project.cabal
src/Lib.hs

其中 cabal 文件包含以下内容:

name: project
version: 0.1.0.0
build-type: Simple
license: MIT
cabal-version: >= 1.18

library
  exposed-modules: Lib
  build-depends: base < 5
  hs-source-dirs: src
  default-language: Haskell2010

并且Lib.hs有

module Lib where

hello :: Int -> IO ()
hello x = putStrLn (show x)

如您所见,这很简单。当我执行cabal build时,它似乎很高兴。请注意,无论如何我都不是 haskell 专家,所以我可能在这里犯了一些初学者错误。

为了使用 Nix 构建它,我一直在阅读 https://github.com/Gabriel439/haskell-nix 以获取我的信息。我执行了 cabal2nix . > default.nix 以获得我的 cabal 文件的 Nix 版本。然后我创建了一个 release.nix 文件来实际构建它。两个文件内容如下:

default.nix

{ mkDerivation, base, stdenv }:
mkDerivation {
  pname = "project";
  version = "0.1.0.0";
  src = ./.;
  libraryHaskellDepends = [ base ];
  license = stdenv.lib.licenses.mit;
}

release.nix

let
  pkgs = import <nixpkgs> { };
in
  pkgs.haskellPackages.callPackage ./default.nix { }

完成后,我执行了nix-build release.nix并返回

these derivations will be built:
  /nix/store/p481alkpm89712n3hnwai0nxhmjrm8b2-project-0.1.0.0.drv
building path(s) ‘/nix/store/yszy2a6wd88pf6zlw0nw99l5wzvc0s9x-project-0.1.0.0’
setupCompilerEnvironmentPhase
Build with /nix/store/d5w12a8bprd2518xnqp1cwh3rbjiagyx-ghc-8.0.1.
unpacking sources
unpacking source archive /nix/store/fsn4b9w54h2jdpv546nwvy82vnkszl1w-project
source root is project
patching sources
compileBuildDriverPhase
setupCompileFlags: -package-db=/tmp/nix-build-project-0.1.0.0.drv-0/package.conf.d -j4 -threaded
[1 of 1] Compiling Main             ( /nix/store/4mdp8nhyfddh7bllbi7xszz7k9955n79-Setup.hs, /tmp/nix-build-project-0.1.0.0.drv-0/Main.o )
Linking Setup ...
...
...
Building project-0.1.0.0...
Preprocessing library project-0.1.0.0...
dist/build/Lib_o_split: getDirectoryContents: does not exist (No such file or
directory)
builder for ‘/nix/store/p481alkpm89712n3hnwai0nxhmjrm8b2-project-0.1.0.0.drv’ failed with exit code 1
error: build of ‘/nix/store/p481alkpm89712n3hnwai0nxhmjrm8b2-project-0.1.0.0.drv’ failed

这当然不好。我在这里犯了什么错误?我在构建可执行文件而不是库的类似尝试中取得了成功,因此我怀疑它与此有关。我关注的 github 存储库也在使用可执行文件。

我相信默认情况下 nix 与普通 cabal 不同,它会尝试使用拆分对象功能构建任何 Haskell 项目,per cabal's manual:

--enable-split-objs

Use the GHC -split-objs feature when building the library. This reduces the final size of the executables that use the library by allowing them to link with only the bits that they use rather than the entire library. The downside is that building the library takes longer and uses considerably more memory.

我不太确定为什么这可能会在您的系统上失败,但根据您的 nixpkgs 版本,可以通过添加以下之一来禁用:

enableSplitObjs = false;

enableDeadCodeElimination = false;

推导。

有关其他属性/选项的列表,您可以参考 https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/generic-builder.nix 不幸的是,我不知道有任何官方文档更详细地描述这些。