docker ubuntu:20.04构建c++ grpc环境
由c++ grpc必须源码编译,ubuntu版本不同可能出现的问题也不同,这里分享下我的构建过程。
我是vscode结合docker去安装c++虚拟环境,我不想污染本机环境。
vscode的插件Dev Containers
Dockerfile如下(如果单纯是ubuntu环境构建,可忽略该文件):
# 使用官方的基础镜像作为起点
FROM ubuntu:20.04
# 设置环境变量,避免交互式配置提示
ENV DEBIAN_FRONTEND=noninteractive
# 设置工作目录
WORKDIR /app
# 将当前目录下的所有文件复制到容器内的/app目录
COPY .. /app/
# 保持容器运行
CMD ["bash"]
ubuntu 安装grpc开始
1.安装相关的依赖工具和依赖包
# 安装pkg-config
sudo apt-get install pkg-config
# 安装依赖包
sudo apt-get install autoconf automake libtool make g++ unzip
sudo apt-get install libgflags-dev libgtest-dev
sudo apt-get install clang libc++-dev
#安装cmake(有的话可以不安装,最好保证cmake版本大于3.13,查看版本命令:cmake --version)
apt install cmake
#安装golang,(不同于其他人的安装依赖,但我在安装grpc时报错了缺乏golang的安装,这条命令你可以不执行,等待实际报错后执行)
apt install golang-go
源码编译:
#下载grpc源码
git clone https://github.com/grpc/grpc.git
cd grpc
#切换到特定分支
git checkout 57586a1ca7f17b1916aed3dea4ff8de872dbf853
为何要特定分支?解决的issue如链接所述
**# 下载其依赖的子模块
git submodule update --init
编译构建protobuf(grpc依赖protobuf)
# 此时应在grpc文件夹下
cd third_party/protobuf/
# 更新依赖的子模块
git submodule update --init --recursive
# 生成配置脚本
sudo ./autogen.sh
# 生成makefile文件
sudo ./configure
# 从makefile读取指令编译
sudo make
# 可能报错,但不影响安装
sudo make check
# 安装
sudo make install
# 更新共享库缓存
sudo ldconfig
# 查看安装的位置
which protoc
#查看是否安装成功
protoc --version
重新回去编译构建grpc环境
# 回到grpc的根目录
cd -
mkdir -p cmake/build
cd cmake/build
cmake ../..
如果cmake报错如下: Could not find Go
则使用前面我说的apt安装golang环境。 下面make -j8报错则替换成make(日志比较详细),make -j8 install同理换成make install
# 编译,并行编译,但是可能存在报错了日志不详细的问题,报错了建议换成make
make -j8
如果报错信息如下:
[ 93%] Building CXX object third_party/boringssl/crypto/CMakeFiles/crypto_test.dir/x509/x509_test.cc.o
/workspaces/demo/grpc/third_party/boringssl/crypto/x509/x509_test.cc: In member function 'virtual void X509Test_ZeroLengthsWithX509PARAM_Test::TestBody()':
/workspaces/demo/grpc/third_party/boringssl/crypto/x509/x509_test.cc:712:10: error: declaration of 'struct X509Test_ZeroLengthsWithX509PARAM_Test::TestBody()::Test' shadows a member of 'X509Test_ZeroLengthsWithX509PARAM_Test' [-Werror=shadow]
712 | struct Test {
| ^~~~
In file included from /workspaces/demo/grpc/third_party/boringssl/crypto/x509/x509_test.cc:19:
/workspaces/demo/grpc/third_party/boringssl/third_party/googletest/include/gtest/gtest.h:375:23: note: shadowed declaration is here
375 | class GTEST_API_ Test {
| ^
cc1plus: all warnings being treated as errors
make[2]: *** [third_party/boringssl/crypto/CMakeFiles/crypto_test.dir/build.make:635: third_party/boringssl/crypto/CMakeFiles/crypto_test.dir/x509/x509_test.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:3444: third_party/boringssl/crypto/CMakeFiles/crypto_test.dir/all] Error 2
详细报错信息
其实grpc官方已经解决了,但是我已经构建到了93%,如果继续换版本,不知道又会有哪些问题,因此我决定改源码,这个报错主要是因为 x509_test.cc 文件中的一个结构体声明与类成员函数名称冲突,并且由于启用了 -Werror 选项,警告被当作错误处理。具体来说,struct Test 声明与 X509Test_ZeroLengthsWithX509PARAM_Test 类的成员函数 TestBody 内部的 Test 结构体名称冲突。
因此直接改/workspaces/demo/grpc/third_party/boringssl/crypto/x509/x509_test.cc文件,该文件路径会在报错中展示,没展示的原因可能是你是并行构建,改成make可能会展示详细。
修改源码
vi /workspaces/demo/grpc/third_party/boringssl/crypto/x509/x509_test.cc
关键改动如下:均是Test -> TestStruct
#报错了则重新make
make
make -j8 install
测试是否安装成功,运行官方案例
#grpc根目录
cd examples/cpp/helloworld
mkdir build
cd build
# 编译
cmake ..
make -j8
编译完成后,在文件夹下就生成了可执行文件,如图:
运行greeter_server服务
./greeter_server
自此grpc c++环境安装成功,并且可以将该docker生成个基础镜像,方便后续重复使用,后面就是docker相关的内容了,如果只是单纯在ubuntu构建的可以忽略后续步骤了。
ubuntu 安装grpc结束
构建Docker镜像开始
#查看正在运行的docker
docker ps
基于该docker构建镜像
# 6619ddff53f0换成你的container的id
docker commit 6619ddff53f0 ubuntu20.04-grpc:latest
#运行
docker run -d --name grpc-test ubuntu20.04-grpc:latest
#进入容器内部(8c5a06f569be31d41b72fcfa8c5a68fab1edf78fa86d7f4a04ea5c3003ee9f44换成)
docker exec -it grpc-test /bin/bash
后续就是验证grpc配置在新环境是否有效,只需要git clone源码后编译examples/cpp/helloworld项目即可。
(在新环境你会发现你前面的grpc源码都没有了,是因为vscode是把用户路径映射到了容器内部,docker commit不会拷贝这个路径,借此可以很巧妙地生成grpc干净环境)