【CMake】《CMake构建实战:项目开发卷》笔记-Chapter6-CMake构建初探

项目开发 - CMake教程+实战 通过Cmake 搭建一个demo,已熟悉cmake 的相关命令。 本文需要达到的目标 构建多个文件的demo vs 工程,生成exe 界面采用Qt 依赖三方库 自定义配置一些宏 1、 cmake 介绍 CMake 是一个开源、跨平台的工具系列,旨在构建、测试和打包软件 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装。也就是项目或者工程对的搭建,例如:windows 的vs , linux 下 makefile 。要知道这些工程的搭建是非常麻烦的。 CMake 功能强大。 阅读详情

第6章 CMake构建初探

从本章开始,我们不再仅仅停留在CMake脚本程序中,而是开始将CMake看作一个用于构建项目的利器了。在了解CMake的具体用法之前,先要清楚地掌握CMake项目的构建流程。换句话说,就是要清楚地掌握CMake项目的生命周期——从源程序和CMake目录程序,到构建好的二进制文件,再到这些二进制文件的安装和打包分发,最终到其他项目的源程序借助CMake使用这些二进制文件提供的功能。

本章会说明CMake是怎样实现这样一个生命周期的,重点介绍其构建项目过程中的6个阶段,尤其是与构建紧密相关的阶段。另外,本章还会介绍CMake缓存变量配置相关内容、CMake命令行的使用及与Visual Studio的搭配使用方法等,了解这些内容将有助于更好地使用CMake完成项目的构建。

另外,本章在介绍构建项目的后续阶段及CMake命令行的部分形式时,会涉及安装与打包的内容,若想了解这些主题的详细内容,可参阅CMake官方文档。如果在阅读过程中还遇到了其他生疏的概念,不必担心,它们还会在这里等待读者的第二次见面。

6.1 CMake项目的生命周期

6.1.1 配置阶段和生成阶段

CMake本身并不实际调用编译器和链接器等,而是根据整个构建流程,生成Makefile或者其他构建工具的配置文件,通过它们来实际调用各种命令完成构建。正因如此,CMake常被称为构建系统生成器。

CMake构建系统生成器在构建项目的过程中涉及两个重要阶段:一是执行CMake目录程序(CMakeLists.txt)的阶段,二是根据程序执行结果生成构建系统配置文件的阶段。前者往往是对项目的构建环境、构建目标等进行配置,因此称为配置阶段(configure stage);而后者用于生成构建系统的配置文件,因此称为生成阶段(generation stage)。这两个阶段均由CMake独立完成,其关系如下图所示。

配置阶段
生成阶段
生成阶段
配置阶段
构建阶段
构建阶段
构建阶段
CMakeLists.txt
CMake持久化缓存和CMakeFiles
IDE项目文件或Makefiles
生成的程序或资源文件
目标文件和库文件和可执行文件等二进制文件
源程序文件

之所以要区分这两个阶段,是因为在配置阶段,CMake仅需确定项目构建目标的依赖关系、构建需求等,与选用的具体构建系统的特殊化配置无关。在生成阶段,CMake必须根据目标构建系统(如Makefile等)的要求,生成出符合具体构建系统要求格式的具体配置。

上图中的“生成的程序或资源文件”既可能是配置阶段由CMake脚本直接生成的,又可能是构建阶段生成的。这是因为有些信息可能与构建系统的配置有关,因此CMake不能直接生成它们,而是将它们的生成过程在生成阶段定义到构建系统的配置中,再由构建系统最终在构建阶段生成。

例如,项目通常有Debug(调试)模式和Release(发布)模式两种构建模式,以对应不同的编译优化级别。对于Makefile构建系统而言,CMake需要对这两种构建模式分别生成不同的Makefile项目配置;而对于Visual Studio构建系统而言,由于其本身支持多种构建模式的切换, CMake只需生成一个Visual Studio的项目配置。试想,如果需要根据当前的构建模式生成不同的头文件内容,该怎么做呢?是否可以直接在CMake目录程序中获取当前构建模式并使用if命令来判断呢?

这对于Makefile这种单构建模式的构建系统是可行的,但对于Visual Studio这种支持多构建模式的构建系统则是不可行的。因为在配置阶段执行CMake目录程序时,CMake并不能够确定多构建模式构建系统当前选择的是哪种构建模式,这个信息只有在构建时才会确定。为了解决这类问题,CMake提供了生成器表达式。顾名思义,生成器表达式就是构建系统生成器的表达式,也就是生成阶段才会被解析的表达式。总而言之,这类问题只有在生成阶段结合了构建系统的具体特性后才可解决。其相关内容将在第8章中讲解。

常用构建系统生成器

执行cmake --help命令可以查看CMake支持的全部构建系统生成器。较为常用的构建系统生成器有以下几种。

  • Visual Studio <主版本号>[ <版本年>],如Visual Studio 16 2019或Visual Studio 16均表示可以生成Visual Studio 2019解决方案的构建系统生成器;

  • Unix Makefiles,即生成标准的UNIX平台的Makefile(包括GNU Makefile)的构建系统生成器;

  • NMake Makefiles,即生成NMake的Makefile的构建系统生成器;

  • Ninja,生成ninja-build(一个性能极高的构建工具)项目配置的构建系统生成器。

有一些构建系统生成器的名称形如<附加生成器> - <主生成器>。短横线前的附加生成器(extra generator)一般是IDE的名称,短横线后的主生成器(main generator)则是常见构建系统的名称。例如,CodeBlocks - Unix Makefiles、CodeBlocks - NMake Makefiles、CodeBlocks - Ninja等,这些生成器分别用于生成基于不同构建系统CodeBlocks集成开发环境的项目文件。CMake还支持其他一些附加生成器,如CodeLite、Eclipse CDT4、Kate和Sublime Text 2等。

实例:CMake的配置和生成阶段

现在通过一个静态库实例来演示CMake的配置和生成阶段。首先,在lib.c 源程序中实现一个用于整数加法的函数add,如下所示。

int add(int a, int b) { return a + b; }

然后,定义CMake目录程序CMakeLists.txt。其中,部分命令与项目构建、安装和打包相关,这里可以参考代码注释来大致理解,如下所示。

cmake_minimum_required(VERSION 3.20)

# 定义项目名称和版本
project(mylib VERSION 1.0.0)

# 添加静态库目标mylib,其源代码包含lib.c
add_library(mylib STATIC lib.c)

# 安装mylib构建目标
install(TARGETS mylib)

# 打包
set(CPACK_PACKAGE_NAME "mylib")
include(CPack)

最后,配置和生成项目。需要注意的是,CMake命令行仅支持同时执行CMake的配置和生成阶段,因此很难观察出CMake的持久化缓存文件CMakeCache.txt 和临时文件夹CMakeFiles是先生成的,而构建系统配置文件是后生成的。不过,CMake提供了一个可视化工具CMake GUI,用于分别执行CMake的配置和生成阶段。读者如果感兴趣,可以自行尝试。

