[CMake] cross platform build with external dependencies

Tom Gwozdz tgwozdz at bigvikinggames.com
Fri Sep 23 11:14:43 EDT 2016


Hello!

I'm working on a relatively large game engine project which consists of
several libraries and a few executables.  The project is supposed to be
cross platform, so should be buildable on OSX with XCode, Windows with
Visual Studio and for the web using the Emscripten cross-compiler.

The project also has a few external dependencies, libraries like pugixml,
glm, sdl2, gtest, etc.  Part of the goal is to make it super easy to build
across all the supported platforms, without having to go out and try to
track down dependencies manually for each platform.

Originally I had set this up as two projects.  There's a Engine project
which contains the libraries and executables that are built on all the
platforms.  There's also an Engine-External project which pulls in all our
dependency libraries using ExternalProject calls.  All of these get built
for a specific platform, and are then placed in
${CMAKE_INSTALL_PREFIX}/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}/${CMAKE_CXX_COMPILER_ID}
(for example Darwin/x86_64/AppleClang/).  The idea was that we could
eventually just build this once (since our dependencies aren't changing
very often), then just have everyone's build point at that installation and
it'll work for all their various platform builds.

Our project is mostly designed to be used as a library, so then there will
be other projects depending on our Engine project.  I've set up our Engine
project to install to a specific directory, and I exported all our symbols
there.  I also have an EngineConfig.cmake file set up that includes our
exported symbols, so 3rd party apps should be able to find our libraries
just fine.

My question is about the external dependencies that we've built in the
Engine-External project.  Currently a 3rd party project just depending on
our Engine project doesn't get all of those included transitively, since
those Engine-External symbols aren't being exported anywhere.  What would
be the best way of getting 3rd party projects to get our Engine-External
dependencies as well?

I can think of a few potential solutions, but I'm not sure what is the
intended CMake solution.

1. Have 3rd party library set its CMAKE_MODULE_PATH to point at both the
Engine install and the Engine-External/<platform>/ install.  Then do
find_package(Engine CONFIG REQUIRED), and do a find_package(...) for each
external dependency manually.  This is what we currently do, but I don't
really like this since 3rd party projects shouldn't have to care about our
external dependencies.

2. Have our EngineConfig.cmake have the find_package(...) calls for the
external dependencies itself.  The 3rd party project would still have to
set its CMAKE_MODULE_PATH to point at both the Engine and the
Engine-External/<platform>/ installs.

3. Option 2 could be simplified somewhat by installing both Engine and
Engine-External to the same place, so that CMAKE_MODULE_PATH would then
only have to point at one location.

4. Set up some kind of Engine-ExternalConfig.cmake that would have the
library imports for all our externals, and have 3rd parties then
find_package(Engine ...) and find_package(Engine-External ...) along with
the appropriate CMAKE_MODULE_PATH.

Are any of these valid approaches?  I'm reluctant to just install all the
Engine and Engine-External implementations globally, because there may be
multiple versions (ie. builds for various different platforms) on the same
machine.  Is there a better way of managing all this so that it works for a
bunch of different local, cross platform, and cross-compiling builds?

Thanks!
Tom
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20160923/95353276/attachment.html>


More information about the CMake mailing list