使用x86_64-w64-mingw32-g++交叉编译google-cloud-cpp失败求助
问题背景
在Ubuntu 20.04 LTS环境下,使用x86_64-w64-mingw32-g++交叉编译tag为v2.14.0的google-cloud-cpp,执行make -j12到88%时,出现field_behavior.pb.h文件枚举定义相关编译错误,核心报错如下:
/workspace/deps/google-cloud-cpp/build/external/googleapis/google/api/field_behavior.pb.h:54:12: 错误:'=' 标记前缺少标识符
54 | OPTIONAL = 1,
| ^
/workspace/deps/google-cloud-cpp/build/external/googleapis/google/api/field_behavior.pb.h:54:12: 错误:'=' 标记前缺少 '}'
/workspace/deps/google-cloud-cpp/build/external/googleapis/google/api/field_behavior.pb.h:52:26: 提示:匹配此处的 '{'
52 | enum FieldBehavior : int {
| ^
问题原因
这是宏冲突导致的:Windows SDK头文件(如winbase.h)中预定义了OPTIONAL宏,用于标记函数参数为可选参数。交叉编译时,mingw工具链会引入这些Windows系统头文件,导致Google API的proto生成代码中,枚举值OPTIONAL被宏替换,破坏了C++枚举的语法结构,从而触发编译错误。
解决方案
方案1:在CMake中取消OPTIONAL宏定义(推荐)
在cmake命令中添加-UOPTIONAL参数,强制取消预定义的OPTIONAL宏;或者添加-DOPTIONAL=OPTIONAL,将宏值设置为自身,避免替换枚举值。修改后的cmake命令如下:
cmake -DCMAKE_INSTALL_MESSAGE=NEVER -DBUILD_TESTING=OFF -DGOOGLE_CLOUD_CPP_ENABLE=bigquery,storage -DOPENSSL_ROOT_DIR=/openssl_dir -Dnlohmann_json_DIR=/nlohmann_json -DCURL_LIBRARY=/curl/libcurl.a -DCURL_INCLUDE_DIR=/curl/include/ -DGOOGLE_CLOUD_CPP_ENABLE_EXAMPLES=OFF -DCMAKE_TOOLCHAIN_FILE=/workspace/cmake/toolchains/mingw-w64-x86_64.cmake -DCrc32c_DIR=/Crc32c/ -D_WIN32_WINNT=0x0A00 -DCMAKE_BUILD_TYPE=Release -UOPTIONAL ..
也可以直接在你的mingw-w64工具链文件(mingw-w64-x86_64.cmake)中添加以下代码,全局取消该宏:
add_definitions(-UOPTIONAL)
方案2:临时修改生成的pb.h文件(应急用)
找到编译生成的field_behavior.pb.h文件,将枚举中的OPTIONAL重命名为其他不冲突的名称(如FIELD_BEHAVIOR_OPTIONAL)。注意:该方法仅作为临时 workaround,一旦重新生成proto头文件(如clean后重新cmake),修改会失效,不推荐长期使用。
方案3:升级依赖或替换googleapis版本
google-cloud-cpp v2.14.0依赖的googleapis版本可能未处理此类跨平台宏冲突。可以尝试升级google-cloud-cpp到更新的稳定版本(如v2.20.0及以上),这类新版本通常会修复此类编译问题;也可以手动替换项目依赖的googleapis为已修复该冲突的版本。
内容的提问来源于stack exchange,提问作者user3079777