下面以在Windows中使用Visual Studio 2019为例,展示调用cmake命令来进行配置和生成阶段的操作:

> cd CMakeBook/src/ch006/mylib
> mkdir build
> cd build
> cmake ..
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.... to target Windows 10....
-- The C compiler identification is MSVC 19....
-- The CXX compiler identification is MSVC 19....
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/.../cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/.../cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/CMake-Book/src/ch006/mylib/build

cmake命令接受源文件目录作为参数,此处即上级目录“..”。在CMake输出的日志中,Configuring done表示配置完成,Generating done表示生成完成。

由于Visual Studio 2019是支持多构建模式的构建系统,在配置生成阶段无须指定构建模式。如果使用的是单构建模式的构建系统,如Makefile,则必须在配置生成阶段使用CMAKE_BUILD_TYPE变量指定构建模式。下面是在Linux操作系统中使用CMake配置和生成Makefile构建系统项目的执行过程:

$ cd CMakeBook/src/ch006/mylib
$ mkdir build_debug
$ mkdir build_release
$ cd build_debug
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
...
$ cd ../build_release
$ cmake -DCMAKE_BUILD_TYPE=Release ..
...

6.1.2 构建阶段

在### 6.1.1 配置阶段和生成阶段图中,已经了解了构建阶段(build stage)的作用,即构建源程序为构建目标的二进制文件等。这个阶段没有特别之处,几乎完全依靠构建系统本身而非CMake来完成。也许构建阶段中会有部分小任务是靠调用CMake来完成的,但那也是由构建系统负责完成这些任务的组织调度。简言之,构建阶段发生的事情和本书第1章所介绍的内容没有本质区别。

构建模式

前面已经提到过构建模式(build configuration)了,这里有必要再详细介绍一下。不同的构建模式分别对应一系列不同的预置编译链接选项,我们可以根据需求方便地切换。 CMake默认提供如下四种构建模式。

  • Debug调试模式,禁用代码优化,便于调试。

  • Release发布模式,启用代码优化并针对速度优化,启用内联并丢失调试符号,几乎无法调试。

  • RelWithDebInfo发布调试模式,启用代码优化,但保留符号且不会内联函数,仍可调试。

  • MinSizeRel最小体积发布模式,启用代码优化,但针对二进制体积进行优化,使其尽可能小。

对于单构建模式的构建系统而言,应在CMake配置生成阶段通过CMAKE_BUILD_TYPE变量选择所需的构建模式。若想同时构建Debug和Release模式的程序,必须分别在两个目录中以不同的CMAKE_BUILD_TYPE变量值配置生成项目,再分别进行构建。6.1.1小节最后的实例中正是这样做的。

对于多构建模式的构建系统而言,无须在配置生成阶段指定构建模式,且仅需在一个目录中配置生成一次,就可以在构建阶段通过具体的构建系统的命令行工具(或cmake --build 命令行的--config参数)指定所需的构建模式。下面的实例展示了这一过程。

实例:使用CMake命令行构建项目

为了构建项目,可以打开Visual Studio的命令行工具,然后调用MSBuild命令行工具构建CMake生成的Visual Studio构建系统配置,即Visual Studio解决方案。也可以直接使用Visual Studio集成开发环境打开解决方案,然后使用可视化界面中提供的构建菜单或工具栏按钮进行构建。但这样未免有些烦琐,而且每一个构建系统都有不同的用户界面或交互方式,学习成本颇高。

CMake命令行提供的--build参数可以帮助调用构建系统(因此实际的构建过程仍由构建系统完成)。这样,无论使用何种构建系统,都可以使用统一的CMake命令接口来调用,从而避免记忆各式构建系统的命令接口,也便于编写自动化构建脚本。构建过程如下:

> cd CMakeBook/src/ch006/mylib
> cd build
> cmake --build . --config Release
用于 .NET Framework 的 Microsoft (R) 生成引擎版本 16....
版权所有(C) Microsoft Corporation。保留所有权利。
 
Checking Build System
Building Custom Rule C:/CMake-Book/src/ch006/mylib/CMakeLists.txt
lib.c
mylib.vcxproj -> C:\CMake-Book\src\ch006\mylib\build\Release\mylib.lib
Building Custom Rule C:/CMake-Book/src/ch006/mylib/CMakeLists.txt

在调用cmake --build命令行时,首先指定CMake项目的构建目录,即当前目录“.”;然后,通过--config参数指定构建模式为Release模式,即发布模式。命令执行完成后,可以在build目录中的Release子目录中找到构建好的静态库mylib.lib。

对于单构建模式的构建系统而言,--config参数是没有意义的,因为构建模式在配置生成阶段就已经通过CMAKE_BUILD_TYPE变量指定了。

6.1.3 安装阶段和打包阶段

如果只是希望把源程序文件构建成可执行文件,然后双击运行,那么上述三个阶段就已经足够完成这个目标了。但事实上,我们常常还需要分发程序包,以便用户安装使用。此时就需要用到CMake的install命令配置程序的安装规则了。我们还会用到CMake集成的CPack提供的打包功能,将需要安装的二进制程序文件打包,以便分发。这两个阶段分别对应安装阶段(install stage)和打包阶段(CPack stage)。

下图展示了CMake项目的完整生命周期。这张图是### 6.1.1 配置阶段和生成阶段图的超集,并且图中的虚线代表不属于本项目的部分,具体内容将在6.1.4小节介绍。

配置阶段
生成阶段
生成阶段
配置阶段
构建阶段
构建阶段
构建阶段
安装阶段
安装阶段
安装阶段
打包CPack阶段
程序包安装阶段
引用程序包
CMakeLists.txt
CMake持久化缓存和CMakeFiles
IDE项目文件或Makefiles
生成的程序或资源文件
目标文件和库文件和可执行文件等二进制文件
源程序文件
安装后的文件
打包后的程序包
安装的程序包
实例:安装和打包CMake项目

下面演示如何使用CMake来安装和打包mylib项目。安装和打包这两个阶段并没有先后依赖关系,可以根据需求执行任一或全部阶段。

首先,使用cmake --install命令安装CMake项目:

> cd CMakeBook/src/ch006/mylib
> cd build
> cmake --install . --prefix ../install
-- Install configuration: "Release"
-- Installing: C:/CMake-Book/src/ch006/mylib/install/lib/mylib.lib

CMake项目的构建目录,即当前目录“.”,应作为cmake --install命令行的第一个参数。然后是--prefix参数,用于指定安装目录前缀,即CMake项目安装位置的根目录。在该实例中,安装目录前缀为与构建目录同级的install目录。最后一行安装日志说明mylib.lib被安装到了安装目录前缀的lib子目录中。

下面使用cpack命令打包CMake项目:

> cd CMakeBook/src/ch006/mylib
> cd build
> cpack -G NSIS
CPack: Create package using NSIS
CPack: Install projects
CPack: - Install project: mylib []
CPack: Create package
CPack: - package: C:/.../build/mylib-1.0.0-win64.exe generated.

