[CMake] Trying to set up a "superbuild" with external project and install it...

Michael Hertling mhertling at online.de
Wed May 11 19:44:18 EDT 2011


On 05/11/2011 09:07 PM, Alexander Neundorf wrote:
> Hi,
> 
> I'd like to set up a kind of meta super project, which builds a bunch of 
> subprojects, which contains executable and shared libraries.
> These subprojects come from different repositories, mostly git repositories.
> 
> AFAIK I can basically do this using the ExternalProject_add() feature of 
> cmake, it will get the sources, configure and build them.
> 
> So far so good.
> 
> 
> Now, what do I do with installing ?
> Usually the external projects are installed at the end of their build step at 
> make-time, and usually somewhere in the build tree.
> 
> But finally I'd like to have these projects installed into a proper system-
> wide directory.
> 
> If I simply do install(DIRECTORY ... ) in the "superproject", stuff which 
> depends on CMAKE_INSTALL_PREFIX, like e.g. RPATH will be wrong after the final 
> install step (since the RPATHs will still point to the install locations in 
> the build tree).
> 
> If I put the final install location as install location in the 
> ExternalProject_Add() call, I will have to build with permissions to install 
> into the final install directory, which is generally not the case. E.g. to 
> install in /opt/ I would basically have to build as root (or change the 
> permissions of /opt/, but that's not possible on a standard system).
> 
> I could maybe also setuid cmake root (ugly too).
> 
> Always set a relative RPATH always using $ORIGIN ?
> (but this will be kind of hard to enforce)
> 
> Any other ideas ?
> Am I missing something ?
> Any ideas how support for this could be added in a clean way ?
> 
> Alex

A quite similar topic has been touched on recently in [1]. My personal
opinion on this particular issue with regard to subprojects is roughly:

1. In the end, each project - subproject or not - must be installed at
the location it has been configured for; this is the only bullet-proof
way to ensure that things like RPATH or incorporated paths derived from
the installation prefix, e.g. <prefix>/etc or /etc if <prefix> is /usr,
will work as expected, or in other words: Relocation after installation
is critical, unless it's taken into account by any appropriate measures.

2. For the, say, intermediate installation of a subproject in the build
tree of the superproject, I'd suggest to use the DESTDIR feature, i.e.:

- Configure and build the subproject with its final installation prefix.
- Install with "make DESTDIR=${CMAKE_BINARY_DIR}/externals" or the like
  with the superproject's CMAKE_BINARY_DIR. Thereafter, you could call
  FIND_PACKAGE() on the subproject with CMAKE_PREFIX_PATH and friends
  set to ${CMAKE_BINARY_DIR}/externals/${CMAKE_INSTALL_PREFIX}[/...]
  which may be important for the actual main project. Nevertheless,
  the subproject's binaries might not run if they strictly require
  to reside at the location they've been configured for.
- At the superproject's installation, use

INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/externals/${CMAKE_INSTALL_PREFIX}/
        DESTINATION ${CMAKE_INSTALL_PREFIX})

  to relocate the subprojects to their configured installation prefix.

3. In the worst case, i.e. subprojects whose binaries must be run from
within the superproject's build tree but insist on being run from the
configured installation prefix, one probably has to configure/build/
install the affected subprojects twice, for the intermediate and for
the final installation, and hope that this won't turn out as overly
expensive. E.g., CMake-aware subprojects could just be reconfigured
with a CMAKE_INSTALL_PREFIX equal to the superproject's one, rebuilt
and reinstalled. Usually, that's cheap to have and does also provide
an alternative to the above-mentioned DESTDIR-equipped intermediate
installation, but in special cases, the consequences possibly reach
right up to a subproject's complete recompilation, cf. [2].

Of course, the DESTDIR approach requires the subprojects to have a
DESTDIR mechanism, but besides CMake-aware projects, this is true
for Autotools-configured projects, too, AFAIK. Moreover, there're
additional chicanes on Windows due to the drive letters, e.g. a
"${CMAKE_BINARY_DIR}/externals/${CMAKE_INSTALL_PREFIX}/" won't
work out of the box. However, IMO, performing the intermediate
installation with a DESTDIR and the final relocation is a quite
systematic approach and particularly applicable if the subproject's
binaries don't need to run from within the superproject's build tree.

Regards,

Michael

[1] http://www.mail-archive.com/cmake@cmake.org/msg35892.html
[2] http://www.mail-archive.com/cmake@cmake.org/msg36128.html


More information about the CMake mailing list