target_include_directories — ИНТЕРФЕЙС не экспортирует путь включения

#cmake

Вопрос:

Я создал очень простой проект cmake для тестирования функций cmake. Каталог проекта содержит две библиотеки. Я хотел бы экспортировать путь включения MyLibA.

Основные CMakeLists.txt:

 cmake_minimum_required(VERSION 3.11)

project(TestProject)

add_subdirectory(MyLibA)
add_subdirectory(MyLibB)
 

Майлиба CMakeLists.txt:

 add_library(MyLibA SHARED)     
target_sources(MyLibA PRIVATE fileA.h fileA.cpp)
target_include_directories(MyLibA INTERFACE "${CMAKE_SOURCE_DIR}/MyLibA")
 

Майлибб CMakeLists.txt:

 add_library(MyLibB SHARED)

target_sources(MyLibB PRIVATE fileB.h fileB.cpp)
target_link_libraries(MyLibB PRIVATE /home/user/MyProjects/CmakeTestProject/build/MyLibA/libMyLibA.so)
 

Я экспортировал путь включения с использованием ключевого слова ИНТЕРФЕЙСА, но следующее включено в файл.h:

#include "fileA.h"

не найден. Что я делаю не так?

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

1. Вместо target_link_libraries(MyLibB PRIVATE <path/to/MyLibA/file>) использования target_link_libraries(MyLibB PRIVATE MyLibA) . Вот как предполагается использовать CMake: при соединении с целевым объектом библиотеки CMake автоматически преобразует его в путь и фактически распространяет все свойства интерфейса целевого объекта.

2. Работает, пожалуйста, преобразуйте свой комментарий в ответ.

Ответ №1:

Вместо

 target_link_libraries(MyLibB PRIVATE <path/to/MyLibA/file>)
 

использовать

 target_link_libraries(MyLibB PRIVATE MyLibA)
 

Вот как предполагается использовать CMake: при соединении с целевым объектом библиотеки CMake автоматически преобразует его в путь и фактически распространяет все свойства интерфейса целевого объекта.

Ответ №2:

Что я делаю не так?

Несколько вещей:

  1. Никогда не ставьте абсолютные пути в свой CMakeLists.txt и всегда ссылайтесь на целевые объекты, а не на библиотечные файлы.
 # Linking to a target propagates usage requirements, like include paths.
target_link_libraries(MyLibB PRIVATE MyLibA)
 
  1. CMAKE_SOURCE_DIR это не то, что ты думаешь. Он всегда ссылается на каталог сборки верхнего уровня, что является неверным предположением, если ваш проект может быть add_subdirectory FetchContent целью или. Ваше использование может быть заменено:
 # Not optimal, see below.
target_include_directories(MyLibA INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
 
  1. Отсутствует $<BUILD_INTERFACE:...> в пути включения, если вы собираетесь экспортировать свои цели. При экспорте целевых объектов их свойства дословно копируются в выходные данные. Отсутствие защиты локального пути включения с $<BUILD_INTERFACE:...> помощью приведет к разрыву пользователей экспортируемой цели.
 target_include_directories(
  MyLibA 
  INTERFACE
    "

lt;BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
)