CMake教程---开始CMake的学习(第一课)

CMake教程版本号:3.16.3

英文原文链接: https://cmake.org/cmake/help/latest/guide/tutorial/index.html#id2

github示例代码 https://github.com/sxpsxp12/cmake-learning-exampes

开始

最基本的项目就是基于源码构建一个可执行程序。对于一个最简单的项目,CMakefile.txt三行就可以搞定。我们的教程就以此作为开始。首先需要在我们的项目根目录下创建一个CMakefile.txt文件。

cmake_minimum_required(VERSION 3.10)

# set the project name
project(helloworld)

# add the executable
add_executable(helloworld main.cpp)

注意:在上面的例子中,我们使用了小写的命令。但是CMake是支持大写,小写和大小写混合命令的。

添加版本号和配置的头文件

第一个特性就是我们将为我们的可执行程序和项目添加一个版本号,虽然可以在源代码中指定,但是在CMakefile.txt文件中配置是更加灵活的。

首先修改CMakefile.txt文件以支持版本号

cmake_minimum_required(VERSION 3.10)

#set the project name and version
project(helloworld VERSION 1.0)

然后,配置一个头文件,以便将版本号传给源文件

configure_file(version.h.in version.h)

因为配置文件会被写到二进制树中,所以我们必须添加那个目录,以便加入搜索头文件的目录列表中。在CMakefile.txt文件最后一行添加以下内容:

target_include_directories(helloworld PUBLIC
                           "${PROJECT_BINARY_DIR}"
                           )

使用你的IDE,在源码目录下创建version.h.in文件,并填加内容如下:

// the configured options and settings for Tutorial
#define Helloworld_VERSION_MAJOR @helloworld_VERSION_MAJOR@
#define Helloworld_VERSION_MINOR @helloworld_VERSION_MINOR@

当CMake配置了这个头文件时,@helloworld_VERSION_MAJOR@@helloworld_VERSION_MINOR@的值会被替换。

接下来,修改main.cpp,包含配置的头文件version.h

最终,我们就可以在源代码中打印出来版本号了。

std::cout << "major:" << int(Helloworld_VERSION_MAJOR)  << std::endl;
std::cout << "minor:" << int(Helloworld_VERSION_MINOR) << std::endl;

指定C++标准

我们需要在CMake文件中明确声明正确的标志。本3.16版本中,通过指定CMAKE_CXX_STANDARD变量为11,且CMAKE_CXX_STANDARD_REQUIRED变量为True。

cmake_minimum_required(VERSION 3.10)

# set the project name and version
project(helloworld VERSION 1.0)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

构建项目

项目目录树tree

.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── helloworld
│   ├── Makefile
├── CMakeLists.txt
└── main.cpp

3 directories, 7 files

在build目录下,运行cmake

cmake ..

执行完构建命令后,会生成三个文件CMakeCache.txt、Makefile、cmake_install.cmake和一个文件夹CMakeFiles,然后执行make

make

执行完make,即可看到二进制可执行程序helloworld

./helloworld

总结

本节我们学习到的CMake命令及其含义如下:

cmake_minimum_required

所属:脚本指令,总是可用的

配置这个项目所需要的cmake最小版本号

cmake_minimum_required(VERSION <min>[...<max>] [FATAL_ERROR])

和可选的都是major.minor[.patch[.tweak]]格式的CMake版本号,...是文本字符串。

如果cmake的版本号低于,会停止处理项目并报告一个错误。可选的如果指定了,必须大于等于。3.12之前的版本对于...的处理结果是,...<max>部分会被忽略,只保留3.12之前版本的特性。

注意 cmake_minimum_required的调用必须在project()命令之前。

project

所属:项目命令,只能用于CMake项目

配置项目的名字

