如何在 NixOS 上使用新的 haskell-ng 基础架构?

Posted

技术标签:

【中文标题】如何在 NixOS 上使用新的 haskell-ng 基础架构?【英文标题】:How do I use the new haskell-ng infrastructure on NixOS? 【发布时间】:2015-05-16 00:21:06 【问题描述】:

如何使用新的 haskell-ng 基础架构在 NixOS 上设置简单的 Haskell 开发环境?

【问题讨论】:

【参考方案1】:

这是基于每个项目的一种方法。我正在开发一个 Yesod webbapp,所以我以我当前的设置为例。

在我的项目文件夹中,我有两个文件:default.nix(指定如何构建我的项目)和shell.nix(指定如何设置构建输入)。

这样我就可以运行nix-shell,它会将我带入一个安装了 ghc 并安装了提供的包和路径设置的环境。

设置

default.nix

 stdenv, haskellPackages :

let
  env = haskellPackages.ghcWithPackages (p: with p; [
    aeson
    bytestring
    cabal-install
    classy-prelude
    classy-prelude-conduit
    classy-prelude-yesod
    conduit
    containers
    data-default
    directory
    fast-logger
    file-embed
    hjsmin
    http-conduit
    monad-control
    monad-logger
    persistent
    persistent-postgresql
    persistent-template
    safe
    shakespeare
    template-haskell
    text
    time
    unordered-containers
    vector
    wai-extra
    wai-logger
    warp
    yaml
    yesod
    yesod-auth
    yesod-bin
    yesod-core
    yesod-form
    yesod-static
  ]);
in
  stdenv.mkDerivation 
    name        = "project-name";
    buildInputs = [env];
    shellHook   = ''
      export NIX_GHC="$env/bin/ghc"
      export NIX_GHCPKG="$env/bin/ghc-pkg"
      export NIX_GHC_DOCDIR="$env/share/doc/ghc/html"
      export NIX_GHC_LIBDIR=$( $NIX_GHC --print-libdir )
    '';
  

shell.nix

 pkgs ? (import <nixpkgs> ) :

(import ./default.nix) 
    stdenv            = pkgs.stdenv;
    haskellPackages = pkgs.haskellPackages;
  

更多信息

有关更多信息,您可以阅读:

A Journey into the Haskell NG infrastructure: Part I

A Journey into the Haskell NG infrastructure: Part II

这些链接解释了 haskell-ng 的工作原理以及未来会发生什么。

如果您想深入了解 haskell-ng 基础架构的来源,我建议:

The file where haskellPackages is defined

The haskell packages module

The haskell-module folder

更新:在启用分析的情况下构建依赖项

haskell-ng 中的所有包都在hackage-packages.nix 中定义。它们是使用cabal.mkDerivation 构建的。

如果您想覆盖一个包的构建方式,您需要覆盖在该包上调用mkDerivation 的方式。 In the Haskell Wiki you have information on how to do that.。基本上你定义了一个新的 haskellPackages 并为每个包添加你想要的覆盖:

let haskellPackages' = haskellPackages.override 
       overrides = self: super: 
         fullstop = super.fullstop.override 
           mkDerivation = (attrs: self.mkDerivation (attrs //  doCheck = false; ));
         ;
       ;
     ;

这可能会很乏味,因此您可以使用 haskell-modules 中的文件 lib.nix 中的辅助函数。

文件haskell-ng 导入lib.nix 并公开它。而haskell-ng 公开为***包,因此您可以轻松访问 lib 函数。

假设我们有一个想要在文本库上启用分析的包,我们可以这样做:

 pkgs ? (import <nixpkgs> ).pkgs :

let
  lib = pkgs.haskell-ng.lib;
  env = pkgs.haskellPackages.ghcWithPackages (p: with p; [
    (lib.enableLibraryProfiling text)
  ]);
in
  pkgs.stdenv.mkDerivation 
    name        = "hello-world-wide-web";
    buildInputs = [env];
    shellHook   = ''
      export NIX_GHC="$env/bin/ghc"
      export NIX_GHCPKG="$env/bin/ghc-pkg"
      export NIX_GHC_DOCDIR="$env/share/doc/ghc/html"
      export NIX_GHC_LIBDIR=$( $NIX_GHC --print-libdir )
    '';
  

这个周末,我通过浏览 haskell-ng 的 nix 源代码并对其进行测试,找到了这些信息。我对 NixOS 和 nix 还是很陌生,所以可能有更好的方法来做到这一点。

【讨论】:

感谢您发布此信息!我觉得有帮助的一件事是如何管理分析,这要求所有依赖项都必须使用分析支持来构建。我找到了一种方法,但我并不完全理解它,并且它目前适用于全球,因此最好了解如何让单个包的环境需要其依赖项的分析版本。 @LeviPearson 不用担心!只是认为将这些信息放在易于访问的地方会很好。请参阅我关于覆盖如何构建包并特别添加分析的编辑! 我是 NixOS 的新手,在一些帮助下,我终于在 Haskell NG 下构建了我的一个 haskell 项目。但是我的 default.nix 看起来像你的 shell.nix,我的 shell.nix 看起来像你的 default.nix。您是否在答案中交换了文件名,或者文件名无关紧要? @musicmatze 如果你的包需要一个运行的 postgresql 服务器,你的default.nix 应该只定义使用 postgresql 所需的库。它不会定义系统需要运行哪些服务。 @musicmatze 以 nginx 为例,default.nix-file 只定义了它的构建、安装和运行的依赖关系。 nginx 的部署方式(是否使用 systemd 启动,是否需要可变目录来存储数据等)在 NixOS service.nix-file 中定义。

以上是关于如何在 NixOS 上使用新的 haskell-ng 基础架构?的主要内容,如果未能解决你的问题,请参考以下文章

如何将我的系统升级到 nixos-unstable?

如何在 configuration.nix 中以声明方式添加 NixOS 不稳定通道

如何在保留 GNOME 的其余部分的同时从我的 NixOS 中删除 Epiphany?

如何在 NixOS 和 cargo 下安装具有 sqlite 支持的diesel-cli?

Nixos 默认音频设备

如何使用nixos中设置的属性的默认值,并对其进行扩展