记一次CMake版本更新导致的策略行为变动导致的问题

记一次CMake版本更新导致的策略行为变动导致的问题

问题现象

最近在搞组内代码库迁移升级,重写CMakeLists.txt后,发现 libarchive 这个库编译不过,报错是找不到 int64_t 类型对应的 HAVE_INT64_T 宏。

问题分析

检视 libarchive 代码,发现这个 HAVE_INT64_T 宏是在构建时通过 configure_file 输入 config.h.in 模板生成的,只要根 CMakeLists.txt 中设置了 HAVE_INT64_T 变量为TRUE,则就会定义这个宏。而 HAVE_INT64_T 是通过 CMake 的内置函数检查数据类型自动生成的:

include(CheckTypeSize)
check_type_size(int64_t INT64_T) # 会设置一个名为HAVE_INT64_T的缓存变量(int64_t存在则为TRUE,否则为FALSE)

开启 --debug-trycompile ,观察其生成的 .c 测试文件,发现其文件中定义了 int64_t 类型的变量,但是没有引入 stdint.h ,因此会编译失败。

那么为什么没有添加这个头文件呢?调试项目的 CMakeLists.txt ,发现其中有手动设置 CMAKE_C_FLAGS_DEBUG 的地方,添加了 /Zl 选项。去掉该选项就正常了。而CMake文档中有说明 CMAKE_<LANG>_FLAGS 会影响 check_type_size 的行为【TODO 测试一下,看下Zl添加与否,生成的.c文件的区别】

但是为什么旧代码库也有 /Zl 但是没有这个问题呢?梳理了一下两者流程,几乎一样,唯一区别就是项目的 cmake 版本号:

-cmake_minimum_version(VERSION 2.8)
+cmake_minimum_version(VERSION 3.17)

而版本号会影响 CMake 选择的策略集。

后通过二分,发现 3.6 版本可以,而 3.7 版本不行。查阅 cmake-policies 得知,3.7 只引入了策略 CMP0066 的变更,尝试将该策略改为 OLD 即可。

posted @ 2026-01-09 19:25  3的4次方  阅读(2)  评论(0)    收藏  举报