В настоящее время я мигрирую несколько проектов 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
.