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. numpy 多维数组的存取

    多维数组的存取和一维数组类似,由于多维数组有多个轴,所以他的下标需要多个值来表示.这里讨论的主要是二维数组.二维数组0轴以行为单位,1轴以列为单位,存取数组使用元组作为下标,需要注意的是,python ...

  2. flask控制上传文件的大小

    1.flask控制上传文件的大小的方案是全局控制:http://docs.jinkan.org/docs/flask/patterns/fileuploads.html from flask impo ...

  3. Android源码和内核源码的下载,编译和执行

    笔者依据罗升阳老师的<Android 系统源码情景分析>一书,尝试下载,编译和执行Android源码和内核源码.但可能是软件源"被墙"或版本号更新的原因.期间遇到诸多问 ...

  4. 使navicat可以通过SSH连接MySQL数据库

    1.编辑/etc/ssh/sshd_config,在最下面添加如下语句 KexAlgorithms diffie-hellman-group1-sha1,curve25519-sha256@libss ...

  5. EffectiveJava(8)覆盖equals是要遵守的约定

    覆盖equals是要遵守的约定 1.覆盖种类: -类的每个1实例本质上都是唯一的 -不关心类是否提供了"逻辑相等"的测试功能(Random测试是否能随机相同数字) -超类已经覆盖了 ...

  6. DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  7. CMake 从文件路径中提取文件名

    FILE(GLOB_RECURSE SRC_FILES "*.c" "*.cc" "*.cpp" "*.h" " ...

  8. 《Java设计模式》之调停者模式(Mediator)

    调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从而使它们能够较松散地耦合.当这些对象中的某些对象之间的相互作用发生改变时,不会马上影响到其它的一些 ...

  9. Excel如何取消显示分页虚线

    点击普通模式,保存文件,关闭文件再打开就好了. 文章来源:刘俊涛的博客 地址:http://www.cnblogs.com/lovebing 欢迎关注,有问题一起学习欢迎留言.评论.

  10. TELNET模拟HTTP请求

    开启nginx服务,查看服务器地址(192.168.11.119) 使用telnet命令连接服务器的80端口 http协议报文格式 1.request 2.response 输入请求行: GET / ...