brpc icon indicating copy to clipboard operation
brpc copied to clipboard

centos7编译brpc报错

Open Kegem0 opened this issue 2 years ago • 23 comments

Describe the bug (描述bug) 基于官方文档开始编译brpc https://github.com/apache/brpc/blob/master/docs/cn/getting_started.md#%E4%BD%BF%E7%94%A8cmake%E7%BC%96%E8%AF%91brpc 使用的是yum install安装的相关依赖,虽然可能会有版本很旧的情况,但是操作流程是按照官方文档来的。

To Reproduce (复现方法) 直接按照官方文档一步一步操作即可,在不同电脑的centos虚拟机上,必定出现同样的问题。都是在同一个位置报段错误,但是同样的代码在unbuntu上可以通过,说明肯定不是代码的问题

Expected behavior (期望行为) 正常编译通过。 事实上我在ubuntu16.04.07机器上按照官方文档的说明进操作,最后编译成功了,但是在centos7上始终卡在对应的问题上。

Versions (各种版本) OS:CentOS-7-x86_64-DVD-2009.iso Compiler:gcc 4.8.5 5.4.0 8.3.0 都尝试过 brpc: master分支,release-1.6.0, release-1.5.0都尝试过 protobuf: yum install默认安装的版本,2.5.0-8.el7

Additional context/screenshots (更多上下文/截图) image

Kegem0 avatar Aug 11 '23 06:08 Kegem0

我尝试自己编译了相关的依赖,包括 protobuf-3.0.0 gmock-1.7.0-master gflags-2.1.2 leveldb-1.18 openssl-OpenSSL_1_1_1

放置在/usr/local/xxx下(为了防止之后依赖冲突,我分别各自建了一个文件夹,删除的时候会方便) 然后重新执行 sh config_brpc.sh --headers="/usr/local/gflags/include /usr/local/protobuf/include /usr/local/leveldb/include /usr/local/openssl/include" --libs="/usr/local/gflags/lib /usr/local/protobuf/lib /usr/local/leveldb/lib /usr/local/openssl/lib /usr/local/gflags/bin /usr/local/protobuf/bin /usr/local/openssl/bin"

make -j6 依然报同样的错误

Kegem0 avatar Aug 11 '23 08:08 Kegem0

把gcc升级到了8.3.0,现在的异常看起来正常了些 image 应该是我使用的protobuf版本不兼容的问题,但是源码来说应该是有这个文件的,为何编译之后该文件丢失了?

Kegem0 avatar Aug 11 '23 11:08 Kegem0

make构建的话,可以加上VERBOSE看看编译参数,看include path能不能找到这个头文件。比如make VERBOSE=1 -j6

lorinlee avatar Aug 11 '23 12:08 lorinlee

貌似 gcc 4.8.5 对 1.6.0 中 doubly_buffered_data.h 中模板支持有问题,可以考虑升级编译器或者使用 1.5.0 中的 doubly_buffered_data.h

应该是我使用的protobuf版本不兼容的问题,但是源码来说应该是有这个文件的,为何编译之后该文件丢失了?

更换编译器后有没有执行 clean 操作呢?

可以看下这个基于 cmake 的编译情况,基本环境应该和你一致。 https://download.copr.fedorainfracloud.org/results/wasphin/brpc/epel-7-x86_64/06235181-brpc/builder-live.log.gz

wasphin avatar Aug 11 '23 15:08 wasphin

make构建的话,可以加上VERBOSE看看编译参数,看include path能不能找到这个头文件。比如make VERBOSE=1 -j6

感谢,我查看了自己编译的protobuf的include的文件,确实没有这个文件。

Kegem0 avatar Aug 11 '23 15:08 Kegem0

貌似 gcc 4.8.5 对 1.6.0 中 doubly_buffered_data.h 中模板支持有问题,可以考虑升级编译器或者使用 1.5.0 中的 doubly_buffered_data.h

应该是我使用的protobuf版本不兼容的问题,但是源码来说应该是有这个文件的,为何编译之后该文件丢失了?

更换编译器后有没有执行 clean 操作呢?

可以看下这个基于 cmake 的编译情况,基本环境应该和你一致。 https://download.copr.fedorainfracloud.org/results/wasphin/brpc/epel-7-x86_64/06235181-brpc/builder-live.log.gz 感谢! 我在社区看到有人遇到了这个问题,他在使用1.5.0之后解决了这个问题,我上午在公司的机器进行了尝试,但是还是一样卡在了这里。我的标题写了我尝试过1.5.0-release,但是似乎没用。

