My local Linux build of LLVM trunk (where LLVM_ENABLE_PROJECTS contains libcxx;libcxxabi, among others) started to fail when I upgraded my Fedora 35 machine from cmake-3.21.3-1.fc35.x86_64 to cmake-3.22.0-1.fc35.x86_64, but I know too little about CMake and its use in the LLVM build system to tell whether this is a bug in CMake or in how LLVM uses it:
`cmake --build . --target install` started to fail with
-- Installing: /home/sbergman/llvm/inst/lib/libc++.so
CMake Error at projects/libcxx/src/cmake_install.cmake:88 (file):
file RPATH_CHANGE could not write new RPATH:to the file:
/home/sbergman/llvm/inst/lib/libc++.so
Call Stack (most recent call first):
projects/libcxx/cmake_install.cmake:56 (include)
projects/cmake_install.cmake:48 (include)
cmake_install.cmake:76 (include)FAILED: CMakeFiles/install.util cd /home/sbergman/llvm/build && /usr/bin/cmake -P cmake_install.cmake
ninja: build stopped: subcommand failed.
where ~/llvm/inst/lib/libc++.so is a plain text file containing the single line
INPUT(libc++.so.1 -lc++abi)
and the relevant section of ~/llvm/build/projects/libcxx/src/cmake_install.cmake:78 is
if("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "xcxxx" OR NOT CMAKE_INSTALL_COMPONENT)
if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libc++.so" AND
NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libc++.so")
file(RPATH_CHECK
FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libc++.so"
RPATH "")
endif()
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE SHARED_LIBRARY FILES "/home/sbergman/llvm/build/lib/libc++.so")
if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libc++.so" AND
NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libc++.so")
file(RPATH_CHANGE
FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libc++.so"
OLD_RPATH "/home/sbergman/llvm/build/lib:"
NEW_RPATH "")
if(CMAKE_INSTALL_DO_STRIP)
execute_process(COMMAND "/usr/bin/llvm-strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libc++.so")
endif()
endif()
endif()
Bisecting CMake pointed at <https://gitlab.kitware.com/cmake/cmake/-/commit/2e1149874d34b63cc16c7330ce1ef5ef779e5140> "cmSystemTools: Support multiple binary formats" as the problematic change: Before that change, cmSystemTools::ChangeRPath -> AdjustRPath on a non-ELF file called
if (se_count == 0) {
return emptyCallback(emsg, elf);
}
calling MakeEmptyCallback's
if (newRPath.empty()) {
// The new rpath is empty and there is no rpath anyway so it is
// okay.
return true;
}
and thus returning true. But after the change ChangeRPathELF returns an empty std::optional, so that cmSystemTools::ChangeRPath returns false, causing the failure.
What would help my build along is the CMake change
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 3699be3a5a..7099581ab4 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2855,7 +2855,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) {
return result.value();
}
- return false;
+ return newRPath.empty();
}
bool cmSystemTools::SetRPath(std::string const& file,
~
However, I don't know whether RPATH_CHANGE legitimately gets called on that non-ELF libc++.so text file in the first place.