Linking issue with clang/libc++

Folks, I’m hitting a funky issue while building a Boost tool with Clang/libc++. Here is the compiler invocation:

$ /opt/llvm-12/bin/clang++ -std=c++11 -O2 -stdlib=libc++ -Wno-mismatched-tags -O2 -s -DNDEBUG builtins.cpp class.cpp … pathunix.cpp -o b2

And I get this:

/opt/llvm-12/bin/…/lib/libc++.so.1: undefined reference to `__divmodti4@GCC_7.0.0’

Clang itself was built with GCC-11… so I fail to understand where this symbol is coming from. Can someone shed some light on this please?

Thanks in advance,
Oleg.

This symbol is a part of compiler runtime. In your case – you need to
link libgcc.

Wow, that’s interesting! Thank you for hint, Anton!

How did this dependency come into the build? I don’t see any direct references to the symbol… so, is it something acquired transitively?.. I am surprised that some (supposedly portable) code contains a buried libgcc dependency… I’m not linking binary artifacts here…

Wow, that's interesting! Thank you for hint, Anton!

How did this dependency come into the build? I don't see any direct
references to the symbol... so, is it something acquired transitively?... I
am surprised that some (supposedly portable) code contains a buried libgcc
dependency... I'm not linking binary artifacts here...

__divmodti4 is a library function for "Divides 128-bit signed integers w/ remainder".
Presumably libc++ has some int128 division which generates the reference.
libc++ has int128 usage in chrono/filesystem/etc. I suspect chrono may
have int128 division, though I don't find the symbol in my build.

`clang -stdlib=libc++ a.o '-###'` prints the linker command line.
You should be able to find an argument -lgcc_s.
Adding -Wl,-t and removing `-###` should tell you which libgcc_s.so.1
file is picked.
You can dump its symbol table and inspect where __divmodti4 is there.

This issue is some installation or setup problem.

Oh, right! Thank you very much, Fangrui!

The issue comes down to the discrepancy between libgcc_s versions. I have an alternative compiler and that’s how Clang was built. That alternative compiler has the right support library:

$ nm /opt/gcc-11/lib64/libgcc_s.so.1 | grep __divmodti4
00000000000061d0 T __divmodti4

And Clang’s ld invocation has this trailer:

…"-lgcc_s" “-lgcc” “-lc” “-lgcc_s” “-lgcc” “/usr/lib/gcc/x86_64-linux-gnu/5.4.0/crtend.o” “/usr/lib/gcc/x86_64-linux-gnu/5.4.0/…/…/…/x86_64-linux-gnu/crtn.o”

Here is it trying and failing to find the symbol in the system’s compiler’s libs.

So, naturally, I can fix this with custom flags as well as --gcc-toolchain=/opt/gcc-11 (I forgot about that completely).

Thanks again!

Hopefully this message will help posterity…

Oleg.