libobjc2 icon indicating copy to clipboard operation
libobjc2 copied to clipboard

v2.1 existence of "libsupc++.a" breaks test suite build

Open Un1Gfn opened this issue 3 years ago • 5 comments

$ uname -a
Linux 820g3 5.11.2-arch1-1 #1 SMP PREEMPT Fri, 26 Feb 2021 18:26:41 +0000 x86_64 GNU/Linux
$ cat /etc/lsb-release
LSB_VERSION=1.4
DISTRIB_ID=Arch
DISTRIB_RELEASE=rolling
DISTRIB_DESCRIPTION="Arch Linux"
$ clang --version
clang version 11.1.0
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

Build v2.1 tarball

$ cmake -B Build -S . \
    -DCMAKE_BUILD_TYPE=None \
    -DCMAKE_CXX_COMPILER=clang++ \
    -DCMAKE_C_COMPILER=clang \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DGNUSTEP_INSTALL_TYPE=NONE \
    -DOLDABI_COMPAT=OFF \
    \
    -DCMAKE_VERBOSE_MAKEFILE=ON
cmake -LA 2>&1
BOEHM_GC:BOOL=FALSE
BUILD_STATIC_LIBOBJC:BOOL=false
CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line
CMAKE_AR:FILEPATH=/usr/bin/ar
CMAKE_ASM_COMPILER:FILEPATH=/usr/bin/clang
CMAKE_ASM_COMPILER_AR:FILEPATH=/usr/bin/llvm-ar
CMAKE_ASM_COMPILER_RANLIB:FILEPATH=/usr/bin/llvm-ranlib
CMAKE_ASM_FLAGS:STRING=
CMAKE_ASM_FLAGS_DEBUG:STRING=-g
CMAKE_ASM_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMAKE_ASM_FLAGS_NONE:STRING=
CMAKE_ASM_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMAKE_ASM_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
CMAKE_BUILD_TYPE:STRING=None
CMAKE_COLOR_MAKEFILE:BOOL=ON
CMAKE_CXX_COMPILER:STRING=/usr/bin/clang++
CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/llvm-ar
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/llvm-ranlib
CMAKE_CXX_FLAGS:STRING=-D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMAKE_CXX_FLAGS_NONE:STRING=
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
CMAKE_C_COMPILER:STRING=/usr/bin/clang
CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/llvm-ar
CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/llvm-ranlib
CMAKE_C_FLAGS:STRING=-D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt
CMAKE_C_FLAGS_DEBUG:STRING=-g
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMAKE_C_FLAGS_NONE:STRING=
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
CMAKE_DLLTOOL:FILEPATH=/usr/bin/llvm-dlltool
CMAKE_EXE_LINKER_FLAGS:STRING=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
CMAKE_EXE_LINKER_FLAGS_NONE:STRING=
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
CMAKE_INSTALL_PREFIX:PATH=/usr
CMAKE_LINKER:FILEPATH=/usr/bin/ld
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make
CMAKE_MODULE_LINKER_FLAGS:STRING=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
CMAKE_MODULE_LINKER_FLAGS_NONE:STRING=
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_NM:FILEPATH=/usr/bin/nm
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
CMAKE_READELF:FILEPATH=/usr/bin/readelf
CMAKE_SHARED_LINKER_FLAGS:STRING=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
CMAKE_SHARED_LINKER_FLAGS_NONE:STRING=
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
CMAKE_SKIP_RPATH:BOOL=NO
CMAKE_STATIC_LINKER_FLAGS:STRING=
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
CMAKE_STATIC_LINKER_FLAGS_NONE:STRING=
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_STRIP:FILEPATH=/usr/bin/strip
CMAKE_VERBOSE_MAKEFILE:BOOL=ON
CPACK_GENERATOR:STRING=TGZ
CPACK_SOURCE_RPM:BOOL=OFF
CPACK_SOURCE_TBZ2:BOOL=ON
CPACK_SOURCE_TGZ:BOOL=ON
CPACK_SOURCE_TXZ:BOOL=ON
CPACK_SOURCE_TZ:BOOL=ON
CPACK_SOURCE_ZIP:BOOL=OFF
CPACK_STRIP_FILES:BOOL=true
CXX_RUNTIME_LIB:FILEPATH=/usr/lib/libsupc++.a
DEBUG_ARC_COMPAT:BOOL=FALSE
ENABLE_OBJCXX:BOOL=true
ENABLE_TRACING:BOOL=FALSE
GNUSTEP_CONFIG:FILEPATH=/usr/bin/gnustep-config
GNUSTEP_INSTALL_TYPE:STRING=NONE
INCLUDE_DIRECTORY:STRING=objc
LEGACY_COMPAT:BOOL=FALSE
LIBOBJC_NAME:STRING=objc
LIB_INSTALL_PATH:STRING=lib
OLDABI_COMPAT:BOOL=OFF
TESTS:BOOL=TRUE
TYPE_DEPENDENT_DISPATCH:BOOL=TRUE
$ make -j1 -C Build
[ 14%] Linking C executable ObjCXXEHInterop
cd /home/darren/.cache/yay/libobjc2/src/libobjc2-2.1/Build/Test && /usr/bin/cmake -E cmake_link_script CMakeFiles/ObjCXXEHInterop.dir/link.txt --verbose=1
/usr/bin/clang -D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -Xclang -fexceptions -Xclang -fobjc-exceptions -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -rdynamic CMakeFiles/ObjCXXEHInterop.dir/ObjCXXEHInterop.mm.o CMakeFiles/ObjCXXEHInterop.dir/ObjCXXEHInterop.m.o CMakeFiles/test_runtime.dir/Test.m.o -o ObjCXXEHInterop  -Wl,-rpath,/home/darren/.cache/yay/libobjc2/src/libobjc2-2.1/Build ../libobjc.so.4.6 -Wl,-Bstatic -lsupc++ -Wl,-Bdynamic
/usr/bin/ld: ../libobjc.so.4.6: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
/usr/bin/ld: ../libobjc.so.4.6: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
/usr/bin/ld: ../libobjc.so.4.6: undefined reference to `std::ios_base::Init::~Init()'
/usr/bin/ld: ../libobjc.so.4.6: undefined reference to `std::cerr'
/usr/bin/ld: ../libobjc.so.4.6: undefined reference to `ceilf'
/usr/bin/ld: ../libobjc.so.4.6: undefined reference to `std::ios_base::Init::Init()'
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)

