Source: i2pd
Version: 2.43.0-1
Severity: serious
Tags: ftbfs patch upstream
Justification: fails to build from source (but built successfully in the past)
X-Debbugs-Cc: i...@hack3r.moe

Dear maintainer(s),

i2pd failed to build on riscv64 due to not linking to libatomic:

```
[100%] Linking CXX executable i2pd
/usr/bin/cmake -E cmake_link_script CMakeFiles/i2pd.dir/link.txt --verbose=1
/usr/bin/c++ -g -O2 -ffile-prefix-map=/<<PKGBUILDDIR>>=. 
-fstack-protector-strong -Wformat -Werror=format-security -Wall -pedantic -O3 
-Wdate-time -D_FORTIFY_SOURCE=2 -Wall -Wextra -Winvalid-pch 
-Wno-unused-parameter -std=c++17 -pipe -fPIC -Wl,-z,relro -Wl,-z,now 
"CMakeFiles/i2pd.dir/<<PKGBUILDDIR>>/daemon/Daemon.cpp.o" 
"CMakeFiles/i2pd.dir/<<PKGBUILDDIR>>/daemon/HTTPServer.cpp.o" 
"CMakeFiles/i2pd.dir/<<PKGBUILDDIR>>/daemon/I2PControl.cpp.o" 
"CMakeFiles/i2pd.dir/<<PKGBUILDDIR>>/daemon/i2pd.cpp.o" 
"CMakeFiles/i2pd.dir/<<PKGBUILDDIR>>/daemon/UPnP.cpp.o" 
"CMakeFiles/i2pd.dir/<<PKGBUILDDIR>>/daemon/UnixDaemon.cpp.o" -o i2pd  
libi2pd.a libi2pdclient.a libi2pdlang.a 
/usr/lib/riscv64-linux-gnu/libboost_system.so.1.74.0 
/usr/lib/riscv64-linux-gnu/libboost_filesystem.so.1.74.0 
/usr/lib/riscv64-linux-gnu/libboost_program_options.so.1.74.0 
/usr/lib/riscv64-linux-gnu/libboost_date_time.so.1.74.0 
/usr/lib/riscv64-linux-gnu/libssl.so /usr/lib/riscv64-linux-gnu/libcrypto.so 
/usr/lib/riscv64-linux-gnu/libminiupnpc.so /usr/lib/riscv64-linux-gnu/libz.so 
/usr/bin/ld: libi2pdclient.a(HTTPProxy.cpp.o): in function 
`std::__exception_ptr::exception_ptr::~exception_ptr()':
/usr/include/c++/12/bits/exception_ptr.h:200: undefined reference to 
`__atomic_exchange_1'
/usr/bin/ld: libi2pdclient.a(HTTPProxy.cpp.o): in function 
`std::__new_allocator<char>::deallocate(char*, unsigned long)':
/usr/include/c++/12/bits/new_allocator.h:158: undefined reference to 
`__atomic_exchange_1'
/usr/bin/ld: libi2pdclient.a(I2PService.cpp.o): in function 
`i2p::client::TCPIPPipe::Terminate()':
./obj-riscv64-linux-gnu/./libi2pd_client/I2PService.cpp:170: undefined 
reference to `__atomic_exchange_1'
/usr/bin/ld: libi2pdclient.a(I2PService.cpp.o): in function 
`__gnu_cxx::__atomic_add_single(int*, int)':
/usr/include/c++/12/ext/atomicity.h:92: undefined reference to 
`__atomic_exchange_1'
/usr/bin/ld: libi2pdclient.a(I2PService.cpp.o): in function 
`std::__shared_count<(__gnu_cxx::_Lock_policy)1>::__shared_count(std::__shared_count<(__gnu_cxx::_Lock_policy)1>
 const&)':
