【01】CMake文件在项目中的分布

CMake文件在项目中的分布

1. 按模块分层的 CMakeLists.txt

用过 CMake 的开发者都清楚,CMakeLists.txt 是一个编译规则的描述文件。一般来说,自己在使用 CMake 的时候,如果项目不大,往往都喜欢仅使用一个 CMakeLists.txt 来管理所有的属性配置。但随着项目越做越大,一个 CMakeLists.txt 的配置维护起来将十分困难。为此需要对每个特定的模块编写 CMakeLists.txt。可以参考 OpenCV 的 CMakeLists.txt 布局。

.
├── cmake
│   └── ...
├── CMakeLists.txt(项目整体配置)
├── include
│   ├── CMakeLists.txt(用于全局包含的 opencv.hpp 的发布)
│   └── ...
├── modules
│   └── core
│       ├── CMakeLists.txt(核心模块 core 的配置)
│       ├── include
│       │   └── ...
│       ├── src
│       │   └── ...
│       └── test
│           └── ...
├── README.md
└── samples

很显然,每个模块的文件夹下都会存在一个 CMakeLists.txt 。

  • 最底层的 CMakeLists.txt 是为了管理该模块功能的编译、测试文件编译,以及提供指定的接口(可以是库,也可以是若干 CMake 变量)给外部。OpenCV 中广泛使用语句 ocv_add_module() 来添加模块。例如:

    # 定义于 <opencv-path>/modules/core/CMakeLists.txt 中的内容
    ocv_add_module(core
                 OPTIONAL opencv_cudev
                 WRAP java objc python js)
    

    这句话大概意思就是说,添加一个名为 core 的模块,opencv_cudev 为模块中可选的,不一定需要参与构建的部分,以及提供 java 等其他语言接口的包装。

    这个语句并不是 CMake 原生语法中自带的,而是程序员自行设计的宏。根据这个宏以及本 CMakeLists.txt 的其余功能,可以创建该 core 模块的目标,并为此添加合适的依赖项。

  • 4.x 系列版本的 OpenCV 设置两级 CMakeList.txt。最高一级 CMakeLists.txt 一般是对于整个库编译选项的设置,以及对系统、平台、编译器等编译环境信息的兼容处理。OpenCV 项目根目录的 CMakeLists.txt 前一大段都是在对当前平台、编译配置的信息做处理,例如:

    # 定义于 <opencv-path>/CMakeLists.txt 中的内容
    if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
        cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
        cmake_policy(VERSION 2.8)
    else()
        cmake_minimum_required(VERSION "${MIN_VER_CMAKE}" FATAL_ERROR)
    endif()
    

2. 扩展名为cmake的文件

CMake 中除了解析 CMakeLists.txt 文件,还允许解析扩展名为 cmake 的文件。一般有两种方式对这类文件进行访问,一种是 find_package(),另一种是 include(),其中第一种方案会在后文中介绍。

2.1 *.cmake

OpenCV 中,*.cmake 文件全部存放在 <opencv-path>/cmake 文件夹下,常见的名称有 Findxxx.cmakeOpenCVxxx.cmake。第一种是本地项目中用于 find_package() 的,例如 OpenCV 中 FindONNX.cmake 等文件。第二种则是添加了各种各样的能够减少重复操作的宏与函数,ocv_add_module() 就是其中之一,他被定义在 OpenCVModule.cmake 中,这种一般需要执行 include() 操作,例如:

# 定义于 <opencv-path>/CMakeLists.txt 中的内容
# --- OpenCL ---
if(WITH_OPENCL)
  include(cmake/OpenCVDetectOpenCL.cmake)
endif()

# --- Halide ---
if(WITH_HALIDE)
  include(cmake/OpenCVDetectHalide.cmake)
endif()

# --- VkCom ---
if(WITH_VULKAN)
  include(cmake/OpenCVDetectVulkan.cmake)
endif()

# --- WebNN ---
if(WITH_WEBNN)
  include(cmake/OpenCVDetectWebNN.cmake)
endif()

2.2 *.in 文件

此类文件严格意义上来说不属于 CMake 文件,而是 OpenCV 项目里的一种模板文件,其后缀统一使用成 *.in 罢。*.in 文件一般是用于在 cmake 执行阶段将其嵌入的 CMake 变量、列表展开,并生成目标文件的过程中的。这一步通常是由 configure_file() 完成,会在后文中进行介绍。

OpenCV 中的此类文件一般放在 <opencv-path>/cmake/template 文件夹下,主要是用于在执行 sudo make install 的时候将OpenCVConfig.cmake 等一系列文件安装至目标路径下,而 OpenCVConfig.cmake 文件的产生,就需要 <opencv-path>/cmake/template 文件夹下的 OpenCVConfig.cmake.in 文件。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
下面是一个使用 CMake 管理的多文件 C++ 项目示例: 假设我们有以下项目结构: ``` myproject/ ├── CMakeLists.txt ├── include/ │ ├── math.h │ └── utility.h └── src/ ├── main.cpp ├── math.cpp └── utility.cpp ``` 其,`include` 目录包含了 `math.h` 和 `utility.h` 两个头文件,`src` 目录包含了 `main.cpp`, `math.cpp`,和 `utility.cpp` 三个源文件。 现在,我们需要使用 CMake 来构建这个项目。我们可以在 `myproject` 目录下创建一个名为 `CMakeLists.txt` 的文件,并添加以下内容: ``` cmake_minimum_required(VERSION 3.10) project(myproject) # 添加头文件搜索路径 include_directories(include) # 添加源文件 add_executable(myproject src/main.cpp src/math.cpp src/utility.cpp) ``` 该 `CMakeLists.txt` 文件指定了项目的最低 CMake 版本和项目名称。`include_directories` 命令添加了头文件搜索路径,它告诉 CMake 在 `include` 目录查找头文件。最后,`add_executable` 命令指定了要编译的源文件,它告诉 CMake 编译 `main.cpp`,`math.cpp` 和 `utility.cpp` 三个源文件,并将它们链接成可执行文件 `myproject`。 完成以上步骤后,我们可以使用以下命令来构建项目: ``` mkdir build cd build cmake .. make ``` `mkdir build` 创建了一个构建目录,`cd build` 进入该目录,`cmake ..` 命令使用上面的 `CMakeLists.txt` 文件来构建项目,`make` 命令编译源代码并生成可执行文件。最终,我们可以在 `build` 目录下找到生成的 `myproject` 可执行文件。 这就是一个简单的 C++文件项目CMake 示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Cccolt_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值