【问题标题】:How to build Swift project on NixOS?如何在 NixOS 上构建 Swift 项目?
【发布时间】:2020-02-08 09:33:40
【问题描述】:

我正在尝试在 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 编译器的 Jira 问题和这个 specific comment。我决定从依赖项中排除clang,只包括swift,因为这种组合似乎有冲突:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  name = "swift-env";

  buildInputs = with pkgs; [
    openssl
    swift
  ];

  shellHook = ''
    CC=clang
  '';
}

这很有效!我终于能够构建项目了!

【问题讨论】:

    标签: swift gcc nixos


    【解决方案1】:

    由于您使用了--pure 选项,您之前的环境中的任何内容都不会被导入到shell 中。这包括 swift 二进制文件本身。所以首先我将swift 添加到buildInputs

    您得到的错误表明gcc 甚至不理解正在传递的命令行选项。我对 Swift 一无所知,但在看到之后我认为它需要一个不同的编译器。果然,经过快速搜索,它看起来像是基于 llvm 的。因此,您还需要将clang 添加到您的构建输入中。此外,您需要使用mkShell 而不是mkDerivation 来设置正确的环境。

    前者是后者的包装器,专门设计用于设置 nix-shell,并确保正确处理环境。您需要传入shellHook 属性以使用CC envvar 将默认c 编译器覆盖为clangshellHook 是一种在 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 并放弃了它。一切都编译并运行成功。

    【讨论】:

    • 感谢您的回答和详尽的解释!我根据您的建议更新了我的问题,但仍然出现编译错误。我想知道它是如何为您工作的,以及您是否包含了我没有的任何其他库?不过我会继续努力的。再次感谢您的回答!
    • 在我成功的构建中,我包含了您原始帖子中的所有buildInputs。看起来你把它修剪到只有 3。也许你修剪得太多了。首先尝试使用完整列表,然后尝试逐个删除条目以将其缩减到最低限度。
    猜你喜欢
    • 2017-11-07
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 2013-03-11
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    相关资源
    最近更新 更多