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命令详解:jobs命令

    转:http://www.cnblogs.com/lwgdream/p/3413571.html 前言 我们可以将一个程序放到后台执行,这样它就不占用当前终端,我们可以做其他事情.而jobs命令用来查 ...

  2. 【spring Boot】1.创建第一个springBoot项目

    入手springBoot,搭建第一个springBoot项目. 看官方文档还是有点别扭. https://docs.spring.io/spring-boot/docs/current-SNAPSHO ...

  3. scp拷贝本地文件到服务器

    拷贝远程服务器的文件到本地:scp -r -P  端口号   用户名@IP地址:/usr/local/tomcat_airc/webapps/        /tmp/kyj/ 拷贝本地文件到远程服务 ...

  4. linux下c,c++头文件的路径

    一. C语言包含的目录: 二. C++包含的目录

  5. 基于Storyboard的创建多分支NavigationController的方法

    如果遇到本文图片只展示一半的情况,多数情况下刷新一下浏览器即可 遇到的问题 我在写程序的时候碰到这样一个简单的需求,用户点击"我的XX"这样的功能时候,需要判断当前用户是否已经登录 ...

  6. sql取随机结果集

    应用场景: 某日,接产品姐姐需求,网站搜索页在搜索特定的内容时候,会现实搜索不到结果!如衣服网站,搜索鞋子等.为了不直接呈现一个赤裸裸的无此商品页面,so,需要在搜索商品件数小于3时,在下面随机推荐本 ...

  7. Win7提示1970-01-01 000000 is not a valid data怎么办.

    1 单击屏幕右下角的时间按钮   2 选个更改日期和时间,更改日历设置   3 把短日期改成"yyyy-m-d"   4 确定即可.发现日期的表示形式变了.

  8. 关系型数据的分布式处理系统MyCAT(转载)

      ——概述和基本使用教程 日期:2014/12/24 文:阿蜜果 1.   MyCAT概述 1.1 背景 随着传统的数据库技术日趋成熟.计算机网络技术的飞速发展和应用范围的扩充,数据库应用已经普遍建 ...

  9. Spring使用经验之StandardServletMultipartResolver实现文件上传的基本配置

    Note:Spring使用版本是4.1.6.RELEASE 1. 在实现了AbstractAnnotationConfigDispatcherServletInitializer的类中重载custom ...

  10. winform对话框拖拽显示文件路径的问题

    allow drop=true; dragEnter dragDrop vs管理员账户拖拽会失败