MantisBT - CMake
View Issue Details
0013934CMakeCMakepublic2013-02-19 12:072016-06-10 14:31
Dimitri Merejkowsky 
Peter Kuemmel 
normalblockalways
closedmoved 
 
 
0013934: cannot find relink libraries at installation when cross-compiling with Ninja
Trying to install libraries when cross-compilig failes because "relink" target is not found

This in unfortunate because it makes it impossible to deploy cross-compiled
code when using Ninja
> sh build.sh cross.cmake

+ rm -fr build
+ mkdir build
+ cd build
+ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=cross.cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dmerejkowsky/src/master/ninjabug/build
+ cd build
+ ninja
[4/4] Linking C shared library libbar.so
+ rm -fr /tmp/inst
+ cd build
+ DESTDIR=/tmp/inst
+ ninja install
[1/1] Install the project...
FAILED: cd /home/dmerejkowsky/src/master/ninjabug/build && /home/dmerejkowsky/src/3rdpart/cmake/build/bin/cmake -P cmake_install.cmake
-- Install configuration: ""
CMake Error at cmake_install.cmake:36 (FILE):
  file INSTALL cannot find
  "/home/dmerejkowsky/src/master/ninjabug/build/CMakeFiles/CMakeRelink.dir/libbar.so".

ninja: build stopped: subcommand failed.


Note that when not specifying a toolchain file, this works just fine:

+ rm -fr build
+ mkdir build
+ cd build
+ cmake -G Ninja ..
-- The C compiler identification is GNU 4.7.2
-- Check for working C compiler using: Ninja
-- Check for working C compiler using: Ninja -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dmerejkowsky/src/master/ninjabug/build
+ cd build
+ ninja
[4/4] Linking C shared library libbar.so
+ rm -fr /tmp/inst
+ cd build
+ DESTDIR=/tmp/inst
+ ninja install
[1/1] Install the project...
-- Install configuration: ""
-- Installing: /tmp/inst/usr/local/lib/libbar.so
-- Removed runtime path from "/tmp/inst/usr/local/lib/libbar.so"
Configuration:

* linux64 bits

* ninja from git: 27f7528

* cmake from git: 2.8.10.20130214-g6323
No tags attached.
gz ninjabug.tar.gz (650) 2013-02-19 12:07
https://public.kitware.com/Bug/file/4647/ninjabug.tar.gz
tar ninja-solution.tar (10,240) 2013-12-06 07:49
https://public.kitware.com/Bug/file/5005/ninja-solution.tar
Issue History
2013-02-19 12:07Dimitri MerejkowskyNew Issue
2013-02-19 12:07Dimitri MerejkowskyFile Added: ninjabug.tar.gz
2013-02-19 12:11Dimitri MerejkowskyNote Added: 0032339
2013-02-19 12:58Brad KingNote Added: 0032340
2013-02-19 12:58Brad KingAssigned To => Peter Kuemmel
2013-02-19 12:58Brad KingStatusnew => assigned
2013-02-19 13:06Dimitri MerejkowskyNote Added: 0032341
2013-02-19 13:15Dimitri MerejkowskyNote Edited: 0032341bug_revision_view_page.php?bugnote_id=32341#r1040
2013-02-19 14:58Alex NeundorfNote Added: 0032342
2013-02-19 15:14Brad KingNote Added: 0032343
2013-02-20 03:47Dimitri MerejkowskyNote Added: 0032350
2013-02-20 03:47Dimitri MerejkowskyNote Edited: 0032350bug_revision_view_page.php?bugnote_id=32350#r1042
2013-11-27 04:13ctafNote Added: 0034583
2013-12-06 03:55LCID FireNote Added: 0034730
2013-12-06 07:48Peter KuemmelAssigned ToPeter Kuemmel =>
2013-12-06 07:49Peter KuemmelFile Added: ninja-solution.tar
2013-12-06 07:52Peter KuemmelNote Added: 0034731
2013-12-06 07:57Peter KuemmelNote Added: 0034732
2013-12-06 10:02Brad KingNote Added: 0034734
2013-12-06 10:02Brad KingAssigned To => Peter Kuemmel
2013-12-06 10:05Peter KuemmelNote Added: 0034735
2013-12-06 10:05Peter KuemmelStatusassigned => backlog
2013-12-06 10:07Brad KingNote Added: 0034736
2013-12-06 10:09Brad KingNote Added: 0034737
2013-12-06 10:23LCID FireNote Added: 0034738
2013-12-06 11:16Brad KingNote Added: 0034740
2013-12-06 13:54Peter KuemmelNote Added: 0034741
2013-12-07 05:23Dimitri MerejkowskyNote Added: 0034742
2013-12-09 09:11Brad KingNote Added: 0034756
2013-12-09 14:32Dimitri MerejkowskyNote Added: 0034765
2014-11-06 10:11Cristian AdamNote Added: 0037157
2014-11-06 10:20Brad KingNote Added: 0037158
2016-06-10 14:28Kitware RobotNote Added: 0042228
2016-06-10 14:28Kitware RobotStatusbacklog => resolved
2016-06-10 14:28Kitware RobotResolutionopen => moved
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0032339)
Dimitri Merejkowsky   
2013-02-19 12:11   
I've found a workaround:

