woboq / moc-ng

A reimplementation of Qt's moc using libclang. Contains both a drop-in remplacement, and a plugin for the clang compiler.
https://woboq.com/blog/moc-with-clang.html
GNU General Public License v3.0
204 stars 23 forks source link

Link errors on Debian sid #6

Closed chrisburel closed 8 years ago

chrisburel commented 8 years ago

I'm using clang version 3.6.2, the binary download from clang's website, and Linux debian 4.2.0. I'm using the downloaded clang binary to do the build. I get the following error while linking:

[  5%] Linking CXX executable moc
cd /home/cburel/src/moc-ng/build/src && /usr/bin/cmake -E cmake_link_script CMakeFiles/moc.dir/link.txt --verbose=1
/home/cburel/apps/clang/bin/clang++      CMakeFiles/moc.dir/main.cpp.o CMakeFiles/moc.dir/mocng.cpp.o CMakeFiles/moc.dir/generator.cpp.o CMakeFiles/moc.dir/propertyparser.cpp.o CMakeFiles/moc.dir/mocppcallbacks.cpp.o CMakeFiles/moc.dir/mocastconsumer.cpp.o CMakeFiles/moc.dir/qbjs.cpp.o CMakeFiles/moc.dir/clangversionabstraction.cpp.o  -o moc -rdynamic -Wl,-Bstatic -lclangFrontend -lclangDriver -lclangCodeGen -lclangSema -lclangAnalysis -lclangRewrite -lclangAST -lclangParse -lclangLex -lclangBasic -lclangARCMigrate -lclangEdit -lclangFrontendTool -lclangRewrite -lclangSerialization -lclangTooling -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore -lclangStaticAnalyzerFrontend -lclangSema -Wl,-Bdynamic -lLLVMLTO -lLLVMObjCARCOpts -lLLVMLinker -lLLVMBitWriter -lLLVMIRReader -lLLVMAsmParser -lLLVMR600CodeGen -lLLVMipo -lLLVMVectorize -lLLVMR600AsmParser -lLLVMR600Desc -lLLVMR600Info -lLLVMR600AsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMHexagonDisassembler -lLLVMHexagonCodeGen -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMCppBackendCodeGen -lLLVMCppBackendInfo -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMPowerPCDisassembler -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMSparcDisassembler -lLLVMSparcCodeGen -lLLVMSparcAsmParser -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMSparcAsmPrinter -lLLVMTableGen -lLLVMDebugInfo -lLLVMOption -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMX86Desc -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMLineEditor -lLLVMInstrumentation -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMCodeGen -lLLVMScalarOpts -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMBitReader -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMMC -lLLVMCore -lLLVMSupport -L/home/cburel/apps/clang/lib -lpthread -ldl -lm -Wl,-Bstatic -lclangAnalysis -lclangRewrite -lclangAST -lclangParse -lclangLex -lclangBasic -lclangARCMigrate -lclangEdit -lclangFrontendTool -lclangSerialization -lclangTooling -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore -lclangStaticAnalyzerFrontend -Wl,-Bdynamic -lLLVMLTO -lLLVMObjCARCOpts -lLLVMLinker -lLLVMBitWriter -lLLVMIRReader -lLLVMAsmParser -lLLVMR600CodeGen -lLLVMipo -lLLVMVectorize -lLLVMR600AsmParser -lLLVMR600Desc -lLLVMR600Info -lLLVMR600AsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMHexagonDisassembler -lLLVMHexagonCodeGen -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMCppBackendCodeGen -lLLVMCppBackendInfo -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMPowerPCDisassembler -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMSparcDisassembler -lLLVMSparcCodeGen -lLLVMSparcAsmParser -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMSparcAsmPrinter -lLLVMTableGen -lLLVMDebugInfo -lLLVMOption -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMX86Desc -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMLineEditor -lLLVMInstrumentation -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMCodeGen -lLLVMScalarOpts -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMBitReader -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMMC -lLLVMCore -lLLVMSupport 
CMakeFiles/moc.dir/main.cpp.o: In function `main':
/home/cburel/src/moc-ng/src/main.cpp:366: undefined reference to `clang::tooling::ToolInvocation::ToolInvocation(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, clang::FrontendAction*, clang::FileManager*)'
/home/cburel/src/moc-ng/src/main.cpp:373: undefined reference to `clang::tooling::ToolInvocation::ToolInvocation(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, clang::FrontendAction*, clang::FileManager*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
src/CMakeFiles/moc.dir/build.make:310: recipe for target 'src/moc' failed
make[2]: *** [src/moc] Error 1                                                                                                                                                                                                                                             
make[2]: Leaving directory '/home/cburel/src/moc-ng/build'                                                                                                                                                                                                                 
CMakeFiles/Makefile2:87: recipe for target 'src/CMakeFiles/moc.dir/all' failed                                                                                                                                                                                             
make[1]: *** [src/CMakeFiles/moc.dir/all] Error 2                                                                                                                                                                                                                          
make[1]: Leaving directory '/home/cburel/src/moc-ng/build'                                                                                                                                                                                                                 
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
chrisburel commented 8 years ago

Here's a comparison of the output of nm -C on the built main.cpp.o file from both Debian sid and Fedora 22:

U clang::tooling::ToolInvocation::ToolInvocation(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, clang::FrontendAction*, clang::FileManager*)
U clang::tooling::ToolInvocation::ToolInvocation(std::vector<std::string, std::allocator<std::string> >, clang::FrontendAction*, clang::FileManager*)

For some reason Debian is writing out std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > instead of just std::string.

ogoffart commented 8 years ago

I believe this has something to do with GCC 5 and it's new ABI. See https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html

Libclang was probably compiled with the old ABI, but you are compiling mocng with the new ABI. I guess because the libclang package were most likely build with GCC 4.x while you now have GCC 5 on your system.

Where did you get the clang packages? was it from thedebian repository or from the llvm website? Maybe using the packages from the debian repository might help.

Otherwise you can try to add --disable-libstdcxx-dual-abi`: Add this to the src/CMakeLists.txt

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  --disable-libstdcxx-dual-abi")

