ritter
ritter

Reputation: 7699

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

I am trying to build LLVM 3.8 (just basic LLVM not Clang, etc) with the 2016 Intel C++ compiler icpc (ICC) 16.0.2 20160204. The build host runs Red Hat Linux.

First thing I ran into were not up-to-date C++11 headers for the Intel compiler. This could be resolved by using the GCC 4.8.5 C++ headers. (Mind that Intel compilers are designed to work with the GCC toolchain.)

Now, some progress into the build [12% or so] it comes to building and linking the tblgen executable. This tool and its execution is required during the further build. Unfortunately linking this tool fails:

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*)'

The linker command leading to this is (I added newlines for better readability. It's one command really)

/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"

I don't have the value of the $ORIGIN variable right now. Not sure how to get this out. (The command was printed when calling make VERBOSE=1).

What the -cxxlib=/opt/crtdc/gcc/4.8.5-4/ flag does is have icpc query GCC for the location of the C++ header files and use them.

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.

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.

I then looked into the CodeGenRegisters.cpp file and extracted all uses of std::swap into separate, small, stand-alone examples to see if I can reproduce this linker error. No, all linking went well for the small examples. (..and I used the GCC headers for this to make the case realistic).

I was hoping to get some input here..

Upvotes: 0

Views: 7112

Answers (1)

Jonathan Wakely
Jonathan Wakely

Reputation: 171303

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

$ORIGIN is not a variable, it's a special token that can be included in DT_RPATH tags to tell the dynamic linker to start searching for shared libraries from the location of the binary that requires them. That's why it is escaped as "\$ORIGIN" to prevent the shell treating it as a shell variable. You can ignore that for now, because it's only matters at run-time, and your error is at link-time.

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.

Right. Those symbols are in the libstdc++.so (and libstdc++.a) library.

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.

It's not enough to tell it where the libraries are, you need to tell it to actually link to the relevant library. Try adding -lstdc++

Upvotes: 1

Related Questions