对 std::__detail::_List_node_base::swap 的未定义引用

undefined reference to std::__detail::_List_node_base::swap

我正在尝试使用 2016 Intel C++ 编译器 icpc (ICC) 16.0.2 20160204 构建 LLVM 3.8(只是基本的 LLVM 而不是 Clang 等)。构建主机运行 Red Hat Linux.

我 运行 进入的第一件事不是 up-to-date C++11 header 英特尔编译器。这可以通过使用 GCC 4.8.5 C++ headers 来解决。 (请注意,英特尔编译器旨在与 GCC 工具链配合使用。)

现在,构建 [12% 左右] 在构建和链接 tblgen 可执行文件方面取得了一些进展。在进一步构建期间需要此工具及其执行。很遗憾,链接此工具失败:

CMakeFiles/obj.llvm-tblgen.dir/CodeGenRegisters.cpp.o: In function `std::list<llvm::CodeGenRegisterClass, std::allocator<llvm::CodeGenRegisterClass> >::swap(std::list<llvm::CodeGenRegisterClass, std::allocator<llvm::CodeGenRegisterClass> >&)':
/opt/crtdc/gcc/4.8.5-4/include/c++/4.8.5/bits/stl_list.h:1212: undefined reference to `std::__detail::_List_node_base::swap(std::__detail::_List_node_base&, std::__detail::_List_node_base&)'
CMakeFiles/obj.llvm-tblgen.dir/CodeGenRegisters.cpp.o: In function `std::list<llvm::CodeGenRegisterClass, std::allocator<llvm::CodeGenRegisterClass> >::_M_transfer(std::_List_iterator<llvm::CodeGenRegisterClass>, std::_List_iterator<llvm::CodeGenRegisterClass>, std::_List_iterator<llvm::CodeGenRegisterClass>)':
/opt/crtdc/gcc/4.8.5-4/include/c++/4.8.5/bits/stl_list.h:1546: undefined reference to `std::__detail::_List_node_base::_M_transfer(std::__detail::_List_node_base*, std::__detail::_List_node_base*)'
CMakeFiles/obj.llvm-tblgen.dir/CodeGenRegisters.cpp.o: In function `void std::list<llvm::CodeGenRegisterClass, std::allocator<llvm::CodeGenRegisterClass> >::_M_insert<llvm::CodeGenRegBank&, llvm::Record*&>(std::_List_iterator<llvm::CodeGenRegisterClass>, llvm::CodeGenRegBank&&&, llvm::Record*&&&)':
/opt/crtdc/gcc/4.8.5-4/include/c++/4.8.5/bits/stl_list.h:1562: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'
CMakeFiles/obj.llvm-tblgen.dir/CodeGenRegisters.cpp.o: In function `void std::list<llvm::CodeGenRegisterClass, std::allocator<llvm::CodeGenRegisterClass> >::_M_insert<llvm::CodeGenRegBank&, llvm::StringRef&, llvm::CodeGenRegisterClass::Key&>(std::_List_iterator<llvm::CodeGenRegisterClass>, llvm::CodeGenRegBank&&&, llvm::StringRef&&&, llvm::CodeGenRegisterClass::Key&&&)':
/opt/crtdc/gcc/4.8.5-4/include/c++/4.8.5/bits/stl_list.h:1562: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

导致这个的链接器命令是(为了更好的可读性我添加了换行符。这真的是一个命令)

/opt/intel/compiler/2016u2/compilers_and_libraries_2016.2.181/linux/bin/intel64/icpc   

-cxxlib=/opt/crtdc/gcc/4.8.5-4/

-std=c++11 
-fPIC 
-fvisibility-inlines-hidden 
-g    
-Wl,-allow-shlib-undefined 

CMakeFiles/obj.llvm-tblgen.dir/AsmMatcherEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/AsmWriterEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/AsmWriterInst.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/Attributes.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/CallingConvEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/CodeEmitterGen.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/CodeGenDAGPatterns.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/CodeGenInstruction.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/CodeGenMapTable.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/CodeGenRegisters.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/CodeGenSchedule.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/CodeGenTarget.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/DAGISelEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/DAGISelMatcherEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/DAGISelMatcherGen.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/DAGISelMatcherOpt.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/DAGISelMatcher.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/DFAPacketizerEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/DisassemblerEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/FastISelEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/FixedLenDecoderEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/InstrInfoEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/IntrinsicEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/OptParserEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/PseudoLoweringEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/RegisterInfoEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/SubtargetEmitter.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/TableGen.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/X86DisassemblerTables.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/X86ModRMFilters.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/X86RecognizableInstr.cpp.o 
CMakeFiles/obj.llvm-tblgen.dir/CTagsEmitter.cpp.o  

-o ../../bin/llvm-tblgen  

-L/usr/lib/gcc/x86_64-redhat-linux/4.4.7  
../../lib/libLLVMSupport.a 
../../lib/libLLVMTableGen.a 
../../lib/libLLVMSupport.a 
-lrt 
-ldl 
-ltinfo 
-lpthread 
-lz 
-lm 

-Wl,-rpath,"$ORIGIN/../lib"

我现在没有 $ORIGIN 变量的值。不知道如何解决这个问题。 (该命令是在调用 make VERBOSE=1 时打印的)。

-cxxlib=/opt/crtdc/gcc/4.8.5-4/ 标志的作用是让 icpc 向 GCC 查询 C++ header 文件的位置并使用它们。

链接器错误消息告诉我(我可能是错的)找到并使用了 GCC C++ headers 文件,但不知何故找不到库的编译部分。

我试图通过将上面的 -L 标志替换为 -L/opt/crtdc/gcc/4.8.5-4/lib64/ 来显式地将编译器推送到 GCC 库中。没用;同样的错误。

然后我查看了 CodeGenRegisters.cpp 文件并将 std::swap 的所有使用提取到单独的小 stand-alone 示例中,看看我是否可以重现此链接器错误。不,对于小示例,所有链接都进行得很顺利。 (..我为此使用了 GCC headers 来使案例变得真实)。

我希望在这里得到一些意见..

I don't have the value of the $ORIGIN variable right now. Not sure how to get this out.

$ORIGIN 不是一个变量,它是一个特殊的标记,可以包含在 DT_RPATH 标签中,告诉动态 linker 从以下位置开始搜索共享库需要它们的二进制文件。这就是为什么它被转义为 "$ORIGIN" 以防止 shell 将其视为 shell 变量。你现在可以忽略它,因为它只在 运行 时间很重要,而你的错误是在 link 时间。

The linker error message says to me (I can be wrong) that the GCC C++ headers files were found and used, but somehow the compiled part of the library was not found.

没错。这些符号在 libstdc++.so(和 libstdc++.a)库中。

I tried to explicitly push the compiler into the GCC library by replacing the above -L flag with -L/opt/crtdc/gcc/4.8.5-4/lib64/. Didn't work; same error.

仅仅告诉它库在哪里是不够的,你需要告诉它实际上 link 到相关的库。尝试添加 -lstdc++