多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 7.6 使用废弃函数、宏和变量 **NOTE**:*此示例代码可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-7/recipe-06 中找到。该示例在CMake 3.5版(或更高版本)中是有效的,并且已经在GNU/Linux、macOS和Windows上进行过测试。* “废弃”是在不断发展的项目开发过程中一种重要机制,它向开发人员发出信号,表明将来某个函数、宏或变量将被删除或替换。在一段时间内,函数、宏或变量将继续可访问,但会发出警告,最终可能会上升为错误。 ## 准备工作 我们将从以下CMake项目开始: ```cmake cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(recipe-06 LANGUAGES NONE) macro(custom_include_guard) if(NOT DEFINED included_modules) set(included_modules) endif() if ("${CMAKE_CURRENT_LIST_FILE}" IN_LIST included_modules) message(WARNING "module ${CMAKE_CURRENT_LIST_FILE} processed more than once") endif() list(APPEND included_modules ${CMAKE_CURRENT_LIST_FILE}) endmacro() include(cmake/custom.cmake) message(STATUS "list of all included modules: ${included_modules}") ``` 这段代码定义了一个自定义的"包含保护"机制,包括一个自定义模块(与前一个示例中的模块相同),并打印所有包含模块的列表。对于CMake 3.10或更高版本有内置的`include_guard`。但是,不能简单地删除`custom_include_guard`和`${included_modules}`,而是使用一个“废弃”警告来弃用宏和变量。某个时候,可以将该警告转换为`FATAL_ERROR`,使代码停止配置,并迫使开发人员对代码进行修改,切换到内置命令。 ## 具体实施 “废弃”函数、宏和变量的方法如下: 1. 首先,定义一个函数,我们将使用它来弃用一个变量: ```cmake function(deprecate_variable _variable _access) if(_access STREQUAL "READ_ACCESS") message(DEPRECATION "variable ${_variable} is deprecated") endif() endfunction() ``` 2. 然后,如果CMake的版本大于3.9,我们重新定义`custom_include_guard`并将`variable_watch`附加到`included_modules`中: ```cmake if (CMAKE_VERSION VERSION_GREATER "3.9") # deprecate custom_include_guard macro(custom_include_guard) message(DEPRECATION "custom_include_guard is deprecated - use built-in include_guard instead") _custom_include_guard(${ARGV}) endmacro() # deprecate variable included_modules variable_watch(included_modules deprecate_variable) endif() ``` 3. CMake3.10以下版本的项目会产生以下结果: ```shell $ mkdir -p build $ cd build $ cmake .. -- custom.cmake is included and processed -- list of all included modules: /home/user/example/cmake/custom.cmake ``` 4. CMake 3.10及以上将产生预期的“废弃”警告: ```cmake CMake Deprecation Warning at CMakeLists.txt:26 (message): custom_include_guard is deprecated - use built-in include_guard instead Call Stack (most recent call first): cmake/custom.cmake:1 (custom_include_guard) CMakeLists.txt:34 (include) -- custom.cmake is included and processed CMake Deprecation Warning at CMakeLists.txt:19 (message): variable included_modules is deprecated Call Stack (most recent call first): CMakeLists.txt:9999 (deprecate_variable) CMakeLists.txt:36 (message) -- list of all included modules: /home/user/example/cmake/custom.cmake ``` ## 工作原理 弃用函数或宏相当于重新定义它,如前面的示例所示,并使用`DEPRECATION`打印消息: ```cmake macro(somemacro) message(DEPRECATION "somemacro is deprecated") _somemacro(${ARGV}) endmacro() ``` 可以通过定义以下变量来实现对变量的弃用: ```cmake function(deprecate_variable _variable _access) if(_access STREQUAL "READ_ACCESS") message(DEPRECATION "variable ${_variable} is deprecated") endif() endfunction() ``` 然后,这个函数被添加到将要“废弃”的变量上: ```cmake variable_watch(somevariable deprecate_variable) ``` 如果在本例中`${included_modules}`是读取 (`READ_ACCESS`),那么`deprecate_variable`函数将发出带有`DEPRECATION`的消息。