cpack命令会打包当前构建目录中的CMake项目,-G参数用于指定程序包生成器,这里指定了NSIS程序包生成器。NSIS是Nullsoft Scriptable Install System的简称,它是Nullsoft公司开发的一个脚本驱动的安装程序生成器。

命令执行后,当前构建目录中将会生成一个基于NSIS的安装程序mylib-1.0.0-win64.exe,双击执行它即可安装构建好的程序包。

6.1.4 程序包安装阶段

这个阶段不属于当前CMake项目,而是属于使用当前项目的其他项目。另外,### 6.1.3 安装阶段和打包阶段图中还有一个“引用程序包”的过程,这并非构建过程的一个阶段,因为它是通过另一个项目的CMake脚本来实现的。尽管如此,这二者仍然是构成CMake项目完整生命周期的重要组成部分。如果一个程序包能方便地被他人使用,那么编写这个程序包就能创造更大的价值。

用户安装打包后的程序包的阶段称为程序包安装阶段(package install stage)。需要注意区分它和安装阶段:程序包安装阶段是将打包好的程序文件解包并安装到当前环境中,而安装阶段则是将构建好的二进制程序文件安装到环境中。二者最终效果是一样的,但来源不同。如果用户直接获取了开发者提供的源程序并构建安装,那么实际上我们只需进行到安装阶段,但这样对用户来说非常耗时,不方便,且要求项目开源。如果用户下载并安装开发者提供的预编译安装包,那么实际上就是在进行程序包安装阶段,这样不需要用户自行构建二进制程序文件。当然,开发者需要预先为不同的构建环境编译好二进制程序并制作相应的安装包。

实例:安装和使用预编译的程序包

本例将新建一个CMake项目,演示如何在该项目中引用前面实例中打包好的静态库。

首先,运行上一实例中打包的安装程序mylib-1.0.0-win64.exe以安装静态库,安装路径可以使用默认值C:\Program Files\mylib 1.0.0。

然后,创建一个C程序main.c,在其中调用mylib静态库提供的加法函数add,并输出1加2的结果,如下所示。

#include <stdio.h>

extern int add(int, int);

int main() {
    printf("%d\n", add(1, 2));
    return 0;
}

该项目的CMake目录程序如下所示。

cmake_minimum_required(VERSION 3.20)

# 定义项目名称
project(use_mylib VERSION 1.0.0)

# 在默认搜索目录的mylib 1.0.0/lib子目录中查找mylib库
# 将目录路径存入mylib_LIBRARY变量中
find_library(mylib_LIBRARY 
    mylib 
    PATH_SUFFIXES "mylib 1.0.0/lib"
)

# 输出 "C:/Program Files/mylib 1.0.0/lib/mylib.lib"
message("${mylib_LIBRARY}")

# 添加可执行文件目标main,其源代码包含main.c
add_executable(main main.c)

# 链接mylib库到main程序
target_link_libraries(main ${mylib_LIBRARY})

其中,find_library就是用于查找库的CMake命令。它会在系统默认目录中进行查找,包括C:\Program Files目录。同时,命令参数中还指定了查找库的路径后缀mylib 1.0.0/lib,这样CMake就能找到静态库的具体位置。静态库的绝对路径会被存到find_library命令的第一个参数所指定的变量中。

target_link_libraries命令用于将一系列库文件或库目标链接到指定的构建目标中。其第一个参数为构建目标,其后的参数为一系列库的构建目标名称或路径,这里填写查找到的mylib库的路径。

下面配置生成、构建该项目,并运行主程序进行测试:

> cd CMakeBook/src/ch006/使用mylib
> mkdir build
> cd build
> cmake ..
...
C:/Program Files/mylib 1.0.0/lib/mylib.lib
-- Configuring done
-- Generating done
-- Build files have been written to: C:/CMake-Book/src/ch006/使用mylib/build
 
> cmake --build .
...
> ./Debug/main.exe
3

6.2 项目配置与缓存变量

在CMake项目的完整生命周期中,缓存变量始终起着至关重要的作用。在### 6.1.3 安装阶段和打包阶段图中可以看到CMake在配置阶段会产生持久化缓存文件。这些持久化缓存文件会在后续执行CMake时直接被加载,因此通常用于存储一些花费较大代价获取的信息。例如,CMake在第一次配置项目时,会检测当前编译环境,搜索确定编译器、链接器等工具的路径,并将这些信息保存到缓存中。总而言之,缓存变量能够被持久化,通常被用于实现对项目的配置。

本节会使用CMake GUI工具,直观地展示CMake在配置阶段做了哪些主要的配置。

6.2.1 使用CMake GUI配置缓存变量

在CMake配置阶段产生的持久化缓存文件CMakeCache.txt中,定义了CMake在该阶段通过对环境(如编译器、构建工具等)的检测所作出的默认配置。下面来了解mylib实例项目中到底有哪些配置吧!

首先,清理之前的build目录,以便重新配置。打开CMake GUI可视化工具,设置好源程序路径及用于构建二进制的路径,点击“Configure”按钮以配置mylib项目。

第一次配置时,CMake GUI会弹出一个对话框,询问采用何种构建系统。这里选择默认选项即可,直接点击“Finish”按钮完成选择。接着,CMake GUI开始配置阶段的执行,日志会输出到界面下方的文本框中。

界面中,以红色高亮显示的缓存变量是当前配置阶段中首次定义的缓存变量。如果再一次点击“Configure”按钮进行配置,大部分红色高亮就会消失。当然,也存在部分项目需要迭代地进行配置,因此第二次配置仍然有部分新的缓存变量被定义,依然以红色高亮显示。对于这类项目,我们应当反复点击“Configure”按钮进行配置,直到再没有红色高亮显示的缓存变量出现。

另外,当前显示的缓存变量只有两个,这并非配置阶段定义的全部缓存变量。一般来说,CMake默认只显示用户更关心的缓存变量,而把其他缓存变量隐藏起来。勾选缓存变量列表上方的Advanced(高级配置)复选框可以显示全部缓存变量。将鼠标指针悬停在列表项上方,可以查看对应缓存变量的描述文本。

6.2.2 常用缓存变量

简单浏览一下部分缓存变量配置。

首先,查看非高级配置,毕竟它们是更需要关注的缓存变量。

  • CMAKE_CONFIGURATION_TYPES,即支持的构建模式列表。其中元素取值可为Debug、Release、 MinSizeRel、RelWithDebInfo,分别代表调试模式、发布模式、最小大小发布模式、带调试信息的发布模式。

  • CMAKE_INSTALL_PREFIX,即安装目录前缀。在介绍安装阶段时介绍过,cmake --install命令可以用--prefix指定安装目录前缀。若省略该参数,则该命令会使用CMAKE_INSTALL_PREFIX缓存变量的值。

勾选Advanced复选框,即可使用高级配置查看所有的缓存变量。首先是文件路径类型的缓存变量:

  • CMAKE_AR,即用于打包静态库的归档工具的路径;

  • CMAKE_LINKER,即链接器的路径。

