• 第6节:cmake语法介绍


    cmake

    • cmake是一个开源的构建工具.cmake是解决Makefile种类多,规范不一.cmake是跨平台的构建工具.是Makefile的上层工具.自动构建出makefile,取代开发者手工构建makefile的繁琐过程.
    • 目前很多开源的额项目都有CMakeLists.txt文件,快捷的实现跨平台构建源码.真正做到"Write Once,Run everywhere".

    CMake变量

    1. cmake文件包括命令+注释+空格+换行;
    2. cmake编写的源文件以CMakeLists.txt或.cmake为扩展
    3. CMakeLists.txt编写的整个项目的构建规则(放在顶层目录),可通过add_subdirectory()命令把下一层源码目录的构建规则添加进去
    4. Cmake的源文件中国所有有效的语句都是命令

    常见变量名

    1. PROJECT_NAME project 命令中写的项目名
    2. CMAKE_VERSION 当前使用的cmake版本
    3. CMAKE_SOURCE_DIR 工程顶层目录,机CMakeLists文件所在路径
    4. PROJECT_SOURCE_DIR 同CMAKE_SOURCE_DIR
    5. CMAKE_BINARY_DIR 工程编译发生的目录,即执行cmake命令进行项目配置的目录,一般为build
    6. CMAKE_CURRENT_SOURCE_DIR 当前CMakeLists.txt所在的路径
    7. CMAKE_CURRRENT_BINARY_DIR 当前处理的CMakeLists.txt中生成目标文件所在编译目录
    8. CMAKE_CURRENT_LIST_FILE:输出调用这个变量的CMakeLists.txt文件的完整路径

    注释

    用“#”进行注释,开始到行尾结束;

    变量

    1. 语法: set(变量名 变量值)
      1. 注意:变量名大小写敏感
    set(var 711) # 定义变量值
    message("var = ${var}")
    message("PATH = $ENV{PATH}")  # 环境变量
    
    • 1
    • 2
    • 3

    bool 变量

    • 布尔变量大小敏感
    true:1, ON, YES, TRUE, Y, 非0的值
    false:0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, 空字符串””, 以-NOTFOUND 结尾的字符串
    
    • 1
    • 2
    • 实例
    set(true 1)
    set(false OFF)
    message("true = " ${true})
    message("false = " ${false})
    
    • 1
    • 2
    • 3
    • 4

    列表

    • 如果一个变量有多个值,不加引号的引用cmake将自动在分号处进行切分成多个列表元素,并把它们作为多个独立的参数传给命令。加了引号的引用cmake不会进行切分并保持分号不动,整个引号内的内容当作一个参数传给命令。
    set(list_var 1 2 3 4) # list_var = 1;2;3;4
    set(list_foo "5;6;7;8") # list_foo = 5;6;7;8
    message(${list_var})#输出: 1234
    message(${list_foo})#输出:5678
    message("${list_var}")#输出:1;2;3;4
    message("${list_foo}")#输出:5;6;7;8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    cmake命令

    在cmake中,条件语句,循环语句,函数或者宏,都是命令。

    操作符

    操作符优先级:一元>二元>逻辑

    逻辑
    NOT, AND, OR
    
    一元
    EXISTS, COMMAND, DEFINED.
    
    二元
    EQUAL, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL, STREQUAL,STRLESS, STRLESS_EQUAL, STRGREATER, STRGREATER_EQUAL,VERSION_EQUAL, VERSION_LESS, VERSION_LESS_EQUAL, VERSION_GREATER, VERSION_GREATER_EQUAL,MATCHES
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    条件命令

    if(表达式)
      # 要执行的命令块
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
    elseif(表达式2)
      # 要执行的命令块
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
    else(表达式)
      # 要执行的命令块
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
    endif(表达式)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    循环命令

    1. 循环可以用break()命令退出,continue()命令可以跳过下面的语句块,立即进入下一次的循环迭代。
    while(表达式)
      # 要执行的命令块
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
      # break 退出循环
      # continue 退出当前轮循环,继续下次循环
    endwhile(表达式)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    遍历

    1. foreach也支持break(),continue()命令操作。
    foreach(循环变量 参数1 参数2 ...)
      # 要执行的命令块
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
    endforeach(循环变量)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    自定义命令(函数)

    命令可以带字符串参数,但没有返回值。命令名是大小写不敏感的,所以SET和set表示同一个命令,但是命令带的参数名是大小写敏感的ARG和arg是两个不同的参数。

    #自定义函数命令格式:
    function( [arg1 [arg2 [arg3 ...]]])
    # 自定义命令块
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
    endfunction()
    
    #调用
    name( [arg1 [arg2 [arg3 ...]]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    自定义宏命令

    1. 宏和函数的基本上是一样的,只是说函数命令有自己的作用域,宏命令的作用域和调用者的作用域一样。
    macro( [arg1 [arg2 [arg3 ...]]])
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
    endmacro()
    
    • 1
    • 2
    • 3
    • 4

    作用域

    1. Cmake三种作用域:全局层/目录层/函数层.
    2. 全局层: cache变量,在整个项目范围之内可见,一般在用set定义变量的时候指定CACHE参数就能定义为cache的变量。
    3. 目录层:在当前目录CMakeLists.txt中定义,及在该文件中包含进来的(通过include或者macro引进的)其他的cmake源文件中定义的变量属于目录层这一级的作用域。
    4. 函数层:在命令函数中定义的变量,属于函数作用域内的变量。
    5. 全局层 < 目录层 < 函数层,作用范围小的变量将覆盖作用范围大的变量。
    6. 在当前作用域修改了上一层作用域的变量,并不会传递到上一层的作用域(当前作用域只是复制上一作用域的全部变量到自己的作用域在进行修改),比如在函数命令中对目录层作用域定义的一个变量进行修改,并不会影响目录层中该变量的值。
    7. 如果修改时通过set命令明确指定PARENT_SCOPE参数,修改的变量作用域就是在上一层作用域,而不是当前作用域。
  • 相关阅读:
    jupyter notebook插件安装及插件推荐
    java 桥接方法
    MySQL中WHERE后跟着N多个OR条件会怎样。。。
    两千字讲明白java中instanceof关键字的使用!
    Android项目出现了同一个依赖库的两个版本
    天融信上网行为管理系统设置wifi短信验证流程
    百度 | 文心一言也开始收费了
    基础-符号表(一)-数据结构和算法(Java)
    Flak-SQLAlchemy的使用
    夜神安卓7导入charles证书
  • 原文地址:https://blog.csdn.net/weixin_32393347/article/details/125994770