Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake: Include vs add_subdirectory: Relative header file path

Tags:

c++

cmake

I have a c++ project with several subdirectories, e.g.

src/
  CMakeLists.txt
  main.cpp
  module1/
     CMakeLists.txt
     code.cpp
     code.h
  module2/
     CMakeLists.txt
     code2.cpp

It seems that the two ways to deal with this in cmake is to either use add_subdirectory(module1) or include(module1) in my src/CMakeLists.txt. Somewhere I read, that the include use is regarded legacy/deprecated. My src/module1/CMakeLists.txt looks like this:

include_directories(${CMAKE_CURRENT_LIST_DIR})

set( SRCS
    ${SRCS}
    ${CMAKE_CURRENT_LIST_DIR}/code.cpp
   )

set( QT_FILE_HEADERS 
    ${QT_FILE_HEADERS} code.h
   )

If I try to use the add_subdirectory method and want to usecode.h in main.cpp I have to write #include "module1/code.h". If I do the include method of adding module1, I can simply write #include "code.h". I would prefer not to specify the relative path of the include files when I use them somewhere else, is there a way to achieve this using the add_subdirectory method? I thought the include_directories line should have taken care of that.

like image 368
numberCruncher Avatar asked Apr 23 '18 14:04

numberCruncher


1 Answers

This is not how you should make modules -- sure you can do it this way, it works, but it is not very useful. Given your layout, simply reference module1/code.cpp in the main CMakeLists.txt file.

However, if you want to use modules, make each one a separate static library. This will really simplify things!

In src/CMakeLists.txt write:

add_subdirectory(module1)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram module1)

In src/module1/CMakeLists.txt write:

add_library(module1 STATIC code.cpp)
target_include_directories(module1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

This way, you are only passing one single thing back from the module1 CMake script: the module1 target. Your main doesn't need to know anything about what happens inside there. If the code in module1 requires specific external libraries, link them there, the main CMake script won't need to know about it. Simply by linking to module1, all the magic will happen behind the scenes, your program will be compiled with the right include directories and linked to the right libraries.

like image 179
Cris Luengo Avatar answered Nov 15 '22 03:11

Cris Luengo