MantisBT - CMake
View Issue Details
0012171CMakeCMakepublic2011-05-09 23:072016-06-10 14:31
Peter O'Gorman (The Written Word, Inc.) 
Kitware Robot 
normalmajoralways
closedmoved 
HP-UX/PAHP-UX 1111.31
CMake 2.8.4 
 
0012171: Runpaths incorrect for all hpux/pa_risc systems
Installing a build with shared libraries on this system causes builddir runpaths to be coded into the installed shared libraries and executables.

e.g.

/opt/TWWfsw/libproxy04/lib/libproxy.sl:
         shared library
         shared library dynamic path search:
             SHLIB_PATH disabled second
             embedded path enabled first /opt/TWWfsw/libproxy04/lib:/usr/lib
         internal name:
             libproxy.sl.1
         shared library list:
             static /opt/build/libproxy-0.4.6/libproxy/../libmodman/libmodman.sl.1
             dynamic /usr/lib/libnsl.1
             dynamic /usr/lib/libcma.2


Because ld is invoked with a command like
aCC -o /path/to/libproxy.sl.1 .... ../libmodman/libmodman.sl.1 ....

The library is added and its type is set to static, this means that the RPATH and env vars have no effect, if the library does not exist at /opt/build/libproxy-0.4.6/libmodman/libmodman.sl.1 the executable will abort.
Build libproxy on HP-UX/PA 32bit. (the 64 bit linker behaves differently).
Attached is the hack that we used to let hpux builds use -L.. -lfoo, which makes the entry "dynamic" so that SHLIB_PATH and the RPATH can have a chance to work. This includes a hack to the install to add -L flags for every path in RPATH prior to other -L paths, this allows us to do 'make install' then rm all the relinked binaries in the build dir, do 'make install' again and have no references to the build dir appear in the installed libraries, because the second relink will use the installed libraries.

Relinking happens in a 'preinstall' rule, and I don't know how to move it to an install rule. If it were in the install: rule then it would work well. Assuming that cmake installs things in dependency order (it appears to, but I don't know if that is guaranteed), we would, for libproxy for example, relink libmodman, install libmodman, relink libproxy using the installed libmodman, install libproxy, relink the 'proxy' utility using both installed libraries, install proxy, and all the embedded paths would be correct. Time permitting, I will continue to look at fixing this properly.
No tags attached.
related to 0012173closed Kitware Robot runpaths incorrect on IRIX 
patch cmake.hack.patch (6,615) 2011-05-09 23:07
https://public.kitware.com/Bug/file/3859/*
Issue History
2011-05-09 23:07Peter O'Gorman (The Written Word, Inc.)New Issue
2011-05-09 23:07Peter O'Gorman (The Written Word, Inc.)File Added: cmake.hack.patch
2011-05-10 10:25Brad KingRelationship addedrelated to 0012173
2011-05-10 11:27Brad KingAssigned To => Brad King
2011-05-10 11:27Brad KingStatusnew => assigned
2011-05-10 11:28Brad KingNote Added: 0026477
2011-05-10 12:12Peter O'Gorman (The Written Word, Inc.)Note Added: 0026479
2011-05-10 13:23Brad KingNote Added: 0026480
2011-05-10 13:58Peter O'Gorman (The Written Word, Inc.)Note Added: 0026482
2011-05-10 14:05Brad KingNote Added: 0026483
2011-05-10 14:08Brad KingNote Added: 0026484
2011-05-10 14:08Brad KingAssigned ToBrad King =>
2011-05-10 14:08Brad KingStatusassigned => backlog
2011-05-10 14:39Peter O'Gorman (The Written Word, Inc.)Note Added: 0026485
2011-05-10 14:46Brad KingNote Added: 0026486
2016-06-10 14:28Kitware RobotNote Added: 0041838
2016-06-10 14:28Kitware RobotStatusbacklog => resolved
2016-06-10 14:28Kitware RobotResolutionopen => moved
2016-06-10 14:28Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0026477)
Brad King   
2011-05-10 11:28   
We used to use -L... -lfoo for ALL linking but had no end of problems with the linker finding the wrong "foo" (shared v. static, circular path ordering constraints, etc.). We really need to continue using full paths to libraries.

Is it possible to specify a file by full path to the linker but get a dynamic entry in the binary?
(0026479)
Peter O'Gorman (The Written Word, Inc.)   
2011-05-10 12:12   
I understand the advantage of using full paths, but don't really think that the current solution is ideal.

