Build failure on Linux with CMake 3.22 ( RPATH_CHANGE)

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/
CMake Error at projects/libcxx/src/cmake_install.cmake:88 (file):
  file RPATH_CHANGE could not write new RPATH:

  to the file:


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/ is a plain text file containing the single line

INPUT( -lc++abi)

and the relevant section of ~/llvm/build/projects/libcxx/src/cmake_install.cmake:78 is

         RPATH "")
  file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE SHARED_LIBRARY FILES "/home/sbergman/llvm/build/lib/")
         OLD_RPATH "/home/sbergman/llvm/build/lib:"
         NEW_RPATH "")
      execute_process(COMMAND "/usr/bin/llvm-strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/")

Bisecting CMake pointed at <> "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 text file in the first place.

CMake maintains backwards compatibility. Any breakage that's not behind a policy is considered a bug.

Someone else seems to already have opened an issue: