CMake 学习

sunrose 发布于 2024-08-04 606 次阅读


4 嵌套的CMakeLists.txt

当我们编译大型工程的时候,有的时候需要编写多个CMakeLists.txt,完成任务

其实多个CMakeLists.txt就是对之前的应用(生成计算库,然后与calc.cpp链接。生成排序库,然后与sort.cpp链接)

根目录

众所周知,Linux的目录是树状结构,所以嵌套的 CMake 也是一个树状结构,最顶层的 CMakeLists.txt 是根节点,其次都是子节点。因此,我们需要了解一些关于 CMakeLists.txt 文件变量作用域的一些信息:

  • 根节点CMakeLists.txt中的变量全局有效
  • 父节点CMakeLists.txt中的变量可以在子节点中使用
  • 子节点CMakeLists.txt中的变量只能在当前节点中使用

我们来看top level的CMakeLists.txt怎么写

cmake_minimum_required(VERSION 3.0)

project(opencv_project)

add_subdirectory(calc)

add_subdirectory(sort)

add_subdirectory(testCalc)

add_subdirectory(testSort)

其实只多了一个函数

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
  • source_dir:指定了CMakeLists.txt源文件和代码文件的位置,其实就是指定子目录
  • 后面两个忽略即可

通过这种方式CMakeLists.txt文件之间的父子关系就被构建出来了。

其他目录

calc目录: 生成一个静态库sunCalc。