If relinking happened in the install rule, and files were installed in dependency order then the installed locations could be encoded into the binaries and the entries changed from static to dynamic using chatr(1)'s -l flag.

chatr `chatr $File | awk '/ static / {printf "-l" $2 " "}'` $File

will change all static entries to dynamic.
(0026480)
Brad King   
2011-05-10 13:23   
The relinking implementation was originally written on Linux and predates the ELF editor. On Linux there were no problems with linking the relinked binaries to the build-tree copies of their dependencies instead of each other. The only difference between the original and relink cases is the RPATH on the command line. Therefore there is no support right now for relinking targets in the right (i.e. dependency) order or linking them to each other.

It does not make sense IMO to install one binary and then relink its dependents against the installed copy. CMake supports relocatable install trees, DESTDIR, etc., so the location of a library file where it happens to be put by "make install" should not be depended upon. Relinking should all be done in the staging area already used in the build tree by the "preinstall" step. Only the following is missing:

  - Relink in dependency order
  - Link to relinked copies of dependencies
  - Reference dependencies as dynamic rather than static entries

The first two are a general problem for the relinking implementation. The last one is specific to this toolchain.

FYI, CMake has never been developed or tested for hpux/pa_risc. Only platforms for which a contributor supplies a nightly testing submission to our dashboard:

  http://www.cdash.org/CDash/index.php?project=CMake [^]

are considered officially supported. Currently there is only an ia64 HP with ELF binaries so it uses install-time editing instead of relinking. What binary format does hpux/pa_risc use?
(0026482)
Peter O'Gorman (The Written Word, Inc.)   
2011-05-10 13:58   
32 bit pa-risc uses SOM:
http://en.wikipedia.org/wiki/System_Object_Model_(file_format) [^]

64 bit is ELF.
(0026483)
Brad King   
2011-05-10 14:05   
- Does CMake do the ELF editing at install time instead of relinking in the 64-bit case?

- I do not have access to a pa_risc system, but the ia64 system I mentioned in 0012171:0026480 does not produce static entries when linking by full path.

- One can set CMAKE_BUILD_WITH_INSTALL_RPATH to skip relinking altogether and just use the final install-tree RPATH values.
(0026484)
Brad King   
2011-05-10 14:08   
Moving to backlog as the needed changes are more significant than I have time to address myself. I'm happy to guide a volunteer to contribute a solution though. There are at least 2 approaches to solving the RPATH update problem:

(a) Fix the relinking implementation as described in 0012171:0026480
(b) Write a SOM editor similar to the current ELF editor to avoid relinking altogether
(0026485)
Peter O'Gorman (The Written Word, Inc.)   
2011-05-10 14:39   
Thanks for all your help on this. We haven't tried 64 bit PA-RISC yet, for IA64 though, we ran into problems at install using the ELF editor:
  file RPATH_CHANGE could not write new RPATH:

    /opt/TWWfsw/libproxy04/lib:/usr/lib

  to the file:

    /opt/TWWfsw/libproxy04/lib/libmodman.so.1.0.0

  The current RUNPATH is:

    /usr/lib

  which does not contain:

    /usr/lib:::::::::::::::::::::::::::

  as was expected.


Looks like the same problem as IRIX, the linker is removing the padding, I could not get this to work by appending a / though, it still stripped the ':'s

cc -b -Wl,-h,libtest.so -Wl,+nodefaultrpath -o libtest.so a.o -Wl,+b,'/opt/foo:::::::::::::::::::'

% elfdump -L libtest.so | grep Runpath
0 Runpath /opt/foo

Simplest fix would appear to be to pad with something else.
cc -b -Wl,-h,libtest.so -Wl,+nodefaultrpath -o libtest.so a.o -Wl,+b,'/opt/foo://///////////////'
elfdump -L libtest.so | grep Runpath
0 Runpath /opt/foo://///////////////

for example.
(0026486)
Brad King   
2011-05-10 14:46   
The padding is added by cmComputeLinkInformation::GetRPathString in Source/cmComputeLinkInformation.cxx. I don't think we can hard-code use of '/' for padding on all platforms because IIRC some toolchains will remove paths that do not exist from the list. It could be configured with a variable like CMAKE_PLATFORM_RPATH_PLACEHOLDER_END added in

  http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8fc3baba [^]

Perhaps you can rename that variable to CMAKE_PLATFORM_RPATH_PAD and generalize it for use as the only means of padding (and use the separator if it is not set).
(0041838)
Kitware Robot   
2016-06-10 14:28   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.