在 linux 下使用 CMake 构建应用程序
级别:初级
王程明 (wangchengming.jlu@gmail), 硕士研究生, 吉林大学计算机科学与技术学院
2009 年 2 月 05 日
本文介绍了一个跨平台的自动化构建系统 CMake 在 linux 上的使用方法。 CMake 是一个比automake 更加容易使用的工具,能够使程序员从复杂的编译连接过程中解脱出来。文中通过一些例子介绍使用 CMake 处理多源文件目录的方法、查并使用其他开发包的方法以及生成 debug 版和 release 版程序的方法。
CMake 简介
CMake 是一个跨平台的自动化建构系统,它使用一个名为 的文件来描述构建过程,可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。文件 需要手工编写,也可以通过编写脚本进行半自动的生成。CMake 提供了比autoconfig 更简洁的语法。在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
1.编写 。
2.执行命令 “cmake PATH” 或者 “ccmake PATH” 生成 Makefile ( PATH 是 所在
的目录 )。
3.使用 make 命令进行编译。
第一个工程
现假设我们的项目中只有一个源文件 main.cpp
清单 1 源文件 main.cpp
1 #include<iostream>
2
3 int main()
4 {
5 std::cout<<"Hello word!"<<std::endl;
6 return 0;
7 }
为了构建该项目,我们需要编写文件 并将其与 main.cpp 放在同一个目录下:
清单
1 PROJECT(main)
2 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
3 AUX_SOURCE_DIRECTORY(. DIR_SRCS)
4 ADD_EXECUTABLE(main ${DIR_SRCS})
< 的语法比较简单,由命令、注释和空格组成,其中命令是不区分大小写的,符号"#"后面的
内容被认为是注释。命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。例如对于清单2的 文件:第一行是一条命令,名称是 PROJECT ,参数是 main ,该命令表示项目的名
称是main 。第二行的命令限定了 CMake 的版本。第三行使用命令 AUX_SOURCE_DIRECTORY 将当前
目录中的源文件名称赋值给变量 DIR_SRCS 。 CMake 手册中对命令 AUX_SOURCE_DIRECTORY 的描述如下:
aux_source_directory(<dir> <variable>)
该命令会把参数 <dir> 中所有的源文件名称赋值给参数 <variable> 。第四行使用命令
ADD_EXECUTABLE 指示变量 DIR_SRCS 中的源文件需要编译成一个名称为 main 的可执行文件。完成了文件 的编写后需要使用 cmake 或 ccmake 命令生成Makefile 。 ccmake 与命令 cmake 的不同之处在于 ccmake 提供了一个图形化的操作界面。cmake 命令的执行方式如下: cmake [options] <path-to-source>
这里我们进入了 main.cpp 所在的目录后执行 “cmake .” 后就可以得到 Makefile 并使用 make 进
行编译,如下图所示。
图 1. camke 的运行结果
处理多源文件目录的方法
CMake 处理源代码分布在不同目录中的情况也十分简单。现假设我们的源代码分布情况如下:
图 2. 源代码分布情况
其中 src 目录下的文件要编译成一个链接库。
第一步,项目主目录中的
在目录 step2 中创建文件 。文件内容如下:
清单 3 目录 step2 中的
cmake如何使用1 PROJECT(main)
2 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
3 ADD_SUBDIRECTORY( src )
4 AUX_SOURCE_DIRECTORY(. DIR_SRCS)
5 ADD_EXECUTABLE(main ${DIR_SRCS} )
6 TARGET_LINK_LIBRARIES( main Test )
相对于清单2,该文件添加了下面的内容: 第三行,使用命令 ADD_SUBDIRECTORY 指明本项目包含一
个子目录 src 。第六行,使用命令 TARGET_LINK_LIBRARIES 指明可执行文件 main 需要连接一个名为Test的链接库。
第二步,子目录中的
在子目录 src 中创建 。文件内容如下:
清单 4. 目录 src 中的
1 AUX_SOURCE_DIRECTORY(. DIR_TEST1_SRCS)
2 ADD_LIBRARY ( Test ${DIR_TEST1_SRCS})
在该文件中使用命令 ADD_LIBRARY 将 src 目录中的源文件编译为共享库。
第三步,执行 cmake
至此我们完成了项目中所有 文件的编写,进入目录 step2 中依次执行命令 “cmake .” 和 “make” 得到结果如下:
图3. 处理多源文件目录时 cmake 的执行结果
在执行 cmake 的过程中,首先解析目录 step2 中的 ,当程序执行命令
ADD_SUBDIRECTORY( src ) 时进入目录 src 对其中的 进行解析。
在工程中查并使用其他程序库的方法
在开发软件的时候我们会用到一些函数库,这些函数库在不同的系统中安装的位置可能不同,编译的时候需要首先到这些软件包的头文件以及链接库所在的目录以便生成编译选项。例如一个需要使用博克利数据库项目,需要头文件db_cxx.h 和链接库 libdb_cxx.so ,现在该项目中有一个源代码文件 main.cp
p ,放在项目的根目录中。
第一步,程序库说明文件
在项目的根目录中创建目录 cmake/modules/ ,在 cmake/modules/ 下创建文件
ake ,内容如下:
清单 5. 文件 ake
01 MESSAGE(STATUS "Using ")
02
03 FIND_PATH(
04 LIBDB_CXX_INCLUDE_DIR
05 db_cxx.h
06 /usr/include/
07 /usr/local/include/
08 )
09
10 FIND_LIBRARY(
11 LIBDB_CXX_LIBRARIES NAMES db_cxx
12 PATHS /usr/lib/ /usr/local/lib/
13 )
文件 ake 的命名要符合规范: ake ,其中NAME 是函数库的名称。ake 的语法与 相同。这里使用了三个命令: MESSAGE ,
FIND_PATH 和 FIND_LIBRARY 。
•命令 MESSAGE 会将参数的内容输出到终端。
•命令 FIND_PATH 指明头文件查的路径,原型如下:
find_path(<VAR> name1 [path1 path2 ...]) 该命令在参数 path* 指示的目录中查文件 name1 并将查到的路径保存在变量 VAR 中。清单5第3-8行的意思是在 /usr/include/ 和
/usr/local/include/ 中查文件db_cxx.h ,并将 db_cxx.h 所在的路径保存在
LIBDB_CXX_INCLUDE_DIR 中。
•命令 FIND_LIBRARY 同 FIND_PATH 类似,用于查链接库并将结果保存在变量中。清单5第10-13行的意思是在目录 /usr/lib/ 和 /usr/local/lib/ 中寻名称为 db_cxx 的链接库,并将结果保存在
LIBDB_CXX_LIBRARIES 。
第二步, 项目的根目录中的
在项目的根目录中创建 :
清单 6. 可以查链接库的
01 PROJECT(main)
02 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
03 SET(CMAKE_SOURCE_DIR .)
04 SET(CMAKE_MODULE_PATH ${CMAKE_ROOT}/Modules ${CMAKE_SOURCE_DIR}/cmake/modules)
05 AUX_SOURCE_DIRECTORY(. DIR_SRCS)
06 ADD_EXECUTABLE(main ${DIR_SRCS})
07
08 FIND_PACKAGE( libdb_cxx REQUIRED)
09 MARK_AS_ADVANCED(
10 LIBDB_CXX_INCLUDE_DIR
11 LIBDB_CXX_LIBRARIES
12 )
13 IF (LIBDB_CXX_INCLUDE_DIR AND LIBDB_CXX_LIBRARIES)
14 MESSAGE(STATUS "Found libdb libraries")
15 INCLUDE_DIRECTORIES(${LIBDB_CXX_INCLUDE_DIR})
16 MESSAGE( ${LIBDB_CXX_LIBRARIES} )
17 TARGET_LINK_LIBRARIES(main ${LIBDB_CXX_LIBRARIES}
18 )
19 ENDIF (LIBDB_CXX_INCLUDE_DIR AND LIBDB_CXX_LIBRARIES)
在该文件中第4行表示到目录 ./cmake/modules 中查 ake ,8-19 行表示查
链接库和头文件的过程。第8行使用命令 FIND_PACKAGE 进行查,这条命令执行后 CMake 会到变
量 CMAKE_MODULE_PATH 指示的目录中查文件 ake 并执行。第13-19行是
条件判断语句,表示如果 LIBDB_CXX_INCLUDE_DIR 和 LIBDB_CXX_LIBRARIES 都已经被赋值,
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论