gRPC 1.47.4在VS2017编译报错:引用已删除函数求助
VS2017 CI流水线编译gRPC 1.47.4时出现C2280错误(本地编译正常)
问题背景
我们正在私有Conan仓库构建gRPC及其全部依赖包,环境固定为:
- Linux/macOS:gcc6.4.0
- Windows:VS2017
已完成构建的依赖版本:
- abseil-cpp:
20210324.2 - c-ares:
1.28.1 - protobuf:
3.21.12 - re2:
2023-03-01 - openssl:
1.1.1s - zlib:
1.2.13
gRPC 1.47.4在Linux和macOS环境下编译正常,但Windows CI/CD流水线中出现C2280错误,且本地Windows环境编译无此问题。
错误详情
[2024-06-20T14:18:33.372Z] C:\j\w@tmp\.cnn\be3a4e\1\include\absl/meta/type_traits.h(166): error C2280: 'absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>> &absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>>::operator =(const absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>> &)': attempting to reference a deleted function [C:\j\w@tmp\.cnn\7e4d97\1\_bld.Debug\_src\grpc.vcxproj] [2024-06-20T14:18:33.372Z] with [2024-06-20T14:18:33.372Z] [ [2024-06-20T14:18:33.372Z] T0=grpc_core::Pending, [2024-06-20T14:18:33.372Z] Child=grpc_core::ReclaimerQueue::Handle [2024-06-20T14:18:33.372Z] C:\j\w@tmp\.cnn\be3a4e\1\include\absl/meta/type_traits.h(166): error C2280: 'absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>> &absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>>::operator =(const absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>> &)': attempting to reference a deleted function [C:\j\w@tmp\.cnn\7e4d97\1\_bld.Debug\_src\grpc_unsecure.vcxproj] [2024-06-20T14:18:33.372Z] with [2024-06-20T14:18:33.372Z] [ [2024-06-20T14:18:33.372Z] T0=grpc_core::Pending, [2024-06-20T14:18:33.372Z] Child=grpc_core::ReclaimerQueue::Handle [2024-06-20T14:18:33.372Z] ] (compiling source file C:\j\w@tmp\.cnn\7e4d97\1\_src\src\core\ext\filters\census\grpc_context.cc) [2024-06-20T14:18:33.372Z] C:\j\w@tmp\.cnn\be3a4e\1\include\absl/meta/type_traits.h(166): error C2280: 'absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>> &absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>>::operator =(const absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>> &)': attempting to reference a deleted function [C:\j\w@tmp\.cnn\7e4d97\1\_bld.Debug\_src\grpc_unsecure.vcxproj] [2024-06-20T14:18:33.372Z] with [2024-06-20T14:18:33.372Z] ] (compiling source file C:\j\w@tmp\.cnn\7e4d97\1\_src\src\core\ext\filters\census\grpc_context.cc) [2024-06-20T14:18:33.372Z] [ [2024-06-20T14:18:33.372Z] T0=grpc_core::Pending, [2024-06-20T14:18:33.372Z] Child=grpc_core::ReclaimerQueue::Handle [2024-06-20T14:18:33.372Z] ] (compiling source file C:\j\w@tmp\.cnn\7e4d97\1\_src\src\core\ext\filters\channel_idle\channel_idle_filter.cc) [2024-06-20T14:18:33.372Z] C:\j\w@tmp\.cnn\be3a4e\1\include\absl/meta/type_traits.h(166): error C2280: 'absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>> &absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>>::operator =(const absl::lts_20210324::variant_internal::Union<T0,grpc_core::RefCountedPtr<Child>> &)': attempting to reference a deleted function [C:\j\w@tmp\.cnn\7e4d97\1\_bld.Debug\_src\grpc.vcxproj]
已尝试的方案
- 将abseil-cpp升级至
20210324.2(patch 2版本) - 强制使用无扩展的C++14标准编译
解决思路
1. 对齐CI与本地的Conan环境配置
- 对比CI和本地的Conan build profile,确保VS2017工具集版本(如v141)、编译类型(Debug/Release)、链接方式(静态/动态)、Runtime库设置(MT/MD/MTd/MDd)完全一致
- 清理CI的Conan缓存,重新拉取依赖包,避免缓存导致的依赖版本或构建配置不一致
- 检查CI中Conan的
compiler.version、compiler.runtime等参数是否与本地匹配
2. 修复gRPC与abseil的Windows兼容性问题
- gRPC 1.47.4与abseil 20210324在Windows下的
variant实现存在兼容性问题:grpc_core::RefCountedPtr的拷贝赋值运算符被删除,但abseil的variant内部Union尝试调用它。可以给gRPC添加补丁:
找到src/core/lib/gprpp/ref_counted_ptr.h中RefCountedPtr的定义,显式实现拷贝赋值运算符,确保其语义符合abseil variant的要求;或者在涉及absl::variant<grpc_core::Pending, grpc_core::RefCountedPtr<ReclaimerQueue::Handle>>的代码处,改用移动语义替代拷贝 - 尝试在gRPC的编译选项中添加
ABSL_FORCE_STD_VARIANT宏,强制abseil使用标准库的std::variant而非自定义实现,规避abseil内部Union的拷贝问题
3. 调整VS2017编译选项
- 检查CI是否启用了
/permissive-编译选项,该选项会严格遵循C++标准,可能触发本地未暴露的错误。尝试在CI中关闭该选项,或添加/Zc:strictStrings-等兼容选项 - 确保CI使用的VS2017更新到最新补丁版本(如15.9.x),旧版本VS2017对C++14特性的支持存在bug,可能导致此编译错误
4. 验证依赖包的构建一致性
- 确认abseil-cpp在Windows CI上是用VS2017编译的,而非其他工具链交叉构建的版本
- 检查abseil的编译选项是否与gRPC一致,比如是否启用了相同的C++标准、Runtime库设置
内容的提问来源于stack exchange,提问作者nablit
相关产品推荐
相关产品推荐

