I have the following CMakeLists.txt file which configures and builds just fine.
cmake_minimum_required (VERSION 3.22)
project (foo)
add_library (pglib SHARED IMPORTED)
set_target_properties (pglib PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/postgres16/lib/libpq.so)
target_include_directories (pglib INTERFACE ${CMAKE_CURRENT_LIST_DIR}/postgres16/include)
target_link_directories (pglib INTERFACE ${CMAKE_CURRENT_LIST_DIR}/postgres16/lib)
target_link_libraries (pglib INTERFACE pq)
add_executable (bar main.cpp)
target_include_directories (bar PUBLIC ./)
target_link_libraries (bar PUBLIC pglib)
if I replace postgres16/include
with postgres16/blabla
, then I get a configuration error and I cannot even try to build. That is what I want, obviously.
Now I separate the CMakeLists.txt file into two different ones in two different directories which I combine via add_subdirectory in a third CMakeLists.txt. My directory structure is as follows:
├── CMakeLists.txt
├── lib
│ ├── CMakeLists.txt
│ └── postgres16
│ └── ...
└── postgres_test
├── CMakeLists.txt
└── main.cpp
./CMakeLists.txt:
cmake_minimum_required (VERSION 3.22)
project (foo)
set (CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
add_subdirectory (lib)
add_subdirectory (postgres_test)
lib/CMakeLists.txt
cmake_minimum_required (VERSION 3.22)
add_library (pglib SHARED IMPORTED)
set_target_properties (pglib PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/lib/postgres16/lib/libpq.so)
target_include_directories (pglib INTERFACE ${PROJECT_SOURCE_DIR}/lib/postgres16/include)
target_link_directories (pglib INTERFACE ${PROJECT_SOURCE_DIR}/lib/postgres16/lib)
target_link_libraries (pglib INTERFACE pq)
postgres_test/CMakeLists.txt
cmake_minimum_required (VERSION 3.22)
add_executable (bar main.cpp)
target_include_directories (bar PUBLIC ./)
target_link_libraries (bar PUBLIC pglib)
Now I configure via mkdir build; cd build; cmake ..
and I see something wired. No error messages, remember that I replaced include with blabla?
So I fix the blabla, reconfigure and compile via cmake --build . --target all
. Now I get missing includes.
grep postgres16 compile_commands.json
shows nothing, which means that target_include_directories
where not honored as before when everything was in one CMakeLists.txt.
BTW, other error messages are emitted. For e.g. if I replace target_include_directories(bar INTERFACE ...)
with target_include_direcoties(bar PUBLIC...)
then I do get the error message that I need to use INTERFACE.
So my three questions are:
- why no error message for non existing include path when using
target_include_directories
in subdirectory? - why no warning message when target_include_directory is ignored for some reason?
- why are target_include_directories ignored in the first place when using
add_subdirectory
?