This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Simplify how we define the linker script for libc++
ClosedPublic

Authored by ldionne on Aug 2 2022, 5:33 PM.

Details

Summary

Trying to be generic didn't work properly because we had to special-case
some interface libraries that we didn't want in the linker script. Instead,
only look at the ABI and the unwinding libraries explicitly.

This should solve the issue reported by @dim in [1].

[1]: https://discourse.llvm.org/t/15-0-0-rc1-has-been-tagged/64174/22

Diff Detail

Event Timeline

ldionne created this revision.Aug 2 2022, 5:33 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 2 2022, 5:33 PM
Herald added a subscriber: mgorny. · View Herald Transcript
ldionne requested review of this revision.Aug 2 2022, 5:33 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 2 2022, 5:33 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript
ldionne accepted this revision.Aug 3 2022, 6:29 AM

CI passes and IMO this is cleaner than what we had before, and there is a chance of fixing the issues that folks were seeing w/ the release, so I'll ship this.

This revision is now accepted and ready to land.Aug 3 2022, 6:29 AM
dim added a comment.Aug 3 2022, 11:13 AM

Unfortunately it doesn't really change anything on the FreeBSD build side. It still shows similar output when I put some messages in there:

DBG: LIBCXX_DEFAULT_ABI_LIBRARY="libcxxrt"
DBG: LIBCXX_CXX_ABI="libcxxrt"
-- LIBCXX_CXX_ABI_INCLUDE_PATHS not set, using /usr/include/c++/v1
-- Looking for cxxabi.h in /usr/include/c++/v1 - found
-- Looking for unwind.h in /usr/include/c++/v1 - found
-- Looking for unwind-arm.h in /usr/include/c++/v1 - found
-- Looking for unwind-itanium.h in /usr/include/c++/v1 - found
DBG: link_libraries="-l$<IF:$<BOOL:$<TARGET_PROPERTY:libcxx-abi-shared,IMPORTED_LIBNAME>>,$<TARGET_PROPERTY:libcxx-abi-shared,IMPORTED_LIBNAME>,$<TARGET_PROPERTY:libcxx-abi-shared,OUTPUT_NAME>>"
DBG: linker_script="INPUT($<TARGET_SONAME_FILE_NAME:cxx_shared> -l$<IF:$<BOOL:$<TARGET_PROPERTY:libcxx-abi-shared,IMPORTED_LIBNAME>>,$<TARGET_PROPERTY:libcxx-abi-shared,IMPORTED_LIBNAME>,$<TARGET_PROPERTY:libcxx-abi-shared,OUTPUT_NAME>>)"

and the resulting linker script is still:

INPUT(libc++.so.1 -l)

This is again likely because libcxx-abi-shared is empty, as the default ABI library is libcxxrt, not libcxxabi.

dim added a comment.Aug 7 2022, 1:58 AM

So I've been trying again with the following diff applied on top of this one:

diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 9abf548abbb9..d6769e4a3e64 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -244,7 +244,9 @@ if (LIBCXX_ENABLE_SHARED)

     set(imported_libname "$<TARGET_PROPERTY:libcxx-abi-shared,IMPORTED_LIBNAME>")
     set(output_name "$<TARGET_PROPERTY:libcxx-abi-shared,OUTPUT_NAME>")
