gcc11.2 与 c++11 的一些编译问题

gcc这几年发展很快,C++20标准之后,gcc版本也随之到了GCC11了,老的代码还是在C++11的标准上,使用-std=c++11来进行编译。

编译当前GRPC的最新版本时,发现所依赖的abseil-cpp有一些问题,编译xxx的时候出现如下错误:

/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::numbers_internal::safe_strto64_base(absl::lts_20210324::string_view, long*, int)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::EndsWithIgnoreCase(absl::lts_20210324::string_view, absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::numbers_internal::safe_strtou64_base(absl::lts_20210324::string_view, unsigned long*, int)'
/usr/bin/ld: libgpr.so.18.0.0: undefined reference to `absl::lts_20210324::Cord::GetFlatAux(absl::lts_20210324::cord_internal::CordRep*, absl::lts_20210324::string_view*)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::string_view::find_first_of(absl::lts_20210324::string_view, unsigned long) const'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::StartsWithIgnoreCase(absl::lts_20210324::string_view, absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::optional_internal::throw_bad_optional_access()'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::numbers_internal::safe_strtou32_base(absl::lts_20210324::string_view, unsigned int*, int)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::Status::SetPayload(absl::lts_20210324::string_view, absl::lts_20210324::Cord)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::StrReplaceAll[abi:cxx11](absl::lts_20210324::string_view, std::initializer_list<std::pair<absl::lts_20210324::string_view, absl::lts_20210324::string_view> >)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::string_view::find(absl::lts_20210324::string_view, unsigned long) const'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::Base64Escape[abi:cxx11](absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::BytesToHexString[abi:cxx11](absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::InternalError(absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::string_view::rfind(char, unsigned long) const'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `bool absl::lts_20210324::str_format_internal::FormatArgImpl::Dispatch<absl::lts_20210324::string_view>(absl::lts_20210324::str_format_internal::FormatArgImpl::Data, absl::lts_20210324::str_format_internal::FormatConversionSpecImpl, void*)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::ByChar::Find(absl::lts_20210324::string_view, unsigned long) const'
/usr/bin/ld: libgpr.so.18.0.0: undefined reference to `absl::lts_20210324::CHexEscape[abi:cxx11](absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::FailedPreconditionError(absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::strings_internal::CatPieces[abi:cxx11](std::initializer_list<absl::lts_20210324::string_view>)'
/usr/bin/ld: libgpr.so.18.0.0: undefined reference to `absl::lts_20210324::Status::ForEachPayload(std::function<void (absl::lts_20210324::string_view, absl::lts_20210324::Cord const&)> const&) const'
/usr/bin/ld: libgpr.so.18.0.0: undefined reference to `absl::lts_20210324::Cord::Cord(absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::ParseTime(absl::lts_20210324::string_view, absl::lts_20210324::string_view, absl::lts_20210324::Time*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::InvalidArgumentError(absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::NotFoundError(absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::string_view::find_first_not_of(absl::lts_20210324::string_view, unsigned long) const'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::UnavailableError(absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::UnimplementedError(absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::FormatTime[abi:cxx11](absl::lts_20210324::string_view, absl::lts_20210324::Time, absl::lts_20210324::TimeZone)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::EqualsIgnoreCase(absl::lts_20210324::string_view, absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::Status::Status(absl::lts_20210324::StatusCode, absl::lts_20210324::string_view)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::CUnescape(absl::lts_20210324::string_view, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::Status::GetPayload(absl::lts_20210324::string_view) const'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::string_view::find(char, unsigned long) const'
/usr/bin/ld: libgrpc.so.18.0.0: undefined reference to `absl::lts_20210324::numbers_internal::safe_strto32_base(absl::lts_20210324::string_view, int*, int)'

当前认为链接选项没有加上,由于是cmake编译,打开详细编译参数,通过

make VERBOSE=1

c++ CMakeFiles/gen_hpack_tables.dir/tools/codegen/core/gen_hpack_tables.cc.o -o gen_hpack_tables -Wl,-rpath,/home/cnangel/works/grpc /usr/lib64/libprotobuf.so -ldl -lrt -lm -lpthread libgrpc.so.18.0.0 libgpr.so.18.0.0 /usr/lib64/libz.so /usr/lib64/libcares.so.2.4.3 libaddress_sorting.so.18.0.0 -pthread -lre2 libupb.so.18.0.0 -ldl -lrt -lm -lpthread /usr/lib64/libabsl_hash.so.2103.0.1 /usr/lib64/libabsl_city.so.2103.0.1 /usr/lib64/libabsl_wyhash.so.2103.0.1 /usr/lib64/libabsl_raw_hash_set.so.2103.0.1 /usr/lib64/libabsl_hashtablez_sampler.so.2103.0.1 /usr/lib64/libabsl_synchronization.so.2103.0.1 /usr/lib64/libabsl_graphcycles_internal.so.2103.0.1 /usr/lib64/libabsl_time.so.2103.0.1 /usr/lib64/libabsl_civil_time.so.2103.0.1 /usr/lib64/libabsl_time_zone.so.2103.0.1 /usr/lib64/libabsl_exponential_biased.so.2103.0.1 /usr/lib64/libabsl_statusor.so.2103.0.1 /usr/lib64/libabsl_status.so.2103.0.1 /usr/lib64/libabsl_cord.so.2103.0.1 /usr/lib64/libabsl_str_format_internal.so.2103.0.1 /usr/lib64/libabsl_bad_optional_access.so.2103.0.1 /usr/lib64/libabsl_stacktrace.so.2103.0.1 /usr/lib64/libabsl_symbolize.so.2103.0.1 /usr/lib64/libabsl_malloc_internal.so.2103.0.1 /usr/lib64/libabsl_debugging_internal.so.2103.0.1 /usr/lib64/libabsl_demangle_internal.so.2103.0.1 /usr/lib64/libabsl_strings.so.2103.0.1 /usr/lib64/libabsl_throw_delegate.so.2103.0.1 /usr/lib64/libabsl_strings_internal.so.2103.0.1 /usr/lib64/libabsl_base.so.2103.0.1 -lpthread /usr/lib64/libabsl_spinlock_wait.so.2103.0.1 /usr/lib64/libabsl_int128.so.2103.0.1 /usr/lib64/libabsl_bad_variant_access.so.2103.0.1 /usr/lib64/libabsl_raw_logging_internal.so.2103.0.1 /usr/lib64/libabsl_log_severity.so.2103.0.1 /usr/lib64/libssl.so /usr/lib64/libcrypto.so

检查发现,并没有发现问题;于是开始排查abseil-cpp的链接符号没有加入造成,通过

nm -Do /usr/lib64/libabsl_* 2>/dev/null|grep XXX # 这里填入对应的符号查询即可

发现符号都存在,且都正常,即使换上静态库也无法进行链接;那说明编译的.o文件有问题,一般是编译问题造成,检查absl和grpc的两者编译选项,发现absl-20210324.2版本已经去除了-std=c++11选项,而grpc为了保证版本gcc的兼容性,仍然使用了-std=c++11选项造成,这里没有对GCC版本做兼容,于是去除选项,整个编译过程无问题。

在GCC11.2上有这个问题,GCC8.4没有发现,GCC的man手册如下:

-std=
Determine the language standard. This option is currently only supported when compiling C or C++.

The compiler can accept several base standards, such as c90 or c++98, and GNU dialects of those standards, such as gnu90 or gnu++98. When a base standard is specified, the compiler accepts all programs following that
standard plus those using GNU extensions that do not contradict it. For example, -std=c90 turns off certain features of GCC that are incompatible with ISO C90, such as the "asm" and "typeof" keywords, but not other GNU
extensions that do not have a meaning in ISO C90, such as omitting the middle term of a "?:" expression. On the other hand, when a GNU dialect of a standard is specified, all features supported by the compiler are
enabled, even when those features change the meaning of the base standard. As a result, some strict-conforming programs may be rejected. The particular standard is used by -Wpedantic to identify which features are GNU
extensions given that version of the standard. For example -std=gnu90 -Wpedantic warns about C++ style // comments, while -std=gnu99 -Wpedantic does not.

并没有说明GCC11版本对c++11的不兼容问题,但选项c++20里面有说到could change in incompatible ways in future releases.,如下图:

2021-10-03 00-02-01 的屏幕截图.png

so, 怎么完美解决这个问题呢? 需要grpc添加一个m4宏如下:

GCC_VERSION=$(cc -dumpversion | sed 's/\([[0-9]]\{1,\}\.[[0-9]]\{1,\}\)\.*\([[0-9]]\{1,\}\)\{0,1\}/\1\2/')
CURR_MIN_VERSION=$(echo "$GCC_VERSION 5.0.0" | tr " " "\n" | sort -rV | head -n 1)
AS_IF([test "$CURR_MIN_VERSION" == '5.0.0' ], [ CXXFLAGS="${CXXFLAGS} -std=c++11" ], [])

这样达到目的。

如果没有记错的话,4.8.5开始支持cxx11。

Monthly Archives

Pages

Powered by Movable Type 7.7.2

About this Entry

This page contains a single entry by Cnangel published on October 2, 2021 11:57 PM.

GRPC一个退出发生Core的问题 was the previous entry in this blog.

fedora35发布了 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.