cmake实战第一篇:初试 cmake

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

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

 

posted @ 2016-05-30 15:57  jason来自星星  阅读(9622)  评论(0编辑  收藏  举报