cmake中一些预定义变量

    1. PROJECT_SOURCE_DIR  工程的根目录
    2. PROJECT_BINARY_DIR    运行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/build
    3. CMAKE_INCLUDE_PATH   环境变量,非cmake变量
    4. CMAKE_LIBRARY_PATH   环境变量
    5. CMAKE_CURRENT_SOURCE_DIR   当前处理的CMakeLists.txt所在的路径
    6. CMAKE_CURRENT_BINARY_DIR   target编译目录
    7. ADD_SURDIRECTORY(src bin)   可以更改此变量的值
    8. SET(EXECUTABLE_OUTPUT_PATH <新路径>)   并不会对此变量有影响,只是改变了最终目标文件的存储路径
    9. CMAKE_CURRENT_LIST_FILE    输出调用这个变量的CMakeLists.txt的完整路径
    10. CMAKE_CURRENT_LIST_LINE    输出这个变量所在的行
    11. CMAKE_MODULE_PATH    定义自己的cmake模块所在的路径
    12. SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)    然后可以用INCLUDE命令来调用自己的模块
    13. EXECUTABLE_OUTPUT_PATH    重新定义目标二进制可执行文件的存放位置
    14. LIBRARY_OUTPUT_PATH    重新定义目标链接库文件的存放位置
    15. PROJECT_NAME    返回通过PROJECT指令定义的项目名称
    16. CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS    用来控制IF ELSE语句的书写方式

cmake常用命令

基本语法规则:
  • cmake变量使用${}方式取值,但是在IF控制语句中是直接使用变量名
  • 环境变量使用$ENV{}方式取值,使用SET(ENV{VAR} VALUE)赋值
  • 指令(参数1 参数2…)
    参数使用括弧括起,参数之间使用空格或分号分开。

    以ADD_EXECUTABLE指令为例:
    ADD_EXECUTABLE(hello main.c func.c)或者
    ADD_EXECUTABLE(hello main.c;func.c)
  • 指令是大小写无关的,参数和变量是大小写相关的。推荐你全部使用大写指令。

