首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >组合本地nix包

组合本地nix包
EN

Stack Overflow用户
提问于 2017-12-01 10:42:32
回答 2查看 3K关注 0票数 5

我想运行一个nix-shell,并安装了以下软件包:

  • 阿法尔
  • aspellDicts.en
  • 你好

我不能简单地做:nix-shell -p aspell aspellDicts.en hello --pure,因为这将不能正确地安装拼写字典。Nix提供了一个aspellWithDict函数,可用于使用字典构建拼写:

代码语言:javascript
复制
nix-build -E 'with import <nixpkgs> {}; aspellWithDicts (d: [d.en])'

我希望将此构建的结果用作另一个本地包(foo)中的依赖项。我现在就是这么做的:

./pkgs/拼写与-dicts/default.nix:

代码语言:javascript
复制
with import <nixpkgs> {};

aspellWithDicts (d: [d.en])

./pkgs/foo/default.nix:

代码语言:javascript
复制
{stdenv, aspellWithDicts, hello}:

stdenv.mkDerivation rec {
    name = "foo";
    buildInputs = [ aspellWithDicts hello ];
}

./习俗-包装。

代码语言:javascript
复制
{ system ? builtins.currentSystem }:

let
  pkgs = import <nixpkgs> { inherit system; };

in

rec {
  aspellWithDicts = import ./pkgs/aspell-with-dicts;

  foo = import ./pkgs/foo {
    aspellWithDicts = aspellWithDicts;
    hello = pkgs.hello;
    stdenv = pkgs.stdenv;
  };
}

运行shell的工作方式与预期相同:nix-shell ./custom-packages.nix -A foo --pure

因此,我的解决方案是可行的,但这个结果能否以更简洁的惯用方式实现呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-02 15:43:50

为了使这段代码更易懂,我有以下建议:

callPackage

使用pkgs.callPackage函数。它将负责传递派生所需的参数。这就是为什么NixPkgs中的许多文件看起来像{ dependency, ...}: something。第一个参数是要注入依赖项的函数,第二个参数是一个属性集,可以用来手动传递一些依赖项。

通过使用callPackage,您不需要import <nixpkgs> {},因此您的代码将更容易在新的上下文中使用-- <nixpkgs>不能被使用,而且它的计算速度会更快一些,因为它只需要计算NixPkgs修复点一次。

(当然,您必须先使用import <nixpkgs>一次才能开始,但在那之后,就没有必要了。)

with

pkgs/aspell-with-dicts/default.nix中,您使用了一个with关键字,这是可以的,但在本例中它并不真正增加值。我更喜欢显式地引用变量,所以在使用一两次时更喜欢阅读pkgs.something,如果使用更频繁,则更喜欢读inherit (pkgs) something。这样,读取器就可以很容易地确定变量来自何处。

我在试验不熟悉的包或功能时确实使用它,因为那时维护不是问题。

pkgs/aspell-with-dicts/default.nix

除非您期望您想要重用的是您的A拼写实例化,否则只在您使用它的地方构造它可能会更容易。

如果您确实希望重用一个包的特定配置,那么您可能希望通过在一个覆盖层中构造它来使它成为一个一流的包。

就这样。我认为最重要的一点是避免使用<nixpkgs>,除此之外,它已经非常惯用了。

我不知道您神秘的foo是什么,但是如果它是开源的,请考虑将它升级到NixPkgs中。在我的经验中,Nix有一个非常欢迎的社区。

票数 2
EN

Stack Overflow用户

发布于 2017-12-02 05:12:14

您需要构建foo吗?您将在foo中使用什么?

假设您只想通过nix-shell使用shell,而不想使用nix-buildnix-env -i构建/安装任何东西,这应该是可行的。

下面的shell.nix

代码语言:javascript
复制
with import <nixpkgs> {};
with pkgs;

let
  myAspell = aspellWithDicts (d: [d.en]);
in
  stdenv.mkDerivation {
    name = "myShell";

    buildInputs = [myAspell hello];

    shellHooks = ''
      echo Im in $name.
      echo aspell is locate at ${myAspell}
      echo hello is locate at ${hello}
    '';
  }

将给您一个带有aspellhello的shell。

代码语言:javascript
复制
$ nix-shell
Im in myShell.
aspell is locate at /nix/store/zcclppbibcg4nfkis6zqml8cnrlnx00b-aspell-env
hello is locate at /nix/store/gas2p68jqbzgb7zr96y5nc8j7nk61kkk-hello-2.10

如果是这样的话,foo需要构建和安装一些代码。

mkDerivation in foo/default.nix必须具有src字段,该字段可以是src = ./.;或类似于fetchurlfetchFromGithub的内容(参见文档中的示例)。

然后,您可以使用callPackagesimport (取决于nix表达式是如何编写的),以foo/default.nix作为参数,将foo提供的内容带到这个shell中。

如果尝试构建此shell.nix (或foo/default.nix),它将因缺少src而失败。

代码语言:javascript
复制
$ nix-build shell.nix 
these derivations will be built:
  /nix/store/20h8cva19irq8vn39i72j8iz40ivijhr-myShell.drv
building path(s) ‘/nix/store/r1f6qpxz91h5jkj7hzrmaymmzi9h1yml-myShell’
unpacking sources
variable $src or $srcs should point to the source
builder for ‘/nix/store/20h8cva19irq8vn39i72j8iz40ivijhr-myShell.drv’ failed with exit code 1
error: build of ‘/nix/store/20h8cva19irq8vn39i72j8iz40ivijhr-myShell.drv’ failed
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47591632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档