1、CMake概述
CMake允许开发者编写一种平添无关的CMakeList.txt文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需本地化Makefile和工程文件,如UNIX的Makefile或Windows的Visual Studio工程。从而做到“Write one,run everywhere”。一些使用CMake作为项目架构系统的知名开源项目有VTK\ITK\KDE\OpenCV\OSG等。
2、单个源文件
创建一个简单的c文件,演示CMake如何进行构建?
//main.c
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Hello world!\n");
return 0;
}
编写CMakeLists.txt
编写CMakeLists.txt文件,保存再main.c目录下。
#指定CMake最低版本
cmake_minimum_required(VERSION 2.8.9)
#项目名称
project(Hello)
#指定生成可执行文件信息
add_executable(hello main.c)
CMakeLists.txt的语法比较简单,由命令、注释和空格组成,其中命令不区分大小写。符号#后的内容被解释为注释信息,这跟Linux上的shell是一致的。命令由命令名称、小括号和参数构成,参数之间由空格进行间隔。
1、cmake_minimum_required:指定运行此配置文件所需的CMake的最低版本
2、project:参数值为Hello,表明该项目的名称为Hello
3、add_executable:将main.c的源文件编译成一个名称为Hello的可执行文件
编译项目
在当前目录执行cmake .,得到Makefile后执行make编译得到hello可执行文件
[root@localhost test02]# cmake .
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- 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
-- 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
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zxy/pcap/test/test02
[root@localhost test02]# ll
总用量 32
-rw-r--r--. 1 root root 12015 4月 11 15:19 CMakeCache.txt
drwxr-xr-x. 5 root root 232 4月 11 15:19 CMakeFiles
-rw-r--r--. 1 root root 1588 4月 11 15:19 cmake_install.cmake
-rw-r--r--. 1 root root 82 4月 11 15:18 CMakeLists.txt
-rw-r--r--. 1 root root 101 4月 11 15:17 main.c
-rw-r--r--. 1 root root 4642 4月 11 15:19 Makefile
[root@localhost test02]# make
Scanning dependencies of target hello
[100%] Building C object CMakeFiles/hello.dir/main.c.o
Linking C executable hello
[100%] Built target hello
[root@localhost test02]# ./hello
Hello world!
3、多个源文件
3.1、同一目录,多个源文件
新建print.h/print.c文件,使得这个工程变成如下形式:
../test03
├── main.c
├── print.c
└── print.h
可将CMakeLists.txt文件修改如下:
#指定CMake最低版本
cmake_minimum_required(VERSION 2.8.9)
#项目名称
project(Hello)
#查找当前目录下所有源文件,并保存到DIR_SRCS变量
aux_source_directory(. DIR_SRCS)
#指定生成可执行文件信息
add_executable(hello ${DIR_SRCS})
1、aux_source_directory:查找当前目录所有源文件,并将结果复制给DIR_SRCS
aux_source_directory(<dir> <variable>)
3.2、多个目录,多个源文件
现在进一步将print.h/print.c移动到print目录下,该工程变为如下形式:
.
├── CMakeLists.txt
├── main.c
└── print
├── CMakeLists.txt
├── print.c
└── print.h
对于这种情况,需要在根目录和print目录下各编写一个CMakeLists.txt文件。为了方便,我们将print目录下的文件编译为静态库再由main函数调用
根目录下CMakeLists.txt
#CMake最低版本
cmake_minimum_required(VERSION 2.8)
#项目信息
project(Hello)
#添加print子目录
add_subdirectory(print)
#指定目标文件
add_executable(hello main.c)
#添加链接库
target_link_libraries(hello print)
1、add_subdirectory:指明本项目包含一个子目录print,这样print目录下的CMakeLists.txt文件和源码也会处理
2、target_link_libraries:指明可执行文件hello需要连接一个名为print的链接库
print目录下CMakeLists.txt
#查找当前目录下源文件,并将结果保存在DIR_LIB_SRCS变量
aux_source_directory(. DIR_LIB_SRCS)
#生成连接库
add_library(print ${DIR_LIB_SRCS})
1、add_library:将指定目录下的源文件编译问静态库
生成过程如下:
[root@localhost test04]# cmake .
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- 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
-- 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
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zxy/pcap/test/test04
[root@localhost test04]# make
Scanning dependencies of target print
[ 50%] Building C object print/CMakeFiles/print.dir/print.c.o
Linking C static library libprint.a
[ 50%] Built target print
Scanning dependencies of target hello
[100%] Building C object CMakeFiles/hello.dir/main.c.o
Linking C executable hello
[100%] Built target hello
[root@localhost test04]# ./hello
Hello world
4、添加版本号
给项目添加和维护一个版本号是一个好习惯,这样有利于了解每个版本的维护情况,并及时了解当前使用版本是否过时
修改顶层CMakeLists.txt文件,再project命令后添加set命令,设置主版本号和副版本号;
根目录CMakeLists.txt文件
cmake_minimum_required(VERSION 2.8)
project(Hello)
#设置主版本号和副版本号
set(VERSION_MAJOR 1)
set(VERSION_MINOR 0)
#添加配置文件config.h
configure_file("${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_BINARY_DIR}/config.h")
#aux_source_directory(. DIR_SRCS)
add_subdirectory(print)
add_executable(hello main.c)
target_link_libraries(hello print)
添加configure_file命令添加一个配置文件config.h,这个文件由CMake从config.h.in生成;再config.h.in添加两个预定义宏
#define VERSION_MAJOR @VERSION_MAJOR@
#define VERSION_MINOR @VERSION_MINOR@
修改main.c函数,添加头文件config.h,并打印版本信息即可
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "config.h"
int main(int argc, char* argv[])
{
printf("Usage : %s version %d.%d\n", argv[0], VERSION_MAJOR, VERSION_MINOR);
print("Hello world\n");
return 0;
}
这样修改CMakeLists.txt文件中版本号,重新make即可
执行结果如下
[root@localhost test05]# cmake .
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- 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
-- 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
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zxy/pcap/test/test05
[root@localhost test05]# make
Scanning dependencies of target print
[ 50%] Building C object print/CMakeFiles/print.dir/print.c.o
Linking C static library libprint.a
[ 50%] Built target print
Scanning dependencies of target hello
[100%] Building C object CMakeFiles/hello.dir/main.c.o
Linking C executable hello
[100%] Built target hello
[root@localhost test05]# ./hello
Usage : ./hello version 1.0
Hello world