其次是一些与编译参数相关的缓存变量配置。

  • CMAKE_<编程语言>_FLAGS,即<编程语言>编译器的参数选项列表。该配置对所有构建模式生效。勾选缓存变量列表上方的Advanced(高级配置)复选框时有对C和CXX(即C++)编程语言的相关配置。

  • CMAKE_<编程语言>_FLAGS_<构建模式>,即配置特定<构建模式>下对应<编程语言>编译器的参数选项列表。该配置仅对指定构建模式生效。

接下来是一些与链接器参数相关的缓存变量配置。

  • CMAKE_<目标类型>_LINKER_FLAGS,即对应<目标类型>的链接参数列表。该配置对所有构建模式生效。 “目标类型”可为EXE、MODULE、SHARED、STATIC,即可执行程序、模块、动态库和静态库。

  • CMAKE_<目标类型>_LINKER_FLAGS_<构建模式>,即配置特定<构建模式>下的对应<目标类型>的链接参数列表。该配置仅对指定构建模式生效。

另外还有很多其他缓存变量配置,在此就不一一介绍了。其中有一些可能在后面的章节中会涉及,建议感兴趣的读者自行查阅相关CMake官方文档。

6.2.3 标记缓存变量为高级配置:mark_as_advanced

第3章介绍过如何使用set或option命令自定义缓存变量。这些自定义缓存变量默认情况下显示在CMake GUI中。如果想将某些缓存变量隐藏到高级配置中,可以调用mark_as_advanced命令:

mark_as_advanced([CLEAR|FORCE] <缓存变量>...)

该命令可以将指定的若干<缓存变量>设置为高级配置,即使其仅在CMake GUI中勾选Advanced复选框后才显示在缓存变量列表中。

若指定CLEAR参数,指定的缓存变量会被取消标记为高级配置;若指定FORCE参数,则指定的缓存变量不论是否已经被标记,都会被强制标记为高级配置;在不指定这两个参数的默认情况下,该命令只会标记尚未标记的缓存变量为高级配置。

如下所示中是一个实例。

cmake_minimum_required(VERSION 3.20)

project(cache-var)

set(MY_CACHE "MY_CACHE" CACHE STRING "")
set(MY_ADVANCED_CACHE "MY_ADVANCED_CACHE" CACHE STRING "")
mark_as_advanced(MY_ADVANCED_CACHE)

使用CMake GUI配置该项目后,MY_CAHCE默认显示在缓存变量列表中;MY_ADVANCED_ CACHE则需要勾选Advanced复选框后才能显示出来。

6.3 CMake命令行的使用

至此,我们已经大致了解了CMake命令行在不同阶段中的用法。在本节中,我们将对本章前面介绍的内容进行总结,并介绍更多的可选参数。

6.3.1 配置和生成

前面提到过CMake是构建系统生成器。因此,为了配置一个CMake项目并为其生成构建系统的配置文件,需要有如下设置。

  • 源文件目录(source directory)。该目录中应当包含该项目全部的源程序文件,包括使用CMake脚本语言编写的CMake目录程序。在源文件目录中(非子目录中)应当有一个CMake目录程序作为顶层CMake目录程序,也就是CMake配置项目的入口。

  • 构建目录(build directory),又称二进制目录(binary directory)。该目录会被作为生成构建系统配置文件及构建的二进制文件的目标目录。CMake持久化缓存文件也会输出到构建目录中。

  • 生成器(generator),即构建系统生成器。CMake支持生成多种构建系统,因此需要选择一个生成器。 cmake --help命令可以列举所有可供选择的生成器及默认的生成器,这通常包括Makefile、Visual Studio等生成器。

构建目录一般会在源文件目录之外,以免污染源文件目录。这种在源文件目录之外进行构建的方式,通常称为源外部编译(out-of-source build)。对应地,在源文件目录中直接生成构建的二进制文件的构建方式,称为源内部编译(in-source build)。

下面看看用于配置和生成项目的CMake命令行该如何书写。其一共有三种调用形式:

cmake [<其他选项>...] <源文件目录>
cmake [<其他选项>...] <已存在的构建目录>
cmake [<其他选项>...] -S <源文件目录> -B <构建目录>

其中,第一种形式只需指定<源文件目录>,使用当前工作目录作为<构建目录>。

当重新配置和生成一个已经生成过的CMake项目时,还可以使用第二种形式,仅指定 <已存在的构建目录>。

第三种形式是设置最全的。由于它不与当前工作目录相关,常常用于自动化构建脚本。

其他常用选项

<其他选项>有很多可选参数可供设置,在4.8节中就介绍过一些控制日志输出的参数,这里仅再列举两个较为常用的参数。完整的参数选项请参考CMake官方文档。

-G <生成器名称>

上述参数用于指定构建系统生成器的名称。若该参数被省略,CMake会先尝试读取CMAKE_GENERATOR环境变量中指定的值。若其值仍不存在,则选用默认的生成器。

执行cmake --help命令可以查看CMake支持的全部构建系统生成器。

-D <变量>:<类型>=<值>
-D <变量>=<值>

上述参数可以指定多次,用于创建或更新若干CMake缓存。该参数定义的CMake缓存值具有最高优先级,也会修改持久化缓存文件CMakeCache.txt,覆盖其中对应缓存变量的值。

若在指定该参数时省略<类型>,则对应缓存变量的类型由持久化缓存文件中定义的类型为准;若持久化缓存文件尚未生成,则根据CMake程序中set命令定义的同名缓存变量的类型来确定;若同名缓存变量从未被set定义过,则认为其没有类型(即文本类型)。若该参数定义的缓存变量被确定为PATH或FILEPATH类型,其值会被转换为绝对路径。

另外,该参数-D与后面变量定义之间的空格可以省略,直接作为一个独立的参数整体,例如,-D<变量>=<值>。

6.3.2 构建

介绍构建阶段时,已经调用过cmake --build命令行形式了,其完整形式如下:

cmake --build <构建目录> [<选项>...] [-- <传递给构建系统的选项>...]

由于CMake构建命令行实际上会调用其生成的构建系统来完成构建,因此可以看到,这里有两组参数选项:用于CMake构建命令行本身的<选项>参数和<传递给构建系统的选项>参数。其中,<传递给构建系统的选项>参数的取值取决于在CMake配置和生成阶段选用的哪种构建系统,与CMake无关。这里仅介绍部分比较常用的<选项>参数取值。

常用选项

下面这些常用选项均用于CMake构建命令的<选项>参数。

--parallel [<并行数量>]
-j [<并行数量>]

上述参数用于指定构建项目的最大并行进程数量。<并行数量>参数部分可以省略,省略后,其取值会先尝试从CMAKE_BUILD_PARALLEL_LEVEL环境变量中读取。若该环境变量未定义,则默认为底层构建系统采用的默认并行数量。

