haskell - 使用 nix 构建简单的 haskell 库

标签 haskell 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文件来实际构建它。两个文件的内容如下:

默认.nix

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

发布.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不幸的是,我不知道有任何官方文档更详细地描述这些内容。

关于haskell - 使用 nix 构建简单的 haskell 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43443961/

相关文章:

c - 用 Haskell 写入二进制数据以供 C 读取?

multithreading - Haskell - 线程时缓慢的套接字连接

haskell - 在 haskell 中的函数中声明字典

nix - 将运行时依赖注入(inject) nix 包

docker - 如何在 docker 镜像中应用 nix-shell 配置?

haskell - 我可以编译这个类型不明确的函数吗?

haskell - 文件开头无用的种类相等错误

zsh - NixOS 之外的 Nix 配置

haskell - 如何通过 Nix 覆盖 nixpkgs 中的 Haskell 包?

shell - 获取 Spacemacs/Emacs GUI 版本以识别 nix-shell 环境