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() {