setting

set(CMAKE_EXECUTABLE_FORMAT "ELF")

in the toolchain file solves the problem.

But after this, incremental builds no longer work
(0032340)
Brad King   
2013-02-19 12:58   
I can reproduce this with CMake 2.8.10.20130218-g0579f0 and Ninja git e758e8d0. The Unix Makefiles generator works fine.

FYI, CMakeLists.txt should not use CMAKE_FORCE_C_COMPILER. The CMakeForceCompiler module documentation states that it is for toolchain files only. Nevertheless, I can remove it from CMakeLists.txt and still reproduce the issue.

Setting CMAKE_EXECUTABLE_FORMAT to ELF in the toolchain file allows CMake to skip relinking to change RPATHs for installation and instead use its builtin ELF editor. Normally CMake detects this automatically but CMAKE_FORCE_C_COMPILER skips such detection and requires the toolchain file to set such information. Even without this issue you may still want to set it. What do you mean by "incremental builds no longer work"?
(0032341)
Dimitri Merejkowsky   
2013-02-19 13:06   
(edited on: 2013-02-19 13:15)
> but CMAKE_FORCE_C_COMPILER skips such detection and requires the toolchain file to set such information.

Actually I did not find clear docs about what should and should not be in the toolchain file ...

Anyway, what's bothering me is that it works fine when cross-compiling using Unix Makefiles

Based on what I've seen in the source code, it looks like the detection is done twice: once for knowing whether to add a new "relink" target, and an other time when writing the cmake_install file, but I'm not sure

Also, there's this TODO:

 // TODO: Add ELF check to ABI detection and get rid of
 // CMAKE_EXECUTABLE_FORMAT.

maybe this is not hard to do ?

I'll be more than happy to try and ipmlement this :)

> What do you mean by "incremental builds no longer work"?

$ touch foo.cpp
$ <deploy>

-> libfoo.so is seen as up to date and is not relinked

(0032342)
Alex Neundorf   
2013-02-19 14:58   
More a workaround: I think when cross compiling it usually doesn't make a lot of sense to have an RPATH for build host, since you usually cannot execute the code on the build host anyway.
So how about skipping the build rpath and building directly with the install rpath ?
This should avoid the need for the relinking.
(0032343)
Brad King   
2013-02-19 15:14   
Re 0013934:0032341: I assigned this to Peter K specifically to investigate why the Ninja generator behaves differently from Unix Makefiles.

The TODO about CMAKE_EXECUTABLE_FORMAT, if resolved, would still not help this case because the ABI check it mentions is skipped by CMAKE_FORCE_C_COMPILER.

I cannot reproduce broken incremental builds. It works fine for me in your test case with CMAKE_EXECUTABLE_FORMAT set to ELF in the toolchain file.
(0032350)
Dimitri Merejkowsky   
2013-02-20 03:47   
@Alex Neundorf: Sounds reasonable to me

@Brad King: Thanks. I'll try to write a minimal example to reproduce the
broken incremental builds.

(0034583)
ctaf   
2013-11-27 04:13   
As a big hack... calling set(CMAKE_PLATFORM_HAS_INSTALLNAME 1) fix the issue. (it force using chrpath).

I added that to /usr/share/cmake-2.8/Modules/Platform/Linux-GNU.cmake to workaround the issue, til a proper fix is found.
(0034730)
LCID Fire   
2013-12-06 03:55   
Is this a WONTFIX? I need cmake & ninja to build a library without any user intervention, so patching cmake is out of question.
Setting CMAKE_PLATFORM_HAS_INSTALLNAME in CMakeLists.txt also did not help.
Strangely when I generate makefiles, this breaks even more.
(0034731)
Peter Kuemmel   
2013-12-06 07:52   
Put in in cross.cmake only your compiler path
set(CMAKE_C_COMPILER ${MYPATH}gcc CACHE PATH "Cross C compiler" FORCE)

