CMake入门学习

  1. 简介
    1. 什么是CMake,解决了什么问题?

CMake的官方定义:CMake是一个开源的跨平台自动化构建系统,用来管理软件建制的程序,并不依赖于某个特定编译器。CMake并不直接构建出最终的软件,而是产生标准的建构档(如Unix的Makefile或Windows Visual C++的projects/workspaces),然后再依一般的构建方式使用。它允许开开发者编写一种平台无关的CMakeList.txt文件来定制整个变异流程,然后再更具目标用户的平台进一步生成所需的本地化Makefile和工程文件,如Unix的Makefile或Windows的Visual Studio工程。从而做到一次编码,然后在任何平台编译运行。总结为一句话就是,CMake解决了软件跨平台编译的问题。

  1. 脚本编写
    1. 语法说明

CMake的语法比较简单,由命令、注释和空格组成,其中命令是不区分大小写的。符号#后面的内容被认为是注释。命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。

1、命令不区分大小写,而参数和变量是区分大小写的;

2、使用“#”表示代码注释;

3、使用${}表示引用变量的值;

4、使用set(变量名称 变量值)来自定义变量。

    1. 基本命令

本文只介绍CMake常用命令,如果不能满足读者的需要,可以参见官网,https://cmake.org/cmake/help/v3.7/manual/cmake-commands.7.html。

1、CMake最低版本号要求

cmake_minimum_required(VERSION 3.10)2、语法说明

2、指定项目名称

project(myProject)

3、查找当前目录下的所有源文件并将名称保存到DIR_SRCS变量,注意“.”和DIR_SRCS之间有空格

aux_source_directory(. DIR_SRCS)

4、生成可执行文件

add_executable(myProject ${DIR_SRCS})

5、将若干库链接到目标库文件

target_link_libraries(myProject common)  #链接common库,默认优先链接动态库,common可以包含库名称的路径,也可以仅仅是库名称

target_link_libraries(myProject libcommon.a)  #显示指定链接静态库

target_link_libraries(myProject libcommon.so)  #显示指定链接动态库

target_link_libraries(myProject lib1 lib2 lib3 …)   #链接的顺序应当符合GCC的链接顺序规则,被链接的库放在依赖它的库的后面,即如果上面的命令中,lib1依赖于lib2,lib2又依赖于lib3,则上述命令中必须严格按照lib1 lib2 lib3的顺序排列,否则会报错。也可以自定义链接选项,比如针对lib1使用-WL选项:target_link_libraries(myProject lib1 –WL, lib2 lib3 …)。

6、生成静态链接库/动态链接库

add_library(myProject [SHARED|STATIC] source1 source2 … sourceN)

add_library(myProject SHARED ${LIBMYPROJECT_SRC})  #生成动态链接库

add_library(myProject STATIC ${LIBMYPROJECT_SRC})  #生成静态链接库

7、设置依赖库的头文件位置,相当于G++命令中的-I选项的作用,可以使用相对或绝对路径,也可以使用自定义的变量值,其中相对路径是相对于当前源目录:

include_directories(${INC_DIR})  #INC_DIR保存了头文件的路径信息

8、添加需要链接的库文件目录,相当于G++命令中的-L选项的作用。

link_directories(${LINK_DIR}) # LINK_DIR保存了库文件的路径信息

9、添加需要链接的库文件

link_libraries(library1 library2 … liararyN)

10、设置全局变量

#设置可执行文件的输出路径

set(EXECUTABLE_OUTPUT_PATH [output_path])

#设置库文件的输出路径

set(LIBRARY_OUTPUT_PATH [output_path])

#设置C++编译参数

set(CMAKE_CXX_FLAGS “-Wall std=c++11”)

#设置源文件集合

set(SOURCES_FILES main.cpp test.cpp …)

#设置编译类型:Debug或者Release。Debug版本会生成相关的调试信息,可以使用GDB进行调试;Release不会生成相关的调试信息。

set(CMAKE_BUILD_TYPE DEBUG)

#设置编译器类型

set(CMAKE_C_FLAGS_DEBUG “-g -Wall”)

#启用特定C++标准,下面两条语句一般一起使用

set(CMAKE_CXX_STANDARD 11)