部分常用命令列表:
  1. PROJECT
    PROJECT(projectname [CXX] [C] [Java])
    指定工程名称,并可指定工程支持的语言。支持语言列表可忽略,默认支持所有语言
  2. SET
    SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
    定义变量(可以定义多个VALUE,如SET(SRC_LIST main.c util.c reactor.c))
  3. MESSAGE
    MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] “message to display” …)
    向终端输出用户定义的信息或变量的值
    SEND_ERROR, 产生错误,生成过程被跳过
    STATUS, 输出前缀为—的信息
    FATAL_ERROR, 立即终止所有cmake过程
  4. ADD_EXECUTABLE
    ADD_EXECUTABLE(bin_file_name ${SRC_LIST})
    生成可执行文件
  5. ADD_LIBRARY
    ADD_LIBRARY(libname [SHARED | STATIC | MODULE] [EXCLUDE_FROM_ALL] SRC_LIST)
    生成动态库或静态库
    SHARED 动态库
    STATIC 静态库
    MODULE 在使用dyld的系统有效,若不支持dyld,等同于SHARED
    EXCLUDE_FROM_ALL 表示该库不会被默认构建
  6. SET_TARGET_PROPERTIES
    设置输出的名称,设置动态库的版本和API版本
  7. CMAKE_MINIMUM_REQUIRED
    CMAKE_MINIMUM_REQUIRED(VERSION version_number [FATAL_ERROR])
    声明CMake的版本要求
  8. ADD_SUBDIRECTORY
    ADD_SUBDIRECTORY(src_dir [binary_dir] [EXCLUDE_FROM_ALL])
    向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制的存放位置
    EXCLUDE_FROM_ALL含义:将这个目录从编译过程中排除
  9. SUBDIRS
    deprecated,不再推荐使用
    (hello sample)相当于分别写ADD_SUBDIRECTORY(hello),ADD_SUBDIRECTORY(sample)
  10. INCLUDE_DIRECTORIES
    INCLUDE_DIRECTORIES([AFTER | BEFORE] [SYSTEM] dir1 dir2 … )
    向工程添加多个特定的头文件搜索路径,路径之间用空格分隔,如果路径包含空格,可以使用双引号将它括起来,默认的行为为追加到当前头文件搜索路径的后面。有如下两种方式可以控制搜索路径添加的位置:LINK_DIRECTORIES
    1. CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过SET这个cmake变量为on,可以将添加的头文件搜索路径放在已有路径的前面
    2. 通过AFTER或BEFORE参数,也可以控制是追加还是置前
  11. LINK_DIRECTORIES
    LINK_DIRECTORIES(dir1 dir2 …)
    添加非标准的共享库搜索路径
  12. TARGET_LINK_LIBRARIES
    TARGET_LINK_LIBRARIES(target lib1 lib2 …)
    为target添加需要链接的共享库
  13. ADD_DEFINITIONS
    向C/C++编译器添加-D定义
    ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),参数之间用空格分隔
  14. ADD_DEPENDENCIES
    ADD_DEPENDENCIES(target-name depend-target1 depend-target2 …)
    定义target依赖的其他target,确保target在构建之前,其依赖的target已经构建完毕
  15. AUX_SOURCE_DIRECTORY
    AUX_SOURCE_DIRECTORY(dir VAR)
    发现一个目录下所有的源代码文件并将列表存储在一个变量中
    把当前目录下的所有源码文件名赋给变量DIR_HELLO_SRCS
  16. EXEC_PROGRAM
    EXEC_PROGRAM(Executable [dir where to run] [ARGS <args>][OUTPUT_VARIABLE <var>] [RETURN_VALUE <value>])
    用于在指定目录运行某个程序(默认为当前CMakeLists.txt所在目录),通过ARGS添加参数,通过OUTPUT_VARIABLE和RETURN_VALUE获取输出和返回值,如下示例

    # 在src中运行ls命令,在src/CMakeLists.txt添加
    EXEC_PROGRAM(ls ARGS "*.c" OUTPUT_VARIABLE LS_OUTPUT RETURN_VALUE LS_RVALUE)
    IF (not LS_RVALUE)
    MESSAGE(STATUS "ls result: " ${LS_OUTPUT}) # 缩进仅为美观,语法无要求
    ENDIF(not LS_RVALUE)
  17. INCLUDE
    INCLUDE(file [OPTIONAL]) 用来载入CMakeLists.txt文件
    INCLUDE(module [OPTIONAL])用来载入预定义的cmake模块
    OPTIONAL参数的左右是文件不存在也不会产生错误
    可以载入一个文件,也可以载入预定义模块(模块会在CMAKE_MODULE_PATH指定的路径进行搜索)
    载入的内容将在处理到INCLUDE语句时直接执行

  18. FIND_

    1. FIND_FILE(<VAR> name path1 path2 …)
      VAR变量代表找到的文件全路径,包含文件名
    2. FIND_LIBRARY(<VAR> name path1 path2 …)
      VAR变量代表找到的库全路径,包含库文件名

      FIND_LIBRARY(libX X11 /usr/lib)
      IF (NOT libx)
      MESSAGE(FATAL_ERROR "libX not found")
      ENDIF(NOT libX)
    3. FIND_PATH(<VAR> name path1 path2 …)
      VAR变量代表包含这个文件的路径

    4. FIND_PROGRAM(<VAR> name path1 path2 …)
      VAR变量代表包含这个程序的全路径
    5. FIND_PACKAGE(<name> [major.minor] [QUIET] [NO_MODULE] [[REQUIRED | COMPONENTS] [componets …]])
      用来调用预定义在CMAKE_MODULE_PATH下的Find<name>.cmake模块,你也可以自己定义Find<name>
      模块,通过SET(CMAKE_MODULE_PATH dir)将其放入工程的某个目录供工程使用
  19. IF
    语法:

    IF (expression)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
    ELSE (expression)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
    ENDIF (expression) # 一定要有ENDIF与IF对应

    IF (expression), expression不为:空,0,N,NO,OFF,FALSE,NOTFOUND或<var>_NOTFOUND,为真
    IF (not exp), 与上面相反
    IF (var1 AND var2)
    IF (var1 OR var2)
    IF (COMMAND cmd) 如果cmd确实是命令并可调用,为真
    IF (EXISTS dir) IF (EXISTS file) 如果目录或文件存在,为真
    IF (file1 IS_NEWER_THAN file2),当file1比file2新,或file1/file2中有一个不存在时为真,文件名需使用全路径
    IF (IS_DIRECTORY dir) 当dir是目录时,为真
    IF (DEFINED var) 如果变量被定义,为真
    IF (var MATCHES regex) 此处var可以用var名,也可以用${var}
    IF (string MATCHES regex)

    当给定的变量或者字符串能够匹配正则表达式regex时为真。比如:
    IF ("hello" MATCHES "ell")
    MESSAGE("true")
    ENDIF ("hello" MATCHES "ell")

    数字比较表达式
    IF (variable LESS number)
    IF (string LESS number)
    IF (variable GREATER number)
    IF (string GREATER number)
    IF (variable EQUAL number)
    IF (string EQUAL number)

    按照字母表顺序进行比较
    IF (variable STRLESS string)
    IF (string STRLESS string)
    IF (variable STRGREATER string)
    IF (string STRGREATER string)
    IF (variable STREQUAL string)
    IF (string STREQUAL string)

    一个小例子,用来判断平台差异:
    IF (WIN32)
    MESSAGE(STATUS “This is windows.”)
    ELSE (WIN32)
    MESSAGE(STATUS “This is not windows”)
    ENDIF (WIN32)
    上述代码用来控制在不同的平台进行不同的控制,但是,阅读起来却并不是那么舒服,ELSE(WIN32)之类的语句很容易引起歧义。
    可以SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
    这时候就可以写成:
    IF (WIN32)
    ELSE ()
    ENDIF ()
    配合ELSEIF使用,可能的写法是这样:
    IF (WIN32)
    #do something related to WIN32
    ELSEIF (UNIX)
    #do something related to UNIX
    ELSEIF(APPLE)
    #do something related to APPLE
    ENDIF (WIN32)
  20. WHILE
    语法:

    WHILE(condition)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
    ENDWHILE(condition)

    其真假判断条件可以参考IF指令

  21. FOREACH
    FOREACH指令的使用方法有三种形式:
    1. 列表
      语法:

      FOREACH(loop_var arg1 arg2 ...)
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
      ...
      ENDFOREACH(loop_var)

      示例:

      AUX_SOURCE_DIRECTORY(. SRC_LIST)
      FOREACH(F ${SRC_LIST})
      MESSAGE(${F})
      ENDFOREACH(F)
    2. 范围
      语法:
      FOREACH(loop_var RANGE total)
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
      ...
      ENDFOREACH(loop_var)

      示例:

      #从0到total以1为步进
      FOREACH(VAR RANGE )
      MESSAGE(${VAR})
      ENDFOREACH(VAR)
      输出:
    3. 范围和步进
      语法:
      FOREACH(loop_var RANGE start stop [step])
      COMMAND1(ARGS ...)
      COMMAND2(ARGS ...)
      ...
      ENDFOREACH(loop_var)

      从start开始到stop结束,以step为步进,
      注意:直到遇到ENDFOREACH指令,整个语句块才会得到真正的执行。

      FOREACH(A RANGE   )
      MESSAGE(${A})
      ENDFOREACH(A)
      输出:
  • cmake中如何生成动态库和静态库参考ADD_LIBRARY和SET_TARGET_PROPERTIES用法

  • t3示例
  • cmake中如何使用动态库和静态库(查找库的路径)

  • 参考INCLUDE_DIRECTORIES, LINK_DIRECTORIES, TARGET_LINK_LIBRARIES用法
  • t4示例使用动态库或静态库
  • t5示例如何使用cmake预定义的cmake模块(以FindCURL.cmake为例演示)
  • t6示例如何使用自定义的cmake模块(编写了自定义的FindHELLO.cmake)
  • 注意读t5和t6的CMakeLists.txt和FindHELLO.cmake中的注释部分
  • cmake中如何指定生成文件的输出路径

  • 如上ADD_SUBDIRECTORY的时候指定目标二进制文件输出路径(推荐使用下面这种)
  • 使用SET命令重新定义EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH变量来指定最终的二进制文件的位置
    SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
    SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

    上面的两条命令通常紧跟ADD_EXECUTABLE和ADD_LIBRARY,与其写在同一个CMakeLists.txt即可

  • cmake中如何增加编译选项

  • 使用变量CMAKE_C_FLAGS添加C编译选项
  • 使用变量CMAKE_CXX_FLAGS添加C++编译选项
  • 使用ADD_DEFINITION添加
  • cmake中如何增加头文件路径

  • 参考INCLUDE_DIRECTORIES命令用法
  • cmake中如何在屏幕上打印信息

