CMake快速入门教程

1.cmake简介

cmake是跨平台的makefile文件生成工具,是为了解决各个平台下面make工具不同造成的makefile文件格式不同的问题.也就是cmake是用来解决跨平台编译问题的.常见的还有autotool工具集,该工具集用于GNU软件协议的makefile文件生成,方便GNU包的编译和安装。

2.cmake文件编辑规则

  • 1)命令不区分大小写,但是变量区分大小写
  • 2)注释使用#符号
  • 3)命令如果有多个参数,互相之间用空格隔开

3.cmake保留变量

cmake里面有很多的预定义变量,是程序环境固有的,比如CUDA_NVCC_FLAGS,不同的变量有固定的作用,比如CUDA_NVCC_FLAGS是nvcc的参数list,变量可以使用set命令和list命令进行赋值和追加值,要注意的是变量可能可以有多个值,值与值之间用分号分开,可以使用set(var a b c)给var赋值a b c,还可以使用list命令给var追加删除插入值等,不同的变量有不同的值域,需要查阅手册

4.cmake变量引用

cmake里面变量的取值引用要使用${var}的形式,但是在赋值的时候是不需要的,和shell命令有点相似.

5.cmake指定Debug和Release版本

指定Debug和Release一共有三种方法:

1.使用ADD_COMPILE_OPTIONS()加入-g指定Debug版本.

2.使用SET( CMAKE_BUILD_TYPE Debug/Rrelease)指定Debug
在下面加入:

SET(CMAKE_CXX_FLAGS_DEBUG "\$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "\$ENV{CXXFLAGS} -O3 -Wall")

上面的设置C++编译选项,对于C语言,设置CMAKE_C_FLAGS_DEBUG、CMAKE_._FLAGS_RELEASE变量,一般来说最好两个都设置原因是CMake 中有一个变量 CMAKE_BUILD_TYPE ,可以的取值是 Debug Release等.当这个变量值为 Debug 的时候,CMake 会使用变量 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_C_FLAGS_DEBUG 中的字符串作为编译选项生成 Makefile

编译动态库or静态库时,最好通过修改CXXFLAGS和CFLAGS,以支持-fPIC,这个选项有时是默认开启,有时默认关闭,但为了以后的应用,库文件最好都使用-fPIC编译

3. 在使用cmake命令时加上-DCMAKE_BUILD_TYPE=Debug/Release

5.cmake指定生成文件

CUDA_ADD_LIBRARY()指明目标文件是库文件,CUDA_ADD_EXECUTABLE()指明生成的文件为可执行文件

6.配置模板

通常我们要在工程目录下面创建include、src文件夹,include文件夹里面存放头文件,src文件夹里面存放源代码,注意这时候的源代码里面包含头文件的路径应该是“../include/xx.h”,然后在工程根目录下面创建CMakeLists.txt文件,里面写入命令.在编译的时候为了不搞乱工程目录,在工程根目录下面创建build文件夹,在里面使用“cmake ..”命令创建CMakefile,再make即可。

#指定cmake最低版本号
cmake_minimum_required(VERSION 3.2)

#指定项目名称
PROJECT(Liner_Struct)

#指定头文件目录,不同目录用空格隔开,目录中有空格可用引号
#如果是相对路径,相对于CMakeLists.txt文件
INCLUDE_DIRECTORIES(include)

#指定源文件目录,DIR_SRCS值自定义变量,下面的命令对其进行了赋值
AUX_SOURCE_DIRECTORY(src DIR_SRCS)

#设置变量用于存放所有的编译文件,
#TEST_LINER_STRUCT是自定义变量,使用SET给其赋值
SET(TEST_LINER_STRUCT ${DIR_SRCS})

#增加编译选项
#判断是否为gcc编译器,如果是,增加编译选项
#c99是c语言的标准,常用的还有c++标准c++11
#下面的命令判断是否编译器是gcc
#message命令是输出信息,例如下面的输出“optional:-std=c99”
if(CMAKE_COMPILER_IS_GNUCXX)
    ADD_COMPILE_OPTIONS(-std=c99)
    message(STATUS "optional:-std=c99")
endif(CMAKE_COMPILER_IS_GNUCXX)

#配置生成文件
#${PROJECT_NAME}是cmake自带变量,其值和PROJECT()命令指定的一样
#${TEST_LINER_STRUCT}是自定义变量,上文赋值的
ADD_EXECUTABLE(${PROJECT_NAME} ${TEST_LINER_STRUCT})

7.if-else语句

cmake中的if-else语句

if(exp)
     cmdA
     cmdB
elseif(exp)
      cmdC
endif(exp)

最简单得到一个应用

if(ARM)
   #ARM平台
else()
  #非ARM平台 
endif()

使用cmake -DARM=1 .. 时编译ARM代码,使用cmake -DAMR=0 ..编译非ARM代码

8.与平台编译器的结合

8.1windows

在windows上运行cmake可以生成对应的VS的工程文件,然后使用相应的VS打开工程就可以进行编译。要注意的是如果使用VS2010及其以前的版本,C不支持C99,也就是变量的命名必须放在函数或者域的最前面,不能放在中间,特别麻烦。VS2015在安装后可能还需要打开VS,新建工程时选择VC++可能相关组件还没有安装,如果这时候使用cmake会提示找不到C、C++编译器(类似yuNo CMAKE_CXX_COMPILER could be found)的错误。安装了相关的组件后cmake即不会有错误。

8.2 为VS2015生成的项目

打开工程文件后可以看到有3个项目,其中只有一个和我们有直接关系,就是我们在CMakeLists.txt里面定义的PROJECT_NAME,剩下的两个是ALL_BUILD和ZERO_CHECK.

ZERO_CHECK
该目标会检查生成工程的 CMake 配置文件( CMakeLists.txt )是否更新。如更新,将运行 CMake 重新生成工程文件。

如果确信 CMakeLists.txt 不会被更新,或者希望手工运行 CMake 重新生成工程文件,可以在 CMakeLists.txt 配置文件中添加 set(CMAKE_SUPPRESS_REGENERATION FALSE) 命令, ZERO_CHECK 目标将不会生成。

ALL_BUILD
该目标会导致工程中所有项目被构建,类似 Visual Studio 的 Build All 或者 make 的 make all命令。

调试程序
在VS2015里面因为有三个项目,直接点击调试会出现找不到目标文件的错误,如果我们要调试我们的程序,则在右边的项目里面找到我们的项目右键选择调试才可以。

发表评论

电子邮件地址不会被公开。 必填项已用*标注