--target <目标名称>...
-t <目标名称>...

上述参数用于构建<目标名称>参数指定的若干目标,多个<目标名称>参数应当使用空格隔开。省略该参数则构建默认构建目标,即构建全部。

--config <构建模式>

对于支持多构建模式的底层构建系统来说,构建时需通过<构建模式>参数指定采用何种构建模式进行构建,其取值通常为Debug、Release、RelWithDebInfo、MinSizeRel之一。

--clean-first

上述参数要求构建系统在构建目标之前先清理项目生成的文件,即执行clean指令构建目标。

--verbose
-v

上述参数用于开启详细的构建日志输出,一般会包含构建的每一步执行的命令行。

若定义了VERBOSE环境变量或CMAKE_VERBOSE_MAKEFILE缓存变量被设置为真值,CMake也会启用详细的构建日志输出。

6.3.3 打开生成的项目

如果采用的构建系统生成器是对应某个集成开发环境的(如Visual Studio、Xcode等生成器),那么生成项目后,可以通过CMake命令行直接用对应的集成开发环境打开项目:

cmake --open <构建目录>

6.3.4 安装

在前面介绍安装阶段时已经调用过cmake --install命令行了。其完整形式如下:

cmake --install <二进制目录> [<选项>...]

<二进制目录>参数实际上就是构建目录。通常,在配置生成和构建时会将该目录称为 “构建目录”,而在构建出二进制文件后称为“二进制目录”。

常用选项

下面是用于cmake --install命令行的常用选项。

--config <构建模式>

对于支持多构建模式的构建系统来说,上述参数用于安装以指定<构建模式>构建的二进制文件。

--component <组件名称>

指定安装的<组件名称>后,CMake安装命令行仅会安装对应组件的二进制文件。组件名称可以通过CMake的install命令的COMPONENT参数设置,具体用法参见CMake官方文档。

--prefix <安装目录前缀>

上述参数用于指定<安装目录前缀>。CMake在进行安装时,所有二进制文件都会安装到相对于指定<安装目录前缀>的子目录中。

--strip

指定上述参数后,CMake在安装前会先清除二进制文件中所包含的调试信息。

--default-directory-permissions <默认目录权限>

上述参数用于指定安装目录的默认权限。<默认目录权限>的格式为u=rwx,g=rx,o=rw,其中等号前的u、g、o分别代表所有者、所在组和任何人,等号后的r、w、x 则分别代表读权限、写权限和执行权限。

--verbose
-v

上述参数用于启用详细日志输出。若VERBOSE环境变量被设置为真值,CMake 也会启用详细日志输出。

6.3.5 内置命令行工具

CMake还提供了一些内置命令行工具,用于替代常用的Shell命令,以文件系统操作为主。 CMake提供这些命令主要是出于跨平台的考虑,避免执行一些系统功能时,还需要对不同平台的Shell进行适配。前面实例中就曾经使用过“${CMAKE_COMMAND} -E echo”这个形式,用于输出指定字符串到标准输出。这些CMake命令行工具通常会配合CMake的execute_command等命令使用。CMake命令行工具的形式主体如下:

cmake -E <命令> [<命令参数>...]

下面会把<命令>和<命令参数>这两个参数放在一起介绍,毕竟二者是不可分割的。例如,在cmake -E cat a.txt这个命令行调用中,cat是<命令>参数, a.txt是<命令参数>参数。

输出文件内容
cmake -E cat <文件名>

该命令用于将指定的多个文件的内容同时输出到标准输出中。

切换当前目录
cmake -E chdir <目录> <命令行> [<命令行参数>...]

该命令用于切换到指定的<目录>,然后执行指定的<命令行>。

比较文件
cmake -E compare_files [--ignore-eol] <文件路径1> <文件路径2>

该命令用于比较指定的两个文件是否内容相同。若相同,则该命令的退出码为0;若不同,则为1;若参数不正确,则为2。--ignore-eol参数可用于忽略换行符的不同。

复制文件
cmake -E copy <文件路径>... <目标路径>

该命令用于复制若干<文件路径>指定的文件到 <目标路径>。其中,<目标路径>可以是一个文件路径或目录路径,但若指定了多个要复制的文件,则<目标路径>必须是一个已存在的目录路径。

该命令在复制时会解析符号链接,即复制符号链接指向的文件或目录。

复制目录
cmake -E copy_directory <目录路径>... <目标路径>

该命令用于复制若干<目录路径>指定的目录到 <目标路径>。其中,<目标路径>必须是一个目录路径(若不存在,该命令会创建该目标目录)。

该命令在复制时会解析符号链接,即复制符号链接指向的目录。

复制修改的文件
cmake -E copy_if_different <文件路径>... <目标路径>

该命令仅在文件发生改变时复制文件,其复制行为与copy命令一致。

创建符号链接
cmake -E create_symlink <指向路径> <符号链接路径>

该命令用于创建一个指向<指向路径>的符号链接。<符号链接路径>的所在目录必须存在。

创建硬链接
cmake -E create_hardlink <指向路径> <硬链接路径>

该命令用于创建一个指向<指向路径>的硬链接。<硬链接路径> 的所在目录和<指向路径>都必须存在。

输出字符串
cmake -E echo [<字符串>...]

该命令用于将指定的字符串和一个换行符输出到标准输出中。

输出字符串(不换行)
cmake -E echo_append [<字符串>...]

该命令用于将指定的字符串输出到标准输出中,最后不换行。

设置环境变量并执行命令
cmake -E env [--unset=<要删除的环境变量>]... 
             [<环境变量>=<环境变量值>]... 
             <命令行> [<命令行参数>...]

该命令用于删除或设置环境变量,然后在新的环境变量设置中执行指定的<命令行>程序。

列举环境变量
cmake -E environment

该命令用于列举所有环境变量。

创建目录
cmake -E make_directory <目录>...

该命令用于创建若干<目录>。当指定<目录>的父级目录不存在时,该命令也会递归地创建它们;当指定的<目录> 已存在时,该命令会忽略它。

重命名或移动
cmake -E rename <原始路径> <目标路径>

该命令用于重命名<原始路径>所对应的文件或目录,或将其移动到<目标路径>。若<目标路径>已存在,该命令会将已存在的文件或目录覆盖。

删除文件或目录
cmake -E rm [-rRf] <文件或目录路径>...

该命令用于删除若干<文件或目录路径>。

-r或-R参数用于递归删除目录。当指定的<文件或目录路径>不存在时,该命令默认返回非0退出码表示发生错误;但指定-f参数后,则会忽略不存在的路径,退出码为0。

延时
cmake -E sleep <秒数>

该命令用于延时指定的<秒数>。

打包或提取归档文件
cmake -E tar [c|x|t][v][z|j|J] <归档文件路径> 
             [--zstd] 
             [--files-from=<清单文件路径>] 
             [--format=<格式>] 
             [--mtime=<修改时间>] 
             [--] [<文件路径>...]

