1.下载和安装
cmake:https://cmake.org/download/ (cmake需要配置环境变量)
cmake并不具备编译功能,需要下载MinGW编译器。
MinGW:https://sourceforge.net/projects/mingw-w64/files/mingw-w64/
cmake官方文档:https://cmake.org/cmake/help/latest/guide/tutorial/index.html#introduction
2.构建,运行与说明
windows环境手动演示过程:
1.先建文件夹demo
2.demo文件夹下创建src和build文件夹
3.src文件下创建main.cpp和CMakeList.txt
-demo
--src
----main.cpp
----CMakeList.txt
--build
命令行演示过程:
1.新建一个构建目录
mkdir build
2.进入该目录并配置项目
cd build
cmake ../src
如果cmake …/src报Cmake Error at CMakeList.txt原因是cmke和编译器版本不对
可以使用命令查看默认的编译器版本
cmake --help
3.如果不是使用默认的Generator,应该添加-G 选项:
cmake -G "MinGW Makefiles" ../src
4.构建
cmake --build.
会生成.exe文件
5.运行.exe文件
3.说明
- cmake命令(可以理解为函数名)不区分大小写,但是参数,变量区分大小写。
- 参数用空格或分号隔开
- 使用${VAR}引用变量
- 引号可加可不加,但如果字符串中有空格必须加
4.概念
- 目标文件(target):可执行文件(add_executable),库文件(add_library)
- 命令(cmake-command):下面要讲得函数
- 变量(cmake-variable):以CMAKE_开头的变量名
- 属性(cmake-properties):文件/文件夹都有各自的属性
5. 命令
官方文档:https://cmake.org/cmake/help/latest/command/project.html
1.cmake_minimum_required
设置最低cmake版本。
cmake_minimum_required(VERSION <min>)
举例:
cmake_minimum_required(VERSION 3.10)
2.project
设置项目名
project(<PROJECT-NAME> [<language-name>...])
project(<PROJECT-NAME>
[VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
[DESCRIPTION <project-description-string>]
[HOMEPAGE_URL <url-string>]
[LANGUAGES <language-name>...])
举例:
project(demo)
project(demo VERSION 1.0 LANGUAGES CXX)
项目名称PROJECT_NAME
可以通过如下命令查看:
message(${PROJECT_NAME}
3.add_executable
用指定的源文件为项目添加可执行文件
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])
例如:name和name.exe一个名字
也可以指定demo的来源文件,如下:
add_executable(demo main.cpp)
4.message
打印信息。
message([<mode>] "message text" ...)
# STATUS 前缀为--的信息
# SEND_ERROR 产生错误,跳过生成过程
# FATAL_ERROR 产生错误,终止运行
5.set
1.将变量设置为指定值。
set(<variable> <value>)
例如:
set(A 1)
message(${A})
2.设置C++标准
例如:C++ 11的标准
set(CMAKE_CXX_STANDARD 11)
3.设置输出文件位置
# 设置运行时目标文件(exe, dll)的输出位置
set(CMAKE_RUNTIME_OUTPUT_DIRCTORY
${CMAKE_BINARY_DIR}/bin)
#设置存档目标文件(lib,a)的输出位置
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
${CMAKE_BINARY_DIR}/lib)
6.option
定义一个开关
option(<variable> "<help_text>" [value])
# value的值为ON 或OFF,默认为OFF
# 命令行 -D<variable>=ON/OFF
例如:设置VERSION_ENABLE为ON
option(VERSION_ENABLE "output version" ON)
7.configure_file
将输入文件进行替换并生成输出文件。
configure_file(<input> <output>)
#输入文件中形如@VAR@ 或${VAR}的字符串会被替换为这些变量的当期值,如果未定义则替换为空字符串。
#其他规则见下
例如:
创建文件:config.h.in,内容如下:
#define PRO_VERSION_MAJOR @PRO_VERSION_MAJOR@
#define PRO_VERSION_MAJOR @PRO_VERSION_MINOR@
CMakeList.txt输入如下内容:
configure_file(config.h.in config.h)
需要注意:上述的话需要定义在定义项目版本之后。
在main.cpp中加入内容
#include "config.h"
int mian()
{
cout<<"version"<< PRO_VERSION_MAJOR<<"."<<PRO_VERSION_MAJOR <<endl;
return 0;
}
还需要添加target_link_librariy,重新build,会输出version:1.0。
#cmakefile VAR
//会被替换为以下两行之一,取决于VAR是否被设置
#define VAR ...
/* #undef VAR */
例如:
CMakeList.txt中添加:
option(DATE_ENABLE "output data" ON)
if(DATE_ENABLE)
SET(date "2022.7.12“)
endif()
config.h.in中添加:
#cmakedefine DATE "2022.7.12“
如果DATE_ENABLE设置为ON,输出的config.h文件中输出为#define VAR 2022.7.12
如果DATE_ENABLE设置为OFF,输出的config.h文件中输出为#undef VAR
8.add_definitions
add_definitions()相当于 C/C++ 里面的 #define 宏定义功能.
add_definitions(-DFOO -DBAR ...)
9.aux_source_directory
搜集所有在指定路径下的源文件的文件名,并将输出结果列表储存在指定的变量中。
aux_source_directory(<dir> <variable>)
例如:
aux_source_directory("./src/." SRX_LIST)
6.添加头文件搜索路径
1.include_directories
指定所有目标的头文件路径。(为所有目标添加路径)
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
#目录会被添加到当前文件的 INCLUDE_DIRECTORIES属性中
#当前文件的每一个目标文件的 INCLUDE_DIRECTORIES属性也会添加该目录
2.target_include_directories
指定目标的头文件路径。(为一个目标添加路径,推荐)
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
# 目标文件有INCLUDE_DIRECTORIES和 INTERFACE_INCLUDE_DIRECTORIES 两个属性
# INCLUDE_DIRECTORIES对内头文件目录
# INTERFACE_INCLUDE_DIRECTORIES 对外头文件目录
例如:
include_director(${PROJECT_BINARY_DIR})
target_include_directories(demo PRIVATE "${PROJECT_BINARY_DIR}")
为了VS中有.h文件
3.FILE
Reading
file(READ <filename> <out-var> [...])
file(STRINGS <filename> <out-var> [...])
file(<HASH> <filename> <out-var>)
file(TIMESTAMP <filename> <out-var> [...])
Writing
file({WRITE | APPEND} <filename> <content>...)
file({TOUCH | TOUCH_NOCREATE} [<file>...])
file(GENERATE OUTPUT <output-file> [...])
Filesystem
file({GLOB | GLOB_RECURSE} <out-var> [...] [<globbing-expr>...])
file(RENAME <oldname> <newname>)
file({REMOVE | REMOVE_RECURSE } [<files>...])
file(MAKE_DIRECTORY [<dir>...])
file({COPY | INSTALL} <file>... DESTINATION <dir> [...])
file(SIZE <filename> <out-var>)
file(READ_SYMLINK <linkname> <out-var>)
file(CREATE_LINK <original> <linkname> [...])
Path Conversion
file(RELATIVE_PATH <out-var> <directory> <file>)
file({TO_CMAKE_PATH | TO_NATIVE_PATH} <path> <out-var>)
Transfer
file(DOWNLOAD <url> <file> [...])
file(UPLOAD <file> <url> [...])
Locking
file(LOCK <path> [...])
产生一个匹配 的文件列表并将它存储到变量 中。文件名替代表达式和正则表达式相似,但更简单。如果 RELATIVE 标志位被设定,将返回指定路径的相对路径。结果将按字典顺序排序。
如果 CONFIGURE_DEPENDS 标志位被指定,CMake 将在编译时给主构建系统添加逻辑来检查目标,以重新运行 GLOB 标志的命令。如果任何输出被改变,CMake都将重新生成这个构建系统。
FILE(GLOB_RECURSE sources CONFIGURE_DEPENDS include/*.h)
4.target_sources
往可执行目标中添加源文件。
target_sources(<target>
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_sources(demo PUBLIC ${sources})
7.库的生成和链接
创建加减乘除的动态库。
1.src下calc目录,calc目录创建文件
addition.h
int add(int x,int y)
addition.cpp
int add(int x,int y)
{
return x + y;
}
subtract.h
int sub(int x, int y)
subtract.cpp
int sub(int x, int y)
{
return x - y;
}
calc中也要构建CMakeList.txt。
CMakeList.txt构建过程添加如上文件
整体目录如下:
-demo
--src
----main.cpp
----CMakeList.txt
----calc
--------addition.h
--------addition.cpp
------subtract.h
------subtract.cpp
--------CMakeList.txt
--build
1.add_subdirectory
添加源文件目录。
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL] [SYSTEM])
# binary_dir 指定编译结果存放的位置
例如:
src下的CMakeList.txt需要添加
add_subdirectory(calc);
2.add_library
用指定的原文生成库。
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[<source>...])
# STATIC 静态库
# SHARED 动态库
# 生成的库文件名为 lib<name>.txt
calc下的CMakeList.txt中,写入:
add_library(addition STATIC addition.cpp)
但这个时候还不可以使用,还需要链接库
3.target_link_libraries
为目标库链接。
target_link_libraries(<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
# item 可以是target名。绝对路径(必须保证文件存在)
例如:
src下的CMakeList.txt需要添加:
target_link_libraries(demo PUBLIC addition)
target_include_directories(demo PUBLIC
${PROJECT_BINARY_DIR}
${PROJECT_SOURCE_DIR}/calc
)
target_include_directories 需要添加头文件
整体文件图可见
cmake_minimum_required(VERSION 3.15)
project(demo)
FILE(GLOB_RECURSE sources CONFIGURE_DEPENDS include/*.h)
aux_source_directory("./src/." SRC_LIST)
add_library(demo STATIC ${SRC_LIST})
target_sources(demo PUBLIC ${sources})