基于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文件
github上工程中的readme

基础工具安装顺序

Visual studio 2019 > CUDA(cudnn) > TensorRT > opencv > CMake

CUDA安装

  • 自定义安装,不要选精简安装
  • 组件中最好全选,一定要确认Visual studio Intergration是否勾选
  • 安装完成后添加系统变量
    • CUDA_PATH
      请添加图片描述
    • 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&note\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 只需要知道网络的结构和参数即可,它支持三种转换入口:

  1. TF-TRT,要求是 TensorFlow 模型
  2. ONNX 模型格式
  3. 使用 TensorRT API 手动把模型搭起来,然后把参数加载进去

第一种不够灵活,第三种比较麻烦,所以最省事方便的就是第二种方法。

========================================================================

基本用法

  1. ‌模型转换‌:将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
  2. ‌性能测试‌:测量引擎的推理延迟和吞吐量,支持随机输入或用户自定义输入。命令格式如下:
    trtexec --loadEngine=<path_to_engine> --iterations=<number_of_iterations> --duration=<seconds>
    例如,测试引擎的推理性能:
    trtexec --loadEngine=model.engine --iterations=100 --duration=10
  3. ‌网络分析‌:查看ONNX或引擎文件的逐层信息,如输入输出维度、算子类型等。命令格式如下:
    trtexec --onnx=<path_to_onnx_model> --networkAnalysis

INT8量化

  1. ‌准备校准数据集‌:需要准备100-1000张代表性数据,用于统计激活值的动态范围。数据格式支持图像文件(如.jpg、.png)或预处理后的.npy文件,需与模型输入形状完全一致。

  2. 模型转换与量化参数设置
    ‌:使用以下命令启用INT8量化模式,并指定校准数据集路径:
    trtexec --onnx=model.onnx --int8 --saveEngine=model_int8.engine --calib=./calibration_data
    参数说明:
    • –int8:启用INT8量化模式。
    • –calib:指定校准数据集路径。
    • –minShapes/–optShapes/–maxShapes:定义动态输入形状范围。
    • –best:结合FP16和INT8混合精度,平衡速度与精度。
  3. ‌校准与缓存生成‌:首次运行时,TensorRT会生成校准缓存文件,用于后续引擎构建的复用。默认使用IInt8EntropyCalibrator2,适合图像分类任务;其他场景可自定义校准器。
  4. ‌动态输入与混合精度优化‌:如果模型支持动态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 --versioncmake --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 文件。

主要作用

  1. 兼容性保证:
    • 确保使用足够新的 CMake 版本来支持项目中使用的语法和特性。
    • 避免因使用旧版本 CMake 而导致的构建问题或不兼容性。
  2. 错误提示:
    • 如果用户的 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:项目的构建输出目录,默认为当前构建目录。

主要作用

  1. 项目名称:
    • 定义项目的名称,CMake 会根据这个名称生成一些构建目录和文件。
    • 项目名称也会被用作生成的构建目标(如安装目录、构建文件等)的一部分。
  2. 语言支持:
    • 明确指定项目中使用的编程语言,CMake 根据语言设置相应的编译器和构建规则。
    • 如果不指定语言,CMake 会自动根据项目中的文件类型推断语言,但显式指定可以提高构建的确定性和性能。
  3. 版本信息:
    • 设置项目的版本号,可以在构建过程中使用这个版本号生成版本相关的文件或信息。
  4. 项目描述:
    • 提供项目的描述信息,这些信息可能会显示在构建文档或构建输出中。
  5. 项目目录设置:
    • 显式指定源代码目录和构建输出目录,这在复杂的构建环境中非常有用。
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 开头,表示定义一个宏。

主要作用

  1. 传递编译器定义:
    • 将指定的宏定义传递给编译器,这些定义会在编译所有源文件时生效。
    • 这些定义可以用于条件编译,控制代码的不同行为。
  2. 配置项目选项:
    • 根据项目需求,通过宏定义来启用或禁用某些功能。
    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:可选参数,用于强制设置变量的值,即使变量已经在缓存中存在。

主要作用

  1. 设置变量值:
    • 设置简单的变量值,用于后续的 CMake 脚本中。
  2. 缓存变量:
    • 将变量添加到缓存中,使得变量值在多次 CMake 运行之间保持不变。
  3. 控制构建选项:
    • 通过设置变量来控制构建选项,如启用或禁用某些功能。

示例
设置简单变量

    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 不会报错。

