linux下CMake的简单介绍

Posted Jqivin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux下CMake的简单介绍相关的知识,希望对你有一定的参考价值。

一、CMake简介

  CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件。
特点:使用简单方便,可以跨平台使用,构建项目编译环境。比直接写Makefile文件简单,可以通过简单的CMake生成复杂的Makefile文件。
关于跨平台
Let’s assume you have some cross-platform project with C++ code shared along different platforms/IDE.Say you use visual studio on Windows,xcode on Mac and Makefile for Linux:
在这里插入图片描述
如果这时候我们工程中增加了一个bar.cpp文件,我们要对Makefile等三个文件进行修改,这就比较麻烦。
在这里插入图片描述
所以当我们使用CMake的时候,我们要先写一个CMake的配置文件CMakeLists.txt,执行cmake .之后在不同的平台就会自动的生成不同的工程文件,在Linux平台生成Makefile文件。这就减少了我们的工作量。
在这里插入图片描述
这时候如果我们添加了一个bar.cpp文件,只需要修改CMakeLists.txt就可以了。在这里插入图片描述

二、CMake的安装

Ubuntu上直接执行sudo apt install cmake,通过cmake -version查看版本。

jqw@jqw-virtual-machine:~/my_code/test6_10$ cmake -version
cmake version 3.16.3

CMake suite maintained and supported by Kitware (kitware.com/cmake).

三、CMake的语法特性的介绍

基本语法格式

    指令(参数1 参数2…)

  • 参数之间用空格或者分号隔开(不要使用逗号)

  • 指令不区分大小写,参数变量是区分大小写的

  • 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
    在这里插入图片描述

CMake常用的指令和变量

1. 常用的指令

[ ] 代表可选项

(1)cmake_minimum_required :指定CMake的最小版本要求

  • 语法:cmake_minimum_required(VERSION versionNumber [FATAL_ERROR])
# CMake最小版本要求为2.8.3
cmake_minimum_required(VERSION 2.8.3)

(2)project :自定义工程名称,并可以指定工程支持的语言

  • 语法:project(projectname [CXX] [C] [Java])
#  CMake指定工程名为HELLOWORLD
project(HELLOWORLD)

(3)set : 显式的定义变量

  • 语法:set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
# Cmake - 定义SRC变量,其值为max.cpp sum.cpp
set(SRC max.cpp sum.cpp)

(4)add_executable:生成可执行文件

  • 语法:add_executable (exename source1 source2 … source n)
# c 编译main.cpp,sum.c max.c生成可执行文件main
add_executable(main main.c sum.c max.c)
# same : g++ -o main main.c sum.c max.c

(5)include_directories: 向工程添加多个特定的头文件搜索路径 ,相当于指定g++编译器的-I参数,也相当于我们配置VScode时的includepath。

  • 语法:include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)
# 将/usr/include/myincludefolder 和 ./include 添加到头文件搜索路径
include_directories(/usr/include/myincludefolder ./include)

(6)link_directories:向工程添加多个特定的库文件搜索路径 —>相当于指定g++编译器的-L参数。

  • 语法:link_directories(dir1 dir2 …)
# 将/usr/lib/mylibfolder 和 ./lib 添加到库文件搜索路径
link_directories(/usr/lib/mylibfolder ./lib)

(7)add_library: 生成库文件

  • 语法:add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)
# 通过变量 SRC 生成 libhello.so 共享库
add_library(hello SHARED ${SRC})

(8)add_compile_options :添加编译参数

# 添加编译参数 -Wall -std=c++11
add_compile_options(-Wall -std=c++11 -O2)

(9)target_link_libraries: 为 target 添加需要链接的共享库 —>相同于指定g++编译器-l参数

  • 语法:target_link_libraries(target library1library2…)
# 将hello动态库文件链接到可执行文件main
target_link_libraries(main hello)

(10)aux_source_directory : 发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表

  • 语法:aux_source_directory(dir VARIABLE)
