Max Ehrlich Max Ehrlich - 2 months ago 18
C++ Question

Clang Build Errors

I am trying to build clang trunk on Ubuntu 16.04 and I am having build errors no matter what I try. First I built llvm/clang/libc++/libc++abi against gcc 5.4, this worked fine. Now I am trying to use the clang I just build to rebuild llvm/clang/libc++/libc++abi. This fails with the following error message:

[162/4396] Linking CXX executable bin/llvm-tblgen FAILED:
: && /usr/local/bin/clang++ -stdlib=libc++
-fPIC
-fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter
-Wwrite-strings -Wcast-qual -Wmissing-field-initializers
-pedantic -Wno-long-long -Wcovered-switch-default
-Wnon-virtual-dtor -Wdelete-non-virtual-dtor
-Werror=date-time -std=c++11 -fcolor-diagnostics
-ffunction-sections -fdata-sections -O3 -DNDEBUG
-lc++ -lc++abi -Wl,-allow-shlib-undefined
-Wl,-O3 -Wl,--gc-sections
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/AsmMatcherEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/AsmWriterEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/AsmWriterInst.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/Attributes.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/CallingConvEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/CodeEmitterGen.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/CodeGenDAGPatterns.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/CodeGenInstruction.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/CodeGenMapTable.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/CodeGenRegisters.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/CodeGenSchedule.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/CodeGenTarget.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/DAGISelEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/DAGISelMatcherEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/DAGISelMatcherGen.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/DAGISelMatcherOpt.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/DAGISelMatcher.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/DFAPacketizerEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/DisassemblerEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/FastISelEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/FixedLenDecoderEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/InstrInfoEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/IntrinsicEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/OptParserEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/PseudoLoweringEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/RegisterInfoEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/SearchableTableEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/SubtargetEmitter.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/TableGen.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/X86DisassemblerTables.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/X86ModRMFilters.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/X86RecognizableInstr.cpp.o
utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/CTagsEmitter.cpp.o
-o bin/llvm-tblgen
lib/libLLVMSupport.a
lib/libLLVMTableGen.a
-lpthread
lib/libLLVMSupport.a
-lrt
-ldl
-ltinfo
-lpthread
-lz
-lm
lib/libLLVMDemangle.a
-Wl,-rpath,"\$ORIGIN/../lib" &&
: utils/TableGen/CMakeFiles/obj.llvm-tblgen.dir/DFAPacketizerEmitter.cpp.o: In function `(anonymous namespace)::DFAPacketizerEmitter::run(llvm::raw_ostream&)': /home/mehrlich/Code/llvm/llvm/utils/TableGen/DFAPacketizerEmitter.cpp:(.text._ZN12_GLOBAL__N_120DFAPacketizerEmitter3runERN4llvm11raw_ostreamE+0x253f): undefined reference to `std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>::~basic_string()' clang-4.0: error: linker command failed with exit code 1 (use -v to see invocation) [162/4396] Building CXX object lib/MC/CMakeFiles/LLVMMC.dir/MCContext.cpp.o ninja: build stopped: subcommand failed.


The relevant error being the undefined symbol:

In function (anonymous namespace)::DFAPacketizerEmitter::run(llvm::raw_ostream&)': /home/mehrlich/Code/llvm/llvm/utils/TableGen/DFAPacketizerEmitter.cpp:(.text._ZN12_GLOBAL__N_120DFAPacketizerEmitter3runERN4llvm11raw_ostreamE+0x253f): undefined reference to std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>::~basic_string()'


Presumably this is for one of two reasons:

1. Clang is using libstdc++ headers:



We can see from the failing command that clang++ picks up the -stdlib=libc++ switch correctly. Running
% clang++ --stdlib=libc++ -E -x c++ - -v < /dev/null
to inspect the default include paths with this options gives

clang version 4.0.0 (trunk 281213) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/local/bin Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5 Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5.4.0 Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6 Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6.0.0 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.3 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.0.0 Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0 Candidate multilib: .;@m64 Selected multilib: .;@m64 Found CUDA installation: /usr/local/cuda, version 7.5 "/usr/local/bin/clang-4.0" -cc1 -triple x86_64-unknown-linux-gnu -E -disable-free -disable-llvm-verifier
-discard-value-names -main-file-name - -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -v -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/local/bin/../lib/clang/4.0.0 -internal-isystem /usr/local/bin/../include/c++/v1 -internal-isystem /usr/local/include
-internal-isystem /usr/local/bin/../lib/clang/4.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir /home/mehrlich/Code/llvm/build -ferror-limit 19 -fmessage-length 343
-fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o - -x c++ - clang -cc1 version 4.0.0 based upon LLVM 4.0.0svn default target x86_64-unknown-linux-gnu ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here: /usr/local/bin/../include/c++/v1 /usr/local/include /usr/local/bin/../lib/clang/4.0.0/include /usr/include/x86_64-linux-gnu /usr/include End of search list.
# 1 "<stdin>"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 328 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "<stdin>" 2


