基于TensorRT的yolo11部署【wang-xinyu版本】
基本信息以及前期准备
工具及链接
github仓库:https://github.com/wang-xinyu/tensorrtx 【部署yolo11框架C++ CUDA版本】
CMake下载地址:https://cmake.org/download/
英伟达 TensorRT 下载地址:https://developer.nvidia.com/nvidia-tensorrt-8x-download
https://developer.nvidia.com/nvidia-tensorrt-8x-download
https://developer.nvidia.com/nvidia-tensorrt-7x-download
CUDA下载地址:https://developer.nvidia.com/cuda-toolkit-archive
cudnn下载地址:https://developer.nvidia.com/rdp/cudnn-archive
opencv官网:https://opencv.org/`
opencv下载链接:https://opencv.org/releases/
官网 > Library > Releases,即可看到对应版本和下载链接
yolo11 对应部署工程中的readme.md文件

基础工具安装顺序
Visual studio 2019 > CUDA(cudnn) > TensorRT > opencv > CMake
CUDA安装
- 自定义安装,不要选精简安装
- 组件中最好全选,一定要确认Visual studio Intergration是否勾选
- 安装完成后添加系统变量
- CUDA_PATH

- Path

- CUDA_PATH
- 最后解压cudnn并将对应文件拷贝到CUDA对应文件夹下即可

安装TRT
下载trt压缩包后,直接解压,并将lib、bin文件夹所在路径添加到系统环境变量中即可
D:\Software\TensorRT-8.6.1.6\lib
D:\Software\TensorRT-8.6.1.6\bin
打开命令行窗口,切换到D:\Software\TensorRT-8.6.1.6\bin目录,执行如下命令
trtexec --onnx=yolo11s.onnx --saveEngine=model.trt --fp16
出现转换后的trt文件即表示成功:
备注:
yolo11转onnx代码:
from ultralytics import YOLO
# 加载一个模型,路径为 YOLO 模型的 .pt 文件
model = YOLO(r"D:\data\doc¬e\TRT\yolo_trt_predict\model_convert/yolo11s.pt")
# 导出模型,设置多种参数
model.export(
format="onnx", # 导出格式为 ONNX
# imgsz=(640, 640), # 设置输入图像的尺寸
# keras=False, # 不导出为 Keras 格式
# optimize=False, # 不进行优化 False, 移动设备优化的参数,用于在导出为TorchScript 格式时进行模型优化
# half=False, # 不启用 FP16 量化
# int8=False, # 不启用 INT8 量化
# dynamic=False, # 不启用动态输入尺寸
# simplify=True, # 简化 ONNX 模型
# opset=None, # 使用最新的 opset 版本
# workspace=4.0, # 为 TensorRT 优化设置最大工作区大小(GiB)
# nms=False, # 不添加 NMS(非极大值抑制)
# batch=1, # 指定批处理大小
# device="cpu" # 指定导出设备为CPU或GPU,对应参数为"cpu" , "0"
)

