当前位置: 首页 > news >正文

CMake 开发者手册

CMake 开发者手册

  • CMake 开发者手册
    • 一、介绍
    • 二、cmake 访问 Windows 注册表
      • 2.1 cmake 查询 Windows 注册表
      • 2.2 cmake 使用 Windows 注册表查找
    • 3. find_package 查找模块
      • 3.1 cmake 查找模块的示例用法
      • 3.2 标准变量名称
      • 3.3 find_package 一个简单的查找模块示例
  • 六、其他文章推荐

CMake 开发者手册

一、介绍

本手册供开发者参考,适用于处理 cmake-language(7) 代码的开发者,无论是编写自己的模块、创建自己的构建系统,还是参与 CMake 本身的开发。

二、cmake 访问 Windows 注册表

CMake 提供了一些功能以在 Windows 平台上访问注册表。

2.1 cmake 查询 Windows 注册表

从 CMake 3.24 版本开始,cmake_host_system_information() 命令允许查询本地计算机上的注册表。有关更多信息,请参见 查询 Windows 注册表。

2.2 cmake 使用 Windows 注册表查找

同样在 CMake 3.24 版本中,find_file()find_library()find_path()find_program()find_package() 命令的 HINTSPATHS 选项允许在 Windows 平台上查询注册表。

使用 BNF 语法,注册表查询的正式语法如下:

registry_query: '[' sep_definition? root_key : ((key_separator sub_key)? (value_separator value_name)?)? ']'
sep_definition: '{' value_separator '}'
root_key: 'HKLM' | 'HKEY_LOCAL_MACHINE' | 'HKCU' | 'HKEY_CURRENT_USER' | 'HKCR' | 'HKEY_CLASSES_ROOT' | 'HKCC' | 'HKEY_CURRENT_CONFIG' | 'HKU' | 'HKEY_USERS'
sub_key: element (key_separator element)*
key_separator: '/' | '\'
value_separator: element | ';'
value_name: element | '(default)'
element: character+
character: <任何字符,除 key_separator 和 value_separator>

sep_definition 可选项允许指定用于分隔 sub_keyvalue_name 的字符串。如果未指定,则使用字符 ;。可以在路径中指定多个 registry_query 项。

例如使用默认分隔符:

find_file(... PATHS "/root/[HKLM/Stuff;InstallDir]/lib[HKLM\\\\Stuff;Architecture]")

指定不同分隔符的例子:

find_library(... HINTS "/root/[{|}HKCU/Stuff|InstallDir]/lib[{@@}HKCU\\\\Stuff@@Architecture]")

如果未指定 value_name 项或其名称为 (default),将返回默认值的内容(如果存在)。支持的 value_name 类型包括:

  • REG_SZ
  • REG_EXPAND_SZ(返回的数据已展开)
  • REG_DWORD
  • REG_QWORD

当注册表查询失败时,通常是因为键不存在或数据类型不受支持,字符串 /REGISTRY-NOTFOUND 会被替代到 [] 查询表达式中。

3. find_package 查找模块

“查找模块”是指一个 Find<PackageName>.cmake 文件,在调用 find_package() 命令时加载。查找模块的主要任务是确定某个包是否可用,设置 <PackageName>_FOUND 变量以反映这一点,并提供使用该包所需的变量、宏和导入目标。

传统方法是使用变量来表示所有内容,包括库和可执行文件;这也是大多数现有 CMake 提供的查找模块所采用的方式。更现代的做法则是尽量像配置文件包那样工作,提供导入目标,这样可以将目标使用要求传播给消费者。

无论使用哪种方式(甚至提供变量和导入目标),查找模块应保持与旧版本的向后兼容性。

3.1 cmake 查找模块的示例用法

find_package(Foo [major[.minor[.patch[.tweak]]]][EXACT] [QUIET] [REQUIRED][[COMPONENTS] [components...]][OPTIONAL_COMPONENTS components...][NO_POLICY_SCOPE])

有关 find_package() 的详细信息,请参考文档。

3.2 标准变量名称

在使用变量的方法中,以下变量名称应保持一致性,以便于查找模块之间的互操作性。所有变量都以 Xxx_ 开头,必须与 FindXxx.cmake 文件的名称完全匹配,包括大小写。

  • Xxx_INCLUDE_DIRS:最终的包含目录集合,供客户端代码使用。
  • Xxx_LIBRARIES:用于该模块的库。
  • Xxx_DEFINITIONS:用于编译使用该模块的代码时的编译定义。
  • Xxx_EXECUTABLE:可执行文件的完整绝对路径。
  • Xxx_LIBRARY_DIRS:供客户端代码使用的最终库目录集合。
  • Xxx_FOUND:当 find_package() 命令返回时,如果模块被认为成功找到,则此变量将被设置为 true

