Чтобы соответствовать структуре каталога Вы указали, файлы CMakeLists.txt может выглядеть следующим образом:
/CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(Main)
add_subdirectory(externals/my_lib/src)
add_executable(my_main main.cpp)
target_link_libraries(my_main my_lib)
/externals/my_lib/src/CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(MyLib)
add_library(my_lib MyClass.cpp MyClass.h)
target_include_directories(my_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
Использование PUBLIC
в target_include_directories
вызова означает, что не только ваша библиотека имеет это как «включать путь», но так же любая цель связывания к нему.
Недостатком этой настройки является то, что вы также собираетесь подвергать любые внутренние заголовки my_lib
также потребляющим целям. Скажем, у вас также есть «Internal.h» как часть my_lib
, которую вы не хотите раскрывать. Вы можете сделать это, перемещая преднамеренно-публичные заголовки в отдельную папку, например. "Включают":
├── CMakeLists.txt
├── externals
│ └── my_lib
│ ├── CMakeLists.txt
│ ├── include
│ │ └── MyClass.h
│ └── src
│ ├── Internal.h
│ └── MyClass.cpp
└── main.cpp
Ваш верхнего уровня CMakeLists.txt не изменится, но /externals/my_lib/CMakeLists.txt (который перешел на уровень выше) теперь гласит:
cmake_minimum_required(VERSION 3.0)
project(MyLib)
add_library(my_lib src/MyClass.cpp src/Internal.h include/MyClass.h)
target_include_directories(my_lib
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
)
Теперь, поскольку папка «src» вашей библиотеки - PRIVATE
- my_lib
, main.cpp не сможет #include "Internal.h"
.
Благодарим вас, это сделало вещь намного яснее, и это действительно сработало! Правильно ли я предполагаю, что любые файлы в каталоге include могут теперь использовать Internal.h? –
«include» dir обычно содержит только заголовки. Эти заголовки должны содержать только '# include' другие заголовки в директории include. Скажем, «MyClass.h» cointained '#include" Internal.h "'. Это будет проблемой для чего угодно, в зависимости от 'my_lib', например. «main.cpp» имеет «#include» MyClass.h ». Компилятор знает, где найти «MyClass.h» - мы рассказывали об «externals/my_lib/include», но он не может найти «Internal.h», который нужен «MyClass.h». Таким образом, ни один из заголовков в «include» не должен ссылаться на файлы в «src». – Fraser
Если нет возможности избежать раскрытия «Internal.h» (часто в случае с кодом шаблона), это нормально разместить в подкаталоге «include» с именем «detail», чтобы указать потребителям библиотеки, что это своего рода частный код которые могут измениться без предупреждения и не должны быть действительно '# include'ed непосредственно ими. – Fraser