第一次使用Cmake,搜索了很多使用教程,包括《Cmake实践》、《Cmake手册》等,但是在针对最新的C++11条件下编程还是会存在一点点问题,需要实验很多次错误并搜索大量文章才能解决问题。这里用新手日记的方式告诉一个Cmake小白如何在C++11下使用Cmake。

  一般情况下,直接阅读文档会不太适应新手,没有感官的认识,没有经验。这里将自己的学习过程记录下来,方便自己查阅,也方便其他新手学习。

  首先先声明一下Cmake脚本,其实就是CMakeLists.txt的基本语法规则:

  •  变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
  •  指令(参数 1 参数 2...) 参数使用括弧括起,参数之间使用空格或分号分开。   
  •  指令是大小写无关的,参数和变量是大小写相关的。但,推荐你全部使用大写指令。

  一、单文件编译

  (1)操作过程

  <1>创建一个目录t1.  

  <2>编写代码:

  main.cpp

 #include <iostream>
#include <vector>
int main()
{ using namespace std;
vector<int> V(,);
for(auto e:V)
cout << e << endl;
cout << "OK" << endl;
return ; }

  <3>编写CMakeLists.txt

  【注意】不要忘记“CMakeLists.txt”中“.”前还有一个“s”,如果你很粗心,估计会在这里抓耳挠腮。

  

PROJECT (HELLO)
SET(CMAKE_C_COMPILER g++)
if(CMAKE_COMPILER_IS_GNUCXX)
add_compile_options(-std=c++11)
  message(STATUS "optional:-std=c++11")
endif(CMAKE_COMPILER_IS_GNUCXX)
SET(SRC_LIST main.cpp)
ADD_EXECUTABLE(hello ${SRC_LIST})

  <4>在t1文件夹下编译

  先运行,注意Cmake后面的小点点“.”表示当前目录。

  

Cmake .

  再运行

  

make

  <5>运行程序  

  此时,再t1文件夹下会产生hello文件,运行

./hello

程序就正确运行啦。

  输出

@ubuntu:~/t1$ ./hello
3
3
3
3
3
OK

  (2)过程解释

  首先,在CMakeLists.txt中,命令可以使用大写、小写、混写。

  PROJECT (HELLO)是CMakeLists.txt的第一句,告诉编译器这个工程名叫hello。

  SET(CMAKE_C_COMPILER g++)声明使用g++编译器,因为如果是.c文件的话通常使用默认的gcc编译器。

  add_compile_options(-std=c++11)告诉编译器使用的是c++11,但是如果不设置g++编译器,又不判断一下编译器的话会出现下面的运行结果:

