从零开始 CMake 学习笔记 (F)Build Type

从零开始 CMake 学习笔记 (F)Build Type

开始前先默念三遍口诀:

  • Declare a target
  • Declare target’s traits
  • It’s all about targets
    本系列主要根据GitHub上的 cmake-examples 项目进行翻译总结,同时对于不清晰的概念及函数进行查阅理解记录形成。

1 介绍

本示例展示了如何在生成可执行二进制文件中设置编译类型,这些类型可以指定项目的优化级别以及是否在二进制文件中包含调试信息。

1.1 文件树

F-build-type $ tree
.
├── CMakeLists.txt
├── main.cpp

1.2 文件简介

  • CMakeLists.txt - 包含了你希望运行的 CMake 命令
// $ cmake --version
cmake_minimum_required(VERSION 3.5)

// 如果编译类型未指定,那么就设置默认编译类型
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  //message可用于在编译cmake时打印信息,比如我们想打印出 `PROJECT_SOURCE_DIR` 这个变量,就可以按下面这行代码
  //message("PROJECT_SOURCE_DIR value is ${PROJECT_SOURCE_DIR}")   -- 打印`PROJECT_SOURCE_DIR`变量的值
  message("Setting build type to 'RelWithDebInfo' as none was specified.")
  //给CMAKE_BUILD_TYPE变量赋值为 RelWithDebInfo ,并将这个值写入缓存,并覆盖缓存中该变量之前的值(如果有的话)。
  set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
  // 当使用cmake-gui的时候,设置编译类型的四个可选项
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
    "MinSizeRel" "RelWithDebInfo")
endif()

// 设置项目名称
project (build_type)

// 添加可执行文件
add_executable(cmake_examples_build_type main.cpp)
  • main.cpp - main 文件
#include <iostream>

int main(int argc, char *argv[])
{
   
   std::cout << "Hello Build Type!" << std::endl;
   return 0;
}

2 概念解析

2.1 编译类型

CMake具有许多内置的构建配置,可用于编译工程。 这些配置指定了代码优化的级别,以及调试信息是否包含在二进制文件中。主要有下面四种:

  • Release - 发行版。顾名思义,程序完成开发后的发布版本,对代码做了优化,速度非常快,但无法跟踪代码,不能打断点调试。可以在编译器追加后: -O3 -DNDEBUG 选择此版本。

  • Debug - 调试版。对代码不做任何优化,可以 debug 项目中的任意文件。一般速度相对会慢,而且体积更大。可以在编译器追加后: -g 选择此版本。

  • RelWithDebInfo - 非常近似与Release版本,代码也是经过优化的,同时还支持添加断点进行调试。可以在编译器追加后: -Os -DNDEBUG 选择此版本。

  • MinSizeRel - 最小体积版本。类似与Release版本,但更偏重于优化文件大小,而不是运行速度。可以在编译器追加后: -O2 -g -DNDEBUG 选择此版本。

2.2 设置当前次的编译类型

2.2.1 CMake图形界面

在这里插入图片描述

2.2.2 CMake命令行

CMake命令行中,同配置其他参数一致,使用 -D 选项

cmake .. -DCMAKE_BUILD_TYPE=Release

2.3 设置默认的编译类型

CMake提供的默认编译类型时不包含优化的。因此,如果我们想要将设置的编译类型应用于所有用户的各个子项目,那我们可以考虑直接更改默认的编译类型。你可以直接在项目顶层的 CMakeLists.txt 文件中设置如下:

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message("Setting build type to 'RelWithDebInfo' as none was specified.")
  //给CMAKE_BUILD_TYPE变量赋值为 RelWithDebInfo ,并将这个值写入缓存,并覆盖缓存中该变量之前的值(如果有的话)。
  set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
  #  当使用cmake-gui的时候,设置编译类型的四个可选项
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
    "MinSizeRel" "RelWithDebInfo")
endif()

2.3.1 set() 拓展

set() 命令可以为普通变量、缓存变量、环境变量赋值。下面分别对三种变量的设置进行说明。

2.3.1.1 设置普通变量

命令格式set(<variable> <value>... [PARENT_SCOPE])

命令含义:将变量variable设置为值<value>...,变量variable的 作用域 为调用set命令的函数或者当前目录,如果使用了PARENT_SCOPE选项,意味着该变量的作用域会传递到上一层(也就是上一层目录或者当前函数的调用者,如果是函数则传递到函数的调用者,如果是目录则传递到上一层目录),并且在当前作用域该变量不受带PARENT_SCOPE选项的set命令的影响(如果变量之前没有定义,那么在当前作用域仍然是无定义的;如果之前有定义值,那么值和之前定义的值保持一致,类似于之前target_include_directoriesINTERFACE 命令,我定义但是我不用)。

关于变量的作用域:每一个新的目录或者函数都会创建一个新的作用域,普通变量的作用域,如果不使用PARENT_SCOPE选项,只能从外层往内层传递。

案例1

最常用的用法示例如下:

cmake_minimum_required(VERSION 3.5)
project (set_test)
set (normal_var a)
message (">>> value =
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值