使用 Nix 的 callCabal2nix 时如何启用 Haskell 分析

Posted

技术标签:

【中文标题】使用 Nix 的 callCabal2nix 时如何启用 Haskell 分析【英文标题】:How can I enable Haskell profiling when using Nix's callCabal2nix 【发布时间】:2019-11-16 14:53:55 【问题描述】:

目前我的 default.nix 看起来像:


  sources ? import ./nix/sources.nix
, compiler ? "ghc865"  :
let
  niv = import sources.nixpkgs 
    overlays = [
      (_ : _ :  niv = import sources.niv ; )
    ] ;
    config = ;
  ;
  pkgs = niv.pkgs;
  myHaskellPackages = pkgs.haskell.packages.$compiler.override 
    overrides = self: super: 
      mkDerivation = args: super.mkDerivation (args // 
        enableLibraryProfiling = true;
      );
    ;
  ;
in
(myHaskellPackages.callCabal2nix "moscoviumorange" (./.) )

我想为我的应用程序及其依赖项启用 Haskell 分析。对于我的应用程序,我可以使用 hpack 处理此问题:

executables:
  moscoviumorange-p:
    ghc-options: -main-is Main -prof -fprof-auto
    source-dirs: src
    main: Main.hs

我如何为依赖库做同样的事情?

【问题讨论】:

【参考方案1】:

这可以使用callCabal2nixWithOptions:

...
(myHaskellPackages.callCabal2nixWithOptions "moscoviumorange" (./.) "--enable-profiling" )

我是怎么想出来的:

使用 nix repl 我找到了函数的路径:

nix-repl> pkgs.haskell.packages.ghc865.callCabal2nix  
«lambda @ /nix/store/54fafxcq7b6ac2hvs8qzp2bgqzgpiiga-nixos-19.09.1019.c5aabb0d603/nixos/pkgs/development/haskell-modules/make-package-set.nix:213:21»

然后,我检查了 nixpkgs 存储库(确保它与我在 default.nix 中引用的提交相同)并导航到我发现的那个文件+行:

    # Creates a Haskell package from a source package by calling cabal2nix on the source.
    callCabal2nixWithOptions = name: src: extraCabal2nixOptions: args:
      let
        filter = path: type:
                   pkgs.lib.hasSuffix "$name.cabal" path ||
                   baseNameOf path == "package.yaml";
        expr = self.haskellSrc2nix 
          inherit name extraCabal2nixOptions;
          src = if pkgs.lib.canCleanSource src
                  then pkgs.lib.cleanSourceWith  inherit src filter; 
                else src;
        ;
      in overrideCabal (callPackageKeepDeriver expr args) (orig: 
           inherit src;
         );

    callCabal2nix = name: src: args: self.callCabal2nixWithOptions name src "" args;

进一步缩小到haskellSrc2nix

  haskellSrc2nix =  name, src, sha256 ? null, extraCabal2nixOptions ? "" :
    let
      sha256Arg = if sha256 == null then "--sha256=" else ''--sha256="$sha256"'';
    in pkgs.buildPackages.stdenv.mkDerivation 
      name = "cabal2nix-$name";
      nativeBuildInputs = [ pkgs.buildPackages.cabal2nix ];
      preferLocalBuild = true;
      allowSubstitutes = false;
      phases = ["installPhase"];
      LANG = "en_US.UTF-8";
      LOCALE_ARCHIVE = pkgs.lib.optionalString (buildPlatform.libc == "glibc") "$buildPackages.glibcLocales/lib/locale/locale-archive";
      installPhase = ''
        export HOME="$TMP"
        mkdir -p "$out"
        cabal2nix --compiler=$self.ghc.haskellCompilerName --system=$hostPlatform.config $sha256Arg "$src" $extraCabal2nixOptions > "$out/default.nix"
      '';
  ;

啊哈!为 cabal2nix 分析做 google - 它似乎支持带有命令行参数的选项。

https://github.com/NixOS/cabal2nix/blob/650d5300c6bb5632bbab6fcb2d939fb476e469c5/src/Cabal2nix.hs#L92

【讨论】:

以上是关于使用 Nix 的 callCabal2nix 时如何启用 Haskell 分析的主要内容,如果未能解决你的问题,请参考以下文章

使用 nix-shell 或 nix shell 在 Linux 64 上运行 MacOS sed

在 nix 上的 haskell 开发环境中使用 hoogle

你如何在 *nix 中卸载?

Nix 中的构建与运行时依赖关系

记住 *nix 命令行参数

使用 QNetworkAccessManager 时如何处理代理