clang-14: Move libc++*.* libraries to libc++ sub-dir, fix install names

This applies a1d4865220, which addressed this for clang-16–18 for
https://trac.macports.org/ticket/68640, to clang-14, to fix a bug
observed while running clang-14 as a linker driver on macOS 15.

When running as a linker driver, clang provides ld with clang’s own LTO
plugin by invoking ld with `-lto_library
${PREFIX}/libexec/llvm-14/lib/libLTO.dylib`. Upon receipt of these
arguments, Xcode ld currently loads the plugin by re-`execve`ing itself
with DYLD_LIBRARY_PATH=${PREFIX}/libexec/llvm-14/lib in effect, causing
dyld to prefer libLTO.dylib in that directory over the
@rpath/libLTO.dylib that ld requests to load via a Mach-O load command.
With DYLD_LIBRARY_PATH in effect, dyld can potentially use any other
module in that same directory to satisfy any other Mach-O load command.
In this case, the directory contained both libc++.dylib and
libc++abi.dylib from clang, and dyld used these to replace the libraries
of the same name ordinarily provided by the OS in /usr/lib (via the dyld
shared cache). This is undesirable in general, but occurred silently on
macOS < 15. It became noticeable on macOS 15 because system libraries
that depend on libc++abi.dylib now reference symbols that are present in
the system’s version, but not in clang’s, causing messages such as

dyld[60301]: symbol '__ZnwmSt19__type_descriptor_t' missing from root that overrides /usr/lib/libc++abi.dylib. Use of that symbol in /usr/lib/swift/libswiftCore.dylib is being set to 0xBAD4007.
dyld[60301]: symbol '__ZdlPvSt19__type_descriptor_t' missing from root that overrides /usr/lib/libc++abi.dylib. Use of that symbol in /usr/lib/swift/libswiftCore.dylib is being set to 0xBAD4007.

repeated for every system library that references those symbols. These
messages warn of potential run-time bugs due to dyld intentionally
mis-resolving the missing symbols.

As clang should not seek to replace the system’s libc++ with its own in
system libraries, this was a latent problem even pre-macOS 15.

The workaround moves clang’s libc++ libraries to a new subdirectory,
${PREFIX}/libexec/llvm-14/lib/libc++, where they will not be found or
used even with DYLD_LIBRARY_PATH set to ${PREFIX}/libexec/llvm-14/lib as
it is when clang runs the linker.

This also contains a fix for the LC_INSTALL_NAMEs of libc++.dylib and
libc++abi.dylib, which should have been recorded as @rpath-relative, but
due to an error in the Portfile’s handling of CMAKE_INSTALL_NAME_DIR,
were instead recorded using absolute paths rooted at
${PREFIX}/libexec/llvm-14/lib. When the libraries were moved elsewhere,
they tripped MacPorts’ check for linking errors due to libc++.dylib’s
dependency on libc++abi.dylib at a path where it was no longer
installed. Discussion at
https://github.com/macports/macports-ports/pull/25918#issuecomment-2377971503.

This is an observable change in the installed clang-14 package, but the
revision is not being bumped in this commit because this change is being
merged atomically in #25919 with another change that updates clang-14’s
revision.

References: https://trac.macports.org/ticket/70779
This commit is contained in:
Mark Mentovai
2024-09-27 19:24:44 +01:00
committed by Chris Jones
parent e8938c3ebf
commit aa0bc47391
+12 -3
View File
@@ -62,15 +62,14 @@ cmake.build_type Release
cmake.install_rpath
configure.pre_args-delete \
-DCMAKE_INSTALL_NAME_DIR=${cmake.install_prefix}/lib \
-DCMAKE_INSTALL_RPATH=${cmake.install_prefix}/lib
-DCMAKE_INSTALL_NAME_DIR="${cmake.install_prefix}/lib"
configure.pre_args-replace \
-DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON \
-DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=OFF
configure.pre_args-replace \
-DCMAKE_SYSTEM_PREFIX_PATH="${prefix}\;/usr" \
-DCMAKE_SYSTEM_PREFIX_PATH="${prefix}\;${cmake.install_prefix}\;/usr" \
-DCMAKE_SYSTEM_PREFIX_PATH="${cmake.install_prefix}\;${prefix}\;/usr"
configure.args-append \
@@ -450,6 +449,16 @@ post-destroot {
macos-setup-codesign.sh \
${lldb_scripts_destdir}
}
if {${subport} eq "clang-${llvm_version}"} {
# move libc++ libraries out of default location to prevent accidental linkage
set libcxx_dir ${destroot}${sub_prefix}/lib/libc++
xinstall -d ${libcxx_dir}
foreach f [glob -nocomplain ${destroot}${sub_prefix}/lib/libc++*.*] {
ui_debug "Moving ${f} to ${libcxx_dir}"
move ${f} ${libcxx_dir}
}
}
}
if {${subport} eq "clang-${llvm_version}"} {