oneTBB icon indicating copy to clipboard operation
oneTBB copied to clipboard

Build fails on 32-bit PowerPC due to missing linking against libatomic

Open glaubitz opened this issue 2 years ago • 5 comments

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

glaubitz avatar Dec 08 '22 10:12 glaubitz

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

glaubitz avatar Dec 08 '22 10:12 glaubitz

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

glaubitz avatar Dec 08 '22 17:12 glaubitz

I think you should open a PR against OneTBB so that all programs that depend on OneTBB will work without a local patch.

rui314 avatar Dec 09 '22 03:12 rui314

@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.

glaubitz avatar Dec 09 '22 11:12 glaubitz

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.

brad0 avatar Jan 27 '23 22:01 brad0