ARM Linux编译gRPC时Abseil-CPP内部编译错误求助
ARM Linux编译gRPC时Abseil-CPP内部编译器错误的解决办法
问题场景
在ARM Linux环境下编译gRPC:将GitHub源码下载并传输至服务器后,进入gRPC目录执行make命令,出现Abseil-CPP相关的内部编译错误。但单独进入abseil-cpp目录编译时完全正常,每次编译整个gRPC都会失败。
错误信息
third_party/abseil-cpp/absl/types/variant.h:509:7: required by substitution of ‘template<class T, long unsigned int I, class Tj, absl::lts_20220623::enable_if_t<std::is_constructible<Tj, T>::value, void>* <anonymous> > constexpr absl::lts_20220623::variant<grpc_core::Pending, grpc_core::RefCountedPtr<grpc_core::ReclaimerQueue::Handle> >::variant(T&&) [with T = absl::lts_20220623::variant<grpc_core::Pending, grpc_core::RefCountedPtr<grpc_core::ReclaimerQueue::Handle> >; long unsigned int I = <missing>; Tj = <missing>; absl::lts_20220623::enable_if_t<std::is_constructible<Tj, T>::value, void>* <anonymous> = <missing>]’ ./src/core/lib/resource_quota/memory_quota.h:211:72: required from here third_party/abseil-cpp/absl/types/variant.h:509:7: internal compiler error: unexpected expression ‘I’ of kind template_parm_index class Tj = absl::variant_alternative_t<I, variant>, ^~~~~
相关代码
template < class T, std::size_t I = std::enable_if< variant_internal::IsNeitherSelfNorInPlace<variant, absl::decay_t<T>>::value, variant_internal::IndexOfConstructedType<variant, T>>::type::value, class Tj = absl::variant_alternative_t<I, variant>, absl::enable_if_t<std::is_constructible<Tj, T>::value>* = nullptr> constexpr variant(T&& t) noexcept(std::is_nothrow_constructible<Tj, T>::value) : Base(variant_internal::EmplaceTag<I>(), absl::forward<T>(t)) {}
解决办法
1. 升级编译器版本
这个内部错误是ARM平台老版本GCC对C++17模板特性的解析bug导致的,建议升级到GCC 9及以上版本:
- 检查当前版本:
gcc --version - 以Debian/Ubuntu为例,通过包管理器升级:
sudo apt update sudo apt install gcc-9 g++-9 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 100 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 100
2. 使用外部Abseil库编译gRPC
放弃gRPC自带的第三方Abseil,单独编译安装Abseil后,指定gRPC使用外部依赖:
- 单独编译安装Abseil:
cd third_party/abseil-cpp mkdir build && cd build cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local/abseil make -j$(nproc) sudo make install - 编译gRPC时指定使用外部Abseil:
cd ../.. # 回到gRPC根目录 make ABSL_PROVIDER=package ABSL_INCLUDE_DIR=/usr/local/abseil/include ABSL_LIB_DIR=/usr/local/abseil/lib
3. 切换gRPC稳定版本
当前使用的gRPC版本可能与自带Abseil存在兼容性问题,切换到最新稳定版(如v1.50.x及以上):
git checkout v1.50.1 # 替换为最新稳定版标签 git submodule update --init --recursive make
4. 强制指定C++标准编译
编译时添加-std=c++17选项,确保编译器启用完整的C++17支持:
make CXXFLAGS="-std=c++17"
原因分析
这个内部编译器错误是由于GCC在解析模板参数默认值时,无法正确处理依赖于前置模板参数I的类型推导逻辑,属于特定版本GCC的bug。单独编译Abseil时,编译选项和宏定义与gRPC整体编译环境不同,因此未触发该问题。
内容的提问来源于stack exchange,提问作者Adeshen
相关产品推荐
相关产品推荐