@ubuntu:~/t1$ make
Scanning dependencies of target hello
[ 50%] Building CXX object CMakeFiles/hello.dir/main.o
c++: error: unrecognized command line option ‘-std=C++11’
CMakeFiles/hello.dir/build.make:62: recipe for target 'CMakeFiles/hello.dir/main.o' failed
make[]: *** [CMakeFiles/hello.dir/main.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/hello.dir/all' failed
make[]: *** [CMakeFiles/hello.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

  有的博客里说能够编译完成,但是在这里有时候就完不成。当然有时候也能完成,这个可能和具体的系统有关吧。

  当出现上述问题时,可以使用设置编译器的方式解决,也可以使用if语句进行判断,这里为了能够将所有情况都讲清楚,就暂时多此一举这个写了。其中CMAKE_COMPILER_IS_GNUCXX用于判断编译器类型。

  但是作者也碰到这样的问题,如果不设置编译器为g++,第一次设置编译器为std=c++11属性时报错,但是一旦设置完成功运行之后,即使吧编译器设置的语句去掉,把t1下面除了main.cpp和CMakeLists.txt之外的语句去掉,也能正常编译。真的有些奇怪。

  message(STATUS "optional:-std=c++11")可以用于打印一些提示信息,这里在运行完CMake .之后,就把“”中的文字打印出来了。实际上, 除了用STATUS打印普通标识,message还有一些其他的打印功能,如用SEND_ERROR,产生错误信息,生成过程被跳过。如果使用 FATAL_ERROR,立即终止所有 cmake 过程。

  接着SET(SRC_LIST main.cpp) 和ADD_EXECUTABLE(hello ${SRC_LIST}) 语句。定义了这个工程会生成一个文件名为 hello 的可执行文件,相关的源文件是 SRC_LIST 中 定义的源文件列表, 本例中也可以直接写成 ADD_EXECUTABLE(hello main.c)。

  ${}来引用变量,这是 cmake 的变量应用方式,但是,有一些例外,比 如在 IF 控制语句,变量是直接使用变量名引用(如这里的CMAKE_COMPILER_IS_GNUCXX),而不需要${}。如果使用了${}去应用变量,其实 IF 会去判断名为${}所代表的值的变量,那当然是不存在的了。

  (3)一点注意

  在CMakeLists.txt脚本中,设置编译选项可以通过add_compile_options命令,也可以通过set命令修改CMAKE_CXX_FLAGSCMAKE_C_FLAGS

  使用这两种方式在有的情况下效果是一样的,但请注意它们还是有区别的: 
  add_compile_options命令添加的编译选项是针对所有编译器的(包括c和c++编译器),而set命令设置CMAKE_C_FLAGSCMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器的。因此,下面的代码也是一样的效果哦!

PROJECT (HELLO)

SET(CMAKE_C_COMPILER g++)
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
endif(CMAKE_COMPILER_IS_GNUCXX) SET(SRC_LIST main.cpp)
ADD_EXECUTABLE(hello ${SRC_LIST})

Cmake新手使用日记(1)【C++11下的初体验】的更多相关文章

  1. Mac下nodeJS初体验

    Mac下nodeJS初体验 这两天博主出门在外,抽空体验一下大名鼎鼎的node 安装 brew install node 安装测试 $ node -v v8.4.0 运行本地脚本 用文本编辑器编辑一段 ...

  2. Ubuntu下Django初体验(一)——开发环境搭建

    一.开发 环境搭建 1. linux下一般有自带的python,如果对版本不满意,可以再自行安装. 2. 安装ipython(推荐) sudo apt-get install ipython sudo ...

  3. Ubuntu下Django初体验(三)——django初体验

    Django中的重要概念: 一次web访问的实质: 1. 客户发送http请求到web服务回 2. web服务器返回html页面给客户 Django概述: 1. URL配置             建 ...

  4. Ubuntu下Django初体验(二)——创建工程及应用

    一.工程目录详解 创建工程后得到如下目录: 1. manage.py 管理项目.创建数据库.启动服务器等.测试等. 查看子命令: python manage.py 启动服务器: python mana ...

  5. php大力力 [001节]2015-08-21.php在百度文库的几个基础教程新手上路日记 大力力php 大力同学 2015-08-21 15:28

    php大力力 [001节]2015-08-21.php在百度文库的几个基础教程新手上路日记 大力力php 大力同学 2015-08-21 15:28 话说,嗯嗯,就是我自己说,做事认真要用表格,学习技 ...

  6. asp.net 项目在 IE 11 下出现 “__doPostBack”未定义 的解决办法

    最近项目在 IE 11 下<asp:LinkButton> 点击出现 “__doPostBack”未定义”,经过一番google,终于知道了原因:ASP.NET 可能无法辨识出一些浏览器的 ...

  7. Linux 0.11下信号量的实现和应用

    Linux 011下信号量的实现和应用 生产者-消费者问题 实现信号量 信号量的代码实现 关于sem_wait和sem_post sem_wait和sem_post函数的代码实现 信号量的完整代码 实 ...

  8. 【转】asp.net 项目在 IE 11 下出现 “__doPostBack”未定义 的解决办法

    最近我们运营的网站有用户反馈在 IE 11 下<asp:LinkButton> 点击出现 “__doPostBack”未定义”,经过一番google,终于知道了原因:ASP.NET 可能无 ...

  9. IOS 11 下适配UITableView

    9月份苹果发布了IOS11和Iphone X,这一操作系统一硬件对于开发者适配上面还是造作了不少蛋疼的地方.先来看看IOS 11,这些蛋疼的需要适配的地方: 1.UIScrollView及其子类在IO ...

随机推荐

  1. JavaScript之onXXXX事件和addEventListener的区别

    JavaScript之onXXXX事件和addEventListener的区别 1.首先介绍两者的用法: 1.1onXXXX的用法:以onclick为例 第一种: obj.onclick = func ...

  2. 《JAVA与模式》之简单工厂模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述简单工厂模式的:简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式.简单工厂模式是由一个工厂 ...

  3. Ehcache 整合Spring 使用页面、对象缓存(1)

    转自:http://www.cnblogs.com/hoojo/archive/2012/07/12/2587556.html Ehcache在很多项目中都出现过,用法也比较简单.一般的加些配置就可以 ...

  4. spring-线程池(1)

    多线程并发处理起来通常比较麻烦,如果你使用spring容器来管理业务bean,事情就好办了多了.spring封装了java的多线程的实现,你只需要关注于并发事物的流程以及一些并发负载量等特性,具体来说 ...

  5. python socket+tcp三次握手四次撒手学习+wireshark抓包

    Python代码: server: #!/usr/bin/python # -*- coding: UTF-8 -*- # 文件名:server.py import socket # 导入 socke ...

  6. 使用PostProcessBuild设定Unity产生的Xcode Project

    简单来说就是unity提供一套api去修改xcode项目工程配置以及修改plist文件内容(当unity build结束后, 会自动回调OnPostProcessBuild). 以下是一些用到的配置处 ...

  7. R语言与分类算法的绩效评估(转)

    关于分类算法我们之前也讨论过了KNN.决策树.naivebayes.SVM.ANN.logistic回归.关于这么多的分类算法,我们自然需要考虑谁的表现更加的优秀. 既然要对分类算法进行评价,那么我们 ...

  8. hadoop 2.7.3 集群安装

    三台虚拟机,centos6.5 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 :: loca ...

  9. 汽车Vin码识别——可以嵌入到手机里的新OCR识别技术

              汽车Vin码识别(车架号识别),顾名思义,就是识别汽车的Vin码(车架号),汽车Vin码识别(车架号识别)利用的是OCR识别技术,支持视频流获取图像,自动触发识别,另外汽车Vin码 ...

  10. VR全景智慧城市:360全景市场需要背景及其优势~

    VR元年已过,VR项目.VR创业潮转为理性,VR行业分为两个方向:硬件和内容. VR全景,又被称为3D实景,是一种新兴的富媒体技术,其与视频,声音,图片等传统的流媒体大的区别是"可操作,可交 ...