C++ - cmake学习笔记

  • cmake 内置命令是不区分大小写的
  • 但是注意区分变量的大小写

打印变量

  • status 表示这是一般的打印信息
    1
    2
    set(USER_KEY, "Hello World")
    message( STATUS "this var key = ${USER_KEY}.")

Set 的用法

Set赋值给一般变量(normal variables)

  • 什么是一般变量,一般变量和代码中变量相似,仅在自身所在作用域起作用,除非后面使用PARENT_SCOPE。

  • 每一个新的目录或者函数都会创建新的作用域,当在新的作用域创建一般变量且后面加上PARENT_SCOPE,该变量可以在父目录或者调用新函数的函数上起作用。

  • 举个栗子:

    1
    2
    set(FOO  “x”)。         //FOO作用域为当前作用域.
    set(FOO "x" PARENT_SCOPE)   //FOO作用域跳上一级.

Set赋值给缓存变量(cache variables)

  • 什么是缓存变量,缓存变量可以理解为当第一次运行cmake时,这些变量缓存到一份文件中(即编译目录下的CMakeCache.txt)。当再次运行cmake时,这些变量会直接使用缓存值,可以利用ccmake或者cmake-gui等工具来重新赋值。缓存变量在整个cmake运行过程中都可以起作用。

  • 当使用CACHE时,且缓存(cache)中没有该变量时,变量被创建并存入缓存(cache)中,如果原缓存(cache)中有该变量,也不会改变原缓存中该变量的值,除非后面使用FORCE。

  • 举个栗子:

    1
    2
    3
    set(FOO, "x" CACHE <type>)  
    //原缓存中没有FOO则将FOO赋值为x且存入cache中。
    //原缓存中有FOO则不做任何改变,即便原cache中FOO存的不是x。
1
2
3
4
set(FOO, "x" CACHE <type><docstring> FORCE)    
//即便原cache中存在FOO也会创建另一个FOO,官方文档原话(If FORCE is specified, the value of the cache variable
//is set, even if the variable is already in the cache.This should normally be avoided, as it will
//remove any changes to the cache variable’s value by the user.),小弟笨拙没有搞懂。
  • 使用CACHE的同时,要设定<type><docstring><type>可以理解为所存入变量类型,<docstring>为变量的描述。

  • <type>分为以下几种类型:

    1
    2
    3
    4
    5
    FILEPATH = File chooser dialog.
    PATH = Directory chooser dialog.
    STRING = Arbitrary string.
    BOOL = Boolean ON/OFF checkbox.
    INTERNAL = No GUI entry (used for persistent variables).
  • 其中INTERNAL将变量为内部变量,即cmake-gui不会向用户显示这类变量,而其它类型的缓存变量用户都可以通cmake-gui按照特定的类型改变。

注意

  • CACHE 与 PARENT_SCOPE 不能一起使用

  • 同一名称(例FOO)的一般变量和缓存变量可以同时存在,但在调用该变量时(${FOO})会在先取一般变量的值,一般变量中没有再取缓存变量的值。

    1
    2
    3
    4
    set(FOO “x”)        //设置一般变量FOO,不会触及cache,但是会隐藏cache中的FOO。

    set(FOO “x” CACHE ...)  //忽视相同名称的一般变量,在cache中检查FOO是否存在,
                    //如果不存在则存入cache中,存在也不会对cache中FOO重新赋值。
  • 当改变cache中的变量时,同名的一般变量会被删除。一般不建议使用相同名称的一般变量和缓存变量。

  • 然而在有些工程中可以很好的借助这一交互例如:

    • 一个工程利用ADD_SUBDIRECTOTY()添加子工程,子工程有它自己的CMakeList.txt。如果在父工程和子工程中都对同一缓存变量赋值,cmake时父工程率先将变量存入cache中,子工程直接在cache中调用该值,保证了父子工程的一致性。当父工程需要改变该变量,而子程序需要利用原值时,可以直接在父工程中设置同名称的一般变量即可。

Option 的用法

  • 使用场景 : 编译脚本传递参数 -> CMake脚本接收option -> 源代码宏

编译脚本传入参数

1
2
3
4
#!/bin/sh

cmake -DTEST_DEBUG=ON .
cmake --build .

CMake脚本接收option

  • cmake 脚本定义TEST_DEBUG 默认关闭OFF
    1
    2
    3
    4
    5
    6
    7
    project(test)

    option(TEST_DEBUG "option for debug" OFF)
    if (TEST_DEBUG)
    add_definitions(-DTEST_DEBUG)
    endif()
    ...

源代码宏 test.c

1
2
3
4
5
#include "test.h"

#ifdef TEST_DEBUG
...
#endif

add_subdirectory 的用法

  • 一般情况下,我们的项目各个子项目都在一个总的项目根目录下,但有的时候,我们需要使用外部的文件夹,怎么办呢?

  • add_subdirectory命令,可以将指定的文件夹加到build任务列表中。

一些关键字

  • UNIX : 在所有的类UNIX平台为TRUE,包括OS X和cygwin
  • WIN32 : 在所有的win32平台为TRUE,包括cygwin

欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 qinhan_shu@163.com

文章标题:C++ - cmake学习笔记

本文作者:QinHan

发布时间:2020-01-19, 11:33:56

最后更新:2020-02-20, 05:42:12

原始链接:https://qinhan.site/2020/01/19/cplus-cmake/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