CMake
一、 CMake简介
CMake是一个开源、跨平台的工具家族,旨在构建、测试和打包软件。CMake用于使用简单的平台和编译器独立的配置文件来控制软件编译过程,并生成可以在您选择的编译器环境中使用的本地makefile和工作区。该CMake工具套件是由Kitware创建的,以满足对开源项目(如ITK和VTK)的强大、跨平台构建环境的需求。
-----https://cmake.org/
二、CMake安装及命令
1、Linux下的CMake安装
使用cmake –version
命令后查看是否有相关信息,如果没有需要手动安装:
输入sudu apt install cmake
命令进行安装即可。
2、CMake常见命令解读
1、 project(name)
:指定项目名称name。在调用project命令指定当前工程名字的同时,cmake内部会为内置变量赋值
2、 cmake_minimum_required
:设定依赖的最小cmake版本号。
3、add_subdirectory
: 添加一个子目录并构建该子目录,子目录下应该包含CMakeLists.txt文件和代码文件。
4、find_path(<VAR> name1[path1 path2 …])
:该命令在參数path*指示的文件夹中查找文件name1并将查找到的路径保存在变量VAR中(当中使用”[…]”包含的项表示可忽略项,使用”…|…”切割的项表示仅仅能选择当中一项)。
5、find_library(${var} NAMES name1[name2 …] PATHS path1 [path2 …] PATH_SUFFIXES suffix1 [uffix2 …])
:搜索一个外部的链接库文件,并将结果的全部路径保存到var变量中
6、find_package(name)
:在指定的模块文件夹中搜索一个名为Find.cmake(比如。FindOSG.cmake)的CMake脚本模块文件,运行当中的内容。意图搜索到指定的外部依赖库头文件和库文件位置。
7、find_program
:搜索一个外部的可运行程序;
8、aux_source_directory(<dir><variable>)
:该命令会把參数dir中全部的源文件(不包含头文件)名称赋值给參数,但是aux_source_directory()也存在弊端,它会把指定目录下的所有源文件都加进来,可能会加入一些我们不需要的文件,此时我们可以使用set命令去新建变量来存放需要的源文件如set(SRCLIST a.c b.c)。
9、include(file)
:在当前文件里包含还有一个CMake脚本文件的内容,用来加载CMakeLists.txt文件,也用于加载提前定义的cmake模块。
10、 include_directories
:指定头文件的搜索路径,用来向project加入多个特定的头文件搜索路径。能够多次调用以设置多个路径,相当于指定gcc的-I參数;
11、link_directories
:加入非标准的共享库搜索路径,设置外部动态链接库或静态链接库的搜素路径,相当于gcc的-L參数;
12、link_libraries
:加入链接库;
13、add_executable
:编译可运行程序,指定编译,好像也能够加入.o文件;
14、add_definitions(-DMACRO1-DMACRO2 …)
:加入编译參数,加入-D预编译宏定义,能够一次加入多个;
15、 add_dependencies
:定义target依赖的其他target,确保在编译本target之前。其他的target已经被构建;
16、 add_library
:能够设置要生成的链接库为SHARED或者STATIC,还能够设置MODULE(插件。可动态调用,但不作为其他project的依赖);
17、add_custom_target(name COMMANDcmd1 [COMMAND cmd2 ..])
:加入一个名为name的编译文件夹,并指定一个或多个自己定义的命令cmd1,cmd2等;注意ADD_CUSTOM_COMMAND与这个命令的差别:前者是针对一个已有的子project进行自己定义编译规则的设置;后者则是建立一个新的自己定义的目标project;
18、target_link_libraries
:能够用来为target加入须要链接的共享库。指定project所用的依赖库,加入链接库,加入动态库或静态库,相当于指定-l參数;
19、message
:打印消息。在控制台或者对话框输出一行或多行调试信息;
20、set
:定义一个用户自己定义变量;
21、set_target_properties
:用来设置输出的名称,对于动态库,还能够用来指定动态库版本号和API版本号;
22、 configure_file(infile outfile)
:将文件infile拷贝到outfile的位置,同一时候运行当中变量的自己主动配置和更替;
23、install
:安装目标project到指定的文件夹,此命令用于定义安装规则,安装的内容能够包含目标二进制、动态库、静态库以及文件、文件夹、脚本等;
24、 option(${var} “text” value)
:向用户提供一个可选项。提示信息为text。初始值为value,并将终于的结果传递到var变量中。
25、 enable_testing
:用来控制Makefile是否构建test目标,涉及project全部文件夹;
26、exec_program
:用于在指定的文件夹运行某个程序;
27、execute_process
:运行一个或多个子进程。按指定的先后顺序运行一个或多个命令;
三、CMake常见内置变量及环境变量
1、CMAKE_C_COMPILER
:指定C编译器;
2、CMAKE_CXX_COMPILER
:指定C++编译器;
3、CMAKE_C_FLAGS
:指定编译C文件时的编译选项,如-g,也能够通过add_ditions加入编译选项;
4、CMAKE_CXX_FLAGS
:设置C++编译选项。
6、CMAKE_COMMAND
:也就是CMake可运行文件本身的全路径;
7、CMAKE_DEBUG_POSTFIX
:Debug版本号生成目标的后缀,通常能够设置为”d”字符;
8、CMAKE_GENERATOR
:编译器名称。比如”UnixMakefiles”, “Visual Studio 7”等;
9、CMAKE_INSTALL_PREFIX
:project安装文件夹。全部生成和调用所需的可运行程序。库文件,头文件都会安装到该路径下,Unix/Linux下默觉得/usr/local, windows下默觉得C:\Program Files;
10、CMAKE_MODULE_PATH
:设置搜索CMakeModules模块(.cmake)的额外路径。用来定义自己的cmake模块所在的路径;
11、CMAKE_CURRENT_SOURCE_DIR
:指的是当前处理的CMakeLists.txt所在的路径。
12、CMAKE_CURRENT_BINARY_DIR
:假设是in-source编译。则跟CMAKE_CURRENT_SOURCE_DIR
一致。假设是out-of-source,指的是target编译文件夹;
13、CMAKE_CURRENT_LIST_FILE
:输出调用这个变量的CMakeLists.txt的完整路径;
14、CMAKE_CURRENT_LIST_LINE
:输出这个变量所在的行;
15、CMAKE_INCLUDE_CURRENT_DIR
:自己主动加入CMAKE_CURRENT_BINARY_DIR
和CMAKE_CURRENT_SOURCE_DIR
到当前处理的CMakeLists.txt;
16、CMAKE_INCLUDE_DIRECTORIES_PROJECT_EFORE
:将project提供的头文件文件夹始终至于系统头文件文件夹的前面,当你定义的头文件确定跟系统发生冲突时能够提供一些帮助。
17、EXECUTABLE_OUTPUT_PATH
:指定可运行文件的存放路径。终于结果的存放文件夹;
18、LIBRARY_OUTPUT_PATH
:指定库文件存放路径,终于结果的存放文件夹;
19、BUILD_SHARED_LIBS
:指定编译成静态库还是动态库;
20、PROJECT_BINARY_DIR(CMAKE_BINARY_DIR)
:假设是内部构建(in-sourcebuild),指的就是project顶层文件夹;假设是外部构建(out-of-source build)。指的是project编译发生的文件夹;
21、PROJECT_NAME
:project名称。即使用PROJECT命令设置的名称;
22、PROJECT_SOURCE_DIR(CMAKE_SOURCE_DIR)
:project源码文件所在的文件夹。指的是project顶层文件夹;
23、CYGWIN
:标识当前系统是否为Cygwin;
24、MSVC
:标识当前系统是否使用MicrosoftVisual C。
25、UNIX
:标识当前系统是否为Unix系列(包含Linux、Cygwin和Apple);
26、WIN32
:标识当前系统是否为Windows及Win64;
四、实例讲解CMake构建过程
1、工程目录结构
在实际应用中,总是多个工程项目分别独立负责各自的模块功能,再通过相互调用来实现业务需求。在此将简单模拟实际应用场景,新建一个工程文件project,此工程负责输出变量的值。供其他模块或主程序(main函数)调用。在此将用main函数调用project工程的库文件。进而输出main函数中想要打印的值。
2、根目录下的CMakefileLists文件展示
1、 指定CMake的最小版本
2、 设置工程名称(此步骤cmake会生成内置变量)
3、 指定输出目录
4、 获取源文件,到变量SRC_LIST
5、 包含工程库的头文件
6、 查找静态库,并把库的路径存放在变量:TESTFUNC_LIB中
7、 由源文件生成可执行文件:main
8、 链接动态库
3、工程目录下的CMakeLists文件展示
1、 查找源文件并赋给变量SRC_LIST
2、 生成动态库,并命名,SHARED可表示生成动态库,STATIC则表示生成静态库
3、 设置生成库的最终名字,还可指定库的版本信息
4、 配置输出目录
4、总结
在build目录中执行cmake ..
即可生成对应的makefile文件及其他中间文件。再执行make命令即可生成动态库文件。库文件生成后,再根目录的build执行以上操作后即可在根目录的bin目录下生成main可执行文件。执行main程序即可输出打印值。
在上述过程中先通过执行目录下的cmake脚本生成中间文件,在进行手动make来执行makefile进行编译。其实这两个步骤可以通过在shell脚本中进行控制,最终只需要在终端下执行一次linux脚本即可。