系统构建之CMake

CMake提供了各种前端操作的客户端,各平台上的命令行客户端和GUI客户端。先主要看一下命令行操作的方法。

官方教程官方API文档

一、简单步骤

0、项目准备:项目的每个目录下都需要有CMakeLists.txt(名字区分大小写)文件

1、cd /path/to/build。#在build目录下运行cmake,因为cmake把当前目录作为build目录,存放生成文件和cache文件

2、cmake /path/to/project。

3、make。#该命令的输入项是位于/path/to/project的CMakeLists.tx文件,该文件可以通过include或add_subdirectory命令添加新的输入文件。

4、./target。#运行生成的程序

5、清理target:make clean。但是make distclean无效,无法清理构建过程文件。所以才在第一步中先进入build目录,这就是所谓的外部构建(out-of-source build)。

 

二、CMakeLists.txt语法

0、通用规则:

    a #开头的行为注释行。

    b 指令(参数1 参数2...) 参数使用括弧括起,参数之间使用空格或分号 分开,参数可使用双引号包着SET(SRC_LIST “main.c”)。指令是大小写无关的,参数和变量是大小写相关的。但,推荐指令全部使用大写。

    c 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名

    d /字符用作转义字符。

    e 用户可以自定义macro和function,用法同command指令

1、变量类型:Lists and Strings

    a 变量的基本类型是String

    b 变量也可以是list类型。list可被foreach命令枚举、list命令操作。定义list方法如下:

2、流程控制

    a 条件判断:if

# some_command will be called if the variable's value is not:
# empty, 0, N, NO, OFF, FALSE, NOTFOUND, or -NOTFOUND.
if(var)
   some_command(...)
elseif(var)
   other_command(...)
else(var)
   last_option(...)
endif(var) 

    b 循环:foreach

set(VAR a b c)
  # loop over a, b,c with the variable f
foreach(f ${VAR})
    message(${f})
endforeach(f) 

    c 循环:while

while(var)
    message(${var})
endwhile(var)

    d 过程定义:macro 和 function

       函数在2.6及以上版本才支持,函数和宏的区别在于函数中可定义局部变量,而宏定义的变量都是全局变量,或者应该是函数是局部的,宏是全局的。

# define a macro hello
macro(hello MESSAGE)
    message(${MESSAGE})
endmacro(hello)
# call the macro with the string "hello world"
hello("hello world")

# define a function hello
function(hello MESSAGE)
    message(${MESSAGE})
endfunction(hello) 

 3、支持正则表达式

^ Matches at beginning of a line or string
$ Matches at end of a line or string
 . Matches any single character other than a newline
[ ] Matches any character(s) inside the brackets
[^ ] Matches any character(s) not inside the brackets
[-] Matches any character in range on either side of a dash
* Matches preceding pattern zero or more times
+ Matches preceding pattern one or more times
? Matches preceding pattern zero or once only
() Saves a matched expression and uses it in a later replacement

 

三、命令API

虽然说Kitware有点儿不厚道的在卖Mastering CMake 这本书,而且貌似网上没有电子版,但是官方提供的文档 还是够用的。在写这篇心得时cmake是2.8版本。

文档也可以通过“cmake --help-html > help_name.html”在当前运行目录生成。

1、command api

2、variables api

 

四、使用技巧

1、如何在构建过程中打印debug等信息到console?

使用MESSAGE命令。message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)

2、过程文件和最终构建的目标文件的路径设置问题。

cmake有一些预定义的变量来设置各种路径。

PROJECT_BINARY_DIR:运行目录,生成过程文件的目录。运行cmake ..的工作目录。这个目录总会有些过程文件生成,因此需要外部构建。

PROJECT_SOURCE_DIR:代码目录,运行cmake ..时..指定的目录

工程组织方式:

proj +
       |
       +src
       +bin
       +build
       |    + bin_1
       +CMakeLists.txt

一般在CMakeLists.txt文件中用ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])指定src、bin目录,可以用相对路径也可以用绝对路径。

但 是要注意,如果用相对路径的话,source_dir是相对PROJECT_SOURCE_DIR(这里是proj目录)的,binary_dir是相对 PROJECT_BINARY_DIR(这里是build)的。所以如果是add_subdirectory(src bin)的话,bin是build下面的bin_1。

 

EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH 定义纯净的最终目标文件位置,可以通过下面方法修改

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
 

1、预定义变量

PROJECT_BINARY_DIR

PROJECT_SOURCE_DIR

EXECUTABLE_OUTPUT_PATH

LIBRARY_OUTPUT_PATH

CMAKE_INSTALL_PREFIX

2、基本指令

PROJECT(projectname [CXX] [C] [Java])

SET(VAR [VALUE [VALUE2] [VALUE3]] [CACHE TYPE DOCSTRING [FORCE]])

MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)

ADD_EXECUTABLE(targetRunable ${SRC_LIST})

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

目录的安装:INSTALL(DIRECTORY src_dirs... DESTINATION <dir>

                           [FILE_PERMISSIONS permissions...]

                           [DIRECTORY_PERMISSIONS permissions...]

                           [USE_SOURCE_PERMISSIONS]

                           [CONFIGURATIONS [Debug|Release|...]]

                           [COMPONENT <component>]

                           [[PATTERN <pattern> | REGEX <regex>] [EXCLUDE] [PERMISSIONS permissions...]][...])

DIRECTORY 后面连接的src_dirs注意abc 和 abc/有很大的区别。如果目录名不以/结尾,那么这个目录将被安装为目标路径下的 abc,如果目录名以/结尾, 代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。

3、换个地方保存目标二进制:在 ADD_EXECUTABLE 或 ADD_LIBRARY所在的CMakeLists.txt文件里面定义

    SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

    SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值