使用来自已安装目标的find_package来cmake包含依赖项

时间:2019-03-27 08:26:46

标签: c++ c cmake

我目前正在迁移几个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的新手:如果您拥有所有源代码,这甚至是您做事的方式吗?

编辑:有关后续问题的更多详细信息,如评论中所述。库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的一部分。

0 个答案:

没有答案