cmake включает зависимости, используя find_package из установленной цели - PullRequest
1 голос
/ 27 марта 2019

В настоящее время я мигрирую несколько проектов CodeBlock для использования CMake и Visual Studio Code.Я сталкиваюсь с проблемой, связанной с тем, что каталог включения не известен цели-потребителю.

Я следовал руководству, поскольку до сих пор не знал о "современном способе CMake", использующем цели вообще.В основном, ссылаясь здесь: https://rix0r.nl/blog/2015/08/13/cmake-guide/ и официальные документы CMake.Есть две библиотеки (.so).Одному из них нужно, чтобы другой был там (собрал), когда он будет загружен приложением позже.Я не уверен, что все предназначено для работы, как я предполагаю, что это работает, поэтому я просто продолжу с кодом и ожидаемым результатом.

Библиотека A (которая необходима Библиотеке B) имеет следующие CMakeLists

cmake_minimum_required(VERSION 3.0.0)
project(A)

set(SOURCE somesource.c)

include(GNUInstallDirs)

find_package(JNI REQUIRED)
add_library(JNI SHARED IMPORTED)
set_property(TARGET JNI PROPERTY INTERFACE_INCLUDE_DIRECTORIES $ENV{JAVA_HOME}/include $ENV{JAVA_HOME}/include/linux)
set_property(TARGET JNI PROPERTY IMPORTED_LOCATION ${JNI_LIBRARIES})

add_library(${PROJECT_NAME} SHARED ${SOURCE})

target_include_directories(${PROJECT_NAME} 
    PUBLIC 
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include $ENV{JAVA_HOME}/include $ENV{JAVA_HOME}/include/linux>
        $<INSTALL_INTERFACE:include>
)

install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Config
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

install(EXPORT ${PROJECT_NAME}Config DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake)

Обратите внимание: у меня есть только один включаемый файл, который является открытым и находится в «include», поэтому он используется самой библиотекой, но также должен быть частью интерфейса установки, используемого «потребляющей» целью.

Библиотека B (которая использует Библиотеку A и ее заголовок)

cmake_minimum_required(VERSION 3.0)
project(B)

set(SOURCE somesource.c)

add_library(${PROJECT_NAME} SHARED ${SOURCE})

find_package(A REQUIRED)

target_include_directories(${PROJECT_NAME}
    PRIVATE ${PROJECT_SOURCE_DIR}
)

Поэтому в Библиотеке BI предположим, что мне не нужно снова добавлять include_directories из Библиотеки A.Вот почему я на самом деле применил целевой подход, поэтому нет необходимости отслеживать зависимости компоновщика / включения."find_package" должен обрабатывать их самостоятельно?Я не делаю ссылки ни потому, что это общий объект, а не статическая библиотека.Обе библиотеки используют один и тот же CMAKE_INSTALL_PREFIX ofc, и библиотека A была установлена ​​(make install).Я дважды проверил это.В случае использования другого префикса или не установки, CMake уже жалуется, что не нашел его.

Итак, рассмотрим проблему сейчас: в исходном файле из библиотеки B я использую

#include <libcobjava.h>

, приводящий к ошибке при сборке, поскольку компилятор жалуется на «Нет такого файла или каталога». Я что-то упустил?Файл определенно находится по адресу CMAKE_INSTALL_PREFIX / include.

Кроме того, поскольку я все еще новичок в CMake: это даже так, как если бы у вас был весь источник?

РедактироватьНекоторые подробности о последующей проблеме, как обсуждалось в комментариях.Библиотека A - это libcobjava.

Сначала у меня была часть target_include_directories, как показано ниже (включая путь, где jni.h находится в $<INSTALL_INTERFACE:)

target_include_directories(${PROJECT_NAME} 
    PUBLIC 
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include $ENV{JAVA_HOME}/include $ENV{JAVA_HOME}/include/linux> 
        $<INSTALL_INTERFACE:include $ENV{JAVA_HOME}/include $ENV{JAVA_HOME}/include/linux>        
)

, приводит к следующей ошибке:

[cmake] Configuring done
[cmake] CMake Error in CMakeLists.txt:
[cmake]   Target "libcobjava" INTERFACE_INCLUDE_DIRECTORIES property contains path:
[cmake] 
[cmake]     "/media/rbs42/data/Gebos/RBS42/tools/libcobjava/${_IMPORT_PREFIX}/include"
[cmake] 
[cmake]   which is prefixed in the source directory.
[cmake] 
[cmake] 
[cmake] Generating done
[cms-driver] Error during CMake configure: [cmake-server] Failed to compute build system.

Вот почему я снова удалил $ENV{JAVA_HOME}/include $ENV{JAVA_HOME}/include/linux> из $<INSTALL_INTERFACE.

Фактическая ошибка, которую я сейчас получаю в библиотеке B, связана с компиляцией:

[build] /media/rbs42/data/rbs42/usr/include/libcobjava.h:1:10: fatal error: jni.h: No such file or directory
[build]  #include <jni.h>

потому что библиотека B не имеет каталогов включения из библиотеки A, которые не включены в $<INSTALL_INTERFACE.Это то, что можно ожидать.И по этой причине я добавил следующий код в библиотеку A.

set_property(TARGET JNI PROPERTY INTERFACE_INCLUDE_DIRECTORIES $ENV{JAVA_HOME}/include $ENV{JAVA_HOME}/include/linux)

, который, как я предполагал, заботится о распространении включаемых зависимостей из библиотеки A в «потребляющую» библиотеку B, хотя они не являются частью$<INSTALL_INTERFACE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...