[CMake] How to depend on external cmake projects?

James Johnston JamesJ at motionview3d.com
Mon Aug 17 11:17:29 EDT 2015


> -----Original Message-----
> From: CMake [mailto:cmake-bounces at cmake.org] On Behalf Of Robert
> Dailey
> Sent: Sunday, August 16, 2015 13:32
> To: CMake
> Subject: [CMake] How to depend on external cmake projects?
> 
> There are certain repositories on Github I'd like to pull in as a
dependency.
> These repositories already use CMake to build their source code. Based on
> personal experience and reading material online, there are a couple of
> different options:
> 
> 1. Pull down the repository as a submodule to my own git repository.
> Then call add_subdirectory() on it to make it part of the build, allowing
me to
> refer to those targets as dependencies in my own targets.

That's one way to do it.  It might be a good way if the dependency is
relatively small.  Benefits:

 * Simpler/flattened build process (no hierarchy of makefiles are generated)
 * No need to delete timestamp files generated by ExternalProject_Add if you
need to incrementally build the project.

Problems:

 * Everything must be built with same compiler, generator, build settings,
etc. (benefit for some projects, a problem for others).
 * The dependency must use CMake.
 * Potential for interference between CMake variables/properties set by your
top-level project and your included submodule.  ExternalProject_Add is
guaranteed to work because this can't happen, but add_subdirectory is not
guaranteed to work.
 * Incrementally building a bunch of these projects, or a big project, could
be slow (e.g. your make tool has to check if the files in the submodule
changed, in addition to your own.  ExternalProject_Add sidesteps this with
the timestamps).

> 
> 2. Use ExternalProject_Add(). This seems like legacy, I'm not sure if I
should
> use this. It also seems very verbose and boilerplate.

I don't think it's legacy at all, lots of projects use it.  It exists
because of the problems of add_subdirectory shown above.  The downside is
you get these goofy timestamp files you have to manually delete now & again
if your submodule changes.

You can still include the project as a submodule, just use SOURCE_DIR
parameter to pass the submodule path and skip the preliminary steps before
CONFIGURE.

Even if CMake in the distant future supports different C++
compilers/architectures in the same project, there will still be a need to
build non-CMake dependencies and thus a place for ExternalProject. 

> 
> 3. Use packages. The [CMake package documentation][1] does not go into
> great detail on support for both installed versions and build tree for a
single
> package. Does this require two scripts? Can it share a single one? Where
are
> the examples?

Well, you'd do this in conjunction with ExternalProject_Add.  A well-written
CMake external project will provide a <project>Config.cmake file which you
will then find using find_package.

> 
> How do I accomplish this?
> 

A high-level CMake project that does nothing but call ExternalProject_Add;
this is called a superbuild.  Your own CMake projects will be
ExternalProjects to this high-level project and the superbuild would pass
the location to your project via -D<project>_DIR=<location> so that
find_package can locate the Config file.

Best regards,

James Johnston




More information about the CMake mailing list