这与配置错误有关,但这是一台全新的计算机,完全通过miniconda/conda-forge安装,所以它应该可以工作。
我的miniconda配置非常简单:conda-forge
是除默认(~/.condarc
)之外的唯一通道:
changeps1: false
channels:
- conda-forge
- defaults
它是最新的(conda update --all
)。
GNU C、c++和Fortran编译器已通过5.0后编译器环境安装。以下是conda list linux
的列表:
# packages in environment at /home/jpivarski/miniconda3:
#
# Name Version Build Channel
binutils_impl_linux-64 2.36.1 h193b22a_2 conda-forge
binutils_linux-64 2.36 hf3e587d_33 conda-forge
gcc_impl_linux-64 9.3.0 h6df7d76_17
gcc_linux-64 9.3.0 hf25ea35_33 conda-forge
gfortran_impl_linux-64 9.3.0 hc4a2995_19 conda-forge
gfortran_linux-64 9.3.0 hdc58fab_33 conda-forge
gxx_impl_linux-64 9.3.0 hbdd7822_17
gxx_linux-64 9.3.0 h3fbe746_33 conda-forge
kernel-headers_linux-64 2.6.32 he073ed8_14 conda-forge
ld_impl_linux-64 2.36.1 hea4e1c9_2 conda-forge
libgcc-devel_linux-64 9.3.0 hb95220a_17
libstdcxx-devel_linux-64 9.3.0 hf0c5c8d_17
sysroot_linux-64 2.12 he073ed8_14 conda-forge
andconda list compiler
:
# packages in environment at /home/jpivarski/miniconda3:
#
# Name Version Build Channel
c-compiler 1.2.0 h7f98852_0 conda-forge
compilers 1.2.0 ha770c72_0 conda-forge
cxx-compiler 1.2.0 h4bd325d_0 conda-forge
fortran-compiler 1.2.0 h1990efc_0 conda-forge
andconda list binutil
:
# packages in environment at /home/jpivarski/miniconda3:
#
# Name Version Build Channel
binutils 2.36.1 hdd6e379_2 conda-forge
binutils_impl_linux-64 2.36.1 h193b22a_2 conda-forge
binutils_linux-64 2.36 hf3e587d_33 conda-forge
这是一个Debian系统,它安装了一个名为gcc-8-base
的包,
gcc-8-base/stable,now 8.3.0-6 amd64 [installed]
但是那个包没有在路径中添加gcc
命令,所以它不是用户可见的。这个Debian在Chromebook (/proc/version
)上的Crostini VM中:
Linux version 5.4.119-14943-gff839c7fedcc (chrome-bot@chromeos-ci-legacy-us-east1-d-x32-83-pa8b) (Chromium OS 12.0_pre422132_p20210405-r4 clang version 13.0.0 (/var/tmp/portage/sys-devel/llvm-12.0_pre422132_p20210405-r4/work/llvm-12.0_pre422132_p20210405/clang cd442157cff4aad209ae532cbf031abbe10bc1df)) #1 SMP PREEMPT Wed Jul 28 21:06:01 PDT 2021
现在,有趣的部分。下面是最简单的c++程序:
// #include <iostream>
int main(int argc, char** argv) {
int x = 2 + 4;
// std::cout << "hello world" << std::endl;
return 0;
}
(是的,我注释掉了"hello world"当它不起作用时
用下列任意选项编译它:
g++ tmp.cpp
g++ -std=c++11 tmp.cpp
g++ -std=c++11 -lstdc++ tmp.cpp
收益率
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: /home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/lib/../lib/libstdc++.so: undefined reference to `aligned_alloc@GLIBC_2.16'
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: /home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/lib/../lib/libstdc++.so: undefined reference to `clock_gettime@GLIBC_2.17'
collect2: error: ld returned 1 exit status
顺便说一下,ldd /that/long/path/to/libstdc++.so
:
./../../x86_64-conda-linux-gnu/lib/../lib/libstdc++.so
linux-vdso.so.1 (0x00007ffd2e8d1000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ef64da8e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ef64d8cd000)
/lib64/ld-linux-x86-64.so.2 (0x00007ef64dd92000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ef64d8b3000)
nothing is "not found.
我可以使用gcc
:
gcc -std=c++11 tmp.cpp
但是如果我把#include <iostream>
和std::cout
放回去,编译器错误是:
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: /tmp/cc8BE1Tc.o: warning: relocation against `_ZSt4cout' in read-only section `.text'
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: /tmp/cc8BE1Tc.o: in function `main':
tmp.cpp:(.text+0x20): undefined reference to `std::cout'
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: tmp.cpp:(.text+0x25): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: tmp.cpp:(.text+0x2f): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: tmp.cpp:(.text+0x3a): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: /tmp/cc8BE1Tc.o: in function `__static_initialization_and_destruction_0(int, int)':
tmp.cpp:(.text+0x6a): undefined reference to `std::ios_base::Init::Init()'
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: tmp.cpp:(.text+0x7f): undefined reference to `std::ios_base::Init::~Init()'
/home/jpivarski/miniconda3/bin/../lib/gcc/x86_64-conda-linux-gnu/9.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
它怎么可能被如此错误地配置,如何修复它?这是一个新安装。还没发生什么奇怪的事。如果这应该是一个bug报告给conda-forge,我不知道在哪里发布。
答案:我重新安装了它,这次它可以工作了。
由于我不能同时尝试这两个(这是在一个磁盘空间有限的Chromebook上,所以这不是一个选项),我只能根据这次的不同来推测原因:
- 我安装了所有的低级
gcc_linux-64
,gxx_linux-64
等和高级compilers
,c-compiler
,cxx-compiler
在一个单一的"conda install
";命令,而不是单独的命令。 - 我将
channel_priority: strict
添加到我的~/.condarc
配置中。
我没有使用高级compilers
包(并让它拉入gcc_linux-64
,gxx_linux-64
等作为依赖项)的唯一原因是因为我不知道它。在我的第一次安装尝试中,我安装了gcc_linux-64
和gxx_linux-64
,它们被添加为可执行文件,可以通过CC
和CXX
环境变量访问,但不像gcc
和g++
那样放在路径上。然后,当我意识到compilers
包是面向用户的gcc
和g++
(通过c-compiler
和cxx-compiler
)时,我随后安装了它。可能在这些包之间的依赖关系中有一个错误的假设,因为conda install
应该使所有这些包彼此一致(特别是在conda update --all
之后)。这是猜测#1。
第二次尝试也是不同的,因为我添加了channel_priority: strict
,按照我在conda-forge上找到的说明。显然,严格优先级的主张是如此强烈,以至于它将成为conda 5.0的默认设置。也许我的第一次尝试混合了conda-forge和default ?(如果是这样的话,我不知道为什么我以前从来没有遇到过这个问题——严格的优先级对我来说是新的,尽管我只使用过两个通道。)这是猜测2,我比猜测1更相信它。
为了完整起见,我还用mamba做了第二次尝试,而不是conda(有限的CPU功率;我没有时间等),尽管我不相信这会有什么不同。如果是这样,那对康达和曼巴来说都是个坏消息。
我把这对问答留给子孙后代,以防其他人遇到类似的问题。(如果你这样做,你可能能够添加数据来解决上面的歧义。)