The first header search path
#include <...> search starts here: /usr/local/bin/../include/c++/v1
is the correct location of libc++ headers. So I highly doubt it is this

2. Clang is not linking against libc++



Adding the options
-lc++ -lc++abi
to CMAKE_EXE_LINKER_FLAGS, CMAKE_SHARED_LINKER_FLAGS, CMAKE_MODULE_LINKER_FLAGS, and CMAKE_STATIC_LINKER_FLAGS gives this following error:

[65/4396] Linking CXX static library lib/libLLVMDemangle.a
FAILED: : && /usr/bin/cmake -E remove lib/libLLVMDemangle.a && /usr/bin/ar qc lib/libLLVMDemangle.a -lc++ -lc++abi lib/Demangle/CMakeFiles/LLVMDemangle.dir/ItaniumDemangle.cpp.o && /usr/bin/ranlib lib/libLLVMDemangle.a && :
/usr/bin/ar: invalid option -- '+'
Usage: /usr/bin/ar [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV] [--plugin <name>] [member-name] [count] archive-file file...
/usr/bin/ar -M [<mri-script]
commands:
d - delete file(s) from the archive
m[ab] - move file(s) in the archive
p - print file(s) found in the archive
q[f] - quick append file(s) to the archive
r[ab][f][u] - replace existing or insert new file(s) into the archive
s - act as ranlib
t - display contents of archive
x[o] - extract file(s) from the archive
command specific modifiers:
[a] - put file(s) after [member-name]
[b] - put file(s) before [member-name] (same as [i])
[D] - use zero for timestamps and uids/gids (default)
[U] - use actual timestamps and uids/gids
[N] - use instance [count] of name
[f] - truncate inserted file names
[P] - use full path names when matching
[o] - preserve original dates
[u] - only replace files that are newer than current archive contents
generic modifiers:
[c] - do not warn if the library had to be created
[s] - create an archive index (cf. ranlib)
[S] - do not build a symbol table
[T] - make a thin archive
[v] - be verbose
[V] - display the version number
@<file> - read options from <file>
--target=BFDNAME - specify the target object format as BFDNAME
optional:
--plugin <p> - load the specified plugin
emulation options:
No emulation specific options
/usr/bin/ar: supported targets: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 plugin srec symbolsrec verilog tekhex binary ihex


And we can see for this, that the linker options are being passed to
/usr/bin/ar
by cmake for static libraries (this seems like the wrong thing to do to me but I am not an expert in build processes so I might be wrong). Removing these options from CMAKE_STATIC_LINKER_FLAGS reverts to the original error message about undefined symbols, so presumably the
llvm-tblgen
target is a static library.
llvm-tblgen
is definitely an executable, not sure the CMAKE_EXE_LINKER_FLAGS are not being applied to it
flags are being applied, which means I have no idea why this would not be working...

At this point I'm not sure who's fault this is, mine, clang, or cmake, but if anyone has any advice or expertise in doing this process, I'd appreciate the help.

Update



Now errors are in compiler-rt:

projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_unwind_linux_libcdep.cc.o: In function `__sanitizer::Unwind_GetIP(_Unwind_Context*)':
/home/mehrlich/Code/llvm/llvm/projects/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc:98: undefined reference to `_Unwind_GetIP'
projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_unwind_linux_libcdep.cc.o: In function `Unwind_GetIP':
/home/mehrlich/Code/llvm/llvm/projects/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc:98: undefined reference to `_Unwind_GetIP'
projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_unwind_linux_libcdep.cc.o: In function `__sanitizer::BufferedStackTrace::SlowUnwindStack(unsigned long, unsigned int)':
/home/mehrlich/Code/llvm/llvm/projects/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc:125: undefined reference to `_Unwind_Backtrace'
projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonLibc.x86_64.dir/sanitizer_unwind_linux_libcdep.cc.o: In function `SlowUnwindStack':
/home/mehrlich/Code/llvm/llvm/projects/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc:125: undefined reference to `_Unwind_Backtrace'


Seems related to this bug

Answer

This was caused by a recent bug in libc++ which accidentally removed the definition of ~basic_string() from versions of libc++.so built with GCC. The bug was introduced September 9th and I fixed it earlier today.

Unfortunately your libc++ installation is buggy and it will need to be updated before building Clang. You can simply install a new libc++ over top of the existing installation. This can probably be done using sudo make install-cxx from your current (buggy) build directory. Then you can continue building Clang as normal.

For more info about building/installing libc++ see http://libcxx.llvm.org/docs/BuildingLibcxx.html.

(Note: Fixing the libc++ installation should not require rebuilding LLVM or Clang.)