参考MESSAGE用法

cmake中如何给变量赋值

参考SET和AUX_SOURCE_DIRECTORY用法

建议:在Project根目录先建立build,然后在build文件夹内运行cmake ..,这样就不会污染源代码, 如果不想要这些自动生成的文件了,只要简单的删除build文件夹就可以。

例:

#It seems must set compiler at first
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_C_COMPILER "mips-linux-gnu-gcc")
SET(CMAKE_CXX_COMPILER "mips-linux-gnu-g++")
#SET(CMAKE_BUILD_TYPE Debug CACHE STRING "set build type to Debug")
PROJECT (SDK)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0) IF(PROJECT_BINARY_DIR STREQUAL PROJECT_SOURCE_DIR)
MESSAGE(STATUS "BINARY dir path: " ${PROJECT_BINARY_DIR})
MESSAGE(STATUS "SOURCE dir path: " ${PROJECT_SOURCE_DIR})
MESSAGE(FATAL_ERROR "Do NOT support in-source build!!\n"
"Please:\n"
" 1. mkdir build;cd build\n"
" 2. cmake ..\n"
" 3. make\n")
ELSE()
MESSAGE(STATUS "BINARY dir path: " ${PROJECT_BINARY_DIR})
MESSAGE(STATUS "SOURCE dir path: " ${PROJECT_SOURCE_DIR})
ENDIF()
ADD_DEFINITIONS(-DCONFIG_SOC="${SOC}" -D${SOC_WHO})
ADD_DEFINITIONS(-DCONFIG_SINGLE_BS) IF(NOT EXISTS $ENV{ISVP_ENV_TOP})
MESSAGE(FATAL_ERROR "please cd to isvp top and run \"source build/env_setup.sh first\"")
ENDIF()
SET(CMAKE_INSTALL_PREFIX $ENV{ISVP_ENV_RELEASE_DIR_SDK}) SET(LIB_INSTALL_DIR_GLIBC lib/glibc)
SET(LIB_INSTALL_DIR_UCLIBC lib/uclibc)
SET(BIN_INSTALL_DIR_GLIBC bin/glibc)
SET(BIN_INSTALL_DIR_UCLIBC bin/uclibc) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include/api/${LANGUAGE})
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include/soc/${SOC}) ADD_SUBDIRECTORY(include)
ADD_SUBDIRECTORY(src)
#ADD_SUBDIRECTORY(test)
ADD_SUBDIRECTORY(doc)
ADD_SUBDIRECTORY(samples)

