首页 > 解决方案 > 如何使用 Nix 指定包/派生运行时依赖项?

问题描述

我正在制作一个haskell程序,并且我正在设置buildInput这样的内容pkgs.ffmpeg-full

(myHaskellPackages.callCabal2nix "App" (./.) {}).overrideAttrs (oldAttrs: {
  buildInputs = (oldAttrs.buildInputs or []) ++ [ pkgs.ffmpeg-full ];
})

然而,这似乎使 ffmpeg 包只能在构建时访问,而不是在应用程序的运行时访问。

我需要设置哪些属性才能ffmpeg-full在运行时可用 - 能够调用ffmpeg可执行文件?

在nix pills中有一个关于运行时依赖的部分,但我不明白那个部分,它如何总是通过哈希来确定运行时依赖是没有意义的?我的意思是,如果我在 shell 脚本中引用可执行文件 - nix 肯定不会解析 shell 脚本来确定我引用的可执行文件。https://nixos.org/guides/nix-pills/automatic-runtime-dependencies.html#idm140737320205792

但是,运行时依赖项有所不同。一旦在任何派生调用中使用构建依赖项,Nix 就会自动识别它们,但我们从不指定派生的运行时依赖项是什么。

真的有黑魔法。乍一看,它会让你觉得“不,这不能长期工作”,但同时它工作得非常好,以至于整个操作系统都建立在这个魔法之上。

换句话说,Nix 会自动计算派生的所有运行时依赖项,这要归功于存储路径的散列。

标签: nix

解决方案


默认.nix:

{
  ghc ? "ghc8106",
  pkgs ? import <nixpkgs> {}
}:
with pkgs.haskell.lib;
let
  haskellPkgs = pkgs.haskell.packages.${ghc};
  inherit (pkgs) lib;

  mySourceRegexes = [
    "^app.*$"
    "^.*\\.cabal$"
    "package.yaml"
  ];

  myApp = (haskellPkgs.callCabal2nix "my-hello"
    (lib.sourceByRegex ./. mySourceRegexes) { });

in myApp
   .overrideAttrs(
      oa: {
        nativeBuildInputs = oa.nativeBuildInputs ++ [pkgs.hello pkgs.makeWrapper];
        installPhase = oa.installPhase + ''
          ln -s ${pkgs.hello.out}/bin/hello $out/bin/hello
        '';
        postFixup = ''
          wrapProgram $out/bin/x-exe --prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.hello ]}
        '';
      })

src/Main.hs:

module Main where

import System.Process (callCommand)

main :: IO ()
main = do
  putStrLn "HELLO"
  callCommand "hello"
  putStrLn "BYE"

推荐阅读