cmake include_directories order AFTER/BEFORE
I don't think this is a problem with CMake; I believe gcc will always find your "time.h" before the system one, regardless of whether you use quotes or brackets in the #include
and regardless of the various options in include_directories
. See the entries for -I
and -isystem
in the gcc documentation
The AFTER
option of CMake's include_directories
relates only to the order of the directories as listed in the gcc command, it doesn't relate to gcc's -idirafter
flag.
It's not a great plan to have your own files with identical names to system files, but if your hands are tied, you could avoid this issue without renaming time.h by qualifying the path for your own includes more fully, so rather than e.g.
CMakeLists.txt: include_directories(${PROJECT_SOURCE_DIR}/src)
header file: #include <time.h> // we want but don't get system one
#include "time.h" // we want and get own custom one
something more like
CMakeLists.txt: include_directories(${PROJECT_SOURCE_DIR})
header file: #include <time.h> // we want and get system one
#include "src/time.h" // we want and get own custom one
An alternative option would be to stick with your current #include
setup (using angle brackets for the system time.h and quotes for your own) and not use include_directories
at all in the CMakeLists.txt. Instead I think you could replace it with something like:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -iquote ${PROJECT_SOURCE_DIR}/src")
Using -iquote
is probably a better option than -idirafter
since the directory specified by -idirafter
is (in this case incorrectly) treated as a system directory, and as such has warnings suppressed, etc.
If you do go for this choice, it's probably worth commenting the CMakeLists.txt to explain why there is no include_directories
to avoid future refactoring reverting back to use the more normal include_directories
command.
All in all, your best option if at all possible would be to rename your "time.h" file though.
cmake - When to include include_directories in a CMakeLists.txt file
How to know whether a library should be included using
include_directories
ortarget_link_libraries
?
Unless a library is a header-only library, call to target_link_libraries
is required for use it.
If Find*
script (called by find_package()
call) sets variable with include directories (this information can be obtained from the script's documentation), it assumes that these directories will be included (via include_directories
or target_include_directories
).
Propagating include directories through the target_link_libraries
occurred in case of IMPORTED target, usually named as <namespace>::<name>
.
In your specific case include_directories
have no effect only because given directory is searched by a compiler by default, this is usual when library is installed through package manager. But find_package
is intended to work even with non-system installations.
How to properly add include directories with CMake
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})
Cmake include_directories()
Quoting the documentation for include_directories
:
The include directories are added to the directory property
INCLUDE_DIRECTORIES for the current CMakeLists file. They are also
added to the target property INCLUDE_DIRECTORIES for each target in
the current CMakeLists file. The target property values are the ones
used by the generators.
The INCLUDE_DIRECTORIES
directory property is inherited to all subdirectories and all targets in the directory.
- Specifying
${CMAKE_CURRENT_SOURCE_DIR}
forinclude_directories
is redundant as relative paths are interpreted as relative to this directory by default. You should throw it out to increase readability. - Specifying an include directory in both a subdirectory and its parent is redundant. You should avoid this and settle on one location.
- Use
get_property
andmessage
to double-check that all directories and targets end up with the correct entries in theirINCLUDE_DIRECTORIES
property. - If you are free to require CMake 2.8.11 as a minimum requirement, consider abandoning
include_directories
completely and usetarget_include_directories
instead. This has the advantage that include dependencies get resolved on a per-target basis exclusively which is usually the more desirable behavior.
What is the difference between include_directories and target_include_directories in CMake?
include_directories(x/y)
affects directory scope. All targets in this CMakeList, as well as those in all subdirectories added after the point of its call, will have the path x/y
added to their include path.
target_include_directories(t x/y)
has target scope—it adds x/y
to the include path for target t
.
You want the former one if all of your targets use the include directories in question. You want the latter one if the path is specific to a target, or if you want finer control of the path's visibility. The latter comes from the fact that target_include_directories()
supports the PRIVATE
, PUBLIC
, and INTERFACE
qualifiers.
Related Topics
Find Command in Bash Script Resulting in "No Such File or Directory" Error Only for Directories
Compile Swift Script with Static Swift Core Library
Start Rails Server Automatically When Ever I Start My Ubuntu MAChine
Is There a Clang Mingw Cross Compiler for Linux
Compressing the Core Files During Core Generation
Can't Install Freetds via Yum Package Manager
Converting Avi Frames to Jpgs on Linux
Erlang: Unix Domain Socket Support
Open O_Creat | O_Excl on Nfs in Linux
How Does Ancillary Data in Sendmsg() Work
How to Add a String to the Beginning of Each File in a Folder in Bash
Linux Mail < File.Log Has Content-Type: Application/Octet-Stream (A Noname Attachment in Gmail)
Kdevtmpfsi - How to Find and Delete That Miner
Run All Shell Scripts in Folder
Fast Way to Find Difference Between Two Strings of Equal Length in Perl