如何从 nix-shell 使用的 nix 表达式中的 nixpkgs 推导中获取名称?
How to get the name from a nixpkgs derivation in a nix expression to be used by nix-shell?
我正在编写一个主要供 nix-shell
使用的 .nix 表达式。我不知道该怎么做。请注意,这不是在 NixOS 上,但我认为这不是很相关。
我正在查看的特定示例是我想要 this version-dependent name 看起来像:
idea-ultimate = buildIdea rec {
name = "idea-ultimate-${version}";
version = "2017.2.2"; /* updated by script */
description = "Integrated Development Environment (IDE) by Jetbrains, requires paid license";
license = stdenv.lib.licenses.unfree;
src = fetchurl {
url = "https://download.jetbrains.com/idea/ideaIU-${version}-no-jdk.tar.gz";
sha256 = "b8eb9d612800cc896eb6b6fbefbf9f49d92d2350ae1c3c4598e5e12bf93be401"; /* updated by script */
};
wmClass = "jetbrains-idea";
update-channel = "IDEA_Release";
};
我的 nix 表达式如下:
let
pkgs = import <nixpkgs> {};
stdenv = pkgs.stdenv;
# idea_name = assert pkgs.jetbrains.idea-ultimate.name != ""; pkgs.jetbrains.idea-ultimate.name;
in rec {
scalaEnv = stdenv.mkDerivation rec {
name = "scala-env";
builder = "./scala-build.sh";
shellHook = ''
alias cls=clear
'';
CLANG_PATH = pkgs.clang + "/bin/clang";
CLANGPP_PATH = pkgs.clang + "/bin/clang++";
# A bug in the nixpkgs openjdk (#29151) makes us resort to Zulu OpenJDK for IDEA:
# IDEA_JDK = pkgs.openjdk + "/lib/openjdk";
# PATH = "${pkgs.jetbrains.idea-ultimate}/${idea_name}/bin:$PATH";
IDEA_JDK = /usr/lib/jvm/zulu-8-amd64;
# IDEA_JDK = /opt/zulu8.23.0.3-jdk8.0.144-linux_x64;
# IDEA_JDK = /usr/lib/jvm/java-8-openjdk-amd64;
buildInputs = with pkgs; [
ammonite
boehmgc
clang
emacs
jetbrains.idea-ultimate
less
libunwind
openjdk
re2
sbt
stdenv
unzip
zlib
];
};
}
我已经注释掉设置 PATH
,因为它取决于在 let
子句中获得 idea_name
。作为一个有趣的旁注,如果我不加注释,这不会失败,但在执行 nix-shell
时会导致一个非常奇怪的错误,关于无法执行 bash
。我还尝试了 let
idea_name = pkgs.jetbrains.idea-ultimate.name;
的更简单的情况,但是稍后当 idea_name
用于设置 PATH
时失败,因为 idea_name
最终未定义.
更新:
我开始探索nix-instantiate
,但是兴趣的推导似乎空洞:
[nix-shell:/nix/store]$ nix-instantiate --eval --xml -E "((import <nixpkgs> {}).callPackage ./3hk87pqgl2qdqmskxbhy23cyr24q8g6s-nixpkgs-18.03pre114739.d0d905668c/nixpkgs/pkgs/applications/editors/jetbrains { }).idea-ultimate";
<?xml version='1.0' encoding='utf-8'?>
<expr>
<derivation>
<repeated />
</derivation>
</expr>
如果您的目的是让 idea-ultimate
进入 nix-shell 环境,那么只需将该包包含到 buildInputs
。我看到它已经包含在内,因此它应该已经存在于您的 PATH
.
中
顺便说一句,您可以扩展 shellHook
并导出 PATH 和其他变量,而不是从那里导出完整的 bash。你为什么要从 bash 开始?少抄袭。当您指定
IDEA_JDK = /usr/lib/jvm/zulu-8-amd64;
在 Nix 中,文件 /usr/lib/jvm/zulu-8-amd64 被复制到 nix 存储并且 IDEA_JDK
被设置为指向 /nix/store
中的文件。那是你的意图吗?
关于 nix-instantiate:
$ nix-instantiate --eval -E 'with import <nixpkgs>{}; idea.pycharm-community.outPath'
"/nix/store/71jk0spr30rm4wsihjwbb1hcwwvzqr4k-pycharm-community-2017.1"
但您仍然需要删除双引号 (https://gist.github.com/danbst/a9fc068ff26e31d88de9709965daa2bd)
此外,吹毛求疵,assert pkgs.jetbrains.idea-ultimate.name != "";
可以删除,因为在 Nix 中不可能有空派生名称。
还有一个吹毛求疵的问题。您很快就会发现每次都从 shell 启动 IDE 非常不方便。指定某些包用于开发似乎是个好主意,但 nix-shell
不适用于非 cli 应用程序。更不用说 Nix GC 和 nix-shell
偶尔出现的问题。你最好安装 IDE 全局或每个用户,这是更好的长期解决方案。
[附录]
您正在寻找这个 (dev-environment.nix
):
with import <nixpkgs> { };
buildEnv {
name = "my-super-dev-env";
paths = [
#emacs
nano
idea.pycharm-community
];
buildInputs = [ makeWrapper ];
postBuild = ''
for f in $(ls -d $out/bin/*); do
wrapProgram $f \
--set IDEA_JDK "/path/to/zulu-jdk" \
--set CLANG_PATH ... \
--set CLANCPP_PATH ...
done
'';
}
您使用 nix-env -if ./dev-environment.nix
安装。它会用这些环境变量包装你的程序,而不会污染你的工作空间(如果你愿意,你可以使用 nix-shell
和 shell 钩子进一步污染它)。
我正在编写一个主要供 nix-shell
使用的 .nix 表达式。我不知道该怎么做。请注意,这不是在 NixOS 上,但我认为这不是很相关。
我正在查看的特定示例是我想要 this version-dependent name 看起来像:
idea-ultimate = buildIdea rec {
name = "idea-ultimate-${version}";
version = "2017.2.2"; /* updated by script */
description = "Integrated Development Environment (IDE) by Jetbrains, requires paid license";
license = stdenv.lib.licenses.unfree;
src = fetchurl {
url = "https://download.jetbrains.com/idea/ideaIU-${version}-no-jdk.tar.gz";
sha256 = "b8eb9d612800cc896eb6b6fbefbf9f49d92d2350ae1c3c4598e5e12bf93be401"; /* updated by script */
};
wmClass = "jetbrains-idea";
update-channel = "IDEA_Release";
};
我的 nix 表达式如下:
let
pkgs = import <nixpkgs> {};
stdenv = pkgs.stdenv;
# idea_name = assert pkgs.jetbrains.idea-ultimate.name != ""; pkgs.jetbrains.idea-ultimate.name;
in rec {
scalaEnv = stdenv.mkDerivation rec {
name = "scala-env";
builder = "./scala-build.sh";
shellHook = ''
alias cls=clear
'';
CLANG_PATH = pkgs.clang + "/bin/clang";
CLANGPP_PATH = pkgs.clang + "/bin/clang++";
# A bug in the nixpkgs openjdk (#29151) makes us resort to Zulu OpenJDK for IDEA:
# IDEA_JDK = pkgs.openjdk + "/lib/openjdk";
# PATH = "${pkgs.jetbrains.idea-ultimate}/${idea_name}/bin:$PATH";
IDEA_JDK = /usr/lib/jvm/zulu-8-amd64;
# IDEA_JDK = /opt/zulu8.23.0.3-jdk8.0.144-linux_x64;
# IDEA_JDK = /usr/lib/jvm/java-8-openjdk-amd64;
buildInputs = with pkgs; [
ammonite
boehmgc
clang
emacs
jetbrains.idea-ultimate
less
libunwind
openjdk
re2
sbt
stdenv
unzip
zlib
];
};
}
我已经注释掉设置 PATH
,因为它取决于在 let
子句中获得 idea_name
。作为一个有趣的旁注,如果我不加注释,这不会失败,但在执行 nix-shell
时会导致一个非常奇怪的错误,关于无法执行 bash
。我还尝试了 let
idea_name = pkgs.jetbrains.idea-ultimate.name;
的更简单的情况,但是稍后当 idea_name
用于设置 PATH
时失败,因为 idea_name
最终未定义.
更新:
我开始探索nix-instantiate
,但是兴趣的推导似乎空洞:
[nix-shell:/nix/store]$ nix-instantiate --eval --xml -E "((import <nixpkgs> {}).callPackage ./3hk87pqgl2qdqmskxbhy23cyr24q8g6s-nixpkgs-18.03pre114739.d0d905668c/nixpkgs/pkgs/applications/editors/jetbrains { }).idea-ultimate";
<?xml version='1.0' encoding='utf-8'?>
<expr>
<derivation>
<repeated />
</derivation>
</expr>
如果您的目的是让 idea-ultimate
进入 nix-shell 环境,那么只需将该包包含到 buildInputs
。我看到它已经包含在内,因此它应该已经存在于您的 PATH
.
顺便说一句,您可以扩展 shellHook
并导出 PATH 和其他变量,而不是从那里导出完整的 bash。你为什么要从 bash 开始?少抄袭。当您指定
IDEA_JDK = /usr/lib/jvm/zulu-8-amd64;
在 Nix 中,文件 /usr/lib/jvm/zulu-8-amd64 被复制到 nix 存储并且 IDEA_JDK
被设置为指向 /nix/store
中的文件。那是你的意图吗?
关于 nix-instantiate:
$ nix-instantiate --eval -E 'with import <nixpkgs>{}; idea.pycharm-community.outPath'
"/nix/store/71jk0spr30rm4wsihjwbb1hcwwvzqr4k-pycharm-community-2017.1"
但您仍然需要删除双引号 (https://gist.github.com/danbst/a9fc068ff26e31d88de9709965daa2bd)
此外,吹毛求疵,assert pkgs.jetbrains.idea-ultimate.name != "";
可以删除,因为在 Nix 中不可能有空派生名称。
还有一个吹毛求疵的问题。您很快就会发现每次都从 shell 启动 IDE 非常不方便。指定某些包用于开发似乎是个好主意,但 nix-shell
不适用于非 cli 应用程序。更不用说 Nix GC 和 nix-shell
偶尔出现的问题。你最好安装 IDE 全局或每个用户,这是更好的长期解决方案。
[附录]
您正在寻找这个 (dev-environment.nix
):
with import <nixpkgs> { };
buildEnv {
name = "my-super-dev-env";
paths = [
#emacs
nano
idea.pycharm-community
];
buildInputs = [ makeWrapper ];
postBuild = ''
for f in $(ls -d $out/bin/*); do
wrapProgram $f \
--set IDEA_JDK "/path/to/zulu-jdk" \
--set CLANG_PATH ... \
--set CLANCPP_PATH ...
done
'';
}
您使用 nix-env -if ./dev-environment.nix
安装。它会用这些环境变量包装你的程序,而不会污染你的工作空间(如果你愿意,你可以使用 nix-shell
和 shell 钩子进一步污染它)。