oneTBB
oneTBB copied to clipboard
Build fails on 32-bit PowerPC due to missing linking against libatomic
The build of oneTBB from git master on 32-Bit Linux PowerPC fails with the following linker error:
[49/324] Linking CXX executable gnu_12.2_cxx11_32_relwithdebinfo/test_tick_count
FAILED: gnu_12.2_cxx11_32_relwithdebinfo/test_tick_count
: && /usr/bin/c++ -O2 -g -DNDEBUG -rdynamic test/CMakeFiles/test_tick_count.dir/tbb/test_tick_count.cpp.o -o gnu_12.2_cxx11_32_relwithdebinfo/test_tick_count -Wl,-rpath,/home/glaubitz/oneTBB/build/gnu_12.2_cxx11_32_relwithdebinfo gnu_12.2_cxx11_32_relwithdebinfo/libtbb.so.12.9 -ldl && :
/usr/bin/ld: gnu_12.2_cxx11_32_relwithdebinfo/libtbb.so.12.9: undefined reference to `__atomic_fetch_sub_8'
/usr/bin/ld: gnu_12.2_cxx11_32_relwithdebinfo/libtbb.so.12.9: undefined reference to `__atomic_load_8'
/usr/bin/ld: gnu_12.2_cxx11_32_relwithdebinfo/libtbb.so.12.9: undefined reference to `__atomic_fetch_add_8'
collect2: error: ld returned 1 exit status
This is a result of a longstanding GCC bug where -latomic is not passed to the linker automatically if needed [1].
I have tried the following simple hack but that didn't fix the problem for me:
diff --git a/cmake/compilers/GNU.cmake b/cmake/compilers/GNU.cmake
index cd76acfe..8e1c3851 100644
--- a/cmake/compilers/GNU.cmake
+++ b/cmake/compilers/GNU.cmake
@@ -24,6 +24,7 @@ elseif (APPLE)
else()
set(TBB_LINK_DEF_FILE_FLAG -Wl,--version-script=)
set(TBB_DEF_FILE_PREFIX lin${TBB_ARCH})
+ set(TBB_LIB_LINK_FLAGS ${TBB_LIB_LINK_FLAGS} -latomic)
endif()
set(TBB_WARNING_LEVEL -Wall -Wextra $<$<BOOL:${TBB_STRICT}>:-Werror> -Wfatal-errors)
I assume that the linker flags set in GNU.cmake are not properly passed down where it's needed.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81358
A working workaround is passing CXXFLAGS="-Wl,--no-as-needed -latomic -Wl,--as-needed" on the environment:
# cmake -E env CXXFLAGS="-Wl,--no-as-needed -latomic -Wl,--as-needed" cmake -G Ninja .. -DTBB_STRICT=OFF
This particular change fixes the problem and was inspired by the corresponding code in mold [1]:
diff --git a/cmake/compilers/GNU.cmake b/cmake/compilers/GNU.cmake
index cd76acfe..8282b54e 100644
--- a/cmake/compilers/GNU.cmake
+++ b/cmake/compilers/GNU.cmake
@@ -44,6 +44,20 @@ if (NOT MINGW)
set(TBB_COMMON_LINK_LIBS dl)
endif()
+include(CheckCXXSourceCompiles)
+check_cxx_source_compiles("#include <atomic>
+int main() {
+ std::atomic<uint8_t> w1;
+ std::atomic<uint16_t> w2;
+ std::atomic<uint32_t> w4;
+ std::atomic<uint64_t> w8;
+ return ++w1 + ++w2 + ++w4 + ++w8;
+}" HAVE_FULL_ATOMIC_SUPPORT)
+
+if(NOT HAVE_FULL_ATOMIC_SUPPORT)
+ set(TBB_COMMON_LINK_LIBS ${TBB_COMMON_LINK_LIBS} atomic)
+endif()
+
# Ignore -Werror set through add_compile_options() or added to CMAKE_CXX_FLAGS if TBB_STRICT is disabled.
if (NOT TBB_STRICT AND COMMAND tbb_remove_compile_flag)
tbb_remove_compile_flag(-Werror)
If @rui314 allows, I can open a PR with the above change.
[1] https://github.com/rui314/mold/blob/main/CMakeLists.txt#L227
I think you should open a PR against OneTBB so that all programs that depend on OneTBB will work without a local patch.
@rui314 Done. https://github.com/oneapi-src/oneTBB/pull/987
I just wanted to make sure you're OK if I'm just copying your compile test code.
I'm very wary of these kind of tests. Too often we (OpenBSD) and FreeBSD and other OS's using compiler-rt have to hack around them to disable the broken test. They'll erroneously enable linking against libatomic since it happens to be around in the build environment. Once and awhile luck out later on during the build with --as-needed.