192320 implemented __cxa_thread_atexit so that base's clang now supports c++11's thread_local keyword. However, this seems to now have broken static linking with the GCCs that complain about double definitions: cd /home/mi/h4nn3s/devel/lambda-build/pkg/src && /usr/local/bin/cmake -E cmake_link_script CMakeFiles/lambda.dir/link.txt --verbose=1 /usr/local/libexec/ccache/g++6 -fopenmp -Wno-vla -O3 -DNDEBUG -flto=8 -s -static CMakeFiles/lambda.dir/lambda.cpp.o -o ../bin/lambda -lpthread -lexecinfo -lelf -lz -lbz2 //usr/lib/libc.a(cxa_thread_atexit.o): In function `__cxa_thread_atexit': /usr/src/lib/libc/stdlib/cxa_thread_atexit.c:(.text+0x0): multiple definition of `__cxa_thread_atexit' /usr/local/lib/gcc6/gcc/x86_64-portbld-freebsd11.0/6.3.0/../../../libstdc++.a(atexit_thread.o):/wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/atexit_thread.cc:117: first defined here collect2: error: ld returned 1 exit status So now a I have a workaround for FreeBSD<11 + LLVM and I seem to need one for FreeBSD>=11 + GCC. Needless to say, static linking with LLVM already doesn't work at all, because the necessary openmp .a is not shipped. It's starting to really get confusing :o Anything I can do to help fix this? Thanks!
This is a bug in gcc. The libsupc++ configuration assumes that there are exactly two possibilities: either libc is glibc and implements __cxa_thread_atexit() using __cxa_thread_atexit_impl(), or libsupc++ must provide an implementation on its own. Right solution is to add detection of __cxa_thread_atexit() in libc, to libstdc++ configure.ac and libsupc++/atexit_thread.cc. A workaround for you is might be use of --allow-multiple-definition switch to ld. But what is not quite clear to me, is why libc __cxa_thread_atexit was searched for at all, since static linker should be satisfied with the first definition it found. Ensure that libstdc++.a appears strictly before libc.a on the linker invocation' command line.
(In reply to Konstantin Belousov from comment #1) ok, I have opened an issue over at gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78968 Let's see what they say. Concerning your proposed workaround: Since all the magic is done by cmake I have little influence on the order, although it does seem like it gets into libstdc++ first (see the "first defined here"). I have a different workaround in the code that I have also been using for FreeBSD<11 + LLVM and that I am now just expanding so that thread_local is just never used on FreeBSD right now.
Upstream would be willing to create a workaround, however they are irritated with FreeBSD's solution and the workaround would of course only affect some future releases and not fix the current situation. Upstream suggested there is a better way to solving the whole __cxa_thread_atexit thing and/or that LLVM already has a (different) solution. Are there chances this will be changed, should I re-open https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=192320 ? Thanks!
Created attachment 178484 [details] Provide __cxa_thread_atexit_impl(), split __cxa_thread_atexit() into separate .o. This patch should help with gcc libstdc++ configured on stable/11 with __cxa_thread_atexit() already existing in libc. With the patch applied, gcc configure should detect __cxa_thread_atexit_impl() and generate only a wrapper cxa_thread_atexit() for libsupc++. If gcc was configured on system where __cxa_thread_atexit(3) was not provided, but used on a system where it is, the patch does not make a difference.
Note that since https://reviews.llvm.org/D21803, upstream LLVM does basically the same thing as GCC. That is, it checks for __cxa_thread_atexit_impl in the libc, calling it if available, and emulating it if not. In either case, libc++abi unconditionally defines __cxa_thread_atexit.
A commit references this bug: Author: kib Date: Sat Jan 7 16:05:19 UTC 2017 New revision: 311651 URL: https://svnweb.freebsd.org/changeset/base/311651 Log: Export __cxa_thread_atexit_impl as an alias for __cxa_thread_atexit. libstdc++ before gcc r244057 expected that libc provided __cxa_thread_atexit_impl, and libstdc++ implemented __cxa_thread_atexit, by forwarding the calls to _impl. Mentioned gcc revision checks for __cxa_thread_atexit in libc and does not provide the symbol from libstdc++ if found. This change helps older gcc, in particular, all released versions which implement thread_local, by consolidating the implementation into libc. For that versions, if configured with the current libc, the __cxa_thread_atexit is exported from libstdc++ as a trivial wrapper around libc::__cxa_thread_atexit_impl. The __cxa_thread_atexit implementation is put into separate source file to allow for static linking with older libstdc++.a. gcc bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78968 Reported by: Hannes Hauswedell <h2+fbsdports@fsfe.org> PR: 215709 Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Changes: head/lib/libc/include/libc_private.h head/lib/libc/stdlib/Makefile.inc head/lib/libc/stdlib/Symbol.map head/lib/libc/stdlib/cxa_thread_atexit.c head/lib/libc/stdlib/cxa_thread_atexit_impl.c
Is this still waiting on MFC?