该命令用于打包或提取归档文件,其参数含义分别如下。

  • 指定c参数表示打包归档文件。此时<文件路径>参数用于指定需要被打包的文件,是必须提供的参数。

  • 指定x参数表示提取归档文件。此时<文件路径>参数可用于筛选需要被提取的文件(用于筛选的文件路径可通过-t参数查看)。

  • 指定t参数表示列举归档文件中的文件路径。此时<文件路径>参数可用于筛选需要被列举的文件。

  • 指定v参数表示输出详细日志。

  • 指定z参数表示使用gzip压缩归档。

  • 指定j参数表示使用bzip2压缩归档。

  • 指定J参数表示使用XZ压缩归档。

  • --zstd参数表示使用Zstandard压缩归档。

  • <清单文件路径>参数用于指定一个清单文件,该文件内容的每一行是一个文件路径。这些文件路径会作为<文件路径>参数。清单文件中的空行会被忽略,另外文件路径不能以“-”开头。如果一定要包含以“-”开头的路径,可以通过为该文件路径添加前缀“--add-file=”的方式将其加入清单文件中。

  • <格式>参数用于指定归档格式,其值可为7zip、gnutar、pax、paxr及zip。

    • pax代表可移植归档交换格式(portable archive exchange)。

    • paxe代表受限可移植归档交换格式(restricted pax),也是默认格式。

  • <修改时间>参数用于指定归档中文件的修改时间。

  • --参数用于分隔<文件路径>参数和其他参数,即在--之后的参数都会作为<文件路径>,可用于引用横杠开头的文件路径。

计时执行命令
cmake -E time <命令行> [<命令行参数>...]

该命令用于执行指定的<命令行>程序,并输出执行时间。

Touch文件
cmake -E touch <文件>...

该命令用于创建指定的<文件>,若其已存在,则将其修改和访问时间更新为当前时间。

Touch文件(不创建)
cmake -E touch_nocreate <文件>...

该命令用于将指定<文件>的修改和访问时间更新为当前时间,若<文件>不存在,则忽略它。

返回成功
cmake -E true

该命令仅用于返回成功,即其退出码为0。它不做任何其他操作。

返回错误
cmake -E false

该命令仅用于返回错误,即其退出码为1。它不做任何其他操作。

生成文件校验和
cmake -E md5sum <文件>...
cmake -E sha1sum <文件>...
cmake -E sha224sum <文件>...
cmake -E sha256sum <文件>...
cmake -E sha384sum <文件>...
cmake -E sha512sum <文件>...

这些命令用于创建指定的若干<文件>的校验和文件。该命令创建的校验和文件格式可以兼容对应算法的校验工具。例如,使用md5sum工具可以校验cmake -E md5sum命令生成的校验和。

获取CMake能力
capabilities

该命令用于获取当前CMake版本所具有的能力,并通过一个JSON对象输出。该JSON对象具有如下键和子键。

  • version,这是一个表示CMake版本信息的JSON对象,其子键如下。

    – string,即CMake版本号的字符串表示,如3.20.2。

    – major,即CMake主版本号,如3。

    – minor,即CMake的次版本号,如20。

    – patch,即CMake的修订版本号,如2。

    – suffix,即CMake的版本后缀字符串,如rc1。

    – isDirty,表示CMake是否从一个修改过的Git目录树中构建。

  • generators,这是一个表示受支持的构建系统生成器的JSON对象数组。其中每一个对象的键如下。

    – name,即生成器的名称,如Visual Studio 16 2019。

    – toolsetSupport,即该生成器是否支持工具链设置。

    – platformSupport,即该生成器是否支持平台设置。

    – supportedPlatforms,即该生成器支持的平台名称(当且仅当该生成器支持设置平台时存在该键),例如,Visual Studio 16 2019生成器的supportedPlatforms值包含x64、Win32、ARM和ARM64等。

    – extraGenerators,即与该生成器关联使用的附加生成器的名称数组,关于附加生成器的介绍参见6.1.1节。例如,Unix Makefiles生成器的extraGenerators值包含Kate、Sublime Text 2和CodeBlocks等。

  • fileApi,这是一个表示受支持的CMake File API的JSON对象。它具有一个子键requests。

    – requests,即表示受支持的File API请求对象的数组,其中每一个对象的键如下。

      ■ kind,即File API请求对象的类型。
      
      ■ version,即File API请求对象的版本号。这是一个JSON数组,每一个元素代表版本号的一部分。
    
  • serverMode,这是一个表示是否支持CMake服务端模式的布尔值。由于CMake服务端已被弃用,在CMake 3.20版本以后,该值总是false。

6.4 使用Visual Studio打开CMake项目

6.4.1 生成Visual Studio的原生解决方案

使用Visual Studio这个强大的集成开发环境来编辑、调试程序能够极大地提高开发效率。很多构建工具虽然功能强大,但缺少集成开发环境的支持,使得开发效率大大降低,因此很难被广泛的人群采用。CMake作为构建工具的生成器,自然能够更好地解决这一问题——只需使用Visual Studio生成器,将CMake项目配置生成出Visual Studio 支持的解决方案文件。

前面已经介绍过如何使用cmake命令行配置生成项目:

> cd CMakeBook/src/ch006/mylib
> mkdir build
> cd build
> cmake -G "Visual Studio 16" ..
...

配置生成结束后,build构建目录中会生成出一个名为mylib.sln的解决方案文件。双击打开它,即可启动Visual Studio!在Visual Studio的解决方案资源管理器中,可以看到多个 Visual C++ 项目,它们分别对应该CMake项目的各个构建目标。

其中,ALL_BUILD目标表示构建全部,INSTALL目标用于安装项目,mylib目标即创建的静态库目标,PACKAGE目标用于打包项目,ZERO_CHECK目标用于在CMake目录程序发生改变时重新配置生成该项目。

不允许通过Visual Studio的用户界面来为项目添加新的源文件(例如,通过项目的右键菜单来为某个构建目标新建源文件),因为这样创建的文件并不会同步到CMakeLists.txt目录程序中,是没有意义的。应当通过手动修改CMakeLists.txt的方式来添加源文件。

6.4.2 使用Visual Studio直接打开CMake项目

Visual Studio 2015及以前的版本不支持直接打开CMake项目。由于 CMake逐渐成为业界C和C++程序的构建标准,Visual Studio 2017版本终于提供了对CMake的原生支持。

启动Visual Studio,依次选择“文件”→“打开”→“CMake”(或“文件夹”)。在弹出的打开文件对话框中选择CMake目录程序文件(若刚刚执行的是“文件夹”命令,应选择CMake目录程序所在目录)即可打开该项目。

有关Visual Studio直接打开CMake项目后提供的各种功能的具体使用方法,请参考Visual Studio的官方文档。

Visual Studio相当于对CMake做了一定的封装,通过用户界面来提供对CMake的各种操作,对初学者比较友好。因此建议先使用第二种方式打开CMake项目。

