一般在工程中,自动构建可能会编译两个版本的发布包,一个debug版本,一个release版本。那么通过cmake怎样来实现呢?本文就以这个需求为例,来介绍cmake中的逻辑控制。

目录结构

|-- bin
|-- build
|-- CMakeLists.txt
|-- src
|   `-- main.c

Debug-Release模式控制
顶层CMakeLists.txt

cmake_minimum_required(VERSION 3.12)
project(test07)

aux_source_directory(${PROJECT_SOURCE_DIR}/src src_dirs)

# 条件判断
if(CMAKE_BUILD_TYPE AND (CMAKE_BUILD_TYPE STREQUAL "Debug"))
    set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -O0")
    message("Debug mode:${CMAKE_C_FLAGS_DEBUG}")
    add_executable(test_debug ${src_dirs})

elseif(CMAKE_BUILD_TYPE AND (CMAKE_BUILD_TYPE STREQUAL "Release"))
    set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wall -O3")
    message("Release mode:${CMAKE_C_FLAGS_RELEASE}")
    add_executable(test_release ${src_dirs})
else()
    message("else:${CMAKE_BUILD_TYPE}")
    message("else:${CMAKE_C_FLAGS_RELEASE}")
    add_executable(test_release ${src_dirs})
endif()

先简要的描述一下该CMakeLists.txt的控制逻辑。如果CMAKE_BUILD_TYPE的值为"Debug"就采用debug模式编译;如果CMAKE_BUILD_TYPE的值为"Release"就采用release模式编译;如果CMAKE_BUILD_TYPE的值为空,默认采用release模式

默认编译

从上图可以看出,CMAKE_C_FLAGS_RELEASE 编译选项的默认值为-O3 -DNDEBUG。最终生成可执行文件test_release,./test_release输出’hello cmake’。test_release文件大小为8600字节。

release 编译


从上图可以看出,通过cmake命令行指定CMAKE_BUILD_TYPE为Release,最终生成可执行文件test_release,./test_release输出’hello cmake’。test_release文件大小为8600字节。

debug编译


从上图可以看出,通过cmake命令行指定CMAKE_BUILD_TYPE为Debug,最终生成可执行文件test_release,./test_release输出’hello cmake’。test_release文件大小为9872字节。因为debug模式编译生成的可执行文件包含可调试的相关信息,所以文件大小会变大。

控制逻辑

通过上例知道,可以通过if命令来控制cmake的编译逻辑,接下来,详细介绍cmake中if命令的使用。

条件命令

if(<condition>)
  <commands>
elseif(<condition>) # optional block, can be repeated
  <commands>
else()              # optional block
  <commands>
endif()

if条件命名的语法非常简单。这里需要特别说明关于if(<variable>)中variable的注意点,引用文档中的一段话:

The if command was written very early in CMake’s history, predating the ${} variable evaluation syntax, and for convenience evaluates variables named by its arguments as shown in the above signatures. Note that normal variable evaluation with ${} applies before the if command even receives the arguments.

这段话的意思是,由于if命令语法在变量引用${}语法之前出现,所以如果使用if(${var}),那么将会被引用两次;如果使用if(var),将只会被if本身的语法引用一次。也就是要注意两次引用问题。

举个栗子:

# 在前面的CMakeLists.txt中
if(CMAKE_BUILD_TYPE AND (CMAKE_BUILD_TYPE STREQUAL "Debug"))

如果是通过cmake .. 编译,而没有指定CMAKE_BUILD_TYPE的话,那么if命令本身会引用变量CMAKE_BUILD_TYPE,其值为空,if条件判断为假;
如果是通过cmake -DCMAKE_BUILD_TYPE=Debug .. 编译,if命令本身会引用变量CMAKE_BUILD_TYPE,其值为Debug,if条件判断为真;

# 如果将变量CMAKE_BUILD_TYPE通过${}再引用一次,会发生什么?
if(${CMAKE_BUILD_TYPE} AND (CMAKE_BUILD_TYPE STREQUAL "Debug"))

由于 ${CMAKE_BUILD_TYPE}的值为空,if(${CMAKE_BUILD_TYPE}相当于if(空变量),然后if命令再对"空变量"进行引用,显然,语法上错误。即会报如下图错误:


如果你非要使用if($var),那你必须明确的知道变量var的值是另一个变量的变量名。

例如,将前面的CMakeLists.txt做如下修改(虽然没有什么实际意义,仅作为解释语法特点)

cmake_minimum_required(VERSION 3.12)
project(test07)

aux_source_directory(${PROJECT_SOURCE_DIR}/src src_dirs)

set(mode "CMAKE_BUILD_TYPE") # 修改点

# 条件判断
if(${mode} AND (CMAKE_BUILD_TYPE STREQUAL "Debug")) # 修改点
    set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -O0")
    message("Debug mode:${CMAKE_C_FLAGS_DEBUG}")
    add_executable(test_debug ${src_dirs})

elseif(${mode} AND (CMAKE_BUILD_TYPE STREQUAL "Release")) # 修改点
    set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wall -O3")
    message("Release mode:${CMAKE_C_FLAGS_RELEASE}")
    add_executable(test_release ${src_dirs})
else()
    message("else:${CMAKE_BUILD_TYPE}")
    message("else:${CMAKE_C_FLAGS_RELEASE}")
    add_executable(test_release ${src_dirs})
endif()

cmake-debug和release模式相关推荐

  1. Win10+VS2015平台下OpenCV3.1.0的x86和x64平台的Debug与Release模式的编译与配置

    闲话 昨天晚上在新电脑上重新配置了OpenCV3.1,之前虽然也弄过,不过当时是初学者,只是照着网上的教程简单的配置了Debug模式下x86的运行环境(大部分的教程也只教了这种方式的配置......) ...

  2. android 宏替换_android 模拟宏定义,实现Debug amp; Release 模式-一团网

    以前在C/C++ 开发中,我们可以宏定义,Debug模式下,输出日志,方便测试.Release模式下,无日志输出. 使用Java时,Java 是解释语言,无法编译.就无模式之分了.有没有办法实现,De ...

  3. BOOL 值在 debug 和 release 模式下初始化不一样!!!

    原文:http://www.cppblog.com/lai3d/archive/2009/07/08/89514.html 未初始化的bool成员变量在Debug下默认值为false,Test下默认t ...

  4. 关于RN之debug与release模式那些事

    在使用 React Native 时,我们用到两个不同的js引擎 JS引擎 在iOS.Android的模拟器或是真机上,React Native使用的是JavaScriptCore,也就是Safari ...

  5. C#根据Debug、Release模式动态加载dll

    //根据Debug.Release状态动态加载dll文件         #if (DEBUG)                 const string dllPathCamera = @" ...

  6. VS2008 解决方案配置器,即Debug,Release 模式选择

    新装的VS2008 ,在工具栏上找不到解决方案配置器,也就是学用的选择Debug或Release 模式的选择框. 查看网上的一些方法,总结如下,分两步 1. VS2008里 工具-选项-项目和解决方案 ...

  7. 关于Debug模式和Release模式

    使用VS的都知道,在编译的时候,会有debug和release俩中模式,那么这俩种模式到底有什么不同呢? 首先我们要明确的是Debug和Release模式并没有本质的区别,他们编译的都是同一份源码. ...

  8. 关于bin和obj文件夹。debug 和release的区别(转)

    关于bin和obj文件夹. 楼主hcaihao(影子男孩)2002-05-29 20:04:24 在 .NET技术 / C# 提问 VS.Net会生成bin和obj文件夹以及它们下面的Debug和Re ...

  9. 深入了解Debug和Release的区别

    原文地址:https://blog.csdn.net/sky___ice/article/details/8993885 一: Bin 目录用来存放编译的结果,bin是二进制binrary的英文缩写, ...

  10. VS:使用一个pros文件在Debug和Release下配置opencv

    目录 1.背景 2.目的 3.方法 4.配置 4.1. OpenCV 4.4.0: 4.2. OpenCV3.4.6 4.3. Opencv2.4.13 4.4 添加该.pros文件 1.背景 某个偶 ...

最新文章

  1. linux音频驱动dma数据,Linux音频驱动简述
  2. 从JVM看类的加载过程与对象实例化过程
  3. 数据结构: 插值查找算法
  4. HTML如何在按钮右侧显示div,如何实现点击页面中的一个按钮相应位置的div显示隐藏?...
  5. 《Credit Risk Scorecard》第八章: Scorecard Implementation
  6. 数据中心在疫情期间发挥的作用
  7. 玩转嵌入式,且看痞子衡
  8. Linux x86主机运行天数是是24.8的倍数都有可能引发oracle bug及解决方法
  9. nuget.org 无法加载源 https://api.nuget.org/v3/index.json 的服务索引
  10. 线性代数【一】:行列式的概念与计算
  11. 1000道Python题库系列分享三(30道)
  12. ”易书网“开发总结——技术篇
  13. Java获取一个月每周星期一至星期日的日期
  14. 个人笔记-Minecraft阿里云服务器搭建
  15. 机器学习十大算法(一)
  16. Win10安装CUDA10和cuDNN
  17. html多重阴影效果,如何使用css3实现文字的单阴影效果和多重阴影效果(附完整代码)...
  18. 触屏笔哪个牌子好?平替电容笔性价比高的推荐
  19. 云可信 数未来| 中国电子云总部揭牌
  20. 计算机及统计学,统计学中及计算机视觉中的各种 距离 汇总。。。

热门文章

  1. 企业组织机构代码验证JavaScript版和Java版 - 修正版V20090214
  2. Windows域的管理
  3. xpath 解析之爬取招聘信息
  4. ASCII码八、十、十六进制对照表
  5. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1106:年龄与疾病
  6. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1077:统计满足条件的4位数
  7. Git《二》时光机穿梭
  8. 【C/C++13】天气APP:数据挖掘/HTTP协议/非结构化数据存储(filetoblob.cpp),数据管理/监控告警(hsmtable.cpp,tbspaceinfo.cpp)
  9. 【Tools】Ubuntu中vscode安装和使用
  10. 【Tiny4412】烧写最小文件系统到EMMC