Nix 和 GCC - “找不到 crt1.o”

Reb*_*ebs 5 gcc nix

我在 Ubuntu 18.x 的 WSL 上运行 Nix。

我安装了 GCC,其中$ nix-env -i gcc安装了gcc-7.3.0.

我正在尝试使用 GCC 编译一个简单的 CPP 文件(由 Ferret 生成)。但 GCC 出现以下错误:

$ g++ -std=c++11 -x c++ test_1.cpp -o test_1
/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

似乎我期望 Nix 包含常见的依赖项以及 GCC(build-essential等效项),但我认为这不是真的。

使用 Nix ( nix-env -qaP 'gcc', nix-env -qaP --description | grep -i gcc) 进行搜索并没有提供太多帮助。

其他帖子提到安装gcc-multilib(apt 包)。Nix 中唯一提到的是测试包:

$ nix-env -qaP --description | grep -i multilib
nixpkgs.tests.cc-multilib-gcc                                            cc-multilib-test                               
nixpkgs.tests.cc-multilib-clang                                          cc-multilib-test
Run Code Online (Sandbox Code Playgroud)

我不知道如何让构建环境正常工作。我找不到任何关于我需要启动哪些软件包的文档。这是非常简单的事情。

Emm*_*osa 2

简而言之,Nix 的做法有所不同。使用 Nix 时,您不需要像大多数发行版那样安装工具和库,而是创建一个“Nix 表达式”,它声明您的构建依赖项和编译程序的说明。例如,假设您有一个hello.cc源代码:

#include <iostream>
using namespace std;

int main() 
{
    cout << "Hello, World!";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

要使用 Nix 编译它,您可以使用default.nix如下文件(在同一目录中):

let
    pkgs = (import <nixpkgs>) {};
    gcc = pkgs.gcc;
    stdenv = pkgs.stdenv;
in
    stdenv.mkDerivation {
        name = "hello";
        version = "1.0.0";
        src = ./.;
        phases = [ "unpackPhase" "buildPhase" "installPhase" ];

        buildPhase = ''
            ${gcc}/bin/g++ -std=c++11 -x c++ hello.cc -o hello
        '';

        installPhase = ''
            mkdir -p $out/bin
            cp hello $out/bin
        '';
    }
Run Code Online (Sandbox Code Playgroud)

...你可以像这样构建:nix build

您最终会得到一个./result指向$out上面使用的目录的符号链接。上面installPhase将二进制文件复制到$out/bin,因此可以通过运行来执行程序./result/bin/hello

Nix 语言在其文档中进行了描述,您可以从 Nixpkgs文档中获取如何使用它来构建内容的概述。

  • 这似乎不对。我只是使用 nix 包管理器。我并不追求完整的操作系统/构建系统抽象。我有足够的工具来学习。我正在寻找一些东西来减少我的工作量,而不是增加工作量。肯定只是缺少一些我需要与 GCC 一起安装的软件包吗? (5认同)
  • @EmmanuelRosa 真的没有办法做到这一点吗?我认为 `nix-env -i packagename` 的目的是将此类依赖项放入 `~/.nix-profile/bin`、`~/.nix-profile/lib` 等中,以便可以看到它们并用过的。即使我完全接受 Nix 的抽象,我仍然需要能够以传统方式使用这些工具,例如下载和编译不附带“default.nix”的 C++ 项目。 (4认同)