我有一个交叉编译的cmake项目,该项目依赖于来自单独项目的库,该项目恰好也使用了cmake:
/myProject/CMakeLists.txt (uses cross-compiler)
/anotherProject/CMakeLists.txt (platform-agnostic)
另一个项目可以单独完全独立构建。它根本不了解myProject。
现在,另一个项目有许多我需要的模块,例如:
anotherProject/A/CMakeLists.txt (produces static lib A.a)
anotherProject/B/CMakeLists.txt (produces static lib B.a)
etc
当我构建myProject时,我想构建并链接另一个Project / A和另一个Project / B,以生成共享的lib myproject.so。如果可能的话,我想利用另一个项目的现有cmake-ness,而不是从myProject手动对其各种源集进行通配。
使用cmake实现这一目标的正确方法是什么?我觉得我错过了一些明显的东西。
如果,例如,myProject只是另一个项目下的子目录,或者如果有一个可以引用myProject和另一个项目的顶级CMakeLists.txt,那将是直截了当的;但是我所追求的也不是。我知道我可以构建另一个项目并将其库导出到一个众所周知的位置,然后从myProject引用导出目录 - 但我也想避免这种设置。
答案 0 :(得分:1)
解决方案是使用CMake packages。
基本上,在另一个项目中,您可以创建一个CMake配置文件,您可以在其中设置myProject使用的变量(例如,包含目录,库列表,编译标志......),甚至是目标。
然后,在myProject中,使用find_package()
机制,以便CMake找到此配置文件并导入当前项目中的变量/目标。
CMake维基上有tutorial。
答案 1 :(得分:0)
根据您的要求,我能想到的唯一替代设置是允许您的主(从属)项目使用find_package
发现另一个(dependee)项目。
在您的主项目CMakeLists.txt
中,您应该添加以下内容:
find_package(anotherProject CONFIG)
if(anotherProject_FOUND)
message(STATUS "Found project dependency: anotherProject")
else
# change WARNING to FATAL_ERROR if the dependency is NOT optional
message(WARNING "package anotherProject was not found")
endif()
关于CONFIG
和MODULE
模式之间的差异,请查看文档和link。
然后假设您的主项目创建了一个可执行文件,您可以像这样连接已发现的依赖项:
add_executable(myProject ${SOURCES})
[...]
if(anotherProject_FOUND)
target_link_libraries(myProject PUBLIC anotherProject)
endif()
这也应该处理所需的包含文件和定义。
现在在dependee项目CMakeLists.txt
中你应该这样做:
set(PRJ_NAME "anotherProject")
string(TOLOWER ${PRJ_NAME} PRJ_NAME_LOWER)
set(ANOTHERPROJECT_EXPORT_NAME "${PRJ_NAME}")
install(TARGETS ${PRJ_NAME} EXPORT ${ANOTHERPROJECT_EXPORT_NAME}
RUNTIME DESTINATION .)
install(EXPORT ${ANOTHERPROJECT_EXPORT_NAME} DESTINATION "share/cmake")
这会将导出与目标相关联,然后安装导出。
现在,如果您检查该导出文件,它会要求找到某些内容并include
d,这可能是您的项目所特有的。为了使其尽可能柔和,您可以使用configure
功能从模板生成它们,然后从构建目录生成install
。
因此,在名为share/cmake
的子目录下的项目中,您可以拥有一个名为config.cmake.in
的文件,其中包含内容:
include(${CMAKE_CURRENT_LIST_DIR}/@PRJ_NAME@.cmake)
在主项目CMakeLists.txt
中,您需要添加以下内容以从该模板生成文件:
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/share/cmake/config.cmake
${CMAKE_CURRENT_BINARY_DIR}/share/cmake/${PRJ_NAME_LOWER}-config.cmake)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/share/
DESTINATION share)
请注意,我使用了PRJ_NAME
,因为您可能会重用它来命名add_executable
命令中的实际可执行文件。如果导出的目标与生成的目标具有相同的名称,则在心理上有所帮助。
这是一个更通用的版本,可以容纳this教程的多个子项目。