[libcxx-dev] Build failure on Linux with CMake 3.22 (libc++.so RPATH_CHANGE)

Stephan Bergmann via libcxx-dev libcxx-dev at lists.llvm.org
Mon Nov 29 04:50:29 PST 2021


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.



More information about the libcxx-dev mailing list