CMake入门实践(一)

一、CMake 简介

CMake 是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。它能够输出各种各样的makefile 或者 project 文件,能测试编译器所支持的C++ 特性,类似 UNIX 下的 automake 。只是 CMake 的组态组态档取名为 CMakeLists.txt。 CMake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。

cmake特点:

1. 开发源代码。http://cmake.org/HTML/Copyright.html 

2. 跨平台,并可生成 native 编译配置文件,在 Liunx/Unix 平台,生成 makefile;在苹果平台,可以生成 xcode,在Windows 平台,可以生成 MSVC 的工程文件。

3. 能够管理大型项目, KDE4 就是最好的证明。

4. 简化编译构建过程和编译过程。 CMake 的工具链非常简单: cmake + make。

5. 高效率,按照 KDE 官方说法,CMake 构建 KDE4 的 kdelibs 要比使用 autotools 来构建 KDE3.5.6 的 kdelibs 快 40%,主要是因为 CMake 在工具链中没有 libtool

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

在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:

1. 编写 CMake 配置文件 CMakeLists.txt

2. 执行命令 cmake PATH 或者 ccmake PATH 生成 Makefile。 其中 PATH 是 CMakeLists.txt 所在的目录

3. 使用 make 命令进行编译

二、Hello World

举一个 Hello World 的例子对 CMake 进行初步的理解。项目目录为  HelloWorld,其中建立两个文件,分别是 main.cpp 和 CMakeLists.txt 。

main.cpp 代码:

// main.cpp
#include <iostream>

int main() {

    std::cout << "Hello, World!" << std::endl;

    return 0;
}

CMakeLists.txt 文件内容:

cmake_minimum_required(VERSION 3.9)

project(HelloWorld)

set(CMAKE_CXX_STABDARD 11)

add_excutable(HelloWorld main.cpp)

所有的文件创建完成后, HelloWorld 目录中存在两个文件 main.cpp 和 CMakeLists.txt 两个文件。接下来我们来构建这个工程,在这个目录下运行:(注意命令后面的点,代表本目录)

cmake .

输出的大概如下:

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/enningxie/xiekun/WorkSpace/LearningCMake/HelloWorld

查看目录下的内容会发现,系统生成了 CMakeFiles  CMakeCache.txt  cmake_install.cmake 等文件,并且生成了 Makefile。不需要理会这些文件,其中最关键的就是自动生成了 Makefile 文件。

然后进行工程的实际构建,在这个目录下 输入 make 命令:(通过 make VERBOSE=1 命令可以看到 make 构建的详细过程)

make 

大概的输出如下: 

Scanning dependencies of target HelloWorld
[ 50%] Building CXX object CMakeFiles/HelloWorld.dir/main.cpp.o
[100%] Linking CXX executable HelloWorld
[100%] Built target HelloWorld

此时,我们需要的目标文件 HelloWorld 已经构建完成,位于当前目录,通过  ./HelloWorld 命令输出:

./HelloWorld

输出结果:

Hello, World!

三、基本语法解释

上面简单的 HelloWorld 案例介绍了 使用 cmake 构建项目的完整过程。对于新手,细节之处存在很多疑问。比如 CMake 怎么使用,CMakeLists.txt 文件到底写了什么东西等。下面进行简单的语法介绍,之后的教程中会逐步展开介绍。

CMakeLists.txt 文件时 cmake 的构建定义文件,文件名是大小写相关的。如果工程存在多个目录,需要确保每个要管理的目录都存在一个 CMakeLists.txt。(关于多目录工程,后续介绍)

CMakeLists.txt 文件内容如下:

cmake_minimum_required(VERSION 3.9)

project(HelloWorld)

set(CMAKE_CXX_STANDARD 11)

add_executable(HelloWorld main.cpp)

第一行: cmake_minimum_required(VERSION 3.9) 表示指定运行此配置文件所需 CMake 的最低版本;有些CMakeLists.txt 文件没有写也是正常的,但是还是推荐写,是因为可以避免由于不同版本 cmake 引起构建错误。

第二行:project(HelloWorld) 该命令指定项目的名称。project 指令语法:

project(projectname [CXX] [C] [Java])

project 指令定义工程名称,并指定工程支持的语言,支持的语言列表是可以忽略的,默认情况下表示支持所有语言。所以我们常使用 project(projectname) 就足够了。

project 指令隐式的定义了两个 cmake 变量:<projectname>_BINARY 和 <projectname>_SOURCE_DIR。这里就是  HelloWorld_BINARY_DIR 和 HelloWorld_SOURCE_DIR。 因为采用内部编译,两个变量只得都是 HelloWorld 工程所在的路径。后面会介绍内部编译和外部编译的不同。

同时 cmake 系统也帮助我们预定义了 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR 变量,它们的值分别跟 HelloWorld_BINARY_DIR 与 HelloWorld_SOURCE_DIR 一致。为了统一起见,建议以后直接使用PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR,即 <projectname>_SOURCE_DIR 修改工程名称后,需要同时修改这些变量。

第三行: set(CMAKE_CXX_STANDARD 11) 这里把之后的编译选项设置为了 C++ 11 。 set 指令的语法:

set (VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

现阶段,只需要了解 set 指令可以显示的定义变量即可。案例用到的是 set(SRC_LIST main.cpp),如果有多个源文件,也可以定义为  set(SRC_LIST main.cpp t1.cpp t2.cpp) 。

第四行: add_executable(HelloWorld main.cpp) ,将名为 main.cpp 的源文件编译成一个名称为 HelloWorld 的可执行文件。

set_executable 指令语法:

add_executable(executable_name ${SRC_LIST})

定义了工程会生成一个文件名为 executable_name 的可执行文件,相关的源文件是 SRC_LIST 中定义的源文件列表。

内部构建和 外部构建

通俗讲,内部构建就是在项目内部有CMakeList.txt的地方,直接cmake . 比如我们前面讲的简单案例都是最简单的内部构建。结果你也看见了,就是在项目下面生成了很多的临时文件。

外部构建就是不直接在项目目录下面运行 cmake ,而是自己建立一个 接收 cmake 之后的临时文件的文件夹(习惯为 bulid文件夹),然后在该文件夹下面  cmake <CMakeLists_path> 来构建,运行 make 构建工程。最大的好处就是对于原有的工程没有任何影响,所有执行全部发生在编译目录下面,同时避免产生过多的临时文件造成不必要的麻烦。

通过外部编译, <projectname>_SOURCE_DIR 仍然指代工程路径;而 <projectname>_BINARY_DIR 则指代编译路径。

后续。。。

参考链接:http://www.cnblogs.com/52php/p/5681745.html 

猜你喜欢

转载自blog.csdn.net/JACK_YOUNG007/article/details/88830661