使用带有 nix 的最新版本的包
Use latest version of package with nix
我正在尝试为我的应用程序设置一个依赖于 asio
和 fmt
的 nix 构建脚本(现在跳过第一个,因为它是一个更复杂的故事)。他们不是最新的 nix 包,所以我不能简单地从那里得到它。
但我意识到它基本上是另一个nix文件,应该很可能嵌入到我的项目中,所以de dependency会在之前构建。
我试过将它嵌入到 default.nix
文件中,但那样行不通。
with import <nixpkgs> {};
stdenv.mkDerivation rec {
pname = "fmt";
version = "7.0.3";
outputs = [ "out" "dev" ];
src = fetchFromGitHub {
owner = "fmtlib";
repo = "fmt";
rev = version;
};
nativeBuildInputs = [ cmake ];
cmakeFlags = [
"-DBUILD_SHARED_LIBS=ON"
"-DCMAKE_SKIP_BUILD_RPATH=OFF" # for tests
];
}
stdenv.mkDerivation {
name = "my-app";
src = ./.;
buildInputs = [ fmt ];
buildPhase = "c++ -o main main.cpp -lfmt";
}
如何安装latest/desired版本的包?
如何组合多个推导并依赖?
简答:您需要使用 let 绑定。 (长答案:使用单独的文件 + callPackage
,见下文)
with import <nixpkgs> {};
# create a binding for fmt (which is like an assignment but declarative)
let fmt = stdenv.mkDerivation rec {
pname = "fmt";
version = "7.0.3";
outputs = [ "out" "dev" ];
src = fetchFromGitHub {
owner = "fmtlib";
repo = "fmt";
rev = version;
};
nativeBuildInputs = [ cmake ];
cmakeFlags = [
"-DBUILD_SHARED_LIBS=ON"
"-DCMAKE_SKIP_BUILD_RPATH=OFF" # for tests
];
}
# terminate your bindings with the `in` keyword. The following expression is returned
in
stdenv.mkDerivation {
name = "my-app";
src = ./.;
buildInputs = [ fmt ];
buildPhase = "c++ -o main main.cpp -lfmt";
}
callPackage
我建议复制整个文件,以保持可读性。
Nixpkgs 中的包通常在文件中描述,这些文件本身不是可构建的表达式(即返回派生),而是从包到派生的函数。所以本质上你需要用包集来应用函数,但我们使用 pkgs.callPackage
函数而不是正常的函数应用程序,它负责反映参数所以你不必使用 { x, ... }:
语法并添加 override
属性。
它还允许覆盖包并通过第二个参数传递额外的参数。
pkgs.callPackage ./fmt.nix {}
或者在您的情况下只是 callPackage
因为您已经在本来可以称为 pkgs
(let pkgs = import <nixpkgs> {}; in
).[=22= 的内容上使用了 with
关键字]
我通常建议避免使用 with
关键字,因为它不必要地使 Nix 的作用域规则复杂化,并且它会使我们这些大脑中没有 Nix 求值器的人更难找到绑定。
我正在尝试为我的应用程序设置一个依赖于 asio
和 fmt
的 nix 构建脚本(现在跳过第一个,因为它是一个更复杂的故事)。他们不是最新的 nix 包,所以我不能简单地从那里得到它。
但我意识到它基本上是另一个nix文件,应该很可能嵌入到我的项目中,所以de dependency会在之前构建。
我试过将它嵌入到 default.nix
文件中,但那样行不通。
with import <nixpkgs> {};
stdenv.mkDerivation rec {
pname = "fmt";
version = "7.0.3";
outputs = [ "out" "dev" ];
src = fetchFromGitHub {
owner = "fmtlib";
repo = "fmt";
rev = version;
};
nativeBuildInputs = [ cmake ];
cmakeFlags = [
"-DBUILD_SHARED_LIBS=ON"
"-DCMAKE_SKIP_BUILD_RPATH=OFF" # for tests
];
}
stdenv.mkDerivation {
name = "my-app";
src = ./.;
buildInputs = [ fmt ];
buildPhase = "c++ -o main main.cpp -lfmt";
}
如何安装latest/desired版本的包?
如何组合多个推导并依赖?
简答:您需要使用 let 绑定。 (长答案:使用单独的文件 + callPackage
,见下文)
with import <nixpkgs> {};
# create a binding for fmt (which is like an assignment but declarative)
let fmt = stdenv.mkDerivation rec {
pname = "fmt";
version = "7.0.3";
outputs = [ "out" "dev" ];
src = fetchFromGitHub {
owner = "fmtlib";
repo = "fmt";
rev = version;
};
nativeBuildInputs = [ cmake ];
cmakeFlags = [
"-DBUILD_SHARED_LIBS=ON"
"-DCMAKE_SKIP_BUILD_RPATH=OFF" # for tests
];
}
# terminate your bindings with the `in` keyword. The following expression is returned
in
stdenv.mkDerivation {
name = "my-app";
src = ./.;
buildInputs = [ fmt ];
buildPhase = "c++ -o main main.cpp -lfmt";
}
callPackage
我建议复制整个文件,以保持可读性。
Nixpkgs 中的包通常在文件中描述,这些文件本身不是可构建的表达式(即返回派生),而是从包到派生的函数。所以本质上你需要用包集来应用函数,但我们使用 pkgs.callPackage
函数而不是正常的函数应用程序,它负责反映参数所以你不必使用 { x, ... }:
语法并添加 override
属性。
它还允许覆盖包并通过第二个参数传递额外的参数。
pkgs.callPackage ./fmt.nix {}
或者在您的情况下只是 callPackage
因为您已经在本来可以称为 pkgs
(let pkgs = import <nixpkgs> {}; in
).[=22= 的内容上使用了 with
关键字]
我通常建议避免使用 with
关键字,因为它不必要地使 Nix 的作用域规则复杂化,并且它会使我们这些大脑中没有 Nix 求值器的人更难找到绑定。