不过,由于CMake确实非常复杂,Visual Studio提供的封装可能不够全面,有时也不够稳定。如果使用Visual Studio直接打开CMake项目时遇到了问题,那么不妨先生成项目的解决方案后再用Visual Studio打开CMake项目。

6.5 小结

本章带领读者体验了CMake项目从构建到使用的完整生命周期,尽管并未涉及很多细节,但也希望本章能够帮助读者对CMake在构建过程中发挥的作用建立宏观的认识。

另外,本章也详细地介绍了CMake命令行工具和GUI工具的使用方法,以及如何在Visual Studio中打开CMake项目。读者阅读完本章后,应当已经可以通过CMake完成简单项目的配置生成和构建了。不妨从互联网上下载一个使用CMake作为构建工具的开源项目,尝试在自己的计算机中构建一下。

既然已经能够使用CMake构建项目,那么,如何使用CMake组织一个自己的项目呢?这正是第7章将带领大家深入了解的内容。请继续阅读吧!

Makefile和CMake实战.pdf Makefile和CMake实战 立即下载

相关推荐

CMake实战.pdf

cmkae使用方法介绍

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter1-构建之旅

结合前两个例程能够发现,使用要求在被传递时存在多种可能性:1.传递到使用者的构建要求;2.传递到使用者的使用要求;3.同时传递到使用者的构建要求和使用要求。前面两个例程分别对应第一种情况和第三种情况。第二种情况一般在当头文件(接口)使用了某个库,而源程序(实现)中并没有使用这个库时才会用到,多见于伪构建目标。举个另类但还算实用的例子:当希望引用一个接口库就可以自动链接多个库时,实际上就是要将多个链接库的使用要求传递给这个接口库的使用要求。接口库是伪构建目标,不需要编译,也就不存在构建要求。

江湖人称菠萝包 1406

cmake实践 修订版 pdf

在原版的基础上,修正了若干小错误,并添加了简单的目录。

【免费下载】 CMake实战.pdf - 构建自动化工具深度指南

CMake实战.pdf - 构建自动化工具深度指南 【下载地址】CMake实战.pdf-构建自动化工具深度指南分享 CMake实战.pdf - 构建自动化工具深度指南欢迎来到 **CMake实战.pdf** 的资源页面 项目地址:...

gitblog_06612的博客 1594

Cmake实践.pdf

cmake是kitware公司以及一些开源开发者在开发几个工具套件(VTK)的过程中衍 生品,最终形成体系,成为一个独立的开放源代码项目。项目的诞生时间是2001年。其官 方网站是www.cmake.org,可以通过访问官方网站获得更多关于cmake的信息。cmake 的流行其实要归功于KDE4的开发(似乎跟当年的svn一样,KDE将代码仓库从CVS迁移到 SVN,同时证明了SVN管理大型项目的可用性),在KDE开发者使用了近10年autotools 之后,他们终于决定为KDE4选择一个新的工程构建工具,其根本原因用KDE开发者的话来 说就是:只有少数几个“编译专家”能够掌握KDE现在的构建体系 (admin/Makefile.common),在经历了unsermake, scons以及cmake的选型和尝 试之后,KDE4决定使用cmake作为自己的构建系统。在迁移过程中,进展异常的顺利,并 获得了cmake开发者的支持。所以,目前的KDE4开发版本已经完全使用cmake来进行构 建。像kdesvn,rosegarden等项目也开始使用cmake,这也注定了cmake必然会成为 一个主流的构建体系。

CMake实践PDF

本教程主要讲解如何利用cmake工具在服务器领域构建c/c++工程,当然在不同平台上的很多工具都用cmake构建,熟悉掌握cmake的使用,可以更深入的了解代码编译深层的东西,推荐大家在学习编程时选择Linux平台,对技术理解有更多益处,本书虽然篇幅不多,但通过示例讲解,还是推荐大家阅读

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter7-构建目标和属性

属性用于定义编译(预处理)C和C++程序时所用到的宏。该属性值为列表字符串,每一个元素都代表一个宏定义。其元素格式为<宏名称>或<宏名称>=<值>。属性用于定义库目标对使用者的宏定义要求。任何构建目标,若链接到具有该属性的库目标,都会定义该属性所要求的宏。换句话说,该属性作为使用要求,会被自动传递给依赖者的构建要求。该传递过程由CMake在配置生成阶段隐式地完成,并不会改变依赖者的属性。属性仅包含为目标自身定义的构建要求,不包含传递过来的构建要求。

江湖人称菠萝包 1227

【二合一】CMake 实践+开发手册详解.pdf

【二合一】CMake 实践+开发手册详解.pdf

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter4-常用命令

CMake主要为构建服务,因此提供了专门生成宏定义的模板,可以非常方便地用于代码生成。例如,可以将定义在CMake程序中的版本号等信息以宏定义的形式生成到头文件中,并最终构建到可执行文件中。宏定义模板主要分为两种形式:一种是值为0或1的宏定义,另一种是自定义值的宏定义。后一种形式的自定义值可为空值,用于表示存在性。#cmakedefine01 <变量>#cmakedefine <变量> [<值>]#define <变量> 0/* #undef <变量> */如下所示中是一个实例。

江湖人称菠萝包 1074

CMake实战-20200708.pdf

CMake实战-20200708.pdf

树莓派国内镜像源一键配置指南

本文提供树莓派国内镜像源一键配置指南,解决默认国外源访问缓慢问题。通过自动检测系统版本并支持清华、阿里云、中科大等主流镜像站选择,大幅提升软件更新与安装速度。包含详细的手动配置方法和常见问题排查,帮助用户快速完成树莓派换源优化。

tequila的博客 1379

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter9-模块

尽管CMake内置了相当多软件包的查找模块,但难免还会有特殊的需求。本节将介绍如何自己编写一个查找模块。在查找模块的实现中,往往需要查找软件包所需的可执行文件、库文件、头文件目录等路径。CMake提供了一系列命令用以辅助完成这些工作。下面先介绍这些命令。

江湖人称菠萝包 1376

【过检测】2026调试级去虚拟化虚拟机成品

EternalBlaze调试级虚拟机是由恒烈开发的定制化VMware环境,适用于逆向工程、病毒分析等专业场景。该虚拟机基于Windows 10 1909专业版,预装Python/JDK等开发环境和逆向工具包,支持快照回溯功能。特色包括:一键去虚拟化方案、双机调试支持、驱动开发环境等。适用场景涵盖CTF竞赛、软件调试、病毒行为分析等,但不支持DX12游戏和视频盗录。使用前需按步骤关闭安全中心、安装特定VMware版本并执行去虚拟化操作。虚拟机提供基础版和逆向调试增强版两种配置,均预装必要工具链。(149字)

Heng_lie的博客 2679

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter2-CMake简介

CMake官网给出了如下的定义:CMake是一个跨平台开源工具家族,用于构建、测试和打包软件。CMake通过简单的平台无关且编译器无关的配置文件来控制软件的编译流程,并能够生成原生的Makefile和工作空间,以便用于用户所选择的编译环境。为了满足开源项目对强大的跨平台构建工具的需求,Kitware公司创建了CMake工具套装。定义中,“跨平台”和“开源”这两个特性不必多说,要注意的是“工具家族”这个说法。

