我编写了一个非常简单的default.nix文件,我应该能够用它构建gnu hello包(类似于nix药丸)。
但现在我遇到了一个错误:
jane@nixos:~/graphviz$ nix-构建-A hello
错误:未定义变量'pkgs‘在/home/jane/graphviz/default.nix:3:47
这是源代码:
[jane@nixos:~/graphviz]$ cat default.nix
{
pkgs = import <nixpkgs> {};
mkDerivation = import ./autotools.nix pkgs;
hello = import ./hello.nix { inherit mkDerivation ;};
}这对我来说是完全没有意义的,因为我在上面定义了pkgs。
因为我看不出是怎么回事,我打开了尼克斯瑞尔,进入了队伍。
nix-repl> pkgs = import <nixpkgs> {}
nix-repl> mkDerivation = import ./autotools.nix pkgs
nix-repl> hello = import ./hello.nix { inherit mkDerivation ;}
nix-repl> hello
«derivation /nix/store/g2y6sf5q236icvv2gwyg0lnij3mkr36j-hellooo.drv»你瞧,它起作用了。所以我不明白为什么default.nix会失败。我只能想象default.nix在某种程度上是特殊的,但就语法而言,它必须是好的,否则nix也不能工作。
有人能解释我为什么会出现这个未定义的变量错误吗?
编辑:在问完这个问题后,我找到了一种解决未定义变量错误的方法,如果我这样说的话:
let pkgs = import <nixpkgs> {}; mkDerivation = import ./autotools.nix pkgs;
in
{
hello = import ./hello.nix { inherit mkDerivation ;};
}它起作用了。
但我最初的问题仍然存在。
发布于 2020-02-09 02:10:35
{ }语法只定义一个值。它不把它中的属性带入作用域。您可以使用rec { }语法,这两者都可以。
rec {
pkgs = import <nixpkgs> {};
mkDerivation = import ./autotools.nix pkgs;
hello = import ./hello.nix { inherit mkDerivation ;};
}nix repl所做的实际上是在每次命名某物时创建一个let绑定。您的repl会话可以看作是一个交互式构建的表达式:
let pkgs = import <nixpkgs> {};
in /* nixlang scope on 2nd prompt */
let mkDerivation = import ./autotools.nix pkgs
in /* nixlang scope on 3rd prompt */
let hello = import ./hello.nix { inherit mkDerivation ;}
/* nixlang scope on 4th prompt */
in hello为了说明属性集创建和名称绑定之间的区别,可以将属性集命名为属性集并在其自身的定义中使用它。
let
myScope = {
# myScope is like any other attribute set
pkgs = import <nixpkgs> {};
# laziness permits the attributes inside to reference myScope
mkDerivation = import ./autotools.nix myScope.pkgs;
hello = import ./hello.nix { inherit (myScope) mkDerivation ;};
};
in
# the value of this file is the myScope attribute set
myScope这相当于rec示例,但只在作用域中引入一个名称:myScope。
https://stackoverflow.com/questions/60131414
复制相似问题