Un1Gfn avatar Mar 02 '21 06:03 Un1Gfn

Build succeeds with -DTESTS=OFF but how may I build the test suite then?

Un1Gfn avatar Mar 02 '21 06:03 Un1Gfn

Interesting. It looks as if the runtime is picking up some C++ standard library symbol dependencies. I think this may be a thing that happens with libstdc++ if you include iostream, whether you actually use it or not. I don't know which compilation units are pulling that in - we don't include it directly, so must be transitively including it somehow. Can you look at the preprocessed versions of the [Objective-]C++ files and see where it comes from?

I suspect on Ubuntu (which we test in CI) there's no libsupc++, so this is masked by the build system deciding to unconditionally link libstdc++. On Arch, it seems to find a libsupc++.a. We shouldn't be using a static libsupc++, so the correct fix is probably to tweak the libsupc++ lookup to find only the SHARED version. Can you try tweaking the CMakeLists.txt to do that and see if it works for you?

davidchisnall avatar Mar 02 '21 10:03 davidchisnall

Ubuntu 20.10 Groovy Gorilla provides /usr/lib/gcc/x86_64-linux-gnu/10/libsupc++.a in package libstdc++-10-dev

Arch Linux:

$ pacman --query --owns /usr/lib/lib{sup,std}*
/usr/lib/libsupc++.a is owned by gcc 10.2.0-6
/usr/lib/libstdc++.a is owned by gcc 10.2.0-6
/usr/lib/libstdc++fs.a is owned by gcc 10.2.0-6
/usr/lib/libstdc++.so is owned by gcc-libs 10.2.0-6
/usr/lib/libstdc++.so.6 is owned by gcc-libs 10.2.0-6
/usr/lib/libstdc++.so.6.0.28 is owned by gcc-libs 10.2.0-6

I will not remove /usr/lib/libsupc++.a by uninstalling gcc :/

tweak the libsupc++ lookup to find only the SHARED version

$ pacman --files --regex 'libsupc.*so.*'
$ 

Simply patch it out, as a complete NOOB to CMake, no shared version anyway :)

$ patch --verbose CMakeLists.txt <<"EOP"
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -289,7 +289,7 @@
    # If it doesn't, then look for GNU libsupc++.so instead (either works,
    # they're ABI compatible).
    if (NOT CXX_RUNTIME)
-     test_cxx(supc++ false)
+     #
    endif (NOT CXX_RUNTIME)
    # libc++abi does not currently work, don't try it.
    if (NOT CXX_RUNTIME)
EOP
$ cmake -B Build -S . \
    -DCMAKE_BUILD_TYPE=None \
    -DCMAKE_CXX_COMPILER=clang++ \
    -DCMAKE_C_COMPILER=clang \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DGNUSTEP_INSTALL_TYPE=NONE \
    -DLIBOBJC_NAME=objc2 \
    -DOLDABI_COMPAT=OFF \
    -DTESTS=ON \
    \
    -DCMAKE_VERBOSE_MAKEFILE=OFF

Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed

$ make -C Build
$ make -C test

Success

Un1Gfn avatar Mar 02 '21 15:03 Un1Gfn

I think we still have a bug. The existence of libsupc++.a should not break the build.

davidchisnall avatar Mar 02 '21 15:03 davidchisnall

FYI

before (collapsed in <black_solid_triangular> cmake -LA 2>&1):

CXX_RUNTIME_LIB:FILEPATH=/usr/lib/libsupc++.a

after:

$ cmake -S .. -B . -LA |& grep CXX_RUNT
CXX_RUNTIME_LIB:FILEPATH=CXX_RUNTIME_LIB-NOTFOUND

Un1Gfn avatar Mar 02 '21 15:03 Un1Gfn

The CMake has now been reworked and doesn't try to link directly against a C++ runtime. Can you try again?

davidchisnall avatar Feb 19 '23 16:02 davidchisnall