CMake配置

135 阅读4分钟

CMake

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。


CMake 可以编译源代码、制作程序库、产生适配器(wrapper)、还可以用任意的顺序建构执行档。CMake 支持 in-place 建构(二进档和源代码在同一个目录树中)和 out-of-place 建构(二进档在别的目录里),因此可以很容易从同一个源代码目录树中建构出多个二进档。CMake 也支持静态与动态程式库的建构。

“CMake”这个名字是“cross platform make”的缩写。虽然名字中含有“make”,但是CMake和Unix上常见的“make”系统是分开的,而且更为高阶。


cmake

安装

cmake:cmake.org/download/

MinGW:sourceforge.net/projects/mi…

构建和运行

(1)创建一个demo目录,里面创建src(源代码文件)和bulid(放二进制文件的)

image-20220803003225799

(2)我们去src上写点内容(写了一个简单的程序)

image-20220803003701458

(3)同时再创建一个CMakeLists.txt写上

cmake_minimum_required(VERSION 3.10)
​
# set the project name
project(Tutorial)
​
# add the executable
add_executable(Tutorial tutorial.cxx)

image-20220803091926625

(4)去到build目录执行命令

cmake ../src   //因为我们的源代码目录是src

image-20220803092125762

可能会失败,这是因为编译器版本和默认版本不同导致的

image-20220803092949935

cmake  -G "MinGW Makefiles"  ..\src

重新生成文件

cmake --build  .     //.代表在当前文件夹下创建

simage-20220803095510690

输入名字,运行

image-20220803095643573

image-20220803135821154


www.bilibili.com/video/BV1nU…

命令

cmake_minimum_required

设置最低cmake版本。

cmake_minimum_required(VERSION <min>)
cmake_minimum_required(VERSION 3.10)

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_NAME 和 CMAKE_PROJECT_NAME 中
# PROJECT_SOURCE_DIR 等价于 <PROJECT-NAME>_SOURCE_DIR
# PROJECT_BINARY_DIR 等价于 <PROJECT-NAME>_BINARY_DIR
​
# 如果定义了版本号
# 版本号被保存在 PROJECT_VERSION 和 <PROJECT-NAME>_VERSION 中
# 主版本号被保存在 PROJECT_VERSION_MAJOR 和 <PROJECT-NAME>_VERSION_MAJOR 中
# 次版本号被保存在 PROJECT_VERSION_MINOR 和 <PROJECT-NAME>_VERSION_MINOR 中
project(Tutorial)
project(Tutorial C CXX)
project(Tutorial VERSION 2.3 LANGUAGES CXX)

add_executable

用指定的源文件为项目添加可执行文件。

add_executable(<name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               [source1] [source2 ...])
​
# <name>即生成可执行文件的名字(与项目名没有关系),在一个项目中必须唯一
# 如windows系统会生成<name>.exe文件
add_executable(Tutorial tutorial.cxx)

message

打印信息。

message([<mode>] "message text" ...)
​
# STATUS 前缀为--的信息
# SEND_ERROR 产生错误,跳过生成过程
# FATAL_ERROR 产生错误,终止运行

set

将变量设置为指定值。

set(<variable> <value>)

设置C++标准

set(CMAKE_CXX_STANDARD 11)

设置输出文件位置

# 设置运行时目标文件(exe、dll)的输出位置
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
​
# 设置存档目标文件(lib、a)的输出位置
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

option

定义一个开关。

option(<variable> "<help_text>" [value])
​
# value的值为 ONOFF ,默认为 OFF
# 命令行 -D<variable>=ON/OFF

configure_file

将输入文件进行替换并生成输出文件。

configure_file(<input> <output>)
​
# 输入文件中形如 @VAR@ 或 ${VAR} 的字符串会被替换为这些变量的当前值,如果未定义则被替换为空字符串
# 其他规则见下
#cmakedefine VAR ...
// 会被替换为以下两行之一,取决于VAR是否被设置
#define VAR ...
/* #undef VAR */

例:

// config.h.in文件:
#cmakedefine FOO_ENABLE
#cmakedefine FOO_STRING "@FOO_STRING@"
# CMakeLists.txt文件
option(FOO_ENABLE "Enable Foo" ON)
if(FOO_ENABLE)
    set(FOO_STRING "foo")
endif()
configure_file(foo.h.in foo.h)
// 如果FOO_ENABLE为ON,则生成以下内容的.h文件
#define FOO_ENABLE
#define FOO_STRING "foo"// 如果FOO_ENABLE为OFF,则生成以下内容的.h文件
/* #undef FOO_ENABLE */
/* #undef FOO_STRING */

include_directories

指定所有目标的头文件路径。

include_directories(dir1 [dir2 ...])
​
# 目录会被添加到当前文件的 INCLUDE_DIRECTORIES 属性中
# 当前文件的每一个目标文件的 INCLUDE_DIRECTORIES 属性也会添加该目录

target_include_directories

指定目标的头文件路径。

target_include_directories(<target>
                           <INTERFACE|PUBLIC|PRIVATE> [items1...]
                           [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
                           
# 目标文件有 INCLUDE_DIRECTORIES 和 INTERFACE_INCLUDE_DIRECTORIES 两个属性
# INCLUDE_DIRECTORIES 对内头文件目录
# INTERFACE_INCLUDE_DIRECTORIES 对外头文件目录
INCLUDE_DIRECTORIESINTERFACE_INCLUDE_DIRECTORIES
PRIVATE
INTERFACE
PUBLIC

参考:zhuanlan.zhihu.com/p/82244559

add_subdirectory

添加源文件目录。

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
​
# binary_dir 指定编译结果存放的位置

add_library

用指定的源文件生成库。

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [<source>...])
​
# STATIC 静态库
# SHARED 动态库
# 生成的库文件名为 lib<name>.xxx

target_link_libraries

为目标链接库。

target_link_libraries(<target>
                      <PRIVATE|PUBLIC|INTERFACE> <item>...
                     [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
​
# item 可以是target名、绝对路径(必须保证文件存在)

区分

# 头文件目录
include_directories()
target_include_directories()
​
# 链接时库目录
link_directories()
target_link_directories()
​
# 链接库
link_libraries()
target_link_libraries()
​
# 都推荐使用以target_开头的函数

安装

cmake代码

在对应目录的CMakeLists.txt中使用。

install(TARGETS <target> DESTINATION <dir>)
install(FILES <file> DESTINATION <dir>)
install(PROGRAMS <非目标文件的可执行程序> DESTINATION <dir>)   # 如脚本
install(DIRECTORY <dir> DESTINATION <dir>)  # 安装目录
install(TARGETS MathFunctions DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)
install(DIRECTORY doc/ DESTINATION doc)

命令行

cmake --install .                   # 安装到默认目录 CMAKE_INSTALL_PREFIX
cmake --install . --prefix <dir>    # 安装到指定目录