llvm trunk build failed in cmake_install.cmake on ARM platform

Hi dear list,

I tried to build llvm+clang on an OpenSuse BuildServer for ARM. The build was carried out with CMake 2.8.11. In the installation step I got the following error:

[26815s] -- Installing: /home/abuild/rpmbuild/BUILDROOT/llvm-3.4.99-336.1.arm/usr/lib/libLLVMSupport.so
[26815s] CMake Error at lib/Support/cmake_install.cmake:45 (FILE):
[26815s] file RPATH_CHANGE could not write new RPATH:
[26815s]
[26815s] $ORIGIN/../lib
[26815s]
[26815s] to the file:
[26815s]
[26815s] /home/abuild/rpmbuild/BUILDROOT/llvm-3.4.99-336.1.arm/usr/lib/libLLVMSupport.so
[26815s]
[26815s] No valid ELF RPATH or RUNPATH entry exists in the file;
[26815s] Call Stack (most recent call first):
[26815s] cmake_install.cmake:48 (INCLUDE)
[26815s]
[26815s] make: *** [install] Error 1
[26815s] error: Bad exit status from /var/tmp/rpm-tmp.FHUFsz (%install)
[26815s]
[26815s] RPM build errors:
[26815s] Bad exit status from /var/tmp/rpm-tmp.FHUFsz (%install)

Any ideas for what might have gone wrong?

TIA,
Mathias

CMake by default links binaries in the build tree such that they can
be run immediately with no special environment by using RPATH/RUNPATH.
Then at installation time it has a builtin ELF editor that replaces
the build-tree RPATH with one for the install tree as specified by
the INSTALL_RPATH target property:

http://www.cmake.org/cmake/help/v2.8.12/cmake.html#prop_tgt:INSTALL_RPATH

When the desired install-tree RPATH is longer than the build tree
one then CMake adds bogus content to the end of the RPATH value for
the build tree to reserve space.

I'm not familiar with the tools for the platform in question, but
some linkers have a security feature that drops RPATH values that
are invalid. This sometimes trips up CMake's attempt at reserving
space for the install-tree RPATH. One may work around the problem
by telling CMake to build directly with the install-tree RPATH:

http://www.cmake.org/cmake/help/v2.8.12/cmake.html#variable:CMAKE_BUILD_WITH_INSTALL_RPATH
http://www.cmake.org/cmake/help/v2.8.12/cmake.html#prop_tgt:BUILD_WITH_INSTALL_RPATH

The cost is one may not be able to run the binaries from the build
tree. To set this for the whole build without modifying the source,
just add -DCMAKE_BUILD_WITH_INSTALL_RPATH=1 to the cmake command line
when configuring the project.

-Brad

Hi Brad,

We try to change cmake's behaviour so that it uses $ORIGIN in the rpath, making the binaries relocatable. That might be falling in here for some reason.

We try to change cmake's behaviour so that it uses $ORIGIN
in the rpath, making the binaries relocatable. That might
be falling in here for some reason.

Yes, we can see from the reported output:

[26815s] -- Installing: /home/abuild/rpmbuild/BUILDROOT/llvm-3.4.99-336.1.arm/usr/lib/libLLVMSupport.so
[26815s] CMake Error at lib/Support/cmake_install.cmake:45 (FILE):
[26815s] file RPATH_CHANGE could not write new RPATH:
[26815s]
[26815s] $ORIGIN/../lib
[26815s]
[26815s] to the file:
[26815s]
[26815s] /home/abuild/rpmbuild/BUILDROOT/llvm-3.4.99-336.1.arm/usr/lib/libLLVMSupport.so
[26815s]
[26815s] No valid ELF RPATH or RUNPATH entry exists in the file;

that CMake is trying to update the installed binary file's
RPATH to contain the $ORIGIN/../lib value. It complains
that no RPATH field at all is found in the file. The linker
may be dropping it for some reason, which is why I asked
Mathias to try:

just add -DCMAKE_BUILD_WITH_INSTALL_RPATH=1 to the cmake command line

We need to know whether this works. Either way, we also need
to see what the linker command line used to create the binary
in the build tree looks like.

-Brad

that CMake is trying to update the installed binary file's
RPATH to contain the $ORIGIN/../lib value. It complains
that no RPATH field at all is found in the file. The linker
may be dropping it for some reason, which is why I asked
Mathias to try:

Btw, an awesome way to fix this would be to set rpath to
$ORIGIN/../lib during the link itself. That way it doesn't need to be
update during install. Is there a way to do that with cmake?

Thanks,
Rafael

Use -DCMAKE_BUILD_WITH_INSTALL_RPATH=1 to skip RPATH support for
the build tree and link directly with the final installation RPATH.
See my first response in this thread for details.

However, CMake's install-time RPATH update is a widely used feature
that is known to work in general. (On non-ELF systems it even does
a preinstall step that re-links the binaries with the installation
tree RPATH.) There must be something particular to the ARM platform
linker or the way it is being invoked that prevents the RPATH field
from appearing in the binary, but we'll have to wait for Mathias to
report back.

-Brad

The point is that it is unnecessary for us. We can always use $ORIGIN.
That is what we have been doing with configure for ages. I have just tried
the attached patch and it fixes my last remaining reason for using
configure! :slight_smile:

Running "readelf -dW lib/LLVMgold.so" shows

0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/../lib]

Both in the build and in the install directory, which is exactly what we want.

I will try to port this to also work on OS X and not break windows and send for
code review.

Thanks,
Rafael

t.patch (855 Bytes)

Okay. Your proposed patch sets rpath flags manually. You can still
use CMake's infrastructure to do it:

  set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib")
  set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)

CMake will link directly with this RPATH and add the appropriate
flags on each platform.

-Brad

Hi,

sorry for the late response, we had some serious problems with our build system and our build engineer switched to the "configure" based build, so it took me some time to test the CMake build again.