cmake的一些词的解释的更多相关文章

  1. Python 爬取 热词并进行分类数据分析-[解释修复+热词引用]

    日期:2020.02.02 博客期:141 星期日 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入] c.[拓扑 ...

  2. Python 爬取 热词并进行分类数据分析-[拓扑数据]

    日期:2020.01.29 博客期:137 星期三 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入] c.[拓扑 ...

  3. 0103MySQL中的B-tree索引 USINGWHERE和USING INDEX同时出现

    转自博客http://www.amogoo.com/article/4 前提1,为了与时俱进,文中数据库环境为MySQL5.6版本2,为了通用,更为了避免造数据的痛苦,文中所涉及表.数据,均来自于My ...

  4. DBImport v3.3 中文版发布:数据库数据互导及文档生成工具(IT人员必备)

    前言: 好久没写文了, 距离上一篇文章是3个月前的事了,虽然工作很忙,主要还是缺少写作的内容和激情,所以没怎么动手. 之前有一个来月不断面试不同层次来应聘的人员,很有想写文的冲动,后来还是忍住了. 估 ...

  5. 【初探HTML本相】道之真谛不过自然,html标签脱俗还真

    前言 须弥般若有无空,阴阳道化真虚同:洗尽前恩本非相,还吾面目下九重. 咳咳,其实老夫对佛教文化有点点研究啦,说以我们这里来了一点很有哲理的东西,因为我这里准备干一件很戳的事情,我准备来看看我们的ht ...

  6. HTML5和CSS3基础教程(第8版)-读书笔记

    第1章 网页的构造块 一个网页主要包括以下三个部分: n        文本内容(text content):在页面上让访问者了解页面内容的纯文字. n        对其他文件的引用(referen ...

  7. HTML常用文本元素

    HTML是超文本标记语言,它提供网页的具体内容,包括文本.表单.图像.表格.链接.多媒体.列表等.其中文本是我们遇到的最多的展示内容.正确的使用文本标签,会使页面具有语义化,也有利于SEO. 文本标签 ...

  8. [转]C#基础回顾:Asp.net 缓存

    本文转自http://www.cnblogs.com/stg609/archive/2009/03/22/1418992.html 缓存的作用      你买电脑的时候,是否会在意CPU的二级缓存?是 ...

  9. Java的内存回收机制

    原文出处: cnblogs-小学徒V 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C ...

随机推荐

  1. ubuntu中配置samba方法

    1.在保证能上网的前提下,安装samba软件包,中途出现是否执行,一直点击回车键 #sudo apt-get install samba #sudo apt-get install smbclient ...

  2. S3C2440 SPI驱动框架

    S3C2440 SPI驱动代码详细解读: https://www.linuxidc.com/Linux/2012-08/68402p4.htm 一.platform device and board_ ...

  3. selenium定位方式源码的存放位置

    find_element方法源码存在位置 by定位方法

  4. 【原创】官方文档-hive 启动命令

    [一起学Hive]之十六-Hive的WEB页面接口-HWI Apache Hive 管网 hive metrics hive常用命令整理 Hive学习之HiveServer2服务端配置与启动 启动hi ...

  5. 22 mysql有那些”饮鸩止渴”提高性能的方法?

    22 mysql有那些”饮鸩止渴”提高性能的方法? 正常的短连接模式是连接到数据库后,执行很少的SQL语句就断开,下次需要的时候再重新连接.如果使用的是短连接,在业务高峰期的时候,就可能出现连接数突然 ...

  6. Python Twisted系列教程7:小插曲,Deferred

    作者:dave@http://krondo.com/an-interlude-deferred/  译者:杨晓伟(采用意译) 你可以从这里从头开始阅读这个系列 回调函数的后序发展 在第六部分我们认识这 ...

  7. Linux quota命令参数及用法详解---Linux磁盘配额限制设置和查看命令

    功能说明:显示磁盘已使用的空间与限制. 语 法:quota [-quvV][用户名称...] 或 quota [-gqvV][群组名称...] 补充说明:执行quota指令,可查询磁盘空间的限制,并得 ...

  8. Hibernate4.3.5搭建Log4j日志环境

    本文记录Hibernate4.3.5搭建Log4j日志环境的过程 1.搞清楚Hibernate4.3.5的日志环境依赖 方法:查看帮助文档 3.5. Logging Important Complet ...

  9. 玩转angularJs——通过自定义ng-model,不仅仅只是input可以实现双向数据绑定

    体验更优排版请移步原文:http://blog.kwin.wang/programming/angularJs-user-defined-ngmodel.html angularJs双向绑定特性在开发 ...

  10. CXF动态客户端如何优化JaxWsDynamicClientFactory.createClient -- 慢

    在CXF动态创建客户端时,如下: JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); Client ...