本篇博客是根据 <<CMake Practice>> 一文编写, 目的有三:

其一: 提取出其中的精要部分;

其二: 对其中不易理解的地方进行简要说明;

其三: 方便后续查找复习.

1. 第一个例子

1.1 实验代码一

新建一个目录 cmake_turtorial, cd到该目录,建立 main.cpp 和 CMakeLists.txt(注意文件名大小写).

main.cpp 文件内容:

// main.cpp
#include <iostream>
using namespace std;
int main()
{
cout<<"Hello World from cmake_tutorial Main!"<<endl;
return 0;
}

CMakeLists.txt文件内容:

PROJECT (HELLO)
SET(SRC_LIST main.cpp)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello SRC_LIST)

在该目录下执行终端命令:

cmake .  (命令后面的点号,代表本目录)
make

执行终端命令

./hello

即可获得输出.

1.2 代码解释

CMakeLists.txt, 这个文件是 cmake 的构建定义文件, 文件名是大小写相关的, 如果工程存在多个目录,需要确保每个要管理的目录都存在一个CMakeLists.txt.

PROJECT (HELLO)
SET(SRC_LIST main.c)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello ${SRC_LIST})

PROJECT 指令的语法是:
PROJECT(projectname [CXX] [C] [Java])
你可以用这个指令定义工程名称,并可指定工程支持的语言,支持的语言列表是可以忽略的,默认情况表示支持所有语言。

这个指令隐式的定义了两个 cmake 变量:
<projectname>_BINARY_DIR 以及<projectname>_SOURCE_DIR,这里就是HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR(所以 CMakeLists.txt 中两个 MESSAGE
指令可以直接使用了这两个变量). 这两个变量等价于 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR变量 , 使用时直接使用后两者即可. 因为修改工程名称后,不需要同时修改这些变量。
SET 指令的语法是:
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

例如这样用:

SET(SRC_LIST main.c t1.c t2.c)

MESSAGE 指令的语法是:
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"...)
这个指令用于向终端输出用户定义的信息,包含了三种类型:
SEND_ERROR,产生错误,生成过程被跳过。
SATUS ,输出前缀为 — 的信息。

FATAL_ERROR,立即终止所有 cmake 过程.

ADD_EXECUTABLE(hello ${SRC_LIST})
定义了这个工程会生成一个文件名为 hello 的可执行文件,相关的源文件是 SRC_LIST 中定义的源文件列表.

这个例子使用了${}来引用变量,这是 cmake 的变量应用方式,但是,有一些例外,比如在 IF 控制语句,变量是直接使用变量名引用,而不需要${}。

如果使用了${}去应用变量,其实 IF 会去判断名为${}所代表的值的变量,那当然是不存在的了。

指令是大小写无关的,参数和变量是大小写相关的。但,推荐你全部使用大写指令。

如果源文件包含空格, 则可以写成如下这样:

SET(SRC_LIST “fu nc.cpp”)
SET(SRC_LIST “fu nc.cpp” "main.cpp" "test.cpp")
SET(SRC_LIST test.cpp; main.cpp; user.cpp)
ADD_EXECUTABLE(t1 main.c t1.c)可以写成
ADD_EXECUTABLE(t1 main.c; t1.c).

对构建结果进行清理(清理掉生成的可执行文件)

make clean

在源文件所在目录进行构建成为内部构建, 在源文件之外的目录进行构建成为外部构建.

下面演示外部构建:

在tutorial文件夹下创建build文件夹,然后cd过去

cmake ..
make

 ..代表父目录, 因为父目录存在我们需要的CMakeLists.txt,如果你在其他地方建立了 build 目录,需要运行 cmake <工程的全路径>),

查看一下 build 目录,就会发现了生成了编译需要的 Makefile 以及其他的中间文件.

2. 第二个例子

为了让前面的 Hello World 更像一个工程,我们需要作的是:
1,为工程添加一个子目录 src,用来放置工程源代码;
2,添加一个子目录 doc,用来放置这个工程的文档 hello.txt
3,在工程目录添加文本文件 COPYRIGHT, README;
4,在工程目录添加一个 runhello.sh 脚本,用来调用 hello 二进制
4,将构建后的目标文件放入构建目录的 bin 子目录;
5,最终安装这些文件:将 hello 二进制与 runhello.sh 安装至/usr/bin,将 doc 目录的内容以及 COPYRIGHT/README 安装到/usr/share/doc/cmake/t2

2.1 实验代码二

在第一节我们提到了<projectname>_BINARY_DIR 和 PROJECT_BINARY_DIR 变量, 他们指的编译发生的当前目录,如果是内部编译,

就相当于 PROJECT_SOURCE_DIR 也就是工程代码所在目录,如果是外部编译,指的是外部编译所在目录,也就是本例中的 build 目录。