-    string(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$<IF:$<BOOL:${imported_libname}>,${imported_libname},${output_name}>")
+    # NOTE: We cannot use the LOCATION target property, since that is forbidden by the CMP0026 policy.
+    set(target_file "$<TARGET_FILE:libcxx-abi-shared>")
+    string(APPEND link_libraries "$<IF:$<BOOL:${imported_libname}>,${CMAKE_LINK_LIBRARY_FLAG}${imported_libname},$<IF:$<BOOL:${output_name}>,${CMAKE_LINK_LIBRARY_FLAG}${output_name},${target_file}>>")

     # TODO: Move to the same approach as above for the unwind library
     if (LIBCXXABI_USE_LLVM_UNWINDER)

E.g. what this does is fall-back to $<TARGET_FILE:libcxx-abi-shared>, if both IMPORTED_LIBNAME and OUTPUT_NAME are unset, which turns out to be the case if LIBCXX_CXX_ABI=libcxxrt. That causes the linker script to look like:

INPUT(libc++.so.1 /usr/lib/libcxxrt.so)

Which works up to a point, but then it turns out that during the runtime builds for some reason the line target_compile_definitions(libcxx-abi-headers INTERFACE "-DLIBCXXRT") (from libcxx/cmake/Modules/HandleLibCXXABI.cmake) isn't picked up. E.g. the whole of libc++ is then compiled _without_ the -DLIBCXXRT define necessary for supporting libcxxrt, and at the end the build still fails, but now with:

FAILED: bin/llvm-tblgen
: && /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/clang++ -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wstring-conversion -Wmisleading-indentation -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -Wl,--color-diagnostics    -Wl,-z,origin  -Wl,--gc-sections utils/TableGen/CMakeFiles/llvm-tblgen.dir/AsmMatcherEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/AsmWriterEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/AsmWriterInst.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/Attributes.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CallingConvEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeEmitterGen.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeGenDAGPatterns.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeGenHwModes.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeGenInstruction.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeGenMapTable.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeGenRegisters.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeGenSchedule.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeGenTarget.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DAGISelEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DAGISelMatcherEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DAGISelMatcherGen.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DAGISelMatcherOpt.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DAGISelMatcher.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DecoderEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DFAEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DFAPacketizerEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DirectiveEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DisassemblerEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/DXILEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/ExegesisEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/FastISelEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/GICombinerEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/GlobalISelEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/InfoByHwMode.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/InstrInfoEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/InstrDocsEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/IntrinsicEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/OptEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/OptParserEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/OptRSTEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/PredicateExpander.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/PseudoLoweringEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CompressInstEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/RegisterBankEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/RegisterInfoEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/SDNodeProperties.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/SearchableTableEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/SubtargetEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/SubtargetFeatureInfo.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/TableGen.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/Types.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/VarLenCodeEmitterGen.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/X86DisassemblerTables.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/X86EVEX2VEXTablesEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/X86FoldTablesEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/X86MnemonicTables.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/X86ModRMFilters.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/X86RecognizableInstr.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/WebAssemblyDisassemblerEmitter.cpp.o utils/TableGen/CMakeFiles/llvm-tblgen.dir/CTagsEmitter.cpp.o -o bin/llvm-tblgen  -Wl,-rpath,"\$ORIGIN/../lib"  lib/libLLVMSupport.a  lib/libLLVMTableGen.a  -lpthread  lib/libLLVMTableGenGlobalISel.a  lib/libLLVMTableGen.a  lib/libLLVMSupport.a  -lrt  -lexecinfo  -lpthread  -lm  /usr/lib/libz.so  /usr/lib/libtinfo.so  lib/libLLVMDemangle.a && :
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to __cxa_uncaught_exceptions
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to std::logic_error::~logic_error()
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to std::logic_error::what() const
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to typeinfo for std::logic_error
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to typeinfo for std::overflow_error
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to std::overflow_error::~overflow_error()
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to vtable for std::overflow_error
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to vtable for std::logic_error
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to vtable for std::runtime_error
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to typeinfo for std::length_error
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to std::length_error::~length_error()
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to typeinfo for std::out_of_range
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to std::out_of_range::~out_of_range()
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to vtable for std::length_error
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to vtable for std::out_of_range
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to vtable for std::invalid_argument
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to typeinfo for std::invalid_argument
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to std::invalid_argument::~invalid_argument()
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to std::runtime_error::~runtime_error()
ld: error: /home/dim/llvm/15.0.0/rc1/Phase1/Release/llvmCore-15.0.0-rc1.install/usr/local/bin/../lib/x86_64-unknown-freebsd12.3/libc++.so.1: undefined reference to std::runtime_error::what() const
ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)

The errors mean it was assuming it was being linked against libcxxabi instead.

At this point I'm inclined to just do the test builds with LIBCXX_CXX_ABI forced to libcxxabi, as the runtimes seem to be pretty much broken for anything other than libcxxabi. :-)

So I've been trying again with the following diff applied on top of this one:

[...]

At this point I'm inclined to just do the test builds with LIBCXX_CXX_ABI forced to libcxxabi, as the runtimes seem to be pretty much broken for anything other than libcxxabi. :-)

Thanks for digging deeper here. However, I'll admit that I am not willing to keep shooting in the dark with random fixes. Instead, can you please pick up D128084 so we can start testing on FreeBSD? Most of the work has been done already, it just needs a bit of polishing that will be much easier to do with access to a FreeBSD machine locally.

I think this is an excellent example of what I've been saying with respect to untested platforms meaning they are not supported. I really want to provide proper support for FreeBSD, but it's literally impossible to do so if we don't have CI for that platform. We should have CI that builds on FreeBSD against the system libcxxrt ABI library like you do in the releases and none of this release-time churn would happen.