/usr/include/c++/12/bits/shared_ptr_base.h:1075: undefined reference to 
`__atomic_exchange_1'
/usr/bin/ld: 
libi2pdclient.a(I2PService.cpp.o):/usr/include/c++/12/ext/atomicity.h:111: more 
undefined references to `__atomic_exchange_1' follow
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/i2pd.dir/build.make:191: i2pd] Error 1
```

Full buildd log: 
https://buildd.debian.org/status/fetch.php?pkg=i2pd&arch=riscv64&ver=2.43.0-1&stamp=1669692730&raw=0

I've attached a patch that replaces CheckAtomic.cmake with the newer LLVM ones.
This is also submitted upstream [1]. If more help is needed, please let me know.

Cheers,
Eric

[1]: https://github.com/PurpleI2P/i2pd/pull/1828
--- a/build/cmake_modules/CheckAtomic.cmake
+++ b/build/cmake_modules/CheckAtomic.cmake
@@ -1,18 +1,23 @@
 # atomic builtins are required for threading support.
 
 INCLUDE(CheckCXXSourceCompiles)
+INCLUDE(CheckLibraryExists)
 
 # Sometimes linking against libatomic is required for atomic ops, if
 # the platform doesn't support lock-free atomics.
 
 function(check_working_cxx_atomics varname)
   set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
-  set(CMAKE_REQUIRED_FLAGS "-std=c++11")
+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
   CHECK_CXX_SOURCE_COMPILES("
 #include <atomic>
 std::atomic<int> x;
+std::atomic<short> y;
+std::atomic<char> z;
 int main() {
-  return x;
+  ++z;
+  ++y;
+  return ++x;
 }
 " ${varname})
   set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
@@ -27,6 +32,7 @@
 std::atomic<uint64_t> x (0);
 int main() {
   uint64_t i = x.load(std::memory_order_relaxed);
+  (void)i;
   return 0;
 }
 " ${varname})
@@ -34,15 +40,16 @@
 endfunction(check_working_cxx_atomics64)
 
 
-# This isn't necessary on MSVC, so avoid command-line switch annoyance
-# by only running on GCC-like hosts.
-if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
+# Check for (non-64-bit) atomic operations.
+if(MSVC)
+  set(HAVE_CXX_ATOMICS_WITHOUT_LIB True)
+else()
   # First check if atomics work without the library.
   check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
   # If not, check if the library exists, and atomics work with it.
   if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
     check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
-    if( HAVE_LIBATOMIC )
+    if(HAVE_LIBATOMIC)
       list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
       check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
       if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
@@ -58,21 +65,34 @@
 if(MSVC)
   set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
 else()
+  # First check if atomics work without the library.
   check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+  # If not, check if the library exists, and atomics work with it.
+  if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+    check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
+    if(HAVE_CXX_LIBATOMICS64)
+      list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
+      check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
+      if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
+        message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
+      endif()
+    else()
+      message(FATAL_ERROR "Host compiler appears to require libatomic for 
64-bit operations, but cannot find it.")
+    endif()
+  endif()
 endif()
 
-# If not, check if the library exists, and atomics work with it.
-if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
-  check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
-  if(HAVE_CXX_LIBATOMICS64)
-    list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
-    check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
-    if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
-      message(FATAL_ERROR "Host compiler must support std::atomic!")
-    endif()
+# Set variable LLVM_ATOMIC_LIB specifying flags for linking against libatomic.
+if(HAVE_CXX_ATOMICS_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB)
+  # Use options --push-state, --as-needed and --pop-state if linker is known 
to support them.
+  # Use single option -Wl of compiler driver to avoid incorrect re-ordering of 
options by CMake.
+  if(LLVM_LINKER_IS_GNULD OR LLVM_LINKER_IS_GOLD OR LLVM_LINKER_IS_LLD OR 
LLVM_LINKER_IS_MOLD)
+    set(LLVM_ATOMIC_LIB "-Wl,--push-state,--as-needed,-latomic,--pop-state")
   else()
-    message(FATAL_ERROR "Host compiler appears to require libatomic, but 
cannot find it.")
+    set(LLVM_ATOMIC_LIB "-latomic")
   endif()
+else()
+  set(LLVM_ATOMIC_LIB)
 endif()
 
 ## TODO: This define is only used for the legacy atomic operations in
@@ -80,7 +100,6 @@
 ## assumes C++11 <atomic> works.
 CHECK_CXX_SOURCE_COMPILES("
 #ifdef _MSC_VER
-#include <Intrin.h> /* Workaround for PR19898. */
 #include <windows.h>
 #endif
 int main() {

Reply via email to