project(<PROJECT-NAME> [<language-name>...])
project(<PROJECT-NAME>
        [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
        [DESCRIPTION <project-description-string>]
        [HOMEPAGE_URL <url-string>]
        [LANGUAGES <language-name>...])

配置项目的名字,并且将项目名存储在CMake变量PROJECT_NAME,当根目录的CMakefile.txt调用后,会存储在CMake变量CMAKE_PROJECT_NAME中。

命令参数中的关键字如果没有配置,对应的CMake变量会默认设置为空字符串。

  • VERSION

    • 可选
    • 非负整数,并且会设置对应的变量
    PROJECT_VERSION, <PROJECT-NAME>_VERSION
    
    PROJECT_VERSION_MAJOR, <PROJECT-NAME>_VERSION_MAJOR
    
    PROJECT_VERSION_MINOR, <PROJECT-NAME>_VERSION_MINOR
    
    PROJECT_VERSION_PATCH, <PROJECT-NAME>_VERSION_PATCH
    
    PROJECT_VERSION_TWEAK, <PROJECT-NAME>_VERSION_TWEAK.
    
    • 项目根目录的CMakefile.txt调用时,会存储到CMAKE_PROJECT_NAME
  • DESCRIPTION

    • 可选
    • 对应的变量
    PROJECT_DESCRIPTION, <PROJECT-NAME>_DESCRIPTION
    
    • 描述信息建议相对简短的字符串,通常几句话来描述。
    • 项目根目录的CMakefile.txt调用时,会存储到CMAKE_PROJECT_DESCRIPTION
  • HOEMPAGE_URL

    • 可选
    • 对应的变量
    PROJECT_HOMEPAGE_URL, <PROJECT-NAME>_HOMEPAGE_URL
    
    • 是项目主页的URL
    • 项目根目录的CMakefile.txt调用时,会存储到CMAKE_PROJECT_HOMEPAGE_URL
  • LANGUAGE

    • 可选
    • 标识编程语言,如果没有配置,默认是C和CXX。指定该关键字为NONE,或者LANGUAGE关键字但是没有声明语言,会禁用所有语言。可填:C,CXX,OBJC,OBJCXX,Fortran,ASM。
    • 如果启用ASM,请最后列出它,以便CMake可以检查其他语言(例如C)的编译器是否也可以进行汇编

add_executable

所属:项目命令,只能用于CMake项目

使用指定的源文件将可执行文件添加到项目中。

add_executable(<name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               [source1] [source2 ...])

根据列举的源文件列表来构建可执行程序(如果之后使用target_source添加源文件,那么此处可以省略)。在项目中必须是全局唯一的。

关键字 [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL]如果配置了,那么会为二进制可执行程序关联对应的属性。具体描述可查看 https://cmake.org/cmake/help/latest/command/add_executable.html

configure_file

所属:脚本指令,总是可用的

拷贝输入文件到另外一个文件中,并修改其内容

configure_file(<input> <output>
               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])

对应的值表示为@VAR@或者${VAR},每个变量引用都会使用当前变量的值进行替换,比如:

# cmakedefine VAR ...
会被替换成

#define VAR ...
或者
/* #undef VAR */

依赖于CMake是否在if()中为VAR配置了值。#cmakedefine01形式的输入文件,将会被替换成#define VAR 1或者#define VAR 0。

相关例子可以查看: https://cmake.org/cmake/help/latest/command/configure_file.html

对于配置的头文件,可以使用以下命令来指定头文件目录,以便源文件可以使用该头文件

include_directories(${CMAKE_CURRENT_BINARY_DIR})

target_include_directories

所属:项目命令,只能用于CMake项目

为可执行程序提供头文件目录

target_include_directories(<target> [SYSTEM] [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

当编译可执行程序时使用,来制定头文件目录,必须是命令 add_executable() or add_library()创建的,不能是一个别名。

[BEFORE]关键字配置后,后面的参数会作为对应属性的前缀。

INTERFACE PRIVATE PUBLIC关键字会指定接下来参数的作用域。
PRIVATE PUBLIC项会暴露给INCLUDE_DIRECTORIES的属性。PUBLIC和INTERFACE项会暴露给INTERFACE_INCLUDE_DIRECTORIES的属性。剩下的参数指定头文件的目录。

指定头文件的目录可以是绝对路径,也可以是相对路径,多次给调用该指令,会按照顺序追加到可执行对象中。

其他信息可参照: https://cmake.org/cmake/help/latest/command/target_include_directories.html

set

所属:脚本指令,总是可用的

将普通变量,缓冲变量,环境变量设置为某个值。

设置普通变量

set(<variable> <value>... [PARENT_SCOPE])

设置缓冲变量

set(<variable> <value>... CACHE <type> <docstring> [FORCE])

设置环境变量

set(ENV{<variable>} [<value>])

更多信息请查看: https://cmake.org/cmake/help/latest/command/set.html


欢迎各位大佬右侧点赞、关注、打赏,我们再会。。。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章