Skip to content

Latest commit

 

History

History
232 lines (152 loc) · 5.32 KB

04_modules.md

File metadata and controls

232 lines (152 loc) · 5.32 KB

Modules模块

文档:https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html

定义:

cmake中的modules类似于编程语言中的三方库。cmake的脚本有自己的语法,具有完成特定功能的脚本组合在一起就可以形成modules。需要用时引入即可。模块主要作用:提高开发效率

内置Modules:

  • CMake内置的module
  • 自己定制的module

相关命令:

# 显示可用的module模块列表
$ cmake --help-module-list

# 显示指定模块的帮助信息
$ cmake --help-module CMakePrintHelpers

常用内置模块

  • CMakePrintHelpers:方便打印参数
  • GNUInstallDirs:方便配置安装目录
  • check系列模块
    • CheckIncludeFile:检查头文件是否存在
    • CheckSymbolExists:检查Symbol是否存在
    • CheckCCompilerFlag:检查C编译器Flag
  • FetchContent:下载内容模块(下载源代码,文件)
  • CMakePackageConfigHelpers:包配置文件帮助模块
  • Find Modules:用来找依赖库,下节讲
  • CPack:打包模块,后面讲
  • CTest:测试模块
  • GoogleTest:Google测试模块

CMakePrintHelpers模块

提供了两个function/command

  • cmake_print_properties: 方便打印属性
  • cmake_print_variables: 方便打印变量

模块的使用步骤:

  1. 使用include()命令引入模块
  2. 使用模块中提供的function/command

CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(01CMakePrintHelpers)

set(CMAKE_BUILD_TYPE Debug)

message(STATUS "WARNING:CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE})

# 1.引入模块
include(CMakePrintHelpers)

# 2.使用模块中提供的function/command
cmake_print_variables(CMAKE_BUILD_TYPE)

add_executable(CMakePrintHelpers main.c)

GNUInstallDirs

CMAKE_INSTALL_<dir>

  • BINDIR:直接运行的可执行文件、脚本和符号链接的位置。默认为bin。
  • SBINDIR:与BINDIR相似,不过是针对有系统管理权限的情况。默认为sbin。
  • LIBDIR:库和编译文件的路径。根据主机/目标平台,默认设置为lib或其他(可能包括特定于体系结构的子目录)。
  • LIBEXECDIR:不直接由用户调用的可执行文件,但可以通过启动脚本或位于BINDIR中的符号链接的方式运行。默认为 libexec
  • INCLUDEDIR:头文件目录。默认为include。
  • DATAROOTDIR:只读与结构无关的数据点。为了避开DOCDIR的警告,通常不直接引用。
  • DATADIR:与结构无关的只读数据,如图像和其他资源。默认值与DATAROOTDIR相同,用于覆盖项目数据位置的首选 方法。
  • MANDIR:man格式文档的路径。默认为DATAROOTDIR/man。
  • DOCDIR:通用文档路径。默认值为DATAROOTDIR/doc/PROJECT_NAME(参见下面的注释,了解为什么依赖这个默认 值是不安全的)。

安装位置:

  • Winodws:C:\Program FilesC:\Program Files(x86)
  • Unix/Linux:/usr/local/opt

CMAKE_INSTALL_PREFIX变量默认值:Windows平台是C:\Program Files${PROJECT_NAME} ,基于Unix的平台上是/usr/local

CheckIncludeFile

检查头文件是否存在

  • CHECK_INCLUDE_FILE(<include> <variable> [<flags>])

CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(03CheckIncludeFile)

# 1.引入模块
include(CheckIncludeFile)
CHECK_INCLUDE_FILE(stdio.h HAVE_STDIO_H)

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/header.h.in
    ${CMAKE_CURRENT_SOURCE_DIR}/header.h
)

add_executable(CheckIncludeFile main.c)

header.h.in文件:

#cmakedefine HAVE_STDIO_H ${HAVE_STDIO_H}

main.c文件:

#include <stdlib.h>
#include <string.h>
#include "header.h"

#if HAVE_STDIO_H
#include <stdio.h>
#endif

int main(int argc, char* argv[]) {
#if HAVE_STDIO_H
    printf("have stdio.h\n");
#endif
    return 0;
}

CheckSymbolExists

检查Symbol是否存在

Symbol: 符号/标记 (function, variable, macro)

  • check_symbol_exists(<symbol> <files> <variable>)

CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(04CheckSymbolExists)

# 1.引入模块
include(CheckSymbolExists)

# Check for macro SEEK_SET
check_symbol_exists(SEEK_SET "stdio.h" HAVE_SEEK_SET)
# Check for function fopen
check_symbol_exists(fopen "stdio.h" HAVE_FOPEN)

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/header.h.in
    ${CMAKE_CURRENT_SOURCE_DIR}/header.h
)

add_executable(CheckSymbolExists main.c)

header.h.in文件:

#cmakedefine HAVE_SEEK_SET ${HAVE_SEEK_SET}
#cmakedefine HAVE_FOPEN ${HAVE_FOPEN}

main.c文件:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "header.h"

int main(int argc, char* argv[]) {
#if HAVE_FOPEN
    FILE* file = fopen("CMakeLists.txt", "r");
#if HAVE_SEEK_SET
    fseek(file, 0, SEEK_SET);
#endif
#endif

    return 0;
}

FetchContent

CMakePackageConfigHelpers

Modules are <script>.cmake files located in the CMAKE_MODULE_PATH.

Modules can be loaded with the include() command.

其它相关:

变量: CMAKE_MODULE_PATH

通过include()find_package()会去CMAKE_MODULE_PATH下找模块

CMakeDependentOption

设置一个option依赖于另一个option

include(CMakeDependentOption)

cmake_dependent_option(
    option_var "docs"
        ON "condition_expreesion" OFF
)

如果condition_expreesion是true, option_var是ON, 反之option_var是OFF