btw, what is the result of llvm-config --cxxflags ?

chrisburel commented 8 years ago

I'm using the clang packages from llvm website.

undefined references to `clang::QualType::getAsString(clang::PrintingPolicy const&) const' follow
undefined reference to `clang::DeclarationName::getAsString() const'
undefined reference to `clang::Lexer::getSpelling(clang::Token const&, clang::SourceManager const&, clang::LangOptions const&, bool*)'
undefined reference to `clang::NamedDecl::getQualifiedNameAsString() const'
undefined reference to `clang::QualType::getAsString(clang::PrintingPolicy const&) const'
undefined reference to `clang::TypoCorrection::getAsString(clang::LangOptions const&) const'
undefined references to `clang::QualType::getAsString[abi:cxx11](clang::PrintingPolicy const&) const' follow
undefined reference to `clang::DeclarationName::getAsString[abi:cxx11]() const'
undefined reference to `clang::Lexer::getSpelling[abi:cxx11](clang::Token const&, clang::SourceManager const&, clang::LangOptions const&, bool*)'
undefined reference to `clang::NamedDecl::getQualifiedNameAsString[abi:cxx11]() const'
undefined reference to `clang::QualType::getAsString[abi:cxx11](clang::PrintingPolicy const&) const'
undefined reference to `clang::tooling::ToolInvocation::ToolInvocation(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, clang::FrontendAction*, clang::FileManager*)'
undefined reference to `clang::TypoCorrection::getAsString[abi:cxx11](clang::LangOptions const&) const'
[  5%] Building CXX object src/CMakeFiles/moc.dir/main.cpp.o
cd /home/cburel/src/moc-ng/build/src && /usr/bin/c++    -I/home/cburel/apps/clang-for-15.04/include -I/home/cburel/src/moc-ng/build/src  --disable-libstdcxx-dual-abi   -std=c++11 -g -Wall -fno-rtti  -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS  -o CMakeFiles/moc.dir/main.cpp.o -c /home/cburel/src/moc-ng/src/main.cpp
cc1plus: error: unknown pass libstdcxx-dual-abi specified in -fdisable

Here's the output of llvm-config --cxxflags for both the debian-provided clang and the clang from the llvm website:

$ ~/apps/clang/bin/llvm-config --cxxflags
-I/home/cburel/apps/clang-for-15.04/include  -DNDEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -O3 -fomit-frame-pointer -std=c++11 -fvisibility-inlines-hidden -fno-exceptions -fno-rtti -fPIC -ffunction-sections -fdata-sections -Wcast-qual
$ /usr/bin/llvm-config-3.6 --cxxflags
-I/usr/lib/llvm-3.6/include  -DNDEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -g -O2 -fomit-frame-pointer -std=c++11 -fvisibility-inlines-hidden -fno-exceptions -fPIC -ffunction-sections -fdata-sections -Wcast-qual
chrisburel commented 8 years ago

If I add -D_GLIBCXX_USE_CXX11_ABI=0 to the defines list, then building with the clang driver works. It definitely seems this is not a moc-ng issue, but a clang/gcc5 one.

chrisburel commented 8 years ago

Just for the record, this stackoverflow qeustion seems to be relevant, and seems to point to an unresolved clang bug.