The project has roughly the following structure:
include/
lib_name/
public_foo.h
public_bar.h
src/
CMakeLists.txt
foo.c
foo.h
bar.c
bar.h
CMakeLists.txt
The top-level CMakeLists.txt file defines a shared library target
add_library(lib_name SHARED "src/foo.c" "src/bar.c")
At the same time, there’s a custom command
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/src/foo-impl.c" ...)
that generated foo-impl.c in the build directory that is included by `foo.c’ like this:
#include <some_header.h>
#include <other.h>
#include "foo-impl.c"
In order to be able to include foo-impl.cI do the following in src/CMakeLists.txt
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
Looks like it should work, right?
Well, it doesn’t work – the src directory is not added to compiler flags for foo.c. It seems like include directories affect only targets defined in the same directory (or subdirectories).
I know I can just do
include_directories("${CMAKE_CURRENT_BINARY_DIR}/src")
from the root CMakeLists.txt (in fact, this is how I’m doing it at the moment) but that’s not acceptable: every subdirectory will see the parent’s files and this can eventually lead to file name collisions.
How do people overcome this in large projects? or maybe I’m doing something wrong?
Like most cmake commands,
include_directoriesonly affects targets in that directory and subdirectories. And IIRC only targets defined after the command. That’s intentional. It’s how you define different flags for different modules.And when I say like most cmake commands, I really mean most. Most importantly including
add_definitionsandsetexcept withCACHEargument.Also remember, that
include_directoriesapples to targets, not files.Either define the library in the subdirectory (makes most sense to me), put everything in the top-level
CMakeLists.txtor set the flags on the target only usingset_target_properties(lib_name PROPERTIES COMPILE_FLAGS "-I${CMAKE_BINARY_DIR}/src")(must be done after the target is defined).