前言

本人一个小项目就是采用CMake来进行构建的.可以参考参考.顺便点个star🌟.

本文主要记录📝本人学习CMake中对与C和C++使用的一些知识点.方便日后复习.如有错误地方还请指正.


介绍

CMake是个一个开源跨平台自动化建构系统,用来管理软件建置的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个库。 它用配置文件控制建构过程(build process)的方式和Unixmake相似,只是CMake的配置文件取名为CMakeLists.txt。CMake并不直接建构出最终的软件,而是产生标准的建构档(如Unix的Makefile或Windows Visual C++的projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是CMake和SCons等其他类似系统的区别之处。 CMake配置文件(CMakeLists.txt)可设置源代码或目标程序库的路径、产生适配器(wrapper)、还可以用任意的顺序建构可执行文件。CMake支持in-place建构(二进档和源代码在同一个目录树中)和out-of-place建构(二进档在别的目录里),因此可以很容易从同一个源代码目录树中建构出多个二进档。CMake也支持静态与动态程序库的建构。

“CMake”这个名字是”Cross platform Make”的缩写。虽然名字中含有”make”,但是CMake和Unix上常见的“make”系统是分开的,而且更为高端。 它可与原生建置环境结合使用,例如:make、ninja、苹果的Xcode与微软的Visual Studio。

安装&配置

官方地址下载对应系统和框架并安装即可.

Mac用户推荐:brew install cmake

安装完后,看一下版本号.

image-20220518173030976

确保不低于 3.22.4

Windows用户若提示找不到命令可能需要手动配置路径到PATH环境变量下.不过本人对Windows系统有很大意见,建议早日更换linux系统

image-20220518173152302

另外,我们需要确保系统内有C/C++的编译工具🔧(mac用户有Xcode就有C的工具🔧链了)

例如 在Linux下需安装gcc或clang等

因为CMake本身不带编译工具🔧.

知识点

语法

cmake_minimum_required(VERSION 3.10) 指定版本

project(armor) 工程名称

set(CMAKE_BUILD_TYPE RELEASE) 指定编译类型

include_directories(include) 添加头文件目录

file(GLOB SOURCE “src/*.cpp” “main.cpp”) 源文件

add_library(armor SHARED ${SOURCE}) 生成动态链接库

add_library(armor STATIC ${SOURCE}) 生成静态链接库

set(PROJECT_LINK_LIBS libarmor.so) 将库文件存到变量中

link_directories(/home/wenda/cmake/demo_4/build) 添加外部库的搜索路径

target_link_libraries(main ${PROJECT_LINK_LIBS}) 链接外部库文件

add_executable(main main.cpp) 将源文件生成可执行文件

示例Demo

命令cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release && cmake --build build --target all

直接拿我的一个推箱子小游戏项目CMakeLists.txt作为示例Demo吧~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
cmake_minimum_required(VERSION 3.22) #设置CMake的最低版本

project(PushBox
LANGUAGES C
VERSION 1.1.4
DESCRIPTION "免费,开源,推箱子小游戏.A Free, Open Source, PushBox Game."
HOMEPAGE_URL https://github.com/LanYunDev/PushBox
) #设置项目名称,语言类型,项目版本号,项目描述,项目主页。

if (PROJECT_BINARY_DIR STREQUAL PROJECT_SOURCE_DIR) #判断项目目录是否相同
message(WARNING "PROJECT_BINARY_DIR and PROJECT_SOURCE_DIR are the same. This is not recommended.") #输出警告信息
endif () #结束

if (NOT CMAKE_BUILD_TYPE) #判断是否有环境变量CMAKE_BUILD_TYPE
set(CMAKE_BUILD_TYPE Release) #如果没有,则设置为Release
endif () #结束

if (WIN32) #判断是否是Windows平台
add_definitions(-DNOMINMAX -D_USE_MATH_DEFINES) #在windows下,禁用min和max宏,并设置环境变量,防止C++编译器报错
endif () #结束

if (NOT MSVC) #判断是否MSVC编译器,不是则进入.
find_program(CCACHE_PROGRAM ccache) #查找ccache编译器.
if (CCACHE_PROGRAM) #如果有CCache编译器,则设置环境变量,能让编译带有缓存功能,提高编译速度,提高编译效率,提高编译稳定性.
message(STATUS "Found CCache: CCACHE_PROGRAM: ${CCACHE_PROGRAM}") #输出提示信息
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM}) #设置编译命令
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_PROGRAM}) #设置链接命令
endif () #结束
endif () #结束

# 若用户未指定BUILD_SHARED_LIBS,默认为OFF,即编译为STATIC静态库.设置为ON,则编译为SHARED动态库.不过推荐使用OBJECT对象库(此处未展开),虽然动态库更加稳定,更加安全.不过对Windows不友好.
if (NOT DEFINED BUILD_SHARED_LIBS) #判断是否定义变量BUILD_SHARED_LIBS
set(BUILD_SHARED_LIBS ON) #如果没有,则设置为ON
endif () #结束

set(CMAKE_C_STANDARD 23) #设置C语言标准为C 23
set(CMAKE_C_STANDARD_REQUIRED ON) #编译器必须支持C 23,否则出错
set(CMAKE_C_EXTENSIONS ON) #开启GCC编译器对C语言扩展,只支持GCC编译器,降低对(Windows平台的)MSVC的兼容性

find_package(Curses REQUIRED) #查找Curses库

include_directories(${CURSES_INCLUDE_DIR}) #添加Curses库的头文件目录

file(GLOB SRC_FILES CONFIGURE_DEPENDS
"${PROJECT_SOURCE_DIR}/src/*.cpp"
"${PROJECT_SOURCE_DIR}/src/*.c"
"${PROJECT_SOURCE_DIR}/src/*.h"
) #GLOB自动查找当前目录下指定拓展名的文件📃,实现批量添加源文件。添加CONFIGURE_DEPENDS选项,当添加新文件或源文件发生变化时,CMake会自动重新编译项目。

add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES}) #可执行文件名为PushBox,源文件为PushBox.c

if (CMAKE_SYSTEM_NAME MATCHES "Darwin") #判断是否是Mac平台
target_link_libraries(${CMAKE_PROJECT_NAME} ${CURSES_LIBRARY}) #链接Curses库
ELSE () #其他Linux平台
target_link_libraries(${CMAKE_PROJECT_NAME} -lncursesw) #链接Curses库
endif () #结束

关于静态库,动态库哪些东西懒得写了.关于构建也是.

有机会再补充内容和更新吧~