# 定义SRC变量,其值为当前目录下所有的源代码文件
aux_source_directory(. SRC)
# 编译SRC变量所代表的源代码文件,生成main可执行文件
add_executable(main ${SRC})

(11)add_subdirectory: 向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置

  • 语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
# 添加src子目录,src中需有一个CMakeLists.txt
add_subdirectory(src)

2.常用的变量

PROJECT_NAME : 通过 project() 指定项目名称
PROJECT_SOURCE_DIR: 工程的根目录
PROJECT_BINARY_DIR : 执行 cmake 命令的目录
CMAKE_CURRENT_SOURCE_DIR: 当前CMakeList.txt 文件所在的目录
CMAKE_CURRENT_BINARY_DIR : 编译目录,可使用 add subdirectory 来修改
EXECUTABLE_OUTPUT_PATH : 二进制可执行文件输出位置
LIBRARY_OUTPUT_PATH : 库文件输出位置
BUILD_SHARED_LIBS: 默认的库编译方式 ( shared 或 static ) ,默认为 static
CMAKE_C_FLAGS : 设置 C 编译选项
CMAKE_CXX_FLAGS : 设置 C++ 编译选项
CMAKE_CXX_FLAGS_DEBUG: 设置编译类型 Debug 时的编译选项
CMAKE_CXX_FLAGS_RELEASE: 设置编译类型 Release 时的编译选项
CMAKE_GENERATOR : 编译器名称
CMAKE_COMMAND : CMake 可执行文件本身的全路径
CMAKE_BUILD_TYPE : 工程编译生成的版本, Debug / Release

四、CMake编译工程

1.目录结构

项目主目录(顶层目录)要包含一个CMakeLists.txt文件。
有两种方式设置编译规则:
(1)包含源文件的子目录中包含CMakeLists.txt,主目录的CMakeLists.txt通过add_subdirectory指令添加子目录即可。
(2)包含源文件的子目录并没有CMakeLists.txt,子目录编译规则体现在主目录的CMakeLists.txt中。

2. 编译流程

在linux底下的编译流程如下:

  1. 编写CmakeLists.txt
  2. 执行cmake PATH 生成Makefile(PATH是顶层CMakeLists.txt所在的目录)
  3. 执行make命令

3. 两种构建方式

  1. 内部构建
    直接执行cmake . 在当前目录编译本目录的CMakeLists.txt,会生成大量的中间文件,和工程文件放在一块会显得杂乱无章。
  2. 外部构建(简洁)
    将编译产生的中间文件和源文件放到不同的目录中
    在这里插入图片描述
    外部构建:
    在这里插入图片描述
    在这里插入图片描述

五、一个简单工程的构建

1.目录结构

分别创建bin目录,build目录,include目录,src目录。

在这里插入图片描述

2.CMakeLists.txt

在这里插入图片描述

3.过程

使用外部构建的方式,进入build目录执行cmake … ,生成中间文件(Makefile文件等),然后执行make命令,生成可执行文件(bin目录下)。
在这里插入图片描述
在这里插入图片描述
可以看到已经生成了可执行文件和Makefile文件
在这里插入图片描述
执行结果:
在这里插入图片描述

六、静态库和动态库的编译控制

把上面的max和swap源文件直接生成静态库或者动态库,让外部程序直接进行链接使用,代码结构如下:
在这里插入图片描述
最外层的CMakeLists.txt是总控制的编译文件,内容如下:
在这里插入图片描述
src中的CMakeLists.txt是生成库文件的,内容如下:
在这里插入图片描述
test中的CMakeLists.txt是负责生成可执行文件并进行链接的,内容如下:
在这里插入图片描述
执行完cmake 和make命令后:
在这里插入图片描述

以上是关于linux下CMake的简单介绍的主要内容,如果未能解决你的问题,请参考以下文章

Linux下使用cmake的简单示例

cmake交叉编译的使用

CMake 简单介绍 图

Cmake命令之find_library介绍

使用 CMake 在面向 Linux 的 Windows 下跨平台构建

Windows下用CMake编译 libuv