如何在 NixOS 上构建 Swift 项目?
How to build Swift project on NixOS?
我正在尝试在 NixOS 上构建一个简单的 Swift 项目。以下是重现步骤:
git clone https://github.com/PerfectlySoft/PerfectTemplate.git
cd PerfectTemplate
touch shell.nix
添加 shell.nix
内容如下:
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "swift-env";
buildInputs = [
openssl
stdenv
binutils
cmake
pkgconfig
curl
glibc
icu
libblocksruntime
libbsd
libedit
libuuid
libxml2
ncurses
sqlite
swig
];
}
运行 nix-shell --pure shell.nix
然后 swift build
, 给我:
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-target’
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fmodule-name=PerfectCZlib’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fmodules-cache-path=/home/dmi3y/Dev/Swift/PerfectTemplate/.build/x86_64-unknown-linux/debug/ModuleCache’
gcc: error: unrecognized command line option ‘-fblocks’
我很感激任何帮助,因为我对 nix-shell 和 NixOS 还很陌生。
编辑:
我将 shell.nix
更改为:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "swift-env";
buildInputs = with pkgs; [
openssl
clang
swift
];
shellHook = ''
CC=clang
'';
}
但是,当我 运行 nix-shell
后跟 swift build
时,我现在得到:
[1/25] Compiling PerfectCZlib zutil.c
[2/25] Compiling PerfectCZlib uncompr.c
[3/25] Compiling PerfectCZlib inftrees.c
[4/25] Compiling PerfectCZlib inflate.c
[5/25] Compiling PerfectCZlib trees.c
[6/25] Compiling PerfectCZlib inffast.c
[7/25] Compiling PerfectCZlib infback.c
[8/25] Compiling PerfectCZlib gzwrite.c
/nix/store/iz6k7x3l14ykr56crz3dizas1rrkcyzr-clang-wrapper-7.1.0/resource-root/include/module.modulemap:24:8: error: redefinition of module '_Builtin_intrinsics'
# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
^
1 warning and 3 errors generated.
1 warning and 3 errors generated.
可以找到完整的日志 here。
这现在看起来像是缺少库依赖项或版本冲突。
郑重声明,以下是关于我的设置的更多信息,可能会更清楚:
$ nix-channel --list
home-manager https://github.com/rycee/home-manager/archive/master.tar.gz
nixos https://nixos.org/channels/nixos-19.09
$ nix-shell --run 'swift -version'
Swift version 5.0.2 (swift-5.0.2-RELEASE)
Target: x86_64-unknown-linux-gnub
在网上搜索后,我发现了 Swift 编译器和这个 specific comment 的 Jira 问题。我决定从依赖项中排除 clang
,只包含 swift
,因为这个组合似乎是冲突的:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "swift-env";
buildInputs = with pkgs; [
openssl
swift
];
shellHook = ''
CC=clang
'';
}
成功了!我终于能够构建项目了!
自从您使用 --pure
选项后,您之前环境中的任何内容都不会导入到 shell 中。这包括 swift
二进制文件本身。所以首先我会添加 swift
到 buildInputs
.
您收到的错误表明 gcc
甚至不理解传递的命令行选项。我对 Swift 一无所知,但在看到之后我认为它需要一个不同的编译器。果然,快速搜索后它看起来是基于 llvm 的。因此,您还需要将 clang
添加到构建输入中。此外,您需要使用 mkShell
而不是 mkDerivation
来设置适当的环境。
前者是后者的包装器,专门用于设置 nix-shell,并确保正确处理环境。您需要传入 shellHook
属性以使用 CC
envvar 将默认的 c 编译器覆盖为 clang
。 shellHook
是在 shell.
开头的 运行 任意命令的一种方式
最后一点,nix-shell
命令默认搜索 shell.nix
,因此您不必将其作为参数传递。如果 shell.nix
不存在,那么它将尝试 default.nix
。如果两者都不存在,则您必须明确指定 nix 表达式位置。
TLDR
将它们放在一起:
# a more idiomatic way to import nixpkgs, overridable from the cmdline
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "swift-env";
buildInputs = with pkgs; [
# your other inputs
clang
swift
];
shellHook = ''
CC=clang
'';
}
为了确保我的逻辑是正确的,我下载了 repo 并放手了。一切都编译并成功运行。
我正在尝试在 NixOS 上构建一个简单的 Swift 项目。以下是重现步骤:
git clone https://github.com/PerfectlySoft/PerfectTemplate.git
cd PerfectTemplate
touch shell.nix
添加 shell.nix
内容如下:
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "swift-env";
buildInputs = [
openssl
stdenv
binutils
cmake
pkgconfig
curl
glibc
icu
libblocksruntime
libbsd
libedit
libuuid
libxml2
ncurses
sqlite
swig
];
}
运行 nix-shell --pure shell.nix
然后 swift build
, 给我:
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-target’
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fmodule-name=PerfectCZlib’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fmodules-cache-path=/home/dmi3y/Dev/Swift/PerfectTemplate/.build/x86_64-unknown-linux/debug/ModuleCache’
gcc: error: unrecognized command line option ‘-fblocks’
我很感激任何帮助,因为我对 nix-shell 和 NixOS 还很陌生。
编辑:
我将 shell.nix
更改为:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "swift-env";
buildInputs = with pkgs; [
openssl
clang
swift
];
shellHook = ''
CC=clang
'';
}
但是,当我 运行 nix-shell
后跟 swift build
时,我现在得到:
[1/25] Compiling PerfectCZlib zutil.c
[2/25] Compiling PerfectCZlib uncompr.c
[3/25] Compiling PerfectCZlib inftrees.c
[4/25] Compiling PerfectCZlib inflate.c
[5/25] Compiling PerfectCZlib trees.c
[6/25] Compiling PerfectCZlib inffast.c
[7/25] Compiling PerfectCZlib infback.c
[8/25] Compiling PerfectCZlib gzwrite.c
/nix/store/iz6k7x3l14ykr56crz3dizas1rrkcyzr-clang-wrapper-7.1.0/resource-root/include/module.modulemap:24:8: error: redefinition of module '_Builtin_intrinsics'
# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
^
1 warning and 3 errors generated.
1 warning and 3 errors generated.
可以找到完整的日志 here。
这现在看起来像是缺少库依赖项或版本冲突。
郑重声明,以下是关于我的设置的更多信息,可能会更清楚:
$ nix-channel --list
home-manager https://github.com/rycee/home-manager/archive/master.tar.gz
nixos https://nixos.org/channels/nixos-19.09
$ nix-shell --run 'swift -version'
Swift version 5.0.2 (swift-5.0.2-RELEASE)
Target: x86_64-unknown-linux-gnub
在网上搜索后,我发现了 Swift 编译器和这个 specific comment 的 Jira 问题。我决定从依赖项中排除 clang
,只包含 swift
,因为这个组合似乎是冲突的:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "swift-env";
buildInputs = with pkgs; [
openssl
swift
];
shellHook = ''
CC=clang
'';
}
成功了!我终于能够构建项目了!
自从您使用 --pure
选项后,您之前环境中的任何内容都不会导入到 shell 中。这包括 swift
二进制文件本身。所以首先我会添加 swift
到 buildInputs
.
您收到的错误表明 gcc
甚至不理解传递的命令行选项。我对 Swift 一无所知,但在看到之后我认为它需要一个不同的编译器。果然,快速搜索后它看起来是基于 llvm 的。因此,您还需要将 clang
添加到构建输入中。此外,您需要使用 mkShell
而不是 mkDerivation
来设置适当的环境。
前者是后者的包装器,专门用于设置 nix-shell,并确保正确处理环境。您需要传入 shellHook
属性以使用 CC
envvar 将默认的 c 编译器覆盖为 clang
。 shellHook
是在 shell.
最后一点,nix-shell
命令默认搜索 shell.nix
,因此您不必将其作为参数传递。如果 shell.nix
不存在,那么它将尝试 default.nix
。如果两者都不存在,则您必须明确指定 nix 表达式位置。
TLDR
将它们放在一起:
# a more idiomatic way to import nixpkgs, overridable from the cmdline
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "swift-env";
buildInputs = with pkgs; [
# your other inputs
clang
swift
];
shellHook = ''
CC=clang
'';
}
为了确保我的逻辑是正确的,我下载了 repo 并放手了。一切都编译并成功运行。