1.准备工作:

首先,在/code_test 目录下建立一个 cmake 目录,用来放置我们学习过程中的所有练习。(如果以下命令出现xxx: cannot create directory ‘x’: Permission denied错误则需要在命令前加上sudo,编译时也是)
mkdir -p /code_test/cmake
以后我们所有的cmake练习都会放在/code_test/cmake 的子目录下(你也可以自行安排目录,这个并不是限制,仅仅是为了叙述的方便)然后在cmake目录下建立第一个练习目录p1
cd /code_test/cmake
mkdir p1
cd p1

在 p1 目录建立 main.cpp 和 CMakeLists.txt(注意文件名大小写)并用你所熟悉的文本编辑器加入以下内容:

//main.cpp

#include <iostream>

using namespace std;

int main()
{
cout<<"Hello World !"<<endl;return ;
}

//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})

CMakeLists.txt是cmake的构建定义文件,注意文件名是大小写相关的,如果工程存在多个目录,需要确保每个要管理的目录都存在一个CMakeLists.txt。目的是生成Makefile文件,其实也可以直接编写makefile,但是大工程比较复杂,所以用CmakeLists.txt目的就是自动生成Makefile。

下面分析语法:

PROJECT指令的语法是

PROJECT(projectname [CXX] [C] [Java])
这个指令定义工程名称,并可指定工程支持的语言,默认情况表示支持所有语言。非常重要的是这个指令隐式的定义了两个cmake变量: <projectname>_BINARY_DIR 以及<projectname>_SOURCE_DIR 这里就是HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR (所以CMakeLists.txt中两 MESSAGE指令可以直接使用了这两个变量),如果采用的是内部编译,两个变量目前指的都是工程所在路径/code_test/cmake/p1,后面我们会讲到外部编译,两者所指代的内容会有所不同。为了统一起见,建议以后直接使用 PROJECT_BINARY_DIR  PROJECT_SOURCE_DIR,好处是即使修改了工程名称,也不会影响这两个变量。如果使用了<projectname>_SOURCE_DIR,修改工程名称后,需要同时修改这些变量。
 

SET指令的语法是

SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
SET指令可以用来显式的定义变量,比如我们用到的SET(SRC_LIST main.cpp), 也就是将man.cpp赋给SRC_LIST变量,以后SRC_LIST就是指man.cpp可以理解为c++里的别名引用,如果有多个源文件,也可以定义成:SET(SRC_LIST main.cpp x1.cpp x2.cpp)还有一点虽不常用但得注意SET(SRC_LIST main.cpp)也可以写成 SET(SRC_LIST “main.cpp”)是没有区别的,但是假设一个源文件的文件名是 fu nc.cpp(文件名中间包含了空格)。这时候就必须使用双引号,如果写成了 SET(SRC_LIST fu nc.cpp),就会出现错误,提示你找不到 fu 文件和 nc.cpp 文件。
 

MESSAGE 指令的语法是:

MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)
这个指令主要用来调试用,用于向终端输出用户定义的信息,包含了三种类型:
SEND_ERROR,产生错误,生成过程被跳过。
SATUS,输出信息。
FATAL_ERROR,立即终止所有 cmake 过程。
我们在这里使用的是 STATUS 信息输出,显示的效果是: 
This is BINARY dir /code_test/cmake/p1
This is SOURCE dir /code_test/cmake/p1
 
ADD_EXECUTABLE(hello ${SRC_LIST})
定义了这个工程会生成一个文件名为hello的可执行文件(自己随便起名字),相关的源文件是SRC_LIST中定义的源文件列表,本例中你也可以直接写成 ADD_EXECUTABLE(hello main.cpp)。变量使用${}方式取值,这是cmake的变量应用方式,但是,有一些例外,在IF控制语句中是直接使用变量名引用,而不需要${}。
 
注意:1.参数使用括弧括起,参数之间使用空格或分号分开。2.指令是大小写无关的,参数和变量是大小写相关的。但推荐全部使用大写指令。
2.开始构建:构建分为内部构建(in-sourcebuild)和外部构建(out-of-source build),外部构建一个最大的好处是,对于原有的工程没有任何影响,所有动作全部发生在编译目录。而cmake强烈推荐的是外部构建。

内部构建:

这在个目录下输入命令:
cmake .  //注意命令后面的点号,代表本目录

输出大概是这个样子:

你会发现,目录中系统自动生成了:

CMakeFiles, CMakeCache.txt, cmake_install.cmake 等文件,并且生成了Makefile.最关键的是它自动生成Makefile其他的不用理,make主要去找Makefile,make是一个命令工具,是一个解释makefile中指令的命令工具,其实也可以直接编写makefile,但是大工程比较复杂,所以用CmakeLists.txt目的就是自动生成Makefile。
然后进行工程的实际构建,在这个目录输入命令:
 
make 

输出大概是这个样子:

如果你需要看到 make 构建的详细过程,可以使用 make VERBOSE=1 或者 VERBOSE=1命令来进行构建。
我们需要的目标文件 hello 已经构建完成,位于当前目录,尝试运行一下:
./hello

得到输出:

Hello World !

外部编译:

1.首先,请清除p1目录中除main.c CmakeLists.txt之外的所有中间文件,最关键的是CMakeCache.txt。
2.在p1目录中建立build目录,当然你也可以在任何地方建立build目录,不一定必须在工程目录中。
mkdir build
3.进入build目录,运行cmake ..(: .. 代表父目录,因为父目录存在我们需要的CMakeLists.txt,如果你在其他地方建立了build目录,需要运行cmake<工程的全路径>找到CMakeLists.txt),查看一下build目录,就会发现了生成了编译需要的Makefile以及其他的中间文件。
cd build
cmake ..
4.运行make构建工程,就会在当前目录(build目录)中获得目标文件hello 
make

让我们的代码更像个工程:

http://www.cnblogs.com/zjiaxing/p/5557648.html

cmake实战第一篇:初试 cmake的更多相关文章

  1. spring boot实战(第一篇)第一个案例

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   spring boot实战(第一篇)第一个案例 前言 写在前面的话 一直想将spring boot相关内容写成一个系列的 ...

  2. vue+uni-app商城实战 | 第一篇:【有来小店】微信小程序快速开发接入Spring Cloud OAuth2认证中心完成授权登录

    一. 前言 本篇通过实战来讲述如何使用uni-app快速进行商城微信小程序的开发以及小程序如何接入后台Spring Cloud微服务. 有来商城 youlai-mall 项目是一套全栈商城系统,技术栈 ...

  3. Hadoop实战第一篇

    前言:  都说现在是草根为尊的时代,近年来hadoop及spark技术在国内越来越流行.而且渐渐现成为企业的新宠.在DT时代全面来临之前,能提早接触大数据的技术必然能先人一步.本文作为Hadoop系列 ...

  4. (python3爬虫实战-第一篇)利用requests+正则抓取猫眼电影热映口碑榜

    今天是个值得纪念了日子,我终于在博客园上发表自己的第一篇博文了.作为一名刚刚开始学习python网络爬虫的爱好者,后期本人会定期发布自己学习过程中的经验与心得,希望各位技术大佬批评指正.以下是我自己做 ...

  5. cmake实战第二篇:让我们的代码更像个工程

    为工程添加以下文件夹:    bin 用来放编译好的可执行二进制文件. src 用来放源代码. lib 用来放编译好的库文件. include 用来放头文件. sudo mkdir -p /code_ ...

  6. Canal 实战 | 第一篇:SpringBoot 整合 Canal + RabbitMQ 实现监听 MySQL 数据库同步更新 Redis 缓存

    一. Canal 简介 canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费 早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同 ...

  7. SpringCloud实战 | 第一篇:Windows搭建Nacos服务

    前言 为什么放弃eureka选择nacos?本地开发环境需要搭建nacos-server,想着是很简单的事但是被一些文章(少了关键必要的步骤)给带偏了,所以亲测成功后写了这篇文章. 搭建nacos-s ...

  8. Docker实战 | 第一篇:Centos8 安装 Docker

    1. 安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm2 2. 配置镜像源 yum config-manager --a ...

  9. Spring Cloud实战 | 最终篇:Spring Cloud Gateway+Spring Security OAuth2集成统一认证授权平台下实现注销使JWT失效方案

    一. 前言 在上一篇文章介绍 youlai-mall 项目中,通过整合Spring Cloud Gateway.Spring Security OAuth2.JWT等技术实现了微服务下统一认证授权平台 ...

随机推荐

  1. linux之网络配置相关

    ubuntu的网络配置文件在 /etc/network/intrfaces; suse的网络配置在          /etc/sysconfig/network/下面,每个网卡一个配置文件. int ...

  2. shell中的cut命令

    转:http://blog.sina.com.cn/s/blog_5e77c61f0100hqky.html cut是以每一行为一个处理对象的,这种机制和sed是一样的.(关于sed的入门文章将在近期 ...

  3. python的模块itsdangerous

    这个模块主要用来签名和序列化 使用场景: 一.给字符串添加签名: 发送方和接收方拥有相同的密钥--"secret-key",发送方使用密钥对发送内容进行签名,接收方使用相同的密钥对 ...

  4. [React] Use react-rewards to add microinteractions to React app to reward users for some actions

    It's important that our users enjoy using our application or website. One way we can make it happen ...

  5. dev_queue_xmit()函数返回值问题

    函数  dev_queue_xmit()用于直接使用sk_buf发包,此函数有返回值,但是并不能通过 此函数返回值为0来说明包已经发送出去且可以立刻释放sk_buff内存.因为网卡发包是一个异步的过程 ...

  6. 2、cas4.0 单点登录 之 cas-client

    cas4.0 单点登录 之 cas-client cas4.0 单点登录 之 https证书已经做好了证书的准备工作.如今结合cas-server来配置单点登录: 一.安装cas服务端(cas-ser ...

  7. CentOS——yum命令运行错误解决办法

    问题: [root@name user]# yum File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:        ...

  8. JavaScript 屏蔽退格键

    document.onkeydown = function(){//屏蔽Backspace键 if (event.keyCode==8){ event.keyCode=0; event.returnV ...

  9. 基于React的PC网站前端架构分析

    代码地址如下:http://www.demodashi.com/demo/12252.html 本文适合对象 有过一定开发经验的初级前端工程师: 有过完整项目的开发经验,不论大小: 对node有所了解 ...

  10. shell脚本通过ping命令来获取平均延时

    #!/bin/bash #设置环境变量 PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin" exp ...