diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a6af88fd..ae4e2842e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -362,7 +362,7 @@ jobs: run: | sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test sudo apt-get update - GCC_LATEST=$(apt-cache search ^gcc-[0-9]+$ | sort -V | tail -1 | awk '{print $1}') + GCC_LATEST=$(apt-cache search \^gcc-\[0-9\]+\$ | sort -V | tail -1 | awk '{print $1}') GXX_LATEST=$(echo "$GCC_LATEST" | sed 's/gcc/g++/') sudo apt-get install -y "$GCC_LATEST" "$GXX_LATEST" sudo ln -sf "/usr/bin/$GCC_LATEST" /usr/local/bin/cc diff --git a/VERSION.txt b/VERSION.txt index 428cf69cb..724661313 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.20260707.3 +1.20260708.0 diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index de523f9e3..81df2f808 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -34,19 +34,20 @@ if(LIBOPENCOR_PYTHON_BINDINGS) set(PYTHON_BINDINGS_DIR ${CMAKE_BINARY_DIR}/tests/bindings/python CACHE INTERNAL "Python bindings directory.") - # Check whether we need to provide a glibc compatibility wrapper for __isoc23_strtoll(). - # Note: indeed, it is used by our prebuilt LLVM+Clang and libssh2 libraries which are compiled using glibc 2.38+ + # Check whether we need to provide a glibc compatibility wrapper for __isoc23_strtol() and __isoc23_strtoll(). + # Note: indeed, they are used by our prebuilt LLVM+Clang and libssh2 libraries which are compiled using glibc 2.38+ # (Ubuntu 24.04 LTS on GitHub Actions), but there are currently no versions of manylinux that uses glibc - # 2.38+, so we need to provide a compatibility wrapper for this function in order to be able to build our + # 2.38+, so we need to provide a compatibility wrapper for these functions in order to be able to build our # Python wheels. include(CheckSymbolExists) + check_symbol_exists(__isoc23_strtol stdlib.h LIBOPENCOR_GLIBC_HAS_ISOC23_STRTOL) check_symbol_exists(__isoc23_strtoll stdlib.h LIBOPENCOR_GLIBC_HAS_ISOC23_STRTOLL) set(ACTUAL_PYTHON_SOURCE_FILES ${PYTHON_SOURCE_FILES}) - if(LIBOPENCOR_GLIBC_HAS_ISOC23_STRTOLL) + if(LIBOPENCOR_GLIBC_HAS_ISOC23_STRTOL AND LIBOPENCOR_GLIBC_HAS_ISOC23_STRTOLL) list(REMOVE_ITEM ACTUAL_PYTHON_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/glibc.cpp) endif() diff --git a/src/bindings/python/glibc.cpp b/src/bindings/python/glibc.cpp index 3bf7f61b8..6d757641e 100644 --- a/src/bindings/python/glibc.cpp +++ b/src/bindings/python/glibc.cpp @@ -15,15 +15,26 @@ limitations under the License. */ #if defined(__linux__) && defined(__GNUC__) -// On glibc 2.38+, strtoll() is defined as a macro that redirects to __isoc23_strtoll(). - -# include - -# undef strtoll +// On glibc 2.38+, strtol() and strtoll() are redirected to __isoc23_strtol() and __isoc23_strtoll(), respectively, +// either via preprocessor macro (Intel) or via __asm__("__isoc23_strtol") on the declaration (ARM). The latter is a +// compiler-level redirect that cannot be undone with #undef, so calling strtol() inside our __isoc23_strtol() wrapper +// would cause infinite recursion on ARM. To bypass this, we forward-declare strtol()/strtoll() ourselves without the +// compiler-level redirect, giving us a direct reference to glibc's implementation unaffected by any asm redirect on the +// standard names. + +extern "C" { +long strtol(const char *pString, char **pEndPtr, int pBase); +long long strtoll(const char *pString, char **pEndPtr, int pBase); + +__attribute__((weak)) long __isoc23_strtol(const char *pString, char **pEndPtr, int pBase) +{ + return strtol(pString, pEndPtr, pBase); +} -extern "C" long long __isoc23_strtoll(const char *pString, char **pEndPtr, int pBase) +__attribute__((weak)) long long __isoc23_strtoll(const char *pString, char **pEndPtr, int pBase) { return strtoll(pString, pEndPtr, pBase); } +} #endif