set(CMAKE_CXX_STANDARD_REQUIRED True)

11、如果当前目录下还包含子目录时,可以使用add_subdirectory语句,但是子目录中也需要包含有CMakeLists.txt文件

#sub_dir指定包含CMakeLists.txt和源文件的子目录位置,可以是相对路径

#binary_dir是输出路径,一般可以不指定

add_subdirectory(sub_dir [binary_dir])

12、文件操作命令

#将message写入filename文件中,会覆盖文件原有内容

file(WRITE filename “message”)

#将message写入filename文件中,会追加在文件末尾

file(APPEND filename “message”)

#重命名文件

file(RENAME )

#删除文件,相当于rm命令

file(REMOVE [file1 file2 …])

#创建目录

file(MAKE_DIRECTORY [dir1 dir2 …])

#该命令把该文件夹及所有子文件夹的所有后缀为.cpp的文件路径,全部放入SRC_LIST变量中,其它命令类似

file(GLOB_RESOURCE SRC_LIST “*.cpp”)

file(GLOB_RESOURCE HEARDERS “*.h”)

file(GLOB_RESOURCE FORMS “*.ui”)

file(GLOB_RESOURCE RESOURCES “*.qrc”)

13、查找库所在目录,并将查找到的路径放入到变量中

#cmake会在路径”/usr/lib”和”/usr/local/lib”中查找rt库,如果路径中存在rt库,则路径信息会被保存在变量RUNTIME_LIB中,否则被赋值为NO_DEFAULT_PATH

find_library(RUNTIME_LIB rt /usr/lib /usr/local/lib NO_DEFAULT_PATH)

14、定义目标依赖的其他目标,确保在编译本目标之前,其他目标已经被构建

add_dependencies(target-name depend-target1 depend-target2 …)

15、打印CMake脚本运行过程中的信息

message(STATUS “This is message”)  #将“This is message”打印到标准输出

    1. cmake常用变量说明

1、CMAKE_BINARY_DIR、PROJECT_BINARY_DIR、_BINARY_DIR

这三个变量指代的内容是一致的,如果是 in source 编译,指得就是工程顶层目录,如果是 out-of-source 编译,指的是工程编译发生的目录。PROJECT_BINARY_DIR 跟其他指令稍有区别, 目前可暂时理解为他们是一致的。

2、CMAKE_SOURCE_DIR、PROJECT_SOURCE_DIR、_SOURCE_DIR

这三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录。也就是在 in source 编译时,他跟 CMAKE_BINARY_DIR 等变量一致。PROJECT_SOURCE_DIR 跟其他指令稍有区别,目前可暂时理解为他们是一致的。

3、CMAKE_CURRENT_SOURCE_DIR

指的是当前处理的 CMakeLists.txt 所在的路径。

4、CMAKE_CURRRENT_BINARY_DIR

如果是 in-source 编译,它跟 CMAKE_CURRENT_SOURCE_DIR 一致,如果是 out-of-source 编译,他指的是 target 编译目录。使用我们上面提到的 ADD_SUBDIRECTORY(src bin)可以更改这个变量的值。使用 SET(EXECUTABLE_OUTPUT_PATH <新路径>)并不会对这个变量造成影响,它仅仅修改了最终目标文件存放的路径。

5、CMAKE_CURRENT_LIST_FILE

输出调用这个变量的 CMakeLists.txt 的完整路径。

6、CMAKE_CURRENT_LIST_LINE

输出这个变量所在的行。

7、CMAKE_MODULE_PATH

这个变量用来定义自己的 cmake 模块所在的路径。如果你的工程比较复杂,有可能会自己编写一些 cmake 模块,这些 cmake 模块是随你的工程发布的,为了让 cmake 在处理CMakeLists.txt 时找到这些模块,你需要通过 SET 指令,将自己的 cmake 模块路径设置一下。比如SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),这时候你就可以通过 INCLUDE 指令来调用自己的模块了。

8、EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH

分别用来重新定义最终结果的存放目录,前面我们已经提到了这两个变量。

9、PROJECT_NAME

返回通过 PROJECT 指令定义的项目名称。

  1. 工程实践
    1. 环境搭建:windows环境搭建和linux环境搭建