查看可执行程序的链接情况:

ldd <可执行程序名>

CMake 实践教程的更多相关文章

  1. 《CMake实践》笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

  2. 《CMake实践》笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE【转】

    本文转载自:http://www.cnblogs.com/52php/p/5681745.html 前言: 开发了5,6年的时间,如果没有KDE4,也许不会有人或者Linux发行版本重视cmake,因 ...

  3. UGUI全面实践教程

    UGUI全面实践教程   试读文档下载地址:http://pan.baidu.com/s/1hq3UYGk 介绍:UGUI是Unity官方推出的最新UI系统.本教程为国内唯一的UGUI专向资料.本教程 ...

  4. 《CMake实践》笔记二:INSTALL/CMAKE_INSTALL_PREFIX

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

  5. 《CMake实践》笔记三:构建静态库(.a) 与 动态库(.so) 及 如何使用外部共享库和头文件

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

  6. 做中学之Vim实践教程

    做中学之Vim实践教程 Vim VIM是一个非常好的文本编辑器,很多专业程序员使用VIM编辑代码,即使以后你不编写程序,只要跟文本打交道,都应该学学VIM,可以浏览参考一下普通人的编辑利器--Vim这 ...

  7. 《CMake实践》第三部分的示例代码的错误

    <CMake实践>的第三章,初试cmake - cmake的helloworld 中的 PROJECT (HELLO) SET(SRC_LIST main.c) MESSAGE(statu ...

  8. 【分享送书】NGUI全面实践教程V3.8.2 活动开始了!!

    [分享送书]NGUI全面实践教程V3.8.2 活动开始了!! 活动奖品:   活动地址:http://dwz.cn/JHdlu

  9. NGUI全面实践教程(大学霸内部资料)

    NGUI全面实践教程(大学霸内部资料)   试读文档下载地址:链接:http://pan.baidu.com/s/1jGosC9g 密码:8jq5 介绍:NGUI全面实践教程(大学霸内部资料)本书是国 ...

随机推荐

  1. luogu4269 Snow Boots G (并查集)

    对于某个靴子,如果0代表某个格能走,1代表不能走,那么只要连续的1的个数的最大值>=靴子的步长,那这个靴子就不能用. 那么只要对靴子和格子都按深度排个序,然后从大到小来扫一遍(靴子越来越浅,能走 ...

  2. suoi46 最大和和 (线段树)

    <Segment tree Beats!>,反正我不会 #include<bits/stdc++.h> #define pa pair<int,int> #defi ...

  3. Linux下配置ssh免密远程登录

    步骤 使用ssh-keygen生成密钥对 提示要求输入保存的位置,密码等信息.全部使用默认信息即可 使用ssh-copy-id user@host将公钥拷贝到需要免密登录的服务器的账户中. 例如,需要 ...

  4. 笔记: c开发gui程序 (WM_CREATE, WS_CLIPCHILDREN , SetWindowPos)

    过去两年,用c写的gui程序我一般使用的套路是: 在 winMain()中, 先创建一个主窗口, 紧接着就是在下面创建子窗口(子控件). 可能是因为写这方面的程序较少,所以也没遇到什么大问题,之前就是 ...

  5. 信号处理——EMD、VMD的一点小思考

    作者:桂. 时间:2017-03-06  20:57:22 链接:http://www.cnblogs.com/xingshansi/p/6511916.html 前言 本文为Hilbert变换一篇的 ...

  6. 私有仓库GitLab快速入门篇

    私有仓库GitLab快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 安装文档请参考官网:https://about.gitlab.com/installation/#ce ...

  7. Port Forwarding in Windows

    转自:http://woshub.com/port-forwarding-in-windows/ Since Windows XP there is a built-in ability in Mic ...

  8. 函数和常用模块【day06】:xml模块(六)

    本节内容 1.简述 2.xml格式 3.xml节点操作 4.创建新的xml文件 一.简述 xml是实现不同语言或者程序之间进行数据交换的协议,跟json差不多,但是json使用起来更简单,不过,古时候 ...

  9. Linux命令之cd

    cd命令 用处:跳转目录 用法:输入cd加上你想跳转的目录,这里分几种情况 示例: 一.进入当前目录的子目录 我现在的目录是 /home/jim,如图 这个目录下面有好多文件夹是吧,现在我想进入到其中 ...

  10. IDEA中设置Tab多行显示、打开过多自动关闭的方法

    IDEA中默认Tab是单行显示的,而且默认允许同时打开10个Tab,继续打开Tab会根据规则关闭之前打开的Tab.但是可以通过设置来符合自己的使用习惯. 一.打开Tab过多自动关闭 1.选择File→ ...