Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set include_directories from a CMakeLists.txt file?

Tags:

cmake

I seem to be having trouble setting the include path (-I) using the include_directories() command in CMake. My project directory is as follows:

Root
| - CMakeLists.txt
| - libs
| - | - CMakeLists.txt
| - | - inc
| - | - | - // lib specific includes
| - | - src
| - | - | - // lib specific sources
| - proj1
| - | - CMakeLists.txt
| - | - inc
| - | - | - // proj1 specific includes
| - | - src
| - | - | - // proj1 specific sources

The root CMakeLists.txt file looks like so:

project(ROOT)
add_subdirectory(libs)
add_subdirectory(proj1)

The CMakeLists.txt file under libs:

project(lib)
add_library(lib STATIC ${lib_hdrs} ${lib_srcs}) // for conciseness, omitted set() 

And lastly, the CMakeLists.txt file under proj1:

project(proj1)

include_directories("${ROOT_SOURCE_DIR}/lib/inc") # <- problem line?

add_executable(proj1 ${proj1_srcs})
target_link_libraries(proj1 lib)

The goal is to create the library from the source and header files in libs, then link against the executable generated under proj1. Proj1 has some files that #include stuff in libs include, so I need to add the directories to be used with -I. Based on the documentation, that's what include_directories() is supposed to do. However despite explicitly setting that and following it with a debug message(${INCLUDE_DIRECTORIES}), the INCLUDE_DIRECTORIES variable is an empty string, and no directories are specified for the include path, so my compilation of proj1 fails.

I've also attempted removing the quotes around ${ROOT_SOURCE_DIR}/inc to see if that helped but no luck.

like image 215
HD_Mouse Avatar asked Oct 18 '13 23:10

HD_Mouse


People also ask

Where do I put CMakeLists txt?

CMakeLists. txt is placed at the root of the source tree of any application, library it will work for. If there are multiple modules, and each module can be compiled and built separately, CMakeLists. txt can be inserted into the sub folder.

What is the difference between Include_directories and Target_include_directories?

1, include_directories() is accessible for all the files in the source-tree 2, target_include_directories() is-only accessible for a specific target when compile.

How does Cmakelist TXT work?

CMakeLists. txt file contains a set of directives and instructions describing the project's source files and targets (executable, library, or both). When you create a new project, CLion generates CMakeLists. txt file automatically and places it in the project root directory.

What does Include_directories do in CMake?

Add include directories to the build. Add the given directories to those the compiler uses to search for include files. Relative paths are interpreted as relative to the current source directory.


1 Answers

include_directories() populates a directory property called INCLUDE_DIRECTORIES:

http://www.cmake.org/cmake/help/v2.8.12/cmake.html#prop_dir:INCLUDE_DIRECTORIES

Note that CMake 2.8.11 learned the target_include_directories command, which populates the INCLUDE_DIRECTORIES target property. http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:target_include_directories

Note also that you can encode the fact that 'to compile against the headers of the lib target, the include directory lib/inc is needed' into the lib target itself by using target_include_directories with the PUBLIC keyword.

add_library(lib STATIC ${lib_hdrs} ${lib_srcs}) # Why do you list the headers?
target_include_directories(lib PUBLIC "${ROOT_SOURCE_DIR}/lib/inc")

Note also I am assuming you don't install the lib library for others to use. In that case you would need to specify different header directories for the build location and for the installed location.

target_include_directories(lib
  PUBLIC
    # Headers used from source/build location:
    "$<BUILD_INTERFACE:${ROOT_SOURCE_DIR}/lib/inc>"
    # Headers used from installed location:
    "$<INSTALL_INTERFACE:include>"     
)

Anyway, that's only important if you are installing lib for others to use.

After the target_include_directories(lib ...) above you don't need the other include_directories() call. The lib target 'tells' proj1 the include directories it needs to use.

See also target_compile_defintions() and target_compile_options().

like image 181
steveire Avatar answered Sep 20 '22 15:09

steveire