Archduke
Archduke

Reputation: 349

Adding headers in a Modern CMake way in a large project

I'm working on a project that encompasses an SDL-based game framework, an editor, and a game. The directory structure is shaping up to be something like this (edited for brevity)

├── CMake
├── Libraries
├── Resources
└── Source
    ├── Editor
    ├── Framework
    │   └── Source
    │       ├── AI
    │       │   ├── Private
    │       │   └── Public
    │       ├── Game
    │       │   ├── Private
    │       │   └── Public
    │       ├── Graphics
    │       │   ├── Private
    │       │   └── Public
    │       └── Networking
    ├── Game
    │   └── Source
    │       └── Runtime
    │           └── Launch
    │               ├── Private
    │               └── Public
    └── Server

My add_executable command is being ran in Game/Source/Runtime/Launch/Private, and is dependent on files from the other modules.

According to some CMake how-tos and the accepted response for the following question, the headers for a given target should be included in the add_executable call in order for them to be listed as dependencies in the makefile.

How to properly add include directories with CMake

My question is, what is the cleanest way to accomplish this, given the abundance of header files and directories in my project? I can't imagine that the best practice would be to maintain a huge list of files directly in the add_executable call, but I could be wrong.

I was thinking that each directory's CMakeLists.txt could be responsible for adding to a variable that would eventually be used in add_executable, but distributing that intent through so many files seems like poor practice. Is there a better way?

Upvotes: 0

Views: 1104

Answers (1)

Matthieu Brucher
Matthieu Brucher

Reputation: 22023

You can follow exactly the pattern in the link you sent. For each library (I suppose they are libraries/targets in CMake), use:

target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Private PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Public)

By doing this, you tell CMake that the Private folders are just for the current target, but if someone uses the target for another target, it should add the Public include directories.

Now, you just need to do:

target_link_libraries(${target} PRIVATE Framework_Source)

If Framework_Source is the name of a target. ${target} is the name of the target you are currently building.

Upvotes: 1

Related Questions