Cmake:将子项目目标导出到主项目

ShS*_*ShS 6 c++ cmake relocation

我目前有一个名为LIBS的项目,其结构如下:

??? Lib1
?   ??? CMakeLists.txt
?   ??? lib1-class.cpp
?   ??? lib1-class.h
??? lib2
?   ??? CMakeLists.txt
?   ??? lib2-class.cpp
?   ??? lib2-class.h
??? cmake
?   ??? LIBSConfig.cmake.in
??? CMakeLists.txt                                                           
Run Code Online (Sandbox Code Playgroud)

在主cmake文件中,我有:

install(
        TARGETS
        lib1
        lib2
        DESTINATION
        ${PROJECT_DIRNAME_lib}
        EXPORT
        ${PROJECT_NAME}Exports
)

install(
        EXPORT
        ${PROJECT_NAME}Exports
        DESTINATION
        ${PROJECT_DIRNAME_lib}
)
Run Code Online (Sandbox Code Playgroud)

因为我想将它们导出到find_package()可以发现的包中.

我的问题是我生成lib1lib2在各自的目录中安装它们时,Cmake告诉我

Error:install TARGETS given target "lib1" which does not exist in this directory.
Run Code Online (Sandbox Code Playgroud)

正如这里所建议的,我的理解是我应该Export()在lib1和lib2中使用以下形式的东西:

export(TARGETS lib1 FILE lib1Exports.cmake)
Run Code Online (Sandbox Code Playgroud)

LIBS项目中,有这样的事情:

ADD_LIBRARY(lib1 UNKNOWN IMPORTED)
set_property(TARGET lib1 PROPERTY IMPORTED_LOCATION lib1)
Run Code Online (Sandbox Code Playgroud)

但是,它不喜欢我使用从父项目添加的此库的相同名称.它告诉我:

Error:add_library cannot create imported target "lib1" because another target with the same name already exists.
Run Code Online (Sandbox Code Playgroud)

所以库是可用的,我可以链接到它,如果我要在父目录中创建另一个目标,但我无法安装它.

我在这里的错误报告中发现了完全相同的问题,但我相信cmake现在处理的事情不同,我只是没有正确地做到这一点.我做错了吗?我想尽可能避免使用外部包.

更新:接受的解决方案仅适用于lib1,lib2之间没有依赖关系的情况.在这种情况下,应该使用提供给这个问题的解决方案.

Tsy*_*rev 7

如错误报告中所述,您所指install()命令应该从创建目标的同一目录发出。由于您在不同目录中创建了库目标,因此您需要为它们分配不同的导出名称,因此需要为不同的导出文件。

但是您可以自由地将两个导出文件包含到LIBSConfig.cmake脚本中:

cmake/LIBSConfig.cmake

get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
include(${SELF_DIR}/LIBS-lib1.cmake)
include(${SELF_DIR}/LIBS-lib2.cmake)
Run Code Online (Sandbox Code Playgroud)

lib1/CMakeLists.txt

add_library(lib1 ...)
install(TARGET lib1 EXPORT lib1-export ...)
Run Code Online (Sandbox Code Playgroud)

lib2/CMakeLists.txt

add_library(lib2 ...)
install(TARGET lib2 EXPORT lib2-export ...)
Run Code Online (Sandbox Code Playgroud)

CMakeLists.txt

add_subdirectory(lib1)
add_subdirectory(lib2)

install(EXPORT lib1-export FILENAME LIBS-lib1.cmake DESTINATION lib/LIBS)
install(EXPORT lib2-export FILENAME LIBS-lib2.cmake DESTINATION lib/LIBS)
install(FILES cmake/LIBSConfig.cmake DESTINATION lib/LIBS)
Run Code Online (Sandbox Code Playgroud)

请注意,该export命令导出构建树。它通常不适合find_package,它通常用于查找已安装的文件。