and remove in CMakeLists.txt
include(CMakeForceCompiler)
CMAKE_FORCE_C_COMPILER("gcc" GNU)

and it works, see ninja-solution.tar.
(0034732)
Peter Kuemmel   
2013-12-06 07:57   
You could also drop cross.cmake completely and just call cmake with -Dcross=1:


cmake_minimum_required(VERSION 2.8)
if(cross)
    set(CMAKE_C_COMPILER ${MYPATH}gcc CACHE PATH "Cross C compiler" FORCE)
endif()
project(foo C)


be sure you set CMAKE_C_COMPILER before calling project().
(0034734)
Brad King   
2013-12-06 10:02   
Peter, the Ninja generator is missing logic for preinstall and NeedRelinkBeforeInstall code paths from the Makefile generators.
(0034735)
Peter Kuemmel   
2013-12-06 10:05   
Ah, Ok, but I never hat problems with cross-compiling.
(0034736)
Brad King   
2013-12-06 10:07   
Re 0013934:0034583, 0013934:0034730: One approach is that discussed in 0013934:0032339 and 0013934:0032340. By setting CMAKE_EXECUTABLE_FORMAT to "ELF" in the toolchain file you tell CMake that it can use its builtin ELF editor instead of relinking. Another approach is as suggested in 0013934:0034731 to not "force" the compiler (which bypasses the code that detects ELF).
(0034737)
Brad King   
2013-12-06 10:09   
Re 0013934:0034735: There are two problems under discussion here. One is that cross-compiling to an ELF target needs to be done with a toolchain file that tells CMake it is ELF in order to avoid relinking. The other is that compiling with Ninja and targeting a non-ELF platform that has RPATH (e.g. on commercial UNIX systems), whether cross-compiling or not, will not install correctly because the relinking the installation code expects to happen does not. For that the Ninja generator must implement preinstall.
(0034738)
LCID Fire   
2013-12-06 10:23   
@Brad_King is the relinking only necessary because of the rpath?
(0034740)
Brad King   
2013-12-06 11:16   
Re 0013934:0034738: Yes. CMake by default links binaries so they can run in the build tree, so their RPATH points at build tree locations. This is not desirable for installation so CMake needs to change the RPATH to a different value (or remove it) during installation. For ELF CMake knows how to edit the binaries as they are installed. For other binary formats that support RPATH CMake needs to re-run the linker with the new RPATH options. That is done during the "preinstall" step which is a dependency of "make install" and is missing from "ninja install".

FYI, one can use CMAKE_BUILD_WITH_INSTALL_RPATH to tell CMake to put the install-tree RPATH in the build-tree binaries so that no relinking or editing is needed on installation (at the cost of not easily running in the build tree):

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 [^]
(0034741)
Peter Kuemmel   
2013-12-06 13:54   
I can confirm that setting RPATH with a ELF cross-compiler works.
(0034742)
Dimitri Merejkowsky   
2013-12-07 05:23   
What if I just want to install some components ? (so calling 'make install' won't do)

Doc says I should use something like `cmake -DCOMPONENT="runtime" -Pcmake_install.cmake`

But in this case, should I call 'make preinstall' to make sure relinked libraries have been built ?

Or is there something I'm missing there ?
(0034756)
Brad King   
2013-12-09 09:11   
Re 0013934:0034742: Yes, you need to run "make preinstall" first in that case.

To which document do you refer?
(0034765)
Dimitri Merejkowsky   
2013-12-09 14:32   
I think I only found traces of it on stack overflow, actually:

http://stackoverflow.com/questions/9190098/for-cmakes-install-command-what-can-the-component-argument-do [^]

But I also found out you already answered this very question in an old thread
http://www.cmake.org/pipermail/cmake/2006-October/011362.html [^]

:)
(0037157)
Cristian Adam   
2014-11-06 10:11   
Problem reproduces also on QNX 6.5.1 on Windows using ninja.

make install works fine, while ninja install doesn't.

Adding set(CMAKE_PLATFORM_HAS_INSTALLNAME 1) to "cmake\share\cmake-2.8\Modules\Platform\QNX.cmake" fixed the problem.
(0037158)
Brad King   
2014-11-06 10:20   
Re 0013934:0037157: See also the workaround mentioned at the end of 0013934:0034740. That comment also explains what fix is needed upstream (implement preinstall in Ninja).
(0042228)
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.