Каталоги CMake include_directories не помогают находить файлы заголовков

#c #cmake

Вопрос:

Структура каталогов проекта такова:

 project
| bar
| | src
| | | src.cpp (include "a.hpp")
| | | CMakeLists.txt (3)
| | third_party
| | | a.hpp
| | CMakeLists.txt (2)
| main.cpp (include "bar/src/src.cpp")
| CMakeLists.txt (1)
 

CMakeLists1.txt:

 cmake_minimum_required(VERSION 3.15)
set(TARGET Foo)
project(${TARGET})
set( CMAKE_CXX_FLAGS "-std=c  11 -O3" )
add_subdirectory(bar)
add_executable(${TARGET}_out  main.cpp)
 

CMakeLists2.txt:

 include_directories(.)
include_directories(third_party)
add_subdirectory(src)
 

CMakeLists3.txt:

 add_library(${TARGET} SHARED src.cpp)
 

Однако проект не будет компилироваться, потому src.cpp что не может найти a.hpp . Я использовал

 get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
  message(STATUS "dir3='${dir}'")
endforeach()
 

чтобы проверить включенные каталоги из src папки, которая показала, что third_party была включена, почему бы не src.cpp найти заголовок, который уже был в включенном пути?

Если я перейду include_directories(third_party) от CMakeLists2 к CMakeLists1 (изменюсь на bar/third_party ), код компилируется как по волшебству, почему??

Комментарии:

1. Лучше вставить полное выходное сообщение CMake сюда.

Ответ №1:

«каталоги включения_» влияет на включаемые каталоги целевых объектов в этом CMakeLists.txt, и его потомков. Я думаю, проблема в том, что исполняемый файл добавлен (предназначен) в CMakeLists.txt 1; src.cpp на самом деле он не входит в область назначения/сборки CMakeLists 2, поэтому на него не влияют вызовы «include_directories» в CMakeLists 2.

Комментарии:

1. Я предполагаю, что add_subdirectory расширяет область действия, поэтому 2-потомок 1, а 3-2, верно? И странно, если я удалю add_exe в 1, т. Е. просто создам библиотеку, src.cpp теперь можно найти.h, почему?

2. Исполняемый файл предназначен для CMakeLists 1 (родитель 2), а библиотека-для CMakeLists 3 (потомок 2). Поэтому библиотека компилируется с каталогами include_, определенными в 2, в то время как executable-нет. Если исполняемый файл включал библиотеку, а не файл src.cpp, затем они оба скомпилируются.