cmake 简单介绍
----------
1. cmake简介
cmake是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包与一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进
行控制。现在许多跨平台的开源软件都转向了用cmake来做构建工具,如KDE,Kdevelop,hypertable等,使用cmake,你可以不用关心如何去创建编译可执行文
件和动态库。它为了支持不同的平台,提供了以下特性:跨库依赖检查,并行构建和简单的头文件结构,这使它大大减少了跨平台软件的开发和维护过程的复杂性。
对于一些简单的项目,你可能可以立即写出Makfile,如
HelloWorld: helloworld.o
cc -o HelloWorld helloworld.o -lm -lz
helloworld.o: helloworld.c helloworld.h
cc -c helloworld.c
当写好这个Makefile以后,你可以用make命令运行以构建项目,如果有文件被修改,那所有的有依赖关系的文件都会被重新构建。但当你把这个项目移植到另外一台机器,可以就会出这样的错误:cc: Command not found,这是因为这台机器上没有叫cc的编译程序,可能它会叫另外一个名字,如cc-XYZ,所以你必须修改Makfile以便进行重新编译。
通过上面的例子,你会发现一但Makefile被移植到了另一个新的平台,在这个平台上没有叫cc的编译器,那这时make就会出错。
可能有人会说,我们可以有autoconf和automake来对环境进行自动检测,但是它们太复杂了,而且autoconf依赖于shell,这些配置文件不能在没有bash的平台上运行。
而CMake解决了这些问题。它只依赖于系统的本地构建工具,而且它是用标准c++写的,在大多数平台上都能运行。
上面的那个例子用CMake来完成你需要写一人CMakeLists.txt文件,如下:
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
PROJECT (HelloWorld) # 工程名
SET( helloworld_SRCS helloworld.c)
ADD_EXECUTABLE(HelloWorld ${hello_SRCS}) # 根据列出源文件编译出可执行文件
TARGET_LINK_LIBRARIES(HelloWorld z m) # 指定动态链接库
你可以用cmake path 和make来构建项目,它会先从path路径中找到CMakeLists.txt文件,读取进行分析,在当前目录中产生适合与平台的Makefiles文件,
2. cmake特点
2.1 跨平台,因为它使用与平台和编译器无关的配置文件,
2.2 是一种非常简单的脚本语言,这有点像IDL
2.3 依赖发现机制很强大,使用FIND_PACKAGE
2.4 有很好的扩展性,效果也很高,据说KDE4用了它以后构建速度提高了40%
3. 举例说明
3.1 编译一个可执行文件的CMakeLists.txt
PROJECT( helloworld )
SET( hello_SRCS hello.cpp )
ADD_EXECUTABLE( hello ${hello_SRCS})
3.2 编译一个动态库
PROJECT( mylibrary )
SET( mylib_SRCS library.cpp )
ADD_LIBRARY( my SHARED ${mylib_SRCS}) // 这里也可以用STATIC标记来构建一个表态库
NOTE:静态库是在编译的时候去连接库,它会把用到的文件代码加入到你的可执行文件中;而动态库是在运行的时候去连接库,可执行文件中只包括动态库代码的一个相对地址。在linux下编译动态库的时候要加一个-fPIC,意思是Position Independent Code
3.3 分层文件目录
trunk ---> PROJECT(clockapp)
|--doc ADD_SUBDIRECTORY(libwakeup)
| ADD_SUBDIRECTORY(clock)
|--img
|
|--libwakeup --> SET(wakeup_SRCS wakeup.cpp)
| |-- wakeup.cpp ADD_LIBRARY(wakeup SHARED ${wakeup_SRCS})
| `-- wakeup.h
|
|--clock --> SET(clock_SRCS clock.cpp)
| |-- clock.cpp ADD_EXECUTABLE(clock ${clock_SRCS})
`-- clock.h
这里每一个目录都要写一个CMakeLists.txt文件,而不是在trunk写一个文件,这样可的好处是可以把错误分散到每个模块中,是一种分而治
之的思想。
3.4 一些控制流语法: if, foreach ,while
IF(expression)
..
ELSE(expression)
..
ENDIF(expression)
FOREACH(loop_var)
...
ENDFOREACH(loop_var)
之的思想。
3.4 一些控制流语法: if, foreach ,while
IF(expression)
..
ELSE(expression)
..
ENDIF(expression)
FOREACH(loop_var)
...
ENDFOREACH(loop_var)
WHILE(condition)
...
ENDWHILE(condition)
3.5 处理debug和release构建的方法
* SET(CMAKE_BUILD_TYPE Debug) # 设置构建类型
* cmake -DCMAKE_BUILD_TYPE=Release ../trunk
* TARGET_LINK_LIBRARIES(wakeup RELEASE ${wakeup_SRCS})
TARGET_LINK_LIBRARIES(wakeup DEBUG ${wakeup_SRCS})
4. 与其它相似工具的对比
4.1 autotools
优点:历史悠久,使用广泛;可以自动生成Makefile文件
缺点:它需要有支持shell和m4;只支持Unix平台,而Visual Studio,Borland等在Win32平台上的都不支持;依赖发现大部分依赖手工操作;
生成的文件很大,一般很太看明白
4.2 Jam
优点:跨平台;支持平行连接
缺点:最初的实现很粗糙;依赖发现机制大部分依赖手工
4.3 SCons
优点:跨平台;
缺点:你需要学习另一门编程语言才会用它;可扩展性不好;好像DKE的源代码最初是选择用Scons来编译的,但不知为什么后来选择了CMake
5. 参考资料
5.1 http://www.cmake.org/
5.2 http://www.cmake.org/Wiki/CMake#Tutorials
5.3 http://www.elpauer.org/stuff/learning_cmake.pdf
CMake 简单介绍
最新推荐文章于 2024-08-10 21:56:27 发布