【CMake】依赖包调用一瞥

花了一天,终于把 IK 系列连接在了一起,这一波硬读代码,属实有些影响生活了!

本文将列出几个载入外部包的方法,代码已同步至 timrockefeller/IKCMake

从二进制文件开始

一般来说,我们可以通过 add_executable()add_library() 来创建将要 Build 的对象,并为它提供 SRC、INC、LIB 文件以编译并链接。而当生成的库文件需要被使用者使用时,需要用 install(TARGETS) 声明,下面的代码可以将 target_name 对象作为 ${PROJECT_NAME}Targets 成员对外封装:

1
2
3
4
5
6
7
install(
TARGETS ${target_name}
EXPORT "${PROJECT_NAME}Targets"
RUNTIME DESTINATION "bin"
ARCHIVE DESTINATION "${package_name}/lib"
LIBRARY DESTINATION "${package_name}/lib"
)

接着就可以通过 export() 将所有来自${PROJECT_NAME}Targets 的编译定义导出。官方文档如此描述该函数:”Export targets from the build tree for use by outside projects”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# generate the export targets for the build tree
# needs to be after the install(TARGETS) command
export(
EXPORT "${PROJECT_NAME}Targets"
NAMESPACE "KTKR::"
#FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake"
)

# install the configuration targets
install(
EXPORT "${PROJECT_NAME}Targets"
FILE "${PROJECT_NAME}Targets.cmake"
NAMESPACE "KTKR::"
DESTINATION "${package_name}/cmake"
)

refer: CMake命令之export

Package

抛开 CPack 不谈,先看看原生 find_package() 方法。一般来说,find_package() 行为树如下:

1
2
3
4
5
6
7
8
9
graph TD
A[find_package] --> B(圆角)
B --> C{CONFIG or NO_MODULE?}
C --> |Yes| E[[Config Mode]]
C --> |No| D[[Module Mode]]
D --> |Not found| E
E --> |Found| F[End]
D --> |Found| F[End]

当使用 Config 模式时,需要额外创建一些文件以辅助包导入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
include(CMakePackageConfigHelpers)
# generate the config file that is includes the exports
configure_package_config_file(
${PROJECT_SOURCE_DIR}/config/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "${package_name}/cmake"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)

# generate the version file for the config file
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMinorVersion
)

# install the configuration file
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION "${package_name}/cmake"
)

refer: Cmake之深入理解find_package()的用法

FetchContent远程导入

CMake 3.11 后提供了一种通过 git 方式载入包的方法,使用例如下:

1
2
3
4
5
6
7
8
set(IKIT_GIT_TAG  ${version})  # 指定版本
set(IKIT_GIT_URL "https://github.com/timrockefeller/${name}.git") # 指定git仓库地址
FetchContent_Declare(
${name}
GIT_REPOSITORY ${IKIT_GIT_URL}
GIT_TAG ${IKIT_GIT_TAG}
)
FetchContent_MakeAvailable(${name})

EOF.

Share