3.3 find_package 一个简单的查找模块示例

创建一个查找模块的过程如下:

  1. 模块文档:在模块的顶部添加许可证说明,接着是一个空行,然后是一个 reStructuredText 格式的文档注释块。

    # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
    # file Copyright.txt or https://cmake.org/licensing for details.#[=======================================================================[.rst:
    FindFoo
    -------Finds the Foo library.Imported Targets
    ^^^^^^^^^^^^^^^^This module provides the following imported targets, if found:``Foo::Foo``
    The Foo library
    ...
    #]=======================================================================]
    
  2. 查找库:尝试使用 pkg-config 查找库信息。

    find_package(PkgConfig)
    pkg_check_modules(PC_Foo QUIET Foo)
    
  3. 查找路径和库

    find_path(Foo_INCLUDE_DIR NAMES foo.h PATHS ${PC_Foo_INCLUDE_DIRS} PATH_SUFFIXES Foo)
    find_library(Foo_LIBRARY NAMES foo PATHS ${PC_Foo_LIBRARY_DIRS})
    
  4. 使用 FindPackageHandleStandardArgs

    include(FindPackageHandleStandardArgs)
    find_package_handle_standard_args(Foo FOUND_VAR Foo_FOUND REQUIRED_VARS Foo_LIBRARY Foo_INCLUDE_DIR VERSION_VAR Foo_VERSION)
    
  5. 导入目标设置

    if(Foo_FOUND AND NOT TARGET Foo::Foo)add_library(Foo::Foo UNKNOWN IMPORTED)set_target_properties(Foo::Foo PROPERTIESIMPORTED_LOCATION "${Foo_LIBRARY}"INTERFACE_INCLUDE_DIRECTORIES "${Foo_INCLUDE_DIR}")
    endif()
    
  6. 标记高级变量

    mark_as_advanced(Foo_INCLUDE_DIR Foo_LIBRARY)
    

通过上述步骤,开发者可以创建一个有效的 CMake 查找模块,简化库的查找和链接过程,同时保持与 CMake 其他模块的一致性和兼容性。这种模块化的方式可以提高代码的可重用性和可维护性。希望本手册对您的开发工作有所帮助!

六、其他文章推荐

  1. CMakeLists.txt从入门到精通(看这篇就够)
  2. Cmake中Debug 、 Release 、RelWithDebInfo和 MinSizeRel类型说明
  3. cmake构建动态库实例(cmakelist)
  4. C++构建简单静态库实例(cmakelist)
http://www.lryc.cn/news/465834.html

相关文章:

  • Redis入门:在Java程序中高效使用Redis
  • 活着就好20241021
  • 阿里字节技术管理岗位面试要求
  • MySQL !=NULL 与IS NOT NULL
  • [Unity Demo]从零开始制作空洞骑士Hollow Knight第十六集(上篇):制作更多地图,更多敌人,更多可交互对象
  • Soap-UI传参
  • Centos7搭建minio对象存储服务器
  • 递归算法之汉诺塔问题(Tower of Hanoi)详细解读
  • 软件设计模式------工厂方法模式
  • 演示:基于WPF的DrawingVisual开发的高刷新率示波器
  • git入门操作(2)
  • 【AI学习】扩散模型学习总结PPT
  • 【Python】相等性比较运算(==, is)的学习笔记
  • 智慧公厕厂家:智慧公厕建设推动城市公厕智能化变革
  • 大一计算机课程之线性代数
  • 什么是运动控制器?运动控制器的特点
  • [AWS]RDS数据库版本升级
  • (Golang)初识Go语言!!为什么选择Go?如何配置Go的开发环境?VS Code如何配置Go环境?
  • 【人工智能-初级】第15章 TensorFlow 和 PyTorch 的入门:深度学习的利器
  • git禁用 SSL 证书验证
  • C++之《剑指offer》学习记录(2):sizeof
  • linux线程 | 同步与互斥 | 线程池以及知识点补充
  • ArkTS 如何实现表单,地区选择效果
  • Vite 项目的核心配置- vite.config.ts 和 tsconfig.json 全解析
  • 如何使用JMeter进行性能测试的保姆级教程
  • Qt 实战(11)样式表 | 11.1、样式表简介
  • WebGl 多缓冲区和数据偏移
  • 基于SSM的甜品店销售管理系统
  • Spacetime Gaussian Feature Splatting for Real-Time Dynamic View Synthesis
  • PCL 基于FPFH特征描述子获取点云对应关系