tensorRT trtexec.exe的用法[本博客暂时不用]
trtexec.exe 是 TensorRT 官方提供的命令行工具,主要用于将模型转换为TensorRT引擎、进行性能测试和网络分析。以下是trtexec.exe的主要用法和参数配置:
========================================================================
详细链接:《TensorRT 傻瓜式部署流程》https://zhuanlan.zhihu.com/p/527238167
简介:
TensorRT 只需要知道网络的结构和参数即可,它支持三种转换入口:
- TF-TRT,要求是 TensorFlow 模型
- ONNX 模型格式
- 使用 TensorRT API 手动把模型搭起来,然后把参数加载进去
第一种不够灵活,第三种比较麻烦,所以最省事方便的就是第二种方法。
========================================================================
基本用法
- 模型转换:将ONNX、Caffe、UFF等格式的模型转换为TensorRT引擎(.engine或.plan文件)。命令格式如下:
trtexec --onnx=<path_to_onnx_model> --saveEngine=<path_to_output_engine>
例如,将ONNX模型文件转换为TensorRT引擎并保存到指定路径:
trtexec --onnx=model.onnx --saveEngine=model.engine - 性能测试:测量引擎的推理延迟和吞吐量,支持随机输入或用户自定义输入。命令格式如下:
trtexec --loadEngine=<path_to_engine> --iterations=<number_of_iterations> --duration=<seconds>
例如,测试引擎的推理性能:
trtexec --loadEngine=model.engine --iterations=100 --duration=10 - 网络分析:查看ONNX或引擎文件的逐层信息,如输入输出维度、算子类型等。命令格式如下:
trtexec --onnx=<path_to_onnx_model> --networkAnalysis
INT8量化
- 准备校准数据集:需要准备100-1000张代表性数据,用于统计激活值的动态范围。数据格式支持图像文件(如.jpg、.png)或预处理后的.npy文件,需与模型输入形状完全一致。
-
模型转换与量化参数设置
:使用以下命令启用INT8量化模式,并指定校准数据集路径:
trtexec --onnx=model.onnx --int8 --saveEngine=model_int8.engine --calib=./calibration_data
参数说明:- –int8:启用INT8量化模式。
- –calib:指定校准数据集路径。
- –minShapes/–optShapes/–maxShapes:定义动态输入形状范围。
- –best:结合FP16和INT8混合精度,平衡速度与精度。
- 校准与缓存生成:首次运行时,TensorRT会生成校准缓存文件,用于后续引擎构建的复用。默认使用
IInt8EntropyCalibrator2,适合图像分类任务;其他场景可自定义校准器。 - 动态输入与混合精度优化:如果模型支持动态Batch或分辨率,需显式指定形状范围。添加
--fp16参数启用FP16+INT8混合量化,减少精度损失。
opencv安装与配置使用
官网下载windows安装包后直接运行,会得到一个类似解压缩的文件,vc16对应V142。可以添加系统变量,也可以不添加


如果要添加系统变量路径(图片来源网络,非本项目)

cmake安装配置使用
1、下载CMake:在官网下载对应系统的msi安装文件。
2、双击安装:点击“Next”同意协议,选择【Add CMake to the system PATH for all users】,并勾选创建图标选项,点击“Install”开始安装。
3、验证安装:安装完成后,打开cmd窗口,输入cmake --version和cmake --help命令,如果显示版本信息和帮助信息,则表示安装成功。

版本小贴士
tensorRT对于CUDA版本有要求,这个在下载tensorRT时即可查看,而CUDA的编译工具中,对visual studio 版本有要求(C++集成平台v140,140,142,143),所以在使用yolo进行tensorRT部署时,根据CUDA限制torch和visual studio以及tensorRT的版本
1、TensorRT需要下载GA版本(稳定版本),EA版本为抢先版。
2、同样为8.6.1的tensorRT,但存在两个版本,一个是基于11.X CUDA的版本,一个是基于12.X CUDA的版本。但是12.X CUDA的TensorRT版本最高只支持12.1的CUDA。而使用visual studio 2022(V143)进行编译的时候,需要CUDA解释器为12.4或者更高,所以这里能选择的最高版本是:
CUDA 11.8
cudnn 8.9.2.26
TensorRT 8.6.1
visual studio 2019(V142)
CMake 4.0.1(CMake在3.14.0以后才支持V42的集成平台,CMake是向下兼容的)

