我目前正在迁移几个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}
)
因此,在库B中,我假定不需要再次从库A添加include_directories。这就是为什么我实际上采用了目标方法的原因,因此无需跟踪链接器/包含依赖项。 “ find_package”应该自己处理这些吗?我既不链接也不是因为它是共享库,也不是静态库。 两个库都使用相同的CMAKE_INSTALL_PREFIX ofc,并且已经安装了库A(进行安装)。我对此进行了仔细检查。如果使用其他前缀或不执行安装,CMake已经抱怨找不到该前缀。
所以现在考虑这个问题: 在库B的源文件中,我正在使用
#include <libcobjava.h>
在编译时由于编译器抱怨“没有这样的文件或目录”而导致错误,我是否缺少某些内容?该文件肯定位于 CMAKE_INSTALL_PREFIX / include。
除此之外,我还是CMake的新手:如果您拥有所有源代码,这甚至是您做事的方式吗?
首先,我具有以下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
的一部分。