15.2 生成文件并编写平台检查
对于Vim示例,我们需要在配置时生成三个文件,src/auto/pathdef.c、src/auto/config.h和src/auto/osdef.h:
pathdef.c:记录安装路径、编译/链接标志、当前用户和主机名
config.h:编译系统的环境
osdef.h:由
src/osdef.sh生成的文件
这种情况相当普遍。需要CMake配置文件,配置时执行一个脚本,执行许多平台检查命令,来生成config.h。特别是,对于那些可移植的项目,平台检查非常普遍。
在原始目录树中,文件在src文件夹下生成。而我们将使用不同的方法:这些文件会生成在build目录中。这样做的原因是生成的文件通常依赖于所选择的选项、编译器或构建类型,我们希望保持同一个源,可以适配多个构建。要在build目录中启用生成,我们必须对生成文件的脚本进行改动。
构造文件
我们将把与生成文件相关的函数集中放在src/autogenerate.cmake中。在定义可执行目标之前,在src/CMakeLists.txt中调用这些函数:
# generate config.h, pathdef.c, and osdef.h
include(autogenerate.cmake)
generate_config_h()
generate_pathdef_c()
generate_osdef_h()
add_executable(vim
main.c
)
# ...src/autogenerate.cmake中包含了其他检测头文件、函数和库等几个函数:
我们选择了一些用于生成文件的函数,而不是用宏或“裸”CMake代码。在前几章中讨论过的,这是避免了一些问题:
避免多次生成文件,以防多次包含模块。我们可以使用一个包含保护来防止意外地多次运行代码。
保证了对函数中变量范围的完全控制。这避免了这些定义溢出,从而出现变量污染的情况。
根据系统配置预处理宏定义
config.h文件以src/config.h.in为目标所生成的,其中包含根据系统功能配置的预处理标志:
生成的src/config.h示例类似如下情况(定义可以根据环境的不同而不同):
这个页面是一个很好的平台检查示例: https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/How-To-Write-Platform-Checks
在src/configure.ac中,我们可以检查需要执行哪些平台检查,从而来设置相应的预处理定义。
我们将使用#cmakedefine(https://cmake.org/cmake/help/v3.5/command/configure_file.html?highlight=cmakedefine )为了确保不破坏现有的Autotools构建,我们将复制config.h.in为config.h.cmake.in,并将所有#undef SOME_DEFINITION更改为#cmakedefine SOME_DEFINITION @SOME_DEFINITION@。
在generate_config_h函数中,先定义两个变量:
然后,我们执行几个类型检查:
然后,我们对函数进行循环,检查系统是否能够解析:
验证库是否包含特定函数:
然后,我们循环头文件,检查它们是否可用:
然后,我们将CMake选项从转换为预处理定义:
最后,我们检查是否能够编译一个特定的代码片段:
然后,使用定义的变量配置src/config.h.cmake.in生成config.h,其中包含generate_config_h函数:
使用路径和编译器标志配置文件
从src/pathdef.c.in生成pathdef.c:
generate_pathdef_c函数在src/pathdef.c.in进行配置。为了简单起见,我们省略了链接标志:
配置时执行shell脚本
最后,我们使用以下函数生成osdef.h:
为了在${CMAKE_CURRENT_BINARY_DIR}/src/auto而不是src/auto中生成osdef.h,我们必须调整osdef.sh以接受${CMAKE_CURRENT_BINARY_DIR}作为命令行参数。
osdef.sh中,我们会检查是否给定了这个参数:
然后,生成${target_directory}/auto/osdef.h。为此,我们还必须在osdef.sh中调整以下行:
Last updated
Was this helpful?