[CMake] modularizing, specifying dependencies in a project

Geogin Varghese geogin at gmail.com
Wed Jan 3 13:46:19 EST 2018


Hello,

Recently came across these presentations on cmake:

Using Modern CMake Patterns to Enforce a Good Modular Design
(https://www.youtube.com/watch?v=bsXLMQ6WgIk)
Effective CMake
(https://www.youtube.com/watch?v=eC9-iRN2b04)

They encourage using target_* command variants for scripting
CMakeLists.txt.

What would be the recommended way of writing build scripts for a
repository structured as below. The application is compiled from three
modules with a dependency among the modules as in the ascii diagram.

Is it possible to distribute compile info, such that each submodule has
a CMakeLists.txt that describes sources, include and link dependencies needed
to compile that module.

---------------------------------------
.
├── main.cpp
├── ModA
├── ModB
├── ModC

Dependency relation:
--------------------
       +--------+
    +->+main.cpp+<-+
    |  +--------+  |
    |              |
    |              |
    |              |
  +----+        +----+
  |ModA|        |ModB|
  +----+        +----+
    ^              ^
    |              |
    |    +----+    |
    +----+ModC+----+
         +----+

ModA <- ModC: Module A
 depends on Module C
---------------------------------------

My naive effort to do this can be found here:
https://github.com/vargheseg/test

The problem I run into is with describing the dependency relation
between ModA, ModB and ModC.

Details:
.
├── CMakeLists.txt
├── main.cpp
├── ModA
│   ├── a.cpp
│   └── CMakeLists.txt
├── ModB
│   ├── b.cpp
│   └── CMakeLists.txt
├── ModC
│   ├── c.cpp
│   └── CMakeLists.txt

- CMakeLists.txt in the child directories describe compilation
  information for that directory.
- The top level directory includes the CMakeLists.txt from
  subdirectories.
- Cmake buildfile generation fails because the way I set things up; the
  top level CMakeLists.txt ends up including ModC/CMakeLists.txt twice.

---
CMakeLists.txt
---
 cmake_minimum_required(VERSION 3.0)
 project(test_project)

 include(${CMAKE_CURRENT_LIST_DIR}/ModA/CMakeLists.txt)
 include(${CMAKE_CURRENT_LIST_DIR}/ModB/CMakeLists.txt)

 add_executable(main main.cpp)
 target_link_libraries(main PRIVATE ModA ModB)


---
ModA/CMakeLists.txt
---
 include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
 add_library(ModA  $CMAKE_CURRENT_LIST_DIR}/a.cpp)
 target_link_libraries(ModA PRIVATE ModC)


---
ModB/CMakeLists.txt
---
 include(${CMAKE_CURRENT_LIST_DIR}/../ModC/CMakeLists.txt)
 add_library(ModB b.cpp)
 target_link_libraries(ModB
         PRIVATE
         ModC)

Is this way of structuring a project a supported use case?


More information about the CMake mailing list