Build of 15.0.7 fails due to libstdc++ not being linked against

Hello,

I am trying to build llvm within OpenWrt again (which is a buildroot derivative build system) on an ARM system. Again, I don’t know if it’s something I’m doing wrong or something not being passed down the chain, but the build is failing because libstdc++ isn’t being linked:

/mnt/workbench/root/devel/openwrt/staging_dir/host/bin/gcc -O2 -I/mnt/workbench/root/devel/openwrt/staging_dir/host/include -fPIC -fno-semantic-interposition -Werror=date-time -Wal
l -Wextra -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-comment -Wmisleading-indentation -fdiagnostics-color
 -ffunction-sections -fdata-sections -DNDEBUG -L/mnt/workbench/root/devel/openwrt/staging_dir/host/lib    -Wl,-rpath-link,/mnt/workbench/root/devel/openwrt/build_dir/host/llvm-project-1
5.0.7.src/build/./lib  -Wl,--gc-sections tools/clang/tools/clang-fuzzer/dictionary/CMakeFiles/clang-fuzzer-dictionary.dir/dictionary.c.o -o bin/clang-fuzzer-dictionary  -Wl,-rpath,"\$OR
IGIN/../lib"  lib/libLLVM-15.so
/usr/bin/ld: lib/libLLVM-15.so: undefined reference to `std::ctype<char>::_M_widen_init() const@GLIBCXX_3.4.11'
/usr/bin/ld: lib/libLLVM-15.so: undefined reference to `operator new(unsigned long)@GLIBCXX_3.4'
...

The issue here is that either -lstdc++ has to be specified explicitly, or else g++ rather than gcc has to be invoked to link it. I don’t know the ins and outs of building llvm that well, in fact I have no real experience with ninja at all. Does anyone know if this is an issue in llvm’s build?

It seems like it’s calling gcc instead of g++ - did you pass gcc to CMAKE_CXX_COMPILER instead of g++?

I don’t have control over the way OpenWrt builds llvm (I only partially understand llvm’s buildroot system), but this appears to be the options given to llvm when it’s built:

CMAKE_HOST_OPTIONS += \
	-DLLVM_ENABLE_BINDINGS=OFF \
	-DLLVM_INCLUDE_DOCS=OFF \
	-DLLVM_INCLUDE_EXAMPLES=OFF \
	-DLLVM_INCLUDE_TESTS=OFF \
	-DLLVM_ENABLE_PROJECTS="clang;lld" \
	-DLLVM_TARGETS_TO_BUILD=BPF \
	-DCLANG_BUILD_EXAMPLES=OFF \
	-DLLVM_INSTALL_TOOLCHAIN_ONLY=ON \
	-DLLVM_LINK_LLVM_DYLIB=ON \
	-DLLVM_TOOLCHAIN_TOOLS="llvm-objcopy;llvm-objdump;llvm-readelf;llvm-strip;llvm-ar;llvm-as;llvm-dis;llvm-link;llvm-nm;llvm-ranlib;llc;opt" \
	-DCMAKE_SKIP_RPATH=OFF

Up until the point where clang-fuzzer-dictionary fails to link, many other tools are successfully compiled and linked and I see in the log that g++ is used extensively, so it’s definitely not a case where gcc is being used solely.

Could it be that llvm is making the wrong decision on gcc vs g++ when linking clang-fuzzer-dictionary on this platform?

It seems like clang-fuzzer-dictionary is a single C file, so it will select the C compiler to compile and link.

Other binaries that are similar to this one force the CMake linker language to CXX.

I think that needs to happen for clang-fuzzer-dictionary as well. You can try to add this:

set_target_properties(clang-fuzzer-dictionary
  PROPERTIES
  LINKER_LANGUAGE CXX)

in clang/tools/clang-fuzzer/dictionary/CMakeLists.txt

Let me know if that works and I can submit a patch.

Thank-you, trying it out now. It’ll take some time, as this is actually being built on a router.

Question, though, if this is the case, how is it building now? Does invoking gcc as gcc rather than g++ still cause libstdc++ to get linked in on some platforms?

Oh wait - you use shared library linking, then it’s even more curious, libLLVM-15.so should already link libstdc++?

I tried this locally on my machine, and it worked both in static and shared configuration, and if I run ldd on lib/libLLVM-17git.so it shows that it links to libstdc++.

Sorry to take so long to get to this.
The device I’m using to test needed a heatsink I had to wait on.

I don’t think it’s universal that if libA links against libB that linking an executable against libA only will cause the linker to allow symbols in the executable from libB.

In any case, the solution you suggested worked. I made a patch out of it and had the OpenWrt build system apply it and llvm now builds correctly.

ok good - I’ll push that upstream then since the other libraries are behaving the same.