通过使用 include 语句加载并执行一个CMake脚本来引入第三方库
当项目中使用到第三方库时,可以通过使用 include 语句来加载并执行一个CMake脚本,在引入的CMake脚本中进行第三方库的下载、构建和库查找路径的设置等操作,以这种方式简化项目中依赖库的配置。
通常在以 .cmake
为后缀的文件中写CMake语句,称之为CMake脚本。在CMake的语法中,使用 include 语句来引入并执行 CMake 脚本,语法形式为 include(<name>)
。该语句相当于在 include 的当前位置插入 CMake 脚本代码,然后 CMake 脚本中的变量作用域(非函数内部)提升为当前cmake程序变量作用域。
执行 include(<name>)
语句时,CMake 会从 CMAKE_MODULE_PATH
内置变量指定的路径中查找名为 .cmake 的文件,然后执行该文件中定义的 CMake 语句。在项目的目录结构中,一般会有一个名为 cmake 的子目录,用来保存 CMake 脚本,然后将 cmake 目录的路径添加到 CMAKE_MODULE_PATH
变量值中。
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
下面给出一个简单通用的模版:
项目根目录下的 CMakeLists.txt 文件内容如下:
cmake_minimum_required(VERSION 3.16)
project(ONNXModel)
set(CMAKE_CXX_STANDARD 17)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
include(onnxruntime)
cmake目录下的 onnxruntime.cmake 脚本
# cmake目录下的 onnxruntime.cmake 脚本
# 设置第三方库的下载路径和文件的 hash 值
set(URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNXRUNTIME_VERSION}/onnxruntime-osx-arm64-${ONNXRUNTIME_VERSION}.tgz")
set(URL_HASH "SHA256=5c3f2064ee97eb7774e87f396735c8eada7287734f1bb7847467ad30d4036115")
# 如果不能连接互联网,提前下载至本地
set(possible_file_locations "${CMAKE_SOURCE_DIR}/third-part/onnxruntime-osx-arm64-${ONNXRUNTIME_VERSION}.tgz")
if (EXISTS ${possible_file_locations})
set(URL "${possible_file_locations}")
file(TO_CMAKE_PATH "${URL}" URL)
message(STATUS "Found local download onnxruntime: ${URL}")
endif()
# 使用 FetchContent 模块从指定链接中下载(并解压)第三方库
FetchContent_Declare(
onnxruntime
URL ${URL}
URL_HASH ${URL_HASH}
)
FetchContent_MakeAvailable(onnxruntime)
# 在指定路径中查找名为 onnxruntime 库
# 并将库的路径赋值给变量 location_onnxruntime
find_library(location_onnxruntime onnxruntime
PATHS
"${onnxruntime_SOURCE_DIR}/lib"
NO_CMAKE_SYSTEM_PATH
)
message(STATUS "onnxruntime library locate at ${location_onnxruntime}")
# 将 onnxruntime 添加在动态库
# IMPORTED 属性表示该库为外部构建的
add_library(onnxruntime SHARED IMPORTED)
# 设置 onnxruntime 库的一些属性
# IMPORTED_LOCATION 指定库的路径
# INTERFACE_INCLUDE_DIRECTORIES 指定接口目录
# 即指定 include 的查找路径
set_target_properties(onnxruntime PROPERTIES
IMPORTED_LOCATION "${location_onnxruntime}"
INTERFACE_INCLUDE_DIRECTORIES "${onnxruntime_SOURCE_DIR}/include"
)
小结
- 在CMake脚本中定义第三方库的下载、构建和库查找路径的设置等设置,可以轻量化、方便的构建项目中依赖的第三方库。
- 可以通过条件判断 和 CMake 脚本的嵌套,即一个 CMake 脚本中 include 另一个 CMake 脚本来实现更复杂的项目构建。例如根据平台架构来选择 include 特定的 CMake 脚本。sherpa-onnx 是一个不错的学习例子。