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 2 3 4 5 命令行演示过程: 1.新建一个构建目录
mkdir build 1 2.进入该目录并配置项目
cd build cmake ../src 1 2 如果cmake …/src报Cmake Error at CMakeList.txt原因是cmke和编译器版本不对 可以使用命令查看默认的编译器版本
cmake --help 1 3.如果不是使用默认的Generator,应该添加-G 选项:
cmake -G "MinGW Makefiles" ../src 1 4.构建
cmake --build. 1 会生成.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 ) 1 举例:
cmake_minimum_required(VERSION 3.10) 1 2.project 设置项目名
project(...]) project([.[.[.]]]] [DESCRIPTION ] [HOMEPAGE_URL ] [LANGUAGES ...]) 1 2 3 4 5 6 举例:
project(demo) project(demo VERSION 1.0 LANGUAGES CXX) 1 2 项目名称PROJECT_NAME 可以通过如下命令查看:
message(${PROJECT_NAME} 1 3.add_executable 用指定的源文件为项目添加可执行文件
add_executable( [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] [source1] [source2 ...]) 1 2 3 例如:name和name.exe一个名字 也可以指定demo的来源文件,如下:
add_executable(demo main.cpp) 1 4.message 打印信息。
message([] "message text" ...)
STATUS 前缀为--的信息
SEND_ERROR 产生错误,跳过生成过程
FATAL_ERROR 产生错误,终止运行
1 2 3 4 5 5.set 1.将变量设置为指定值。
set() 1 例如:
set(A 1) message(${A}) 1 2 2.设置C++标准 例如:C++ 11的标准
set(CMAKE_CXX_STANDARD 11) 1 3.设置输出文件位置
设置运行时目标文件(exe, dll)的输出位置
set(CMAKE_RUNTIME_OUTPUT_DIRCTORY ${CMAKE_BINARY_DIR}/bin)
#设置存档目标文件(lib,a)的输出位置 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 1 2 3 4 5 6 7 6.option 定义一个开关
option( "<help_text>" [value])
value的值为ON 或OFF,默认为OFF
命令行 -D=ON/OFF
1 2 3 4 例如:设置VERSION_ENABLE为ON
option(VERSION_ENABLE "output version" ON) 1 7.configure_file 将输入文件进行替换并生成输出文件。
configure_file( )
#输入文件中形如@VAR@ 或${VAR}的字符串会被替换为这些变量的当期值,如果未定义则替换为空字符串。 #其他规则见下 1 2 3 4 例如: 创建文件:config.h.in,内容如下:
#define PRO_VERSION_MAJOR @PRO_VERSION_MAJOR@ #define PRO_VERSION_MAJOR @PRO_VERSION_MINOR@ 1 2 CMakeList.txt输入如下内容:
configure_file(config.h.in config.h) 1 需要注意:上述的话需要定义在定义项目版本之后。 在main.cpp中加入内容
#include "config.h" int mian() { cout<<"version"<< PRO_VERSION_MAJOR<<"."<<PRO_VERSION_MAJOR <<endl; return 0; } 1 2 3 4 5 6 还需要添加target_link_librariy,重新build,会输出version:1.0。
#cmakefile VAR //会被替换为以下两行之一,取决于VAR是否被设置 #define VAR ... /* #undef VAR */ 1 2 3 4 例如:
CMakeList.txt中添加:
option(DATE_ENABLE "output data" ON) if(DATE_ENABLE) SET(date "2022.7.12“) endif() 1 2 3 4 config.h.in中添加:
#cmakedefine DATE "2022.7.12“ 1 如果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 ...) 1 9.aux_source_directory 搜集所有在指定路径下的源文件的文件名,并将输出结果列表储存在指定的变量中。
aux_source_directory(
)
1 例如:
aux_source_directory("./src/." SRX_LIST) 1 6.添加头文件搜索路径 1.include_directories 指定所有目标的头文件路径。(为所有目标添加路径)
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
#目录会被添加到当前文件的 INCLUDE_DIRECTORIES属性中 #当前文件的每一个目标文件的 INCLUDE_DIRECTORIES属性也会添加该目录 1 2 3 4 2.target_include_directories 指定目标的头文件路径。(为一个目标添加路径,推荐)
target_include_directories( [SYSTEM] [AFTER|BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
目标文件有INCLUDE_DIRECTORIES和 INTERFACE_INCLUDE_DIRECTORIES 两个属性
INCLUDE_DIRECTORIES对内头文件目录
INTERFACE_INCLUDE_DIRECTORIES 对外头文件目录
1 2 3 4 5 6 7 例如:
include_director({PROJECT_BINARY_DIR}") 1 2 为了VS中有.h文件
3.FILE Reading file(READ ) file(TIMESTAMP [...])
Writing file({WRITE | APPEND} ...) file({TOUCH | TOUCH_NOCREATE} [...]) file(GENERATE OUTPUT [...])
Filesystem file({GLOB | GLOB_RECURSE} ...]) file(RENAME ) file({REMOVE | REMOVE_RECURSE } [...]) file(MAKE_DIRECTORY [
...])
file({COPY | INSTALL} ... DESTINATION ) file(READ_SYMLINK ) file(CREATE_LINK
Path Conversion file(RELATIVE_PATH ) file({TO_CMAKE_PATH | TO_NATIVE_PATH} )
Transfer file(DOWNLOAD [...])
Locking file(LOCK [...])
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 产生一个匹配 的文件列表并将它存储到变量 中。文件名替代表达式和正则表达式相似,但更简单。如果 RELATIVE 标志位被设定,将返回指定路径的相对路径。结果将按字典顺序排序。
如果 CONFIGURE_DEPENDS 标志位被指定,CMake 将在编译时给主构建系统添加逻辑来检查目标,以重新运行 GLOB 标志的命令。如果任何输出被改变,CMake都将重新生成这个构建系统。
FILE(GLOB_RECURSE sources CONFIGURE_DEPENDS include/*.h) 1 4.target_sources 往可执行目标中添加源文件。
target_sources( <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...]) 1 2 3 target_sources(demo PUBLIC ${sources}) 1 7.库的生成和链接 创建加减乘除的动态库。 1.src下calc目录,calc目录创建文件 addition.h
int add(int x,int y) 1 addition.cpp
int add(int x,int y) { return x + y; } 1 2 3 4 subtract.h
int sub(int x, int y) 1 subtract.cpp
int sub(int x, int y) { return x - y; } 1 2 3 4 calc中也要构建CMakeList.txt。 CMakeList.txt构建过程添加如上文件 整体目录如下:
-demo --src ----main.cpp ----CMakeList.txt ----calc --------addition.h --------addition.cpp ------subtract.h ------subtract.cpp --------CMakeList.txt --build 1 2 3 4 5 6 7 8 9 10 11 1.add_subdirectory 添加源文件目录。
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL] [SYSTEM])
binary_dir 指定编译结果存放的位置
1 2 3 例如: src下的CMakeList.txt需要添加
add_subdirectory(calc); 1 2.add_library 用指定的原文生成库。
add_library(...])
STATIC 静态库
SHARED 动态库
生成的库文件名为 lib.txt
1 2 3 4 5 6 7 calc下的CMakeList.txt中,写入:
add_library(addition STATIC addition.cpp) 1 但这个时候还不可以使用,还需要链接库
3.target_link_libraries 为目标库链接。
target_link_libraries(... [<PRIVATE|PUBLIC|INTERFACE> ...]...)
item 可以是target名。绝对路径(必须保证文件存在)
1 2 3 4 5 例如: src下的CMakeList.txt需要添加:
target_link_libraries(demo PUBLIC addition) target_include_directories(demo PUBLIC ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/calc ) 1 2 3 4 5 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})