不过说起来,可能我的操作顺序有问题?我担心依赖冲突,因此开启了一个新的虚拟机(说真的我在个人的机器上,因为先用yum install 安装了protobuf, 然后发现编译不通过又去github上clone了3.0.0 自行编译,最后也是出现了社区一个常见的 编译时Error的问题,当时有一个大佬的解答是依赖冲突,可能是装了多个版本的protobuf导致的,虽然我用yum remove把之前下的卸载了)

我先是用4.8.5的gcc编译了这几个依赖,后来发现用自己编译的依赖还是卡在编译时段错误,就又去升级了gcc8.3.0,可能前后编译用的gcc不同产生了问题? 但是不管怎么说,用gcc4.8.5 编译的protobuf3.0.0,的确没有把gzip_stream.h编译进inlcude里

centos7感觉要操作出一个最佳实践的版本太难了,虽然官网写了对很大的版本范围的依赖都是支持的,但是很多版本似乎真的相互冲突,组内的大佬要我去看一个成熟的用brpc的框架,把他们的docker镜像下下来,查看他们的依赖版本试试。

Kegem0 avatar Aug 11 '23 15:08 Kegem0

如果只是在 centos7 下试用 brpc 的话,也可以考虑从这里 下载安装 rpm 使用,应该会简单些。

wasphin avatar Aug 11 '23 15:08 wasphin

如果只是在 centos7 下试用 brpc 的话,也可以考虑从这里 下载安装 rpm 使用,应该会简单些。

感谢!不过公司可能有相关的需求,因为之后要基于brpc进行一些开发,不然我也不会纠结于centos7了,并且最好确定一个比较稳定的依赖版本集合。

Kegem0 avatar Aug 11 '23 15:08 Kegem0

继续做一个排列组合,我在自己的机器上,用centos默认yum install下载的依赖,并且直接将gcc升级到8.3.0,clean之后重新make,弹出来的错误是protobuf和gflags的undefined reference的问题,截取一段如下:

/home/ym/apache-brpc-1.6.0-src/src/bvar/variable.cpp:920: undefined reference to gflags::RegisterFlagValidator(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*, bool (*)(char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&))' libbrpc.a(variable.o):/home/ym/apache-brpc-1.6.0-src/src/bvar/variable.cpp:925: more undefined references to gflags::RegisterFlagValidator(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const*, bool ()(char const, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&))' follow libbrpc.a(gflag.o): In function bvar::GFlag::get_value[abi:cxx11]() const': /home/ym/apache-brpc-1.6.0-src/src/bvar/gflag.cpp:81: undefined reference to gflags::GetCommandLineOption(char const*, std::__cxx11::basic_string<char, std::char_traits, std::allocator >)' libbrpc.a(gflag.o): In function bvar::GFlag::set_value(char const*)': /home/ym/apache-brpc-1.6.0-src/src/bvar/gflag.cpp:88: undefined reference to gflags::SetCommandLineOption[abi:cxx11](char const, char const*)'

/home/ym/apache-brpc-1.6.0-src/src/bvar/variable.cpp:920: undefined reference to gflags::RegisterFlagValidator(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*, bool (*)(char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&))' libbrpc.a(variable.o):/home/ym/apache-brpc-1.6.0-src/src/bvar/variable.cpp:925: more undefined references to gflags::RegisterFlagValidator(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const*, bool ()(char const, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&))' follow libbrpc.a(gflag.o): In function bvar::GFlag::get_value[abi:cxx11]() const': /home/ym/apache-brpc-1.6.0-src/src/bvar/gflag.cpp:81: undefined reference to gflags::GetCommandLineOption(char const*, std::__cxx11::basic_string<char, std::char_traits, std::allocator >)' libbrpc.a(gflag.o): In function bvar::GFlag::set_value(char const*)': /home/ym/apache-brpc-1.6.0-src/src/bvar/gflag.cpp:88: undefined reference to gflags::SetCommandLineOption[abi:cxx11](char const, char const*)'

这个我在社区好像看到过,是 我在Makefile中加上了这一句 -D_GLIBCXX_USE_CXX11_ABI=0(CXXFLAGS或者CPPFLAGS后应该都行)最后编译成功。不过似乎-D_GLIBCXX_USE_CXX11_ABI=0这个行为并不好,高版本之所以将其抛弃也是其不安全性。这里属于是对编译成功的一种妥协了。