江湖人称菠萝包 921

Arcmap计算土方量教程

1. 创建现状TIN 结果数据: 2. 创建设计TIN 结果数据: 注意:现状TIN和设计TIN构建时候的坐标系不同,设置坐标系见最后的注意事项第1点,就是import(导入)那步骤,现状TIN构建时选择高程点数据或者等高线数据,设计TIN构建时候选择洱海面数据 3. TIN转栅格 改成你要存的数据库,注意中间不要有汉字 结果数据(设计TIN转栅格的同理) 4. 裁剪现状TIN转成的栅格 结果数据: 5. 计算土方量 结果数据: ...

欢迎关注,共同进步! 5017

眼动数据分析基础_AOI分析动态刺激物

如果您正在研究人们对如视频、动画等动态刺激物的视觉行为,动态AOI工具可为您提供类似静态AOI工具对于图片及其他静止刺激物分析的同样功能。创建和编辑动态AOI的过程和静态AOI相似。 关于动态AOI工具的使用,有几点非常重要: 多个看到相同线性动态刺激物的用户的眼动数据叠加是有价值的; 动态AOI不能用于非线性动态记录的分析; 动态AOI不能用于静态刺激物,如图片的分析; 动态AOI可以被开启、关闭、移动、调整大小及跟踪相关分析对象 首先,我们来定义两种不同的动态刺激物:线性动态刺激物(LDS),是指固

Kobe123brant的博客 3504

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter3-基础语法

CMake中有很多预定义的普通变量和环境变量,它们一般以“CMAKE_”开头,即属于保留标识符。预定义变量往往与系统配置、运行环境、构建行为、编译工具链、编程语言等信息相关。CMake中的预定义变量全部可以在其官方文档中找到,本书也会陆续涉及很多常用的预定义变量。在此先简单看一些预定义变量的例子。CMAKE_ARGC表示CMake脚本程序在被cmake -P命令行调用执行时,命令行传递的参数个数。表示CMake脚本程序在被命令行调用执行时,命令行传递的第一个、第二个参数。

江湖人称菠萝包 1291

图像修复黑科技:对比BM3D/DnCNN等5种去噪器在PNP框架中的实战效果

本文深度评测了BM3D、DnCNN等五款主流去噪器在即插即用(PnP)优化框架中的实战表现。通过量化指标、视觉对比及超分等泛化任务测试,揭示了深度学习模型在性能与收敛速度上的优势,并为不同应用场景提供了选型指南与工程化建议。

weixin_29065959的博客 371

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter11-实践:基于onnxruntime的手写数字识别库

读者已经跟着本书实践了很多零零散散的实例,应该能够熟练使用CMake来构建C和C++程序了吧!不过,前面的实例往往都是针对某个特定功能编写的,我们可能很难将它们综合起来实现一个完成度较高的项目。不必担心,本章就带领大家使用C++语言实现一个完整的动态库,以及调用该库的可执行文件——手写数字识别库和手写数字识别命令行工具。相信经过本章的实践,读者一定可以将前面所学的知识融会贯通,应用于中大型项目中了!

江湖人称菠萝包 1469

Ego-Planner实战避坑指南:从环境搭建到仿真运行

本文详细介绍了在Windows系统下,通过WSL2搭建Ego-Planner无人机路径规划算法开发环境的完整流程与实战避坑指南。内容涵盖ROS Noetic安装、第三方依赖库(如Ceres Solver)编译冲突解决、Realsense SDK版本降级处理,以及Gazebo仿真与真机调试的常见问题,旨在帮助开发者高效完成环境配置并成功运行仿真。

weixin_29232507的博客 700

GPU架构(1.1)--介绍 GPU的 VPU(Vision Processing Unit)架构

基于自研的 VPU(Vision Processing Unit)架构,专为高性能图形处理和深度学习设计。VPU 架构通过优化计算单元、内存层次结构、同步机制和指令流水线,提供了卓越的性能和能效。VPU 架构通过优化计算单元、内存层次结构、同步机制和指令流水线,提供了卓越的性能和能效。这种架构不仅适用于高性能图形处理,还广泛应用于深度学习、科学计算和边缘计算等领域。通过了解 VPU 架构的详细设计和工作原理,读者可以更好地利用这些先进的 GPU 技术,开发出高效、可靠的计算系统。

MHD0815的博客 1301

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter8-生成器表达式

关于这两个命令中的哪些参数支持生成器表达式,第7章中均已介绍,这里不再赘述。

江湖人称菠萝包 1310

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter10-策略与向后兼容

CMake相当重视向后兼容性,并且受益于此,能够持续不断地改进和增加新特性,而几乎不会破坏古老的代码仓库。这一点在第2章介绍CMake的特点时已经提到过。CMake的策略机制就是为解决向后兼容问题而生的。有了策略机制,CMake可以基本确保基于旧版本CMake编写的目录程序可以被新版本的CMake配置生成,同时,如果程序中使用了已经弃用的特性,它也能针对性地给出警告信息,鼓励或要求用户重构CMake程序。

江湖人称菠萝包 904

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【CMake】《CMake构建实战:项目开发卷》笔记-Chapter5-实践:CMake快速排序

到这里,终于将CMake中比较常用的命令都讲解完了。本章是本书中第一个实践章节。实践章节不会介绍任何的新内容,而是通过一个具体的项目来实战演练前面学习到的知识。鉴于之前我们一直把CMake当作通用脚本语言来学习,本章也不会含糊,直接实现一个经典算法:快速排序!快速排序的基本原理很简单:找到数列的一个基准值,将数列分成比该值小和比该值大的两部分子数列;变量,分别代表CMake脚本模式下命令行参数的个数及第N个参数的值(包括cmake命令行名称本身)。如果希望传递自定义参数到CMake脚本程序中,可以在调用。

江湖人称菠萝包 285

Shiki v4.0.0 升级指南:破坏性变更、Node.js 20 要求与废弃 API 清理

Shiki 4.0.0 是一次以"清理与收敛"为主题的主版本发布:它放弃了对 Node.js 18 的支持,并将此前若干标记为废弃(deprecated)的 API 与错误拼写的名称彻底移除。本指南逐条梳理 v4 的破坏性变更,给出对应的替换写法与升级检查清单,帮助你在升级 `shiki` 及其生态包(`@shikijs/vitepress-twoslash` 等)时平稳迁移。 ## 升级背景:

gitblog_00068的博客 703
上一篇: 【CMake】《CMake构建实战:项目开发卷》笔记-Chapter5-实践:CMake快速排序
下一篇: 【CMake】《CMake构建实战:项目开发卷》笔记-Chapter7-构建目标和属性
江湖人称菠萝包
博客等级 码龄10年 762粉丝 314原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值