CMake – defining and reusing header files in multiple sub targets

I know, it is silly, but I have no idea how to fix this. I have an old C++ project made using VS and now I have to add CMake to it. The structure of the project is something like this:

PROJECT
|
- include
|       |
|       -folder
|             |-a.h
|             |
|             - folder
|                    b.h
|                ....
- lib1
|    |
|    CMakefiles.txt   
- lib2
|    |
|    CMakefiles.txt   
- main
|    |
|    CMakefiles.txt   
CMakefiles.txt

So, the include folder contains a lot of header files and those are organized in multiple subfolders. The project, beside the main (executable), defines a lot of shared libraries, some of them are dependent on other libraries. Each library folder has its own C++ header and source files. But almost each library includes headers from the include folder BUT just by the name (without path).

Basically I have two questions.

  1. How should I organize the CMake for this folder structure?
  2. How can I defining and reusing header files from the include folder for each library and the executable?

  • Are the headers in include header-only or implemented in one of the libraries? (or even multiple times)

    – 




  • The header files in the include folder are standalone headers. They contain only #define”s.

    – 

  1. In CMake projects its more common to have a root level src/ directory. This is totally optional, though, the structure you’ve provided above is fine. In each library subdirectory, define a target using the add_library command. There you can add any source files you want to that target.
  2. After adding the sources, the headers you have in your “include/” directory can be added to the target using the target_include_directories function. Similarly, dependencies on other libraries in your project, or external libraries can be added using the target_link_libraries command. An example of how that might look:
add_library(liba source1.cpp source2.cpp)

target_link_libraries(liba 
    libb
)

target_include_directories(liba
    PUBLIC
        ${CMAKE_SOURCE_DIR}/include
)

Keep in mind, a target only exists after it has been parsed. if liba depends on libb, you have to add_subdirectory(libb) first. External libraries will have to be added using either find_package, add_subdirectory or fetch_content

Leave a Comment