如何用新版本编译器编译启用-Werror的CMake旧项目?
我尝试构建OpenCV 3.4.16版本,该项目启用了类似-Werror=all的编译选项。在Ubuntu 22.04 + GCC 11.4环境下,执行以下命令可正常构建:
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..; make
但在Ubuntu 24.04 + GCC 13.3环境下构建失败,报错如下:
[ 29%] Building CXX object modules/core/CMakeFiles/opencv_core.dir/src/persistence_types.cpp.o /home/josh/Downloads/opencv-3.4.16/modules/core/src/persistence_base64.cpp: In function ‘bool base64::base64_valid(const uint8_t*, size_t, size_t)’: /home/josh/Downloads/opencv-3.4.16/modules/core/src/persistence_base64.cpp:167:31: error: comparing the result of pointer addition ‘(src + ((sizetype)off))’ and NULL [-Werror=address] 167 | if (src == 0 || src + off == 0) | ~~~~~~~~~~^~~~ cc1plus: some warnings being treated as errors make[2]: *** [modules/core/CMakeFiles/opencv_core.dir/build.make:971: modules/core/CMakeFiles/opencv_core.dir/src/persistence_base64.cpp.o] Error 1
我曾尝试传递-DCMAKE_CXX_FLAGS参数:
cmake -D CMAKE_INSTALL_PREFIX=/usr/local .. -DCMAKE_CXX_FLAGS="-Wno-all -Wno-address"
但并未解决该错误。
核心问题:不修改或维护CMake文件分支的前提下,如何用警告规则更严格的新版本编译器构建将警告视为错误的旧项目?
补充说明:发布问题后,我尝试修改CMake文件暂时绕过该问题,但其他依赖的新版本也导致构建失败,核心问题依然存在。另外,自行构建OpenCV时,使用make -j可能会耗尽内存,建议限制为make -j4。
最小测试示例
test_address.cpp
bool foo(char* ptr, int off){ return ptr + off == 0; }
CMakeLists.txt
cmake_minimum_required(VERSION 3.5) project(test_address) set(CMAKE_CXX_FLAGS "-Werror=address") # 项目设置方式可能不同,不确定是否与OpenCV的设置等价。 add_library(test_address test_address.cpp)
1. 确保禁用警告的参数优先级更高
之前的CMAKE_CXX_FLAGS未生效,是因为OpenCV的CMake配置会将自身的编译选项追加到默认参数之后,导致你的-Wno-address被后续的-Werror=address覆盖。可以通过以下两种方式解决:
方法A:用CMAKE_CXX_FLAGS_APPEND追加禁用选项
该参数会把指定选项追加到所有编译选项的末尾,确保优先级最高:
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D CMAKE_CXX_FLAGS_APPEND="-Wno-address" ..
方法B:直接覆盖CMAKE_CXX_FLAGS并保留必要选项
如果追加仍不生效,可以直接覆盖参数,同时保留Release模式的基础优化选项:
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D CMAKE_CXX_FLAGS="-O2 -DNDEBUG -Wno-address" ..
其中-O2和-DNDEBUG是Release模式的默认优化参数,必须保留以保证构建产物的性能。
2. 全局关闭警告转错误(应急方案)
如果存在多个类似的警告错误,可临时全局关闭-Werror规则,但这会隐藏其他潜在问题,仅建议应急使用:
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D CMAKE_CXX_FLAGS_APPEND="-Wno-error" ..
3. 报错原因说明
GCC 13新增了对「指针加偏移后与NULL比较」的检查(属于-Waddress警告的子集),而旧版GCC没有该规则。OpenCV 3.4.16的代码在当时是合法的,但新版编译器的 stricter 规则触发了错误。禁用-Waddress对应的错误转换是最精准的解决方式。
内容的提问来源于stack exchange,提问作者plswork04