首先下载CMake安装包,官方下载路径:https://cmake.org/download/,找到本地系统对应的安装包并下载。

1、windows系统CMake环境搭建

可以参考该链接:https://jingyan.baidu.com/article/6d704a1352dbb728db51ca8e.html,这里不在赘述。

2、linux系统CMake环境搭建

将下载的linux版本的压缩包解压(安装前保证GCC编译器已经正确安装),在控制台进入CMake工具目录,然后一次输入一下三个命令进行安装:#./bootstrap#gmake#make install,安装完成后即可在控制台中直接使用CMake命令测试,检测是否安装成功。

环境搭建详细步骤参考:https://blog.csdn.net/liuguichenglove/article/details/84196271

    1. 利用VideoSDK源码来创建Windows系统的VideoSDK工程

1、文件目录结构

├── CMakeLists.txt

├── public

│  └── include

    │  └── *.h

│  └── lib

│  └── *.lib

└── src

    ├── b.c

    └── main.c

2、编写CMakeLists.txt

接下来编写CMakeLists.txt文件,该文件放在和src,public的同级目录下,public目录下又包含include(存放头文件)文件夹和lib(存放库文件)文件夹,实际放哪里都可以,只要里面编写的路径能够正确指向就好了。CMakeLists.txt如下所示:

#1、cmake version,指定cmake最低版本

cmake_minimum_required(VERSION 3.10)

#2、指定项目名称,一般和项目的文件名称对应

project(VideoSDK)

#3、设置源文件目录,下面这条语句的意思是将src文件夹中所有源文件保存到变量DIR_SRCS,其中src是相对路径,相对CMakeLists.txt的文件路径。

aux_source_directory(src DIR_SRCS)

#4、设置c++11标准

set(CMAKE_CXX_STANDARD 11)

set(CMAKE_CXX_STANDARD_REQUIRED Ture)

#5、设置环境变量,将头文件路径保存到INC_DIR变量,将库文件所在路径保存到变量LINK_DIR

set(INC_DIR "${CMAKE_SOURCE_DIR}/public/include")

set(LINK_DIR "${CMAKE_SOURCE_DIR}/public/lib")

#6、包含头文件路径

include_directories(${INC_DIR})

#7、附加库目录

link_directories(${LINK_DIR})

#8、添加工程依赖的三方库,由于库文件太多,不一一列出。AnalyzeData.lib等文件存放在lib文件夹中。

link_libraries(AnalyzeData.lib AudioIntercom.lib CrashAPI.lib … )

#9、生成动态链接库,该语句表示工程编译后生成的不是可执行文件,而是动态链接库。若要生成可执行文件,可使用add_executable代替该语句。

add_library(VideoSDK SHARED ${DIR_SRCS})

#10、dd link library,添加生成动态库需要依赖的三方库。 由于依赖的三方库文件太多,不一一列出。

target_link_libraries(VideoSDK AnalyzeData AudioIntercom CrashAPI … )

3、生成工程文件

打开CMake软件,如图1所示

CMake入门学习_第1张图片

图1 CMake软件界面

如上图所示:

(1)选择源码路径,2.1中所说明的文件路径结构就存放在E:/CMakeProject/VideoSDKTest/VideoSDK 路径中。

(2)选择在VideoSDK的同级目录下创建一个名为build的文件夹,把build文件夹的路径加到图1的红框2中。

(3)点击Configure按钮,弹出图1中的右侧对话框,该对话框提示选择编译器版本,选择自己对应的VS版本就行了。

(4)点击finish,需要等待一段时间。

(5)再次点击Configure按钮。

(6)点击Generate。build文件夹下可以看到VideoSDK.sln工程,如图2所示。

CMake入门学习_第2张图片

图2 生成的VideoSDK工程

  1. 总结

本文介绍了什么是CMake,CMake解决了什么问题,CMake常用的命令,如何编写CMakeLists.txt,以及CMake在Windows系统上如何使用。目前只是完成了在Windows系统上利用CMake和源码来创建工程,后续还会总结如何在linux系统上使用CMake和源码来创建工程并实现编译,以及CMake在linux系统上使用的注意事项。

你可能感兴趣的:(CMake入门学习)