Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly add include directories with CMake

Tags:

c++

ubuntu

cmake

About a year ago I asked about header dependencies in CMake.

I realized recently that the issue seemed to be that CMake considered those header files to be external to the project. At least, when generating a Code::Blocks project the header files do not appear within the project (the source files do). It therefore seems to me that CMake consider those headers to be external to the project, and does not track them in the depends.

A quick search in the CMake tutorial only pointed to include_directories which does not seem to do what I wish...

What is the proper way to signal to CMake that a particular directory contains headers to be included, and that those headers should be tracked by the generated Makefile?

like image 549
Matthieu M. Avatar asked Dec 04 '12 13:12

Matthieu M.


People also ask

How do I include a directory in CMake?

To include headers in CMake targets, use the command target_include_directories(...) . Depending on the purpose of the included directories, you will need to define the scope specifier – either PUBLIC , PRIVATE or INTERFACE .

What is an include directory?

By convention, the contents of the include directory are the headers exposed for public consumption. The source directory may have headers for internal use, but those are not meant to be distributed with the compiled library.


2 Answers

Two things must be done.

First add the directory to be included:

target_include_directories(test PRIVATE ${YOUR_DIRECTORY}) 

In case you are stuck with a very old CMake version (2.8.10 or older) without support for target_include_directories, you can also use the legacy include_directories instead:

include_directories(${YOUR_DIRECTORY}) 

Then you also must add the header files to the list of your source files for the current target, for instance:

set(SOURCES file.cpp file2.cpp ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h) add_executable(test ${SOURCES}) 

This way, the header files will appear as dependencies in the Makefile, and also for example in the generated Visual Studio project, if you generate one.

How to use those header files for several targets:

set(HEADER_FILES ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)  add_library(mylib libsrc.cpp ${HEADER_FILES}) target_include_directories(mylib PRIVATE ${YOUR_DIRECTORY}) add_executable(myexec execfile.cpp ${HEADER_FILES}) target_include_directories(myexec PRIVATE ${YOUR_DIRECTORY}) 
like image 142
SirDarius Avatar answered Oct 07 '22 04:10

SirDarius


First, you use include_directories() to tell CMake to add the directory as -I to the compilation command line. Second, you list the headers in your add_executable() or add_library() call.

As an example, if your project's sources are in src, and you need headers from include, you could do it like this:

include_directories(include)  add_executable(MyExec   src/main.c   src/other_source.c   include/header1.h   include/header2.h ) 
like image 22
Angew is no longer proud of SO Avatar answered Oct 07 '22 06:10

Angew is no longer proud of SO