然后尝试编译这个简单样例

cd example/echo_c++
make

make的时候依然报类似的错误: /home/ym/apache-brpc-1.6.0-src/example/echo_c++/../../output/include/butil/class_name.h:35: undefined reference to butil::demangle[abi:cxx11](char const*)' /home/ym/apache-brpc-1.6.0-src/example/echo_c++/../../output/include/butil/class_name.h:35: undefined reference to butil::demangle[abi:cxx11](char const*)' /home/ym/apache-brpc-1.6.0-src/example/echo_c++/../../output/include/butil/class_name.h:35: undefined reference to butil::demangle[abi:cxx11](char const*)' server.o: In function __static_initialization_and_destruction_1': /home/ym/apache-brpc-1.6.0-src/example/echo_c++/../../output/include/butil/class_name.h:35: undefined reference to `butil::demangle[abi:cxx11](char const*)'

当然是同样的操作(ABI=0),这里就发现这种方式很不方便了,yum install默认下载的包都是旧的GCC版本编译的,而我们现在用旧的GCC版本没法编译brpc(而这个问题又仅仅出现在centos上,我的unbuntu系统又运行正常),这就产生了冲突。然后编译通过,执行样例

 ./echo_server  & ./echo_client

当然不会成功,报错如下 ./echo_server: /lib64/libstdc++.so.6: version GLIBCXX_3.4.23' not found (required by ./echo_server) ./echo_server: /lib64/libstdc++.so.6: version CXXABI_1.3.8' not found (required by ./echo_server) ./echo_server: /lib64/libstdc++.so.6: version GLIBCXX_3.4.21' not found (required by ./echo_server) ./echo_server: /lib64/libstdc++.so.6: version GLIBCXX_3.4.20' not found (required by ./echo_server)

看起来它还是找的系统默认路径下libstdc++.so.6,为了维护我把gcc8.3.0下载到了/usr/local/gcc8.3.0,不过估计我下到/usr/local也没用,他又不会覆盖掉默认路径。 我把我的gcc8.3.0下的lib64的libstdc++.so.6拷贝到了默认路径下/usr/lib64,之后运行成功,取得阶段性胜利了属于是。

Kegem0 avatar Aug 11 '23 18:08 Kegem0

但是这么做显然不是一个很好的方案,这里其实最莫名其妙的问题是centos不支持gcc4.8.5直接编译,这个编译时的段错误有点莫名其妙了。因此我们不得不提高gcc的版本,我选择了8.3.0,而且很明显的一点,后面也出现了,旧版本的libstdc++.so.6根本不足以提供项目代码所有的需求,我看文件他应该是用的libstdc++.so.6.0.19,而我们gcc8.3.0用的是libstdc++.so.6.0.25,所以不管怎么说,这个动态链接库是肯定需要升级的。

之后的确没有段错误了,但是因为yum install默认下载的依赖都是旧的gcc编译的,而我们用高版本的gcc去编译brpc,就会导致ABI的不一致,因此我们需要给每个要用到这些依赖的MakeFile中指定-D_GLIBCXX_USE_CXX11_ABI=0。

因此最好还是找几个高并且稳定的版本,自己用gcc8.3.0编译用作依赖,这样这些问题就能避免,

当然,下午的时候我就尝试过自己用gcc 8.3.0去主动编译这些依赖了,问题也已经写在了上面。看来我对c++的理解还是过于浅薄,居然从来没想过头文件可能在编译的过程中不被打包,MakeFile一般不就是指定一下要编译哪些cpp文件吗,难道是因为要编译的cpp文件中并没有这个头文件的依赖,所以就没有打包进来?其实肯定不合乎情理,不然brcp引入这个头文件有啥意义,连相应的代码实现都没有被打包进来,所以我们肯定需要一个有意义的编译。而且protobuf写了的文件又不打包,是什么目的?估计还是我理解不到位。

顺带一提,如果我们要用brpc的CMake,它倒是不像config_brpc.sh --headers="/usr/include" --libs="/usr/lib64 /usr/bin" 可以指定依赖所在的路径,其通过find_path(),find_package()去找依赖,我现在有点难以把握,如果我们把包下载到一个指定位置这个方法能找到吗,而且centos通常有protobuf等的默认依赖,等会他先找到默认的又不好处理了,如果我们之后要形成一个大型项目,最终还是得依赖于cmake,还是先好好学习一下CMake吧

Kegem0 avatar Aug 11 '23 18:08 Kegem0

Compiler:gcc 4.8.5 5.4.0 8.3.0 都尝试过 brpc: master分支,release-1.6.0, release-1.5.0都尝试过

确认一下,使用release-1.5.0版本,还是会出现internal compiler error: Segmentation Fault的报错吗?有没有报错的文件和行号?(按理说doubly_buffer_data.h的修改是1.6.0引入的,1.5.0不应该还在那里报错)

wwbmmm avatar Aug 16 '23 07:08 wwbmmm

把gcc升级到了8.3.0,现在的异常看起来正常了些 image 应该是我使用的protobuf版本不兼容的问题,但是源码来说应该是有这个文件的,为何编译之后该文件丢失了?

找到问题的根源了,需要先执行yum install zlib-devel,以及yum update zlib protobuf执行./configure的时候会进行一些依赖的check,比如他会check zlib的版本。但是,之后的编译不会出问题,而是直接丢弃一些相关的头文件,继续编译。 但是brpc偏偏需要这些头文件,所以导致brpc的编译出错,如果不是在protobuf的issue上看到有人提了一嘴我估计这个问题是一辈子找不出来。

Kegem0 avatar Aug 16 '23 08:08 Kegem0

把gcc升级到了8.3.0,现在的异常看起来正常了些 image 应该是我使用的protobuf版本不兼容的问题,但是源码来说应该是有这个文件的,为何编译之后该文件丢失了?

找到问题的根源了,需要先执行yum install zlib-devel,以及yum update zlib protobuf执行./configure的时候会进行一些依赖的check,比如他会check zlib的版本。但是,之后的编译不会出问题,而是直接丢弃一些相关的头文件,继续编译。 但是brpc偏偏需要这些头文件,所以导致brpc的编译出错,如果不是在protobuf的issue上看到有人提了一嘴我估计这个问题是一辈子找不出来。

请问最后的解决方案是什么呀? 升级gcc到8.3.0,然后执行yum install zlib-devel,以及yum update zlib 最后再进行 make 编译吗?

tkzky avatar Oct 09 '23 02:10 tkzky

同样的环境碰到同样的问题。请问最后的解决方案是什么?

YuncyYe avatar Nov 08 '23 03:11 YuncyYe

需要高版本编译器,同时需要正确安装依赖

wasphin avatar Nov 08 '23 04:11 wasphin

需要高版本编译器,同时需要正确安装依赖

如何做到啊。

YuncyYe avatar Nov 08 '23 04:11 YuncyYe

CentOS 下可以在代码目录下执行以下命令安装相关依赖(需要 root 权限):

yum-builddep package/rpm/brpc.spec

之后可以 source devtoolset-8 的相关配置:

. /opt/rh/devtoolset-8/enable

wasphin avatar Nov 08 '23 05:11 wasphin

CentOS 下可以在代码目录下执行以下命令安装相关依赖(需要 root 权限):

yum-builddep package/rpm/brpc.spec

之后可以 source devtoolset-8 的相关配置:

. /opt/rh/devtoolset-8/enable

[yeyunxi@dev1 apache-brpc-1.7.0-src]$sudo yum-builddep package/rpm/brpc.spec File "/bin/yum-builddep", line 83 except yum.Errors.RepoError, e: ^ SyntaxError: invalid syntax 跑不了

YuncyYe avatar Nov 08 '23 07:11 YuncyYe

同样的环境碰到同样的问题。请问最后的解决方案是什么?

已经找到解决方案。需要的可以私下咨询。

YuncyYe avatar Nov 09 '23 00:11 YuncyYe

执行下面的命令, 再重新编译应该就好了

yum install -y  \
centos-release-scl \
devtoolset-8-gcc-c++ \
devtoolset-8-gcc \
yum-builddep package/rpm/brpc.spec && \
. /opt/rh/devtoolset-8/enable

theDreamBear avatar Dec 01 '23 09:12 theDreamBear

确实有这问题,doubly_buffered_data.h 替换为1.5.0 就可以了!编译成功!

lzhprigrammer avatar Feb 18 '24 08:02 lzhprigrammer

同样的环境碰到同样的问题。请问最后的解决方案是什么?

已经找到解决方案。需要的可以私下咨询。

为什么不能直接在这说呢

MathildaStacy avatar Aug 12 '24 02:08 MathildaStacy

1.5.0万事大吉

hecyxy avatar Oct 11 '24 10:10 hecyxy