CMake Helloworld 01:CMake的安装、使用 以及一个很简单的例子

References:

Ref 1. CMake Practice -- Cjacker

Ref 2. Cmake的介绍和使用 Cmake实践 (http://www.cppblog.com/Roger/archive/2011/11/17/160368.html)

Ref 3. Installing CMake (http://www.cmake.org/install/)

Ref 4. Running CMake (http://www.cmake.org/runningcmake/)

Ref 5. CMake Tutorial (http://www.cmake.org/cmake-tutorial/)

 

一、CMake优点[Ref 1]

1.       开发源代码,实用类BSD许可发布。

2.       跨平台,并可以生成native编译配置文件,在linux/unix平台,生成makefile,在mac平台可以生成 xcode,在windows平台可以生成msvc工程的配置文件。

3.       能够管理大型项目

4.       简化编译构建过程和编译过程,只需要cmake+make就可以

5.       高效率

6.       可扩展,可以为cmake编写特定功能的模块,扩充cmake功能

二、如何下载以及安装CMake (以cmake-3.01版本为例子)

1.       Download Latest Release (3.0.1)Unix/Linux Source file – cmake-3.0.1.tar.gz (see http://www.cmake.org/download/ )

2.   解压该文件:如文件名为:cmake-3.0.1.tar.gz

$ cd cmake-3.0.1.tar.gz所在的目录下;

$ tar –zxv –f cmake-3.0.1.tar.gz C ./ ./:解压缩到当前目录下)

3.   installing:

$ cd 解压缩后的文件所在的目录;

$ ./bootstrap (可能需要sudo 获得超级权限)

$ make (可能需要sudo 获得超级权限);

$ make install(可能需要sudo 获得超级权限);

4.  检查是否安装成功: $ cmake –version; 若有如下提示则表示成功安装

: cmake version 3.0.1

: CMake suite maintained and supported by Kitware (kitware.com/cmake).

三、一个关于helloworld的小例子展示CMake的原理[Ref 1, 2]

我们先创建一个练习目录, 如:/home/ccj/CMakeDemo/t1

Step 1: t1目录下build a main.cpp file:

 //main.cpp

#include<cstdio>

 int main()

{

    printf("hello world from main\n");

    return 0;

}

Step 2:t1目录下创建CMakeLists.txt(注意大小写字母,i.e., Case Sensitive

向该文件中加入以下几行(稍后会做解释)

# CMake command is not sensitive to case, 即指令是大小写字母不敏感的。

# But the parameters and variables are case sensitive. 即变量名参数等是大小写字母敏感的。

# Thus we recommend to always use UPPER CASE letters.

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

# PROJECT这个指令隐式的定义了两个cmake变量:

# <projectname>_BINARY_DIR以及<projectname>_SOURCE_DIR,这里就是

# HELLO_BINARY_DIRHELLO_SOURCE_DIR (所以CMakeLists.txt中两个MESSAGE

# 指令可以直接使用了这两个变量),因为采用的是内部编译,两个变量目前指的都是工程所

# 在路径/home/ccj/CMakeDemo/t1,后面我们会讲到外部编译,两者所指代的内容会有所不同。

# 同时cmake系统也帮助我们预定义了PROJECT_BINARY_DIRPROJECT_SOURCE_DIR

# 变量,他们的值分别跟HELLO_BINARY_DIRHELLO_SOURCE_DIR一致。

# 为了统一起见,建议以后直接使用PROJECT_BINARY_DIRPROJECT_SOURCE_DIR,即

# 使修改了工程名称,也不会影响这两个变量。如果使用了

# <projectname>_SOURCE_DIR,修改工程名称后,需要同时修改这些变量。

Step 3:运行cmake命令:

$ cmake . (or ./)

. Or ./ 表示当前目录,因此这里进行的是in-source build,后面的例子会涉及到out-of-source build, which is recommended by CMake. See the following: CMake supports in-source builds, but we strongly encourage users to adopt the notion of an out-of-source build. Using a build tree that is separate from the source tree will prevent CMake from generating any files in the source tree.

man

注意执行完这句话之后会生成几个文件如下:

CMakeFiles, CMakeCache.txt, cmake_install.cmake等,并且生成了工程配置文件Makefile for Unix/Linux

Step 4:然后执行make 就可以生成可执行文件hello On UNIX, executable files have no suffix or file extension

这时当前目录下就会生成可执行文件如下图:

Step 5:运行生成的可执行文件,$ ./hello

Step 6: 对例子的解释: 

Project的指令的语法是:

PROJECT(projectname [CXX] [C] [JAVA])

这个执行是用来定义工程的名称的和定义工程支持的语言。这个指令也隐式的定义了两个cmake变量:<projectname>_BINARY_DIR以及<projectname>_SOURCE_DIR,这里就是HELLO_BINARY_DIRHELLO_SOURCE_DIR,两个变量指的都是当前工程的路径。

SET指令的语法:

SETVAR[VALUE] [CACHE TYPE DOCSTRING [FORCE]]

Set指令是用来显式的定义变量的,我们之前用到的是SET(SRC_LIST main.cpp)如果有多个源文件,也可以定义成SET(SRC_LIST main.cpp t1.cpp t2.cpp)

MESSAGE指令的语法是:

MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)

这个指令用于向终端输出用户信息,包含三种类型:

SEND_ERROR,产生错误,生成过程被跳过。

SATUS,输出前缀为-的信息。

FATAL_ERROR,立即终止所有cmake过程。

我们在这里使用的是STATUS信息输出,显示了由PROJECT指令生成的两个隐式变量HELLO_BINARY_DIRHELLO_SOURCE_DIR

ADD_EXECUTABLE(hello ${SRC_LIST})

这个工程会生成一个文件名为hello的可执行文件,相关的源文件是SRC_LIST中定义的源文件列表,本例中你可以直接写成ADD_EXECUTABLE(hello main.c)这里需要特别解释的是作为工程名的HELLO和生成的可执行文件hello是没有任何关系的。hello定义了可执行文件的文件名,你完全可以写成:ADD_EXECUTABLE(t1 main.c) 编译后会生成一个名为t1的可执行文件。

 

将本例改写成一个最简化的CMakeLists.txt

PROJECT(HELLO)

ADD_EXECUTABLE(hello main.c)

Step 7: 将上诉的in-source build 改成out-of-source build

1) 首先,清除t1目录中除main.c CmakeLists.txt 之外的所有中间文件,最关键的是CMakeCache.txt

2) t1目录中建立build 目录,当然你也可以在任何地方建立build目录,不一定必须在该工程目录中。

3) 进入build目录(故此时的 cd, i.e., Current Directory 就是 build目录了),运行cmake .. (注意..代表父目录,因为父目录存在我们需要的CMakeLists.txt,如果你在其他地方建立了build目录,需要运行cmake <包含CMakeLists.txt的工程的全路径>),查看一下build目录,就会发现了生成了编译需要的Makefile以及其他的中间文件.

4)运行make构建工程,就会在当前目录(i.e., build目录)中获得目标文件hello

上述过程就是所谓的out-of-source外部编译,一个最大的好处是,对于原有的工程没有任何影响,所有动作全部发生在编译目录。通过这一点,也足以说服我们全部采用外部编译方式构建工程。

Note:

通过外部编译(out-of-source build)进行工程构建,HELLO_SOURCE_DIR仍然指代工程路径, 即/home/ccj/CMakeDemo/t1;但是 HELLO_BINARY_DIR 则指代编译路径,即 /home/ccj/CMakeDemo/t1/build 了。

# Over of this blog (此篇完结)。

posted @ 2014-09-19 06:54  GloryOfFamily  阅读(1210)  评论(0编辑  收藏  举报