CMake share library with multiple executables

When you setup your build environment, you should put some thought into the following three topics (beside others, but for this discussion/answer I reduced it to the three I feel are relevant here):

  1. Dependecies / Coupling
  2. Deployment
  3. Teams

“Strong Coupling”

I came to think of the add_subdirectory() command as supporting “strong coupling” and your current setup implicitly supports:

  • A frequently changing common library
  • A single deployment (process and timing) for all your apps
  • A single team working on the complete source base
    • An IDE would show it all in one solution
    • You generate one build environment for everything

“Loose Coupling”

If you want a more “loose coupling” you could make use of external scripts in other languages or the use of CMake’s ExternalProject_Add() macro. So if you setup the common library (maybe even including “binary delivery”) and each app as a separate project you do support:

  • A less often changing common library
    • Probably with its own release cycles
  • An independent development/deployment cycle for each app
  • A team of different developers working on each app

A Mixture of Both

So as you can see there a lot of things to consider and CMake can give you support for all kind of approaches. Considering that your project might be in the early stages, you probably go by a mixed approach (not right away de-coupling the common library):

CMakeLists.txt

project(toplevel)
cmake_minimum_required(VERSION 3.1)

include(ExternalProject)

ExternalProject_Add(
    app1 
    SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/app1"
    PREFIX app1
    INSTALL_COMMAND ""
)
ExternalProject_Add(
    app2 
    SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/app2"
    PREFIX app2
    INSTALL_COMMAND ""
)

app1/CMakeLists.txt

project(app1)
cmake_minimum_required(VERSION 3.1)

add_subdirectory(../common common)

add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} common)

This will actually generate three build environments. One directly in your binary output directory and one each in app1 and app2 sub-directories.

And in such approaches you may want to think about common CMake toolchain files.

References

Leave a Comment