主要作用

  1. 显式启用语言支持:
    • 显式指定项目需要支持的编程语言,确保 CMake 配置相应的编译器和构建规则。
  2. 处理多语言项目:
    • 在包含多种编程语言的项目中,确保所有需要的语言都已启用。
  3. 条件启用语言:
    • 结合其他 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 …]:要添加的头文件目录路径。

主要作用

  1. 指定头文件路径:
    • 将指定目录添加到编译器的头文件搜索路径中,使得源文件中使用 #include 时能够找到相应的头文件。
  2. 支持相对路径和绝对路径:
    • 可以使用相对路径(相对于 CMakeLists.txt 文件所在的目录)或绝对路径。
  3. 作用范围:
    • 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 …]:要添加的库文件搜索目录路径。

主要作用

  1. 指定库文件路径:
    • 将指定目录添加到链接器的库文件搜索路径中,使得链接器在链接过程中能够找到所需的库文件。
  2. 支持相对路径和绝对路径:
    • 可以使用相对路径(相对于 CMakeLists.txt 文件所在的目录)或绝对路径。
  3. 作用范围:
    • 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() 定义的。
  • [ …]:要链接的库列表,可以是库文件路径、库目标名称或其他目标。

主要作用

  1. 链接库文件:
    • 将指定的库文件链接到目标中。
  2. 链接其他目标:
    • 将其他 CMake 目标(如通过 add_library() 定义的库)链接到当前目标中。
  3. 指定链接顺序:
    • 库的顺序会影响链接过程,某些库可能需要在其他库之前链接。
  4. 传递依赖:
    • 如果一个目标链接了另一个目标,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 静态库目标。

注意事项

  1. 库的顺序:
    • 链接器会按照指定的顺序链接库,某些库可能需要在其他库之前链接。
  2. 作用域:
    • target_link_libraries() 的作用范围是特定的目标,只影响该目标的链接过程。
  3. 库文件路径:
    • 如果库文件不在链接器的默认搜索路径中,需要先使用 link_directories() 指定库文件的搜索路径,或者直接指定库文件的绝对路径。
  4. 关键字:
    • 可以使用 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 的策略范围。

主要作用

  1. 查找包:
    • 自动查找系统中安装的指定包。
  2. 设置包含目录和链接库:
    • 如果包找到,通常会设置 <PackageName>_INCLUDE_DIRS<PackageName>_LIBRARIES 等变量。
  3. 导入目标:
    • 可能会创建导入目标(如 <PackageName>::<target>),方便链接。
  4. 版本检查:
    • 检查包的版本是否符合要求。
  5. 组件支持:
    • 支持指定需要的组件,确保这些组件可用。

示例

查找 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 组件可用。然后,使用这些变量来指定包含目录和链接库。

注意事项

  1. 包配置:
    • 如果包提供了配置文件(如 Config.cmake),则会使用该文件来设置相关变量和目标。
    • 如果没有配置文件,CMake 会查找 Find.cmake 模块文件。
  2. 变量和目标:
    • 通常,find_package() 会设置<PackageName>_FOUND变量,表示包是否找到。
    • 可能会设置 <PackageName>_INCLUDE_DIRS<PackageName>_LIBRARIES等变量。
    • 可能会创建导入目标,如 <PackageName>::<target>,用于链接。
  3. 版本控制:
    • 如果指定了版本号,CMake 会检查包的版本是否符合要求。
  4. 错误处理:
    • 使用 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>:指定文件名模式,用于匹配文件,可以使用通配符(如 * 和 ?)。

主要作用

  1. 递归文件搜索:
    • 递归地搜索指定目录及其所有子目录中的文件。
  2. 模式匹配:
    • 根据提供的文件名模式(如 .cpp、.h)匹配文件。
  3. 变量赋值:
    • 将匹配到的文件列表存储在指定的变量中,以便后续使用。

示例

    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...]:操作所需的参数,具体取决于操作类型。

常见操作

  1. 写入文件
  • WRITE:将内容写入文件,覆盖已有内容。
  • APPEND:将内容追加到文件末尾。

示例:写入和追加文件内容

    file(WRITE "example.txt" "Hello, CMake!\n")
    file(APPEND "example.txt" "This is an appended line.\n")
  1. 读取文件
  • READ:读取文件内容。

示例:读取文件内容

    file(READ "example.txt" file_content)
    message(STATUS "File content:\n${file_content}")
  1. 创建目录
  • MAKE_DIRECTORY:创建目录。

示例:创建目录

    file(MAKE_DIRECTORY "new_directory")
  1. 删除文件或目录
  • REMOVE:删除文件或目录(递归删除)。

示例:删除文件或目录

    file(REMOVE "example.txt")
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值