菜鸟笔记
提升您的技术认知

CMake 入门

阅读 : 1835

1 背景

cmake是kitware公司以及一些开源开发者在开发几个工具套件(VTK)的过程中衍生品,最终形成体系,成为一个独立的开放源代码项目。项目的诞生时间是2001年。其官方网站是 www.cmake.org,可以通过访问官方网站获得更多关于cmake的信息。cmake的流行其实要归功于KDE4的开发(似乎跟当年的svn一样,KDE将代码仓库从CVS迁移到SVN,同时证明了SVN管理大型项目的可用性),在KDE开发者使用了近10年autotools之后,他们终于决定为KDE4选择一个新的工程构建工具,其根本原因用KDE开发者的话来说就是:只有少数几个“编译专家”能够掌握KDE现在的构建体系(admin/Makefile.common),在经历了unsermake, scons以及cmake的选型和尝试之后,KDE4决定使用cmake作为自己的构建系统。在迁移过程中,进展异常的顺利,并获得了cmake开发者的支持。所以,目前的KDE4开发版本已经完全使用cmake来进行构建。像kdesvn,rosegarden等项目也开始使用cmake,这也注定了cmake必然会成为一个主流的构建体系。

2 问题,难道就没有问题?

(1)、cmake很简单,但绝对没有听起来或者想象中那么简单。

(2)、cmake编写的过程实际上是编程的过程,跟以前使用autotools一样,不过你需要编写的是CMakeLists.txt(每个目录一个),使用的是”cmake语言和语法”。

(3)、cmake跟已有体系的配合并不是特别理想,比如pkgconfig,您在实际使用中会有所体会,虽然有一些扩展可以使用,但并不理想。

3 个人的建议:

(1)、如果你没有实际的项目需求,那么看到这里就可以停下来了,因为cmake的学习过程就是实践过程,没有实践,读的再多几天后也会忘记。

(2)、如果你的工程只有几个文件,直接编写Makefile是最好的选择。

(3)、如果使用的是C/C++/Java之外的语言,请不要使用cmake(至少目前是这样)

(4)、如果你使用的语言有非常完备的构建体系,比如java的ant,也不需要学习cmake,虽然有成功的例子,比如QT4.3的csharp绑定qyoto。

(5)、如果项目已经采用了非常完备的工程管理工具,并且不存在维护问题,没有必要迁移到cmake

(6)、如果仅仅使用qt编程,没有必要使用cmake,因为qmake管理Qt工程的专业性和自动化程度比cmake要高很多。

WHY CMake

(1)、开放源代码,使用类BSD许可发布。http://cmake.org/HTML/Copyright.html

(2)、跨平台,并可生成native编译配置文件,在Linux/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功能。

HOW CMake

0x00 起手式

这里假设题主以及其他想入门 CMake 的人像我一样鶸,下面是我个人总结的比较适合的学习路径。首先默念三遍并记住口诀:
1.Declare a target
2.Declare target’s traits
3.It’s all about targets
然后 clone https://github.com/ttroy50/cmake-examples 这个项目到本地,把里面的
01-basic(跳过E-installing,因为和依赖有关,后面会说)
02-sub-projects
两个目录认真的学习一遍,最好自己能够动手跟着做一遍。

每学习完一个小节,把前面的三句口诀复习一下

每遇到一个不认识的命令,在 Effective Modern CMake 这个页面里搜索一下,看看这个命令是否取代了某个老命令。
cmake-examples 这个项目大概是我在 Github 上能找到的最符合“深入浅出”这四个字的。不仅例子符合 Modern CMake,并且每个步骤都会有详细的注释来解释“是什么,为什么”。
例如第一节的 Hello CMake,只有短短的几行:

# Set the minimum version of CMake that can be used
# To find the cmake version run
# $ cmake --version
cmake_minimum_required(VERSION 3.5)

# Set the project name
project (hello_cmake)

# Add an executable
add_executable(hello_cmake main.cpp)

而 Static Library 一节,也只包含了最核心的内容:

cmake_minimum_required(VERSION 3.5)
project(hello_library)

############################################################
# Create a library
############################################################

#Generate the static library from the library sources
add_library(hello_library STATIC 
    src/Hello.cpp
)

target_include_directories(hello_library
    PUBLIC 
        ${PROJECT_SOURCE_DIR}/include
)


############################################################
# Create an executable
############################################################

# Add an executable with the above sources
add_executable(hello_binary 
    src/main.cpp
)

# link the new hello_library target with the hello_binary target
target_link_libraries( hello_binary
    PRIVATE 
        hello_library
)

而之所以先看 01 和 02 是因为这两个目录里的内容已经涵盖了至少80%的使用场景;一下学太多很容易出现遭遇知识洪水的无力感而早早放弃。
对于入门学习来说,知识是螺旋上升的;同时照着优秀的例子 learning by doing 可以很好缓解恐惧感。
Effective Modern CMake 这里的作用类似于 C++ 那几本 Effective。