CMake关键字含义初解
cmake_minimum_required
cmake_minimum_required() 是 CMake 脚本中的一个重要指令,用于指定项目所需的最低 CMake 版本。这个指令告诉 CMake 工具链,项目需要特定版本的 CMake 才能正确构建,从而确保构建过程的一致性和兼容性
语法格式:
cmake_minimum_required(VERSION <major>[.<minor>[.<patch>]] [FATAL_ERROR])
- : 主版本号。
- : 次版本号(可选)。
- : 修订号(可选)。
- FATAL_ERROR: 如果指定的最低版本不满足,CMake 将立即显示错误并停止处理 CMakeLists.txt 文件。
主要作用
- 兼容性保证:
- 确保使用足够新的 CMake 版本来支持项目中使用的语法和特性。
- 避免因使用旧版本 CMake 而导致的构建问题或不兼容性。
- 错误提示:
- 如果用户的 CMake 版本低于指定版本,CMake 将在构建开始时提示错误,而不是在构建过程中中途失败。
- 这有助于快速定位问题并指导用户升级 CMake
cmake_minimum_required(VERSION 3.10)
这个指令表示项目需要至少 CMake 3.10 版本来构建。如果用户的 CMake 版本低于 3.10,CMake 将会显示错误信息并停止构建过程。
注意事项
cmake_minimum_required()通常应该放在CMakeLists.txt文件的开头,以确保在解析其他指令之前就检查 CMake 版本。- 指定的最低版本应该与项目中使用的 CMake 特性和语法的最低支持版本相匹配。
- 使用
FATAL_ERROR是可选的,但通常建议使用,以确保严格的版本检查。
总之,cmake_minimum_required() 是一个关键指令,用于确保项目的构建环境满足要求。通过明确指定最低版本,可以减少因版本不兼容导致的构建问题,提高项目构建的可靠性和一致性。
project
project() 是 CMakeLists.txt 文件中的一个指令,用于定义项目的名称和一些基本设置。它通常在 CMakeLists.txt 文件的开头使用,主要作用如下:
project(<project-name> [LANGUAGES languagename...]
[VERSION major[.minor[.patch[.tweak]]]]
[DESCRIPTION description]
[HOMEPAGE_URL url]
[SOURCE_DIR source_directory]
[BINARY_DIR build_directory])
- project-name:项目的名称,通常会生成一个同名的构建目录。
- LANGUAGES:指定项目中使用的编程语言,如 CXX(C++)、C、CUDA 等。
- VERSION:项目的版本号,可以包含主版本号、次版本号、修订号和修订细节。
- DESCRIPTION:项目的简短描述。
- HOMEPAGE_URL:项目的主页 URL。
- SOURCE_DIR:项目的源代码目录,默认为当前目录。
- BINARY_DIR:项目的构建输出目录,默认为当前构建目录。
主要作用
- 项目名称:
- 定义项目的名称,CMake 会根据这个名称生成一些构建目录和文件。
- 项目名称也会被用作生成的构建目标(如安装目录、构建文件等)的一部分。
- 语言支持:
- 明确指定项目中使用的编程语言,CMake 根据语言设置相应的编译器和构建规则。
- 如果不指定语言,CMake 会自动根据项目中的文件类型推断语言,但显式指定可以提高构建的确定性和性能。
- 版本信息:
- 设置项目的版本号,可以在构建过程中使用这个版本号生成版本相关的文件或信息。
- 项目描述:
- 提供项目的描述信息,这些信息可能会显示在构建文档或构建输出中。
- 项目目录设置:
- 显式指定源代码目录和构建输出目录,这在复杂的构建环境中非常有用。
project(MyProject LANGUAGES CXX VERSION 1.0.0 DESCRIPTION "A simple C++ project" HOMEPAGE_URL "https://example.com/myproject")
在这个示例中:
MyProject是项目的名称。LANGUAGES CXX指定了项目使用 C++ 语言。VERSION 1.0.0设置了项目的版本为 1.0.0。DESCRIPTION "A simple C++ project"提供了项目的简短描述。HOMEPAGE_URL "https://example.com/myproject"指定了项目的主页 URL。
project() 指令不仅定义了项目的名称,还提供了丰富的元数据设置选项,这些信息在构建和打包过程中非常有用,可以提高项目的可维护性和可移植性。
add_definitions
add_definitions() 是 CMake 中的一个指令,用于向构建过程中添加预处理器定义(即宏定义)。这些定义会在编译源代码时传递给编译器,通常用于启用或禁用某些代码特性、指定配置选项等。
add_definitions(-D<definition>...)
- :要添加的预处理器定义,通常以 -D 开头,表示定义一个宏。
主要作用
- 传递编译器定义:
- 将指定的宏定义传递给编译器,这些定义会在编译所有源文件时生效。
- 这些定义可以用于条件编译,控制代码的不同行为。
- 配置项目选项:
- 根据项目需求,通过宏定义来启用或禁用某些功能。
add_definitions(-DENABLE_DEBUG -DVERSION="1.0.0")
在这个示例中:
- -DENABLE_DEBUG 定义了一个名为 ENABLE_DEBUG 的宏,值为 1(默认值,未指定值时通常为 1)。
- -DVERSION=“1.0.0” 定义了一个名为 VERSION 的宏,值为 “1.0.0”。
这些定义可以在源代码中使用,例如:
#include <iostream>
int main() {
#ifdef ENABLE_DEBUG
std::cout << "Debug mode enabled" << std::endl;
#endif
std::cout << "Version: " << VERSION << std::endl;
return 0;
}
使用时机
- 当需要在项目中启用或禁用调试模式时:
add_definitions(-DDEBUG)
- 当需要指定项目版本号时:
add_definitions(-DPROJECT_VERSION="1.2.3")
- 当需要根据不同的目标平台定义特定的代码行为时
add_definitions(-D_WINDOWS)
- 宏定义会对整个项目生效,包括所有源文件,因此需要谨慎使用,以免引起冲突。
- 如果只需要为特定目标指定宏定义,可以使用 target_compile_definitions(),它提供了更细粒度的控制。例如:
target_compile_definitions(my_target PRIVATE -DENABLE_DEBUG)
这样,ENABLE_DEBUG 宏只会在 my_target 目标相关的源文件中生效。
总之,add_definitions() 是一个有用的指令,用于向整个项目添加预处理器定义,以控制代码的编译行为。但在大型项目中,使用 target_compile_definitions() 可以更好地管理宏定义的范围
set
set() 是 CMake 中一个非常常用的指令,用于在 CMakeLists.txt 文件中设置变量的值。这些变量可以在后续的 CMake 脚本中使用,用于控制构建过程、传递参数等
set(<variable> <value> [CACHE <type> <docstring> [FORCE]])
语法格式
set(<variable> <value> [CACHE <type> <docstring> [FORCE]])
- :要设置的变量名。
- :变量的值,可以是字符串、数字、布尔值等。
- CACHE:可选参数,用于将变量添加到缓存中,这样变量的值会在后续的 CMake 运行中保留。
- :变量的类型,如 STRING、BOOL、PATH 等。
- :变量的描述信息,用于文档说明。
- FORCE:可选参数,用于强制设置变量的值,即使变量已经在缓存中存在。
主要作用
- 设置变量值:
- 设置简单的变量值,用于后续的 CMake 脚本中。
- 缓存变量:
- 将变量添加到缓存中,使得变量值在多次 CMake 运行之间保持不变。
- 控制构建选项:
- 通过设置变量来控制构建选项,如启用或禁用某些功能。
示例
设置简单变量
set(MYVariable "Hello, CMake!")
在这个示例中,MYVariable 被设置为字符串 “Hello, CMake!”。可以在后续的 CMake 脚本中使用 ${MYVariable} 来引用这个值。
设置缓存变量
set(MYVariable "Hello, CMake!" CACHE STRING "This is a cached variable")
在这个示例中,MYVariable 被设置为字符串 “Hello, CMake!”,并且被添加到缓存中。类型为 STRING,描述信息为 “This is a cached variable”。
强制设置变量
set(MYVariable "New Value" CACHE STRING "This is a forced variable" FORCE)
在这个示例中,即使 MYVariable 已经在缓存中存在,也会被强制设置为 “New Value”。
使用场景
- 设置编译器选项:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
这里将 C++ 编译器的选项设置为包含 -Wall 和 -Wextra。
- 设置头文件路径:
set(HEADER_DIRS ${PROJECT_SOURCE_DIR}/include)
- 设置源文件列表:
set(SOURCES main.cpp utils.cpp)
- 设置缓存中的布尔值:
set(ENABLE_DEBUG true CACHE BOOL "Enable debug mode")
注意事项**
- 变量作用域:
- 变量在 CMake 脚本中是全局的,但在子目录中可以被重写。如果需要在不同目录之间共享变量,可以使用 CACHE 选项。
- 缓存变量的使用:
- 缓存变量会在 CMake 配置过程中保留,可以通过 CMake GUI 工具进行修改。
- 变量引用:
- 使用
${variable_name}的语法来引用变量的值。
- 使用
总之,set() 是 CMake 中一个非常灵活和强大的指令,用于设置变量值,控制构建过程。通过合理使用 set(),可以实现对构建过程的精细控制。
enable_language
enable_language()是 CMake 中的一个指令,用于显式启用对某种编程语言的支持。虽然 CMake 通常会根据项目中的文件类型自动检测所需的编程语言,但在某些特定情况下,可能需要显式启用语言支持
语法格式
enable_language(<lang> [OPTIONAL])
- :指定要启用的编程语言,例如 C、CXX(C++)、CUDA、Fortran 等。
- OPTIONAL:可选参数。如果指定,并且无法启用该语言(例如,系统中没有相应的编译器),CMake 不会报错。
主要作用
- 显式启用语言支持:
- 显式指定项目需要支持的编程语言,确保 CMake 配置相应的编译器和构建规则。
- 处理多语言项目:
- 在包含多种编程语言的项目中,确保所有需要的语言都已启用。
- 条件启用语言:
- 结合其他 CMake 指令,根据条件启用或禁用特定语言。
示例
显式启用 C++ 支持
enable_language(CXX)
在这个示例中,enable_language(CXX) 显式启用了 C++ 支持。如果系统中没有 C++ 编译器,CMake 会报错。
条件启用 Fortran 支持
if(ENABLE_Fortran)
enable_language(Fortran)
endif()
在这个示例中,只有在 ENABLE_Fortran 变量为真时,才会启用 Fortran 支持。
注意事项
- 自动检测:通常情况下,CMake 会根据项目中的源文件自动检测所需的编程语言。例如,如果项目中有 .cpp 文件,CMake 会自动启用 C++ 支持。
- 显式启用的必要性:在以下情况下可能需要显式调用 enable_language():
- 项目中有条件编译的源文件,这些源文件的语言支持需要动态决定。
- 需要在项目中使用某种语言的特定功能或库,即使没有相应的源文件。
- 错误处理:如果不指定 OPTIONAL 参数,且无法启用指定语言,CMake 会报错并停止配置过程。
版本历史
- enable_language() 在 CMake 2.0 及更高版本中可用。
- 在 CMake 3.0 及更高版本中,enable_language() 的行为更加一致,处理了更多边界情况。
总之,enable_language() 是一个用于显式启用特定编程语言支持的指令。它在处理多语言项目或需要动态启用语言支持时非常有用。
include_directories
include_directories() 是 CMake 中用于指定头文件搜索路径的指令。它告诉 CMake 在编译过程中需要包含哪些目录中的头文件,这些目录会被添加到编译器的头文件搜索路径中。
语法格式
include_directories([AFTER|BEFORE] dir1 [dir2 ...])
- [AFTER|BEFORE]:可选参数,用于指定目录的添加顺序,默认为 AFTER。
- dir1 [dir2 …]:要添加的头文件目录路径。
主要作用
- 指定头文件路径:
- 将指定目录添加到编译器的头文件搜索路径中,使得源文件中使用 #include 时能够找到相应的头文件。
- 支持相对路径和绝对路径:
- 可以使用相对路径(相对于 CMakeLists.txt 文件所在的目录)或绝对路径。
- 作用范围:
include_directories()的作用范围是从其调用点开始,影响当前目录及其子目录中的所有目标(如 add_executable() 或 add_library())。
示例
添加单个目录
include_directories(${PROJECT_SOURCE_DIR}/include)
在这个示例中,${PROJECT_SOURCE_DIR}/include 被添加到头文件搜索路径中。假设 ${PROJECT_SOURCE_DIR} 是项目的根目录,那么头文件在 include 子目录中。
添加多个目录
include_directories(
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/external/libraries/include
)
在这个示例中,同时添加了两个目录到头文件搜索路径中。
注意事项
- 顺序:默认情况下,include_directories() 添加的目录是添加到已有的包含目录列表的后面(即 AFTER)。如果希望将目录添加到列表的前面,可以使用 BEFORE 关键字。
- 作用域:include_directories() 的设置影响当前目录及其所有子目录。如果只想为某个特定目标指定包含目录,可以使用 target_include_directories(),它提供了更精确的控制。
- 相对路径:如果使用相对路径,路径是相对于 CMakeLists.txt 文件所在的目录。
target_include_directories()
在 CMake 的较新版本中(3.x 及更高),鼓励使用 target_include_directories() 来替代 include_directories(),因为它提供了更细粒度的控制和更好的语义。
add_executable(my_target main.cpp)
target_include_directories(my_target PRIVATE ${PROJECT_SOURCE_DIR}/include)
在这个示例中,target_include_directories() 被用来为特定目标 my_target 添加头文件路径,PRIVATE 关键字表示这些包含目录只对该目标可见。
总之,include_directories() 是一个用于指定编译过程中头文件搜索路径的指令,确保编译器能够找到项目的头文件。虽然在新项目中推荐使用 target_include_directories(),但在旧项目或某些特定场景下,include_directories() 仍然非常有用。
link_directories
link_directories()是 CMake 中的一个指令,用于指定链接器在链接过程中搜索库文件的目录。这些目录会被添加到链接器的搜索路径中,以便在链接阶段能够找到所需的库文件。
语法格式
link_directories(directory1 [directory2 ...])
- directory1 [directory2 …]:要添加的库文件搜索目录路径。
主要作用
- 指定库文件路径:
- 将指定目录添加到链接器的库文件搜索路径中,使得链接器在链接过程中能够找到所需的库文件。
- 支持相对路径和绝对路径:
- 可以使用相对路径(相对于 CMakeLists.txt 文件所在的目录)或绝对路径。
- 作用范围:
- link_directories() 的作用范围是从其调用点开始,影响当前目录及其子目录中的所有目标(如 add_executable() 或 add_library())。
示例
添加单个目录
link_directories(${PROJECT_SOURCE_DIR}/lib)
在这个示例中,${PROJECT_SOURCE_DIR}/lib 被添加到链接器的库文件搜索路径中。假设 ${PROJECT_SOURCE_DIR} 是项目的根目录,那么库文件在 lib 子目录中。
添加多个目录
link_directories(
${PROJECT_SOURCE_DIR}/lib
${PROJECT_SOURCE_DIR}/external/libraries/lib
)
在这个示例中,同时添加了两个目录到链接器的库文件搜索路径中。
注意事项
- 作用域:link_directories() 的设置影响当前目录及其所有子目录。如果只想为某个特定目标指定库文件路径,可以使用 target_link_libraries(),它提供了更精确的控制。
- 相对路径:如果使用相对路径,路径是相对于 CMakeLists.txt 文件所在的目录。
- 链接顺序:链接器会按照 link_directories() 指定的目录顺序进行搜索,因此目录的添加顺序可能会影响链接结果。
target_link_libraries()
指定当前库依赖的其他库
add_executable(my_target main.cpp)
target_link_libraries(my_target ${PROJECT_SOURCE_DIR}/lib/mylib.a)
在这个示例中,target_link_libraries() 被用来为特定目标 my_target 指定链接的库文件。
target_link_libraries() 是 CMake 中用于指定目标(如可执行文件或库)在链接时需要链接的库的指令。.dll和.lib均可添加
语法格式
target_link_libraries(<target> [<item1> [<item2> ...]])
- :目标名称,通常是通过 add_executable() 或 add_library() 定义的。
- [ …]:要链接的库列表,可以是库文件路径、库目标名称或其他目标。
主要作用
- 链接库文件:
- 将指定的库文件链接到目标中。
- 链接其他目标:
- 将其他 CMake 目标(如通过 add_library() 定义的库)链接到当前目标中。
- 指定链接顺序:
- 库的顺序会影响链接过程,某些库可能需要在其他库之前链接。
- 传递依赖:
- 如果一个目标链接了另一个目标,CMake 会自动处理它们之间的依赖关系。
示例
链接库文件
add_executable(my_exe main.cpp)
target_link_libraries(my_exe ${PROJECT_SOURCE_DIR}/lib/mylib.a)
在这个示例中,my_exe 可执行文件链接了 mylib.a 静态库。
链接其他目标
add_library(my_static_lib STATIC src/lib.cpp)
add_executable(my_exe main.cpp)
target_link_libraries(my_exe my_static_lib)
在这个示例中,my_exe 可执行文件链接了 my_static_lib 静态库目标。
注意事项
- 库的顺序:
- 链接器会按照指定的顺序链接库,某些库可能需要在其他库之前链接。
- 作用域:
- target_link_libraries() 的作用范围是特定的目标,只影响该目标的链接过程。
- 库文件路径:
- 如果库文件不在链接器的默认搜索路径中,需要先使用 link_directories() 指定库文件的搜索路径,或者直接指定库文件的绝对路径。
- 关键字:
- 可以使用 PUBLIC、PRIVATE、INTERFACE 等关键字来控制链接的可见性和传递性:
- PUBLIC:链接库并将其作为目标的公共依赖项,其他链接此目标的目标也会链接此库。
- PRIVATE:链接库但不将其作为目标的公共依赖项。
- INTERFACE:不链接库,但将其作为目标的公共依赖项,其他链接此目标的目标会链接此库。
- 可以使用 PUBLIC、PRIVATE、INTERFACE 等关键字来控制链接的可见性和传递性:
示例:使用关键字
add_library(my_static_lib STATIC src/lib.cpp)
add_executable(my_exe main.cpp)
target_link_libraries(my_exe PUBLIC my_static_lib)
在这个示例中,my_exe 可执行文件链接了 my_static_lib 静态库,并且将其作为公共依赖项。其他链接 my_exe 的目标也会链接 my_static_lib。
通过使用 target_link_libraries(),可以有效地管理目标的链接依赖关系,确保在构建过程中正确链接所需的库文件。
set_target_properties
来指定库的输出目录
find_package
find_package() 是 CMake 中用于查找和使用外部包(库或工具)的指令。它可以帮助项目自动定位和配置所需的依赖项,从而简化构建过程。这个指令通常用于查找系统中已安装的库,并设置相应的导入目标、包含目录和链接库。
语法格式
find_package(<PackageName> [<Version>] [EXACT] [QUIET] [MODULE] [REQUIRED] [[COMPONENTS] [components...]] [CONFIG] [NO_POLICY_SCOPE])
- PackageName:要查找的包的名称。
- Version:指定所需的包版本。
- EXACT:要求版本号精确匹配。
- QUIET:如果包未找到,不显示错误信息。
- MODULE:优先使用 Find.cmake 模块文件。
- REQUIRED:如果包未找到,CMake 将报错并停止配置。
- COMPONENTS:指定需要的组件。
- CONFIG:优先使用 Config.cmake 配置文件。
- NO_POLICY_SCOPE:不应用 CMake 的策略范围。
主要作用
- 查找包:
- 自动查找系统中安装的指定包。
- 设置包含目录和链接库:
- 如果包找到,通常会设置
<PackageName>_INCLUDE_DIRS和<PackageName>_LIBRARIES等变量。
- 如果包找到,通常会设置
- 导入目标:
- 可能会创建导入目标(如
<PackageName>::<target>),方便链接。
- 可能会创建导入目标(如
- 版本检查:
- 检查包的版本是否符合要求。
- 组件支持:
- 支持指定需要的组件,确保这些组件可用。
示例
查找 OpenGL 包
find_package(OpenGL REQUIRED)
include_directories(${OpenGL_INCLUDE_DIRS})
target_link_libraries(my_target ${OpenGL_LIBRARIES})
在这个示例中,find_package(OpenGL REQUIRED) 查找 OpenGL 包,并设置 OpenGL_INCLUDE_DIRS 和 OpenGL_LIBRARIES。然后,使用这些变量来指定包含目录和链接库。
查找 Boost 包并指定版本和组件
find_package(Boost 1.60.0 REQUIRED COMPONENTS system filesystem)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(my_target ${Boost_LIBRARIES})
在这个示例中,find_package(Boost 1.60.0 REQUIRED COMPONENTS system filesystem) 查找 Boost 包的版本 1.60.0 或更高版本,并确保 system 和 filesystem 组件可用。然后,使用这些变量来指定包含目录和链接库。
注意事项
- 包配置:
- 如果包提供了配置文件(如 Config.cmake),则会使用该文件来设置相关变量和目标。
- 如果没有配置文件,CMake 会查找 Find.cmake 模块文件。
- 变量和目标:
- 通常,find_package() 会设置
<PackageName>_FOUND变量,表示包是否找到。 - 可能会设置
<PackageName>_INCLUDE_DIRS和<PackageName>_LIBRARIES等变量。 - 可能会创建导入目标,如
<PackageName>::<target>,用于链接。
- 通常,find_package() 会设置
- 版本控制:
- 如果指定了版本号,CMake 会检查包的版本是否符合要求。
- 错误处理:
- 使用 REQUIRED 关键字确保包找到,否则 CMake 会报错并停止配置。
通过 find_package(),CMake 能够自动化地查找和配置项目所需的外部依赖项,大大简化了构建过程。
file(GLOB_RECURSE)
在 CMakeLists.txt 文件中,file(GLOB_RECURSE) 是一种强大的文件查找命令,它递归地搜索指定目录及其子目录中匹配特定模式的文件,并将结果存储在一个变量中。该命令在处理大量文件或组织大型项目时非常有用,可以自动化地收集所有相关的源文件或头文件,而无需手动列出每个文件。
语法格式
file(GLOB_RECURSE <variable> [<options>] <search_pattern>)
<variable>:指定一个变量,用于存储匹配文件的完整路径列表。<options>:可选参数,用于指定搜索选项,如 RELATIVE(返回相对路径)或 LIST_DIRECTORIES(包含目录)。<search_pattern>:指定文件名模式,用于匹配文件,可以使用通配符(如 * 和 ?)。
主要作用
- 递归文件搜索:
- 递归地搜索指定目录及其所有子目录中的文件。
- 模式匹配:
- 根据提供的文件名模式(如 .cpp、.h)匹配文件。
- 变量赋值:
- 将匹配到的文件列表存储在指定的变量中,以便后续使用。
示例
file(GLOB_RECURSE SRCS "src/*.cpp")
在这个示例中,file(GLOB_RECURSE) 会递归地搜索 src 目录及其子目录中所有扩展名为 .cpp 的文件,并将这些文件的完整路径存储在变量 SRCS 中。
注意事项
- 相对路径:
file(GLOB_RECURSE)返回的路径是相对于 CMakeLists.txt 文件所在的目录的完整路径,除非使用 RELATIVE 选项。 - 通配符:
- *:匹配任意数量的字符。
- ?:匹配单个字符。
- [seq]:匹配指定范围内的单个字符。
- [!seq]:匹配不在指定范围内的单个字符。
- 排除文件:file(GLOB_RECURSE) 不支持排除特定文件或模式。如果需要排除文件,可能需要结合其他 CMake 指令,如 list(REMOVE_ITEM)。
- 性能:在大型项目中,file(GLOB_RECURSE) 可能会影响 CMake 配置性能,因为它需要遍历文件系统。建议在开发过程中谨慎使用,并尽量限制搜索范围。
示例:完整项目结构
cmake_minimum_required(VERSION 3.10)
project(MyProject)
# 递归查找所有 .cpp 和 .h 文件
file(GLOB_RECURSE SRCS "src/*.cpp" "src/*.h")
# 添加可执行文件
add_executable(my_exe ${SRCS})
在这个示例中,file(GLOB_RECURSE) 用于查找 src 目录及其子目录中的所有 .cpp 和 .h 文件,并将它们添加到可执行文件 my_exe 中。
通过使用 file(GLOB_RECURSE),CMake 可以自动收集项目中的源文件和头文件,减少手动维护文件列表的工作量。
file
file() 是 CMake 中用于执行文件和目录操作的指令。它提供了多种选项,用于读取、写入、创建、删除、复制、比较等文件和目录操作。这是一个非常灵活的指令,可以帮助在构建过程中自动化文件管理任务。
语法格式
file(<OPERATION> [args...])
<OPERATION>:指定要执行的文件或目录操作。[args...]:操作所需的参数,具体取决于操作类型。
常见操作
- 写入文件
- WRITE:将内容写入文件,覆盖已有内容。
- APPEND:将内容追加到文件末尾。
示例:写入和追加文件内容
file(WRITE "example.txt" "Hello, CMake!\n")
file(APPEND "example.txt" "This is an appended line.\n")
- 读取文件
- READ:读取文件内容。
示例:读取文件内容
file(READ "example.txt" file_content)
message(STATUS "File content:\n${file_content}")
- 创建目录
- MAKE_DIRECTORY:创建目录。
示例:创建目录
file(MAKE_DIRECTORY "new_directory")
- 删除文件或目录
- REMOVE:删除文件或目录(递归删除)。
示例:删除文件或目录
file(REMOVE "example.txt")

最低0.47元/天 解锁文章
713

被折叠的 条评论
为什么被折叠?