cmake_minimum_required(VERSION 3.0)
project(CALCLIB)
#搜索calc下所有源文件
file(GLOB SRC ${CMAKE_SOURCE_DIR}/calc/*.cpp)
#包含头文件
include_directories(${CMAKE_SOURCE_DIR}/include)
#定义生成库的存储路径
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
#生成静态库
add_library(sunCalc STATIC ${SRC})

sort目录:生成一个静态库sunSort

cmake_minimum_required(VERSION 3.0)

project(SORTLIB)
#搜索sort下所有源文件
file(GLOB SRC ${CMAKE_SOURCE_DIR}/sort/*.cpp)
#包含头文件
include_directories(${CMAKE_SOURCE_DIR}/include)
#定义生成库的存储路径
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
#生成静态库
add_library(sunSort STATIC ${SRC})

testCalc目录: 将testCalc下所有.cpp文件整合,链接静态库sunCalc 生成可执行文件testCalc

cmake_minimum_required(VERSION 3.0)

project(CALCTEST)

file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

include_directories(${CMAKE_SOURCE_DIR}/include)

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)

link_libraries(sunCalc)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)

add_executable(testCalc ${SRC})

testSort目录: 将testSort下所有.cpp文件整合,链接静态库sunSort 生成可执行文件testSort

cmake_minimum_required(VERSION 3.0)

project(SORTTEST)

file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

include_directories(${CMAKE_SOURCE_DIR}/include)

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)

link_libraries(sunSort)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)

add_executable(testSort ${SRC})

其实这一步没有难度。

接下来

mkdir -p build
cd build 
cmake ..
make 

我们也多了库文件夹lib 可执行文件夹bin

5 日志

message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
  • (无) :重要消息
  • STATUS :非重要消息
  • WARNING:CMake 警告, 会继续执行
  • AUTHOR_WARNING:CMake 警告 (dev), 会继续执行
  • SEND_ERROR:CMake 错误, 继续执行,但是会跳过生成的步骤
  • FATAL_ERROR:CMake 错误, 终止所有处理过程

CMake 生成器 Ninja 与MinGW Makefiles

MinGW Makefiles使用

1 ctrl + shift +p CMake configure
2 cd build
3 cmake ..
4 mingw32-make

可以看到使用MinGW Makefiles构建

Ninja

1 ctrl + shift +p CMake configure
2 cd build
3 ninja

可以看到使用Ninja构建

转换 Ninja 与MinGW Makefiles

修改settings.json

{
   "files.associations": {
       "stdio.h": "c"
  },
   
   //"cmake.generator": "MinGW Makefiles"
   "cmake.generator": "Ninja"
}

CMake 是一个跨平台的自动化构建系统工具,它能够从简单的文本文件(通常是 CMakeLists.txt)来编译复杂的软件项目。CMake 支持多种不同的构建系统作为“生成器”,其中两种常见的生成器是 Ninja 和 MinGW Makefiles。

Ninja 生成器

Ninja 是一种现代且轻量级的构建系统,其设计目标是提高构建速度和效率。Ninja 的主要特点包括:

  • 快速: Ninja 被设计为比传统的 Make 工具更快。
  • 简洁: 产生的构建文件(.ninja 文件)体积小且易于解析。
  • 并行构建: 默认支持多线程构建。
  • 增量构建: 只重新构建需要更新的目标,从而节省时间。
  • 依赖性跟踪: 自动处理依赖关系,当源文件更改时只构建受影响的部分。

当你在 CMake 中使用 Ninja 作为生成器时,它会产生一组 .ninja 文件,这些文件被 Ninja 构建工具用来执行实际的构建操作。

MinGW Makefiles 生成器

MinGW Makefiles 生成器是针对 Windows 平台上的 GNU Make 工具的。当你选择这个生成器时,CMake 会生成一系列的 Makefile 文件,这些文件可以被 GNU Make 解释并用于构建项目。这个生成器的主要特点包括:

  • 传统: 基于经典的 Make 构建系统。
  • 广泛支持: Make 在各种平台上都有很好的支持。
  • 并行构建: 可以通过 -j 参数启用多线程构建。
  • 增量构建: 类似于 Ninja,但它可能不如 Ninja 那么高效。

其他同类型生成器

除了 Ninja 和 MinGW Makefiles 外,CMake 还支持许多其他生成器,包括但不限于:

  • Unix Makefiles: 类似于 MinGW Makefiles,但针对 Unix-like 系统。
  • Visual Studio: 生成 Visual Studio 项目的解决方案文件。
  • Xcode: 生成 Xcode 项目的文件。
  • NMake Makefiles: 针对 Windows 的 NMake 工具。
  • NMake Makefiles JOM: 与 NMake 类似,但 JOM 支持并行构建。
  • Watcom WMake: 适用于 Watcom C/C++ 编译器的 WMake 构建系统。
  • CodeBlocks - MinGW Makefiles: 为 CodeBlocks IDE 生成 Makefile。
  • MSYS Makefiles: 用于 MSYS 环境下的 GNU Make。
  • Borland Makefiles: 为 Borland C++ Compiler 生成 Makefile。
  • Ninja Multi-Config: 生成支持多个配置(如 Debug 和 Release)的 Ninja 文件。

每种生成器都有其特定的优势和适用场景。例如,在 Windows 上,如果你追求构建速度,那么 Ninja 或者 Visual Studio 可能是更好的选择;如果你更倾向于使用传统的 Make 构建方式,则可以选择 MinGW Makefiles 或 MSYS Makefiles。

CMake包与库

CMake 中的包

在 CMake 中,“包”(package)是指一个可以被其他项目使用的软件组件,它可以通过 CMake 的 find_package() 命令来查找和使用。一个 CMake 包通常包括:

  • 头文件:用于声明接口的 .h 或 .hpp 文件。
  • 库文件:可以是静态库或动态库。
  • 配置文件:如 packageConfig.cmake,用于描述包的位置、版本和其他元信息。

库(Library)

在 C++ 中,“库”通常指的是一个或多个源文件和/或二进制文件的集合,它们提供了一组相关的功能。库可以分为静态库和动态库。

  • 静态库:通常以 .a 或 .lib 文件形式存在,当链接程序时,库中的目标文件会被直接嵌入到可执行文件中。
  • 动态库:通常以 .so(Linux)、.dll(Windows)或 .dylib(macOS)等形式存在,它们在运行时被加载,而不是在编译时。
一个努力学习的憨憨
最后更新于 2024-08-13