cmake初认识

来源:互联网 发布:绝地求生 mac 编辑:程序博客网 时间:2024/05/21 22:28
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 功能

个人的建议:
1,如果你没有实际的项目需求,那么看到这里就可以停下来了,因为 cmake 的学习过程就
是实践过程,没有实践,读的再多几天后也会忘记。
2,如果你的工程只有几个文件,直接编写 Makefile 是最好的选择。
3,如果使用的是 C/C++/Java 之外的语言,请不要使用 cmake(至少目前是这样)
4,如果你使用的语言有非常完备的构建体系,比如 java 的 ant,也不需要学习 cmake,
虽然有成功的例子,比如 QT4.3 的 csharp 绑定 qyoto。
5,如果项目已经采用了非常完备的工程管理工具,并且不存在维护问题,没有必要迁移到
cmake
4,如果仅仅使用 qt 编程,没有必要使用 cmake,因为 qmake 管理 Qt 工程的专业性和自
动化程度比 cmake 要高很多。


helloword:
首先,在/backup 目录建立一个 cmake 目录,用来放置我们学习过程中的所有练习。
mkdir -p /backup/cmake
以后我们所有的 cmake 练习都会放在/backup/cmake 的子目录下(你也可以自行安排目录,
这个并不是限制,仅仅是为了叙述的方便)
然后在 cmake 建立第一个练习目录 t1
cd /backup/cmake
mkdir t1
cd t1
在 t1 目录建立 main.c 和 CMakeLists.txt(注意文件名大小写):
main.c 文件内容:
//main.c
#include <stdio.h>
int main()
{
printf(“Hello World from t1 Main!\n”);
return 0;
}
CmakeLists.txt 文件内容:
PROJECT (HELLO)
SET(SRC_LIST main.c)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello SRC_LIST)


然后直接 cmake . 
make
这是内部编译,更好的方法是在此文件夹下另建一个新的文件夹, 在其中cmake ..         &&make 即可,此为外部编译
通过外部编译进行工程构建,HELLO_SOURCE_DIR 仍然指代工程路径,
而 HELLO_BINARY_DIR 则指代编译路径


PROJECT 指令的语法是:
PROJECT(projectname [CXX] [C] [Java])
你可以用这个指令定义工程名称,并可指定工程支持的语言,支持的语言列表是可以忽略的,
默认情况表示支持所有语言。这个指令隐式的定义了两个 cmake 变量:
<projectname>_BINARY_DIR 以及<projectname>_SOURCE_DIR,这里就是
HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR(所以 CMakeLists.txt 中两个 MESSAGE
指令可以直接使用了这两个变量),因为采用的是内部编译,两个变量目前指的都是工程所
在路径/backup/cmake/t1,后面我们会讲到外部编译,两者所指代的内容会有所不同。
同时 cmake 系统也帮助我们预定义了 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR
变量,他们的值分别跟 HELLO_BINARY_DIR 与 HELLO_SOURCE_DIR 一致。
为了统一起见,建议以后直接使用 PROJECT_BINARY_DIR,PROJECT_SOURCE_DIR,即
使修改了工程名称,也不会影响这两个变量。如果使用了
<projectname>_SOURCE_DIR,修改工程名称后,需要同时修改这些变量。
SET 指令的语法是:
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
现阶段,你只需要了解 SET 指令可以用来显式的定义变量即可。
比如我们用到的是 SET(SRC_LIST
main.c),如果有多个源文件,也可以定义成:
SET(SRC_LIST main.c t1.c t2.c)。
MESSAGE 指令的语法是:
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"
...)
这个指令用于向终端输出用户定义的信息,包含了三种类型:
SEND_ERROR,产生错误,生成过程被跳过。
SATUS,输出前缀为—的信息。
FATAL_ERROR,立即终止所有 cmake 过程.
我们在这里使用的是 STATUS 信息输出,演示了由 PROJECT 指令定义的两个隐式变量
HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR。
ADD_EXECUTABLE(hello ${SRC_LIST})
定义了这个工程会生成一个文件名为 hello 的可执行文件,相关的源文件是 SRC_LIST 中
定义的源文件列表, 本例中你也可以直接写成 ADD_EXECUTABLE(hello main.c)。
在本例我们使用了${}来引用变量,这是 cmake 的变量应用方式,但是,有一些例外,比
如在 IF 控制语句,变量是直接使用变量名引用,而不需要${}。如果使用了${}去应用变
量,其实 IF 会去判断名为${}所代表的值的变量,那当然是不存在的了。
将本例改写成一个最简化的 CMakeLists.txt:
PROJECT(HELLO)
ADD_EXECUTABLE(hello main.c)


前面提到过,cmake 其实仍然要使用”cmake 语言和语法”去构建,上面的内容就是所谓的
”cmake 语言和语法”,最简单的语法规则是:
1,变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
2,指令(参数 1 参数 2...)
参数使用括弧括起,参数之间使用空格或分号分开。
以上面的 ADD_EXECUTABLE 指令为例,如果存在另外一个 func.c 源文件,就要写成:
ADD_EXECUTABLE(hello main.c func.c)或者
ADD_EXECUTABLE(hello main.c;func.c)
3,指令是大小写无关的,参数和变量是大小写相关的。但,推荐你全部使用大写指令。

cmake 的语法还是比较灵活而且考虑到各种情况,比如
SET(SRC_LIST main.c)也可以写成 SET(SRC_LIST “main.c”)
是没有区别的,但是假设一个源文件的文件名是 fu nc.c(文件名中间包含了空格)。
这时候就必须使用双引号,如果写成了 SET(SRC_LIST fu nc.c),就会出现错误,提示
你找不到 fu 文件和 nc.c 文件。这种情况,就必须写成:
SET(SRC_LIST “fu nc.c”)
此外,你可以可以忽略掉 source 列表中的源文件后缀,比如可以写成
ADD_EXECUTABLE(t1 main),cmake 会自动的在本目录查找 main.c 或者 main.cpp
等,当然,最好不要偷这个懒,以免这个目录确实存在一个 main.c 一个 main.
同时参数也可以使用分号来进行分割。

原创粉丝点击