[CMake] Changing installation prefix triggers re-linking of all libraries
Michael Hertling
mhertling at online.de
Tue May 3 12:16:22 EDT 2011
On 05/03/2011 11:17 AM, Pere Mato Vila wrote:
>
>> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
>> PROJECT(PREFIX C)
>> SET(CMAKE_VERBOSE_MAKEFILE ON)
>> ADD_LIBRARY(f SHARED f.c)
>> INSTALL(TARGETS f
>> RUNTIME DESTINATION bin
>> LIBRARY DESTINATION lib
>> ARCHIVE DESTINATION lib)
>>
>> with ${CMAKE_SOURCE_DIR}/f.c containing just "void f(void){}". After
>> configuring/building/installing, a reconfiguration with a modified
>> CMAKE_INSTALL_PREFIX does not result in recompiling or relinking.
>
>
> Hi Michael,
>
> In you simple example adding SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") before ADD_LIBRARY(...) does trigger a re-build of the library when changing the length of CMAKE_INSTALL_PREFIX. The reason for this behavior was given by Alex Neundorf:
>
>> Then you set the install RPATH once to "/build/mato/ROOT/install/lib" and then
>> to "/build/mato/ROOT/install2/lib", which is one byte longer. So the binary
>> has to be created again with one byte more room for the install RPATH.
Yes, that's true, indeed, but one must distinguish two factors:
1. Basically, it's the incorporation of the CMAKE_INSTALL_PREFIX in the
library via CMAKE_INSTALL_RPATH that causes the library to be relinked
when CMAKE_INSTALL_PREFIX changes. This is why I have said that solely
changing the latter doesn't cause any recompilation or relinking; one
rather needs further interconnections for this to happen.
2. The, say, placeholder mechanism described by Alex is the reason why
the library is relinked in the *build tree* when CMAKE_INSTALL_RPATH's
length changes although the latter isn't incorporated in the library's
build-tree-instance due to CMAKE_BUILD_WITH_INSTALL_RPATH being FALSE.
If I understand correctly, it's this second point which causes your
astonishment, but it already happens during the build phase in the
build tree, not just when installing with "make install", right?
> The fact that the build is re-done because I change the length of the installation destination I would call this a bug and not really a feature.
IMO, it's not a bug, but even quite clever. The placeholder mechanism
allows to avoid a complete relink operation at installation time when
the final RPATH must be written to the installed binaries. Look at the
cmake_install.cmake script for the above-noted project with the line
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") you mentioned.
You will find a FILE(INSTALL ...) followed by a FILE(RPATH_CHANGE ...)
which operates on the already installed library. The latter command is
implemented by cmSystemTools::ChangeRPath() and probably much cheaper
than a full-featured invocation of the linker involving fork()/exec(),
the compiler's front-end, object files, libraries, LTO, recompilation
of automatically generated source code etc. In other words: Linking
might be expensive, but patching binaries is not.
Now, with the placeholder mechanism, you currently have two (re)link
operations: One for each CMAKE_INSTALL_PREFIX in the build tree, but
none during the two installations. Without the placeholder mechanism,
you'd need three operations: One in the build tree without the final
RPATHs or placeholders and one during each of the two installations.
Therefore, the placeholder mechanism is highly useful - despite the
potentially surprising relink operations within the build tree.
Regards,
Michael
More information about the CMake
mailing list