背景

公司最近采购了一批服务器,其中一台需要安装Protobuf-2.5.0方便算法同学当开发机使用,基础环境编译的需求交给我来完成。打开Protobuf GitHub官方release地址,找到下载链接通过wget下载到服务器:

[root@workstation protobuf]# tar -xzvf protobuf-2.5.0.tar.gz
[root@workstation protobuf-2.5.0]# cd protobuf-2.5.0
#直接运行./configure将默认安装到/usr/local,为了后续多版本切换指定安装目录/opt/protobuf/protobuf-2.5.0 
[root@workstation protobuf-2.5.0]# ./configure --prefix=/opt/protobuf/protobuf-2.5.0 
[root@workstation protobuf-2.5.0]# make

make、cmake、gcc、g++等基础编译工具的安装过程本文就直接跳过了,有问题的可以自行百度或者谷歌。本来以为就是一次简单的编译过程,没想到直接报出一个error:

In file included from ./google/protobuf/stubs/atomicops.h:59:0,
                 from google/protobuf/stubs/atomicops_internals_x86_gcc.cc:36:
./google/protobuf/stubs/platform_macros.h:61:2: error: #error Host architecture was not detected as supported by protobuf
 #error Host architecture was not detected as supported by protobuf
  ^~~~~
In file included from google/protobuf/stubs/atomicops_internals_x86_gcc.cc:36:0:
./google/protobuf/stubs/atomicops.h:161:1: error: stray '#' in program
 #error "Atomic operations are not supported on your platform"
 ^
./google/protobuf/stubs/atomicops.h:188:1: note: in expansion of macro 'GOOGLE_PROTOBUF_ATOMICOPS_ERROR'
 GOOGLE_PROTOBUF_ATOMICOPS_ERROR
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./google/protobuf/stubs/atomicops.h:161:2: error: 'error' does not name a type; did you mean 'perror'?
 #error "Atomic operations are not supported on your platform"
  ^
./google/protobuf/stubs/atomicops.h:188:1: note: in expansion of macro 'GOOGLE_PROTOBUF_ATOMICOPS_ERROR'
 GOOGLE_PROTOBUF_ATOMICOPS_ERROR
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [atomicops_internals_x86_gcc.lo] 错误 1
make[2]: 离开目录“/root/protobuf/protobuf-2.5.0/src”
make[1]: *** [all-recursive] 错误 1
make[1]: 离开目录“/root/protobuf/protobuf-2.5.0”
make: *** [all] 错误 2

和运维确认了一下,为了降低运营成本公司本次采购了一批64位ARM服务器(aarch64架构)来替换此前的Intel/AMD服务器(x64架构),protobuf-2.5.0发布时并未支持ARM架构,如果强制编译就会出现上面的错误。想要在ARM平台下成功编译protobuf-2.5.0就需要改一下源码了。

aarch64架构适配

将适配aarch64架构的源码包重名为protobuf-2.5.0-aarch64.tar.gz并上传到内网代码库提供给各部门使用,接下来将基于该版本进行编译:

[root@workstation protobuf]# tar -xzvf protobuf-2.5.0-aarch64.tar.gz 
[root@workstation protobuf-2.5.0]# cd protobuf-2.5.0-aarch64
[root@workstation protobuf-2.5.0-aarch64]# ./configure --prefix=/opt/protobuf/protobuf-2.5.0
[root@workstation protobuf-2.5.0-aarch64]# make

适配后的源码整个编译过程还是比较顺利的,执行期间不再有error出现,日志如下:

make  all-am
make[3]: 进入目录“/root/protobuf/protobuf-2.5.0-aarch64/src”
/bin/sh ../libtool --tag=CXX   --mode=link g++ -pthread -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -O2 -g -DNDEBUG -version-info 8:0:0 -export-dynamic -no-undefined  -o libprotobuf-lite.la -rpath /opt/protobuf/protobuf-2.5.0/lib atomicops_internals_x86_gcc.lo atomicops_internals_x86_msvc.lo common.lo once.lo stringprintf.lo extension_set.lo generated_message_util.lo message_lite.lo repeated_field.lo wire_format_lite.lo coded_stream.lo zero_copy_stream.lo zero_copy_stream_impl_lite.lo -lpthread -lz
libtool: link: ar cru .libs/libprotobuf-lite.a  atomicops_internals_x86_gcc.o atomicops_internals_x86_msvc.o common.o once.o stringprintf.o extension_set.o generated_message_util.o message_lite.o repeated_field.o wire_format_lite.o coded_stream.o zero_copy_stream.o zero_copy_stream_impl_lite.o
libtool: link: ranlib .libs/libprotobuf-lite.a
libtool: link: ( cd ".libs" && rm -f "libprotobuf-lite.la" && ln -s "../libprotobuf-lite.la" "libprotobuf-lite.la" )
make[3]: 离开目录“/root/protobuf/protobuf-2.5.0-aarch64/src”
make[2]: 离开目录“/root/protobuf/protobuf-2.5.0-aarch64/src”
make[1]: 离开目录“/root/protobuf/protobuf-2.5.0-aarch64”

通过make install完成最后安装,然后移步到目标目录查看结果:

[root@workstation protobuf-2.5.0-aarch64]# cd /opt/protobuf/protobuf-2.5.0/
[root@workstation protobuf-2.5.0]# tree -L 2
.
├── bin
│   └── protoc
├── include
│   └── google
└── lib
    ├── libprotobuf.a
    ├── libprotobuf.la
    ├── libprotobuf-lite.a
    ├── libprotobuf-lite.la
    ├── libprotobuf-lite.so -> libprotobuf-lite.so.8.0.0
    ├── libprotobuf-lite.so.8 -> libprotobuf-lite.so.8.0.0
    ├── libprotobuf-lite.so.8.0.0
    ├── libprotobuf.so -> libprotobuf.so.8.0.0
    ├── libprotobuf.so.8 -> libprotobuf.so.8.0.0
    ├── libprotobuf.so.8.0.0
    ├── libprotoc.a
    ├── libprotoc.la
    ├── libprotoc.so -> libprotoc.so.8.0.0
    ├── libprotoc.so.8 -> libprotoc.so.8.0.0
    ├── libprotoc.so.8.0.0
    └── pkgconfig

5 directories, 16 files

可以看到动态链接库和静态库都已经生成了,最后一步就是验证so库是不是aarch64架构下编译成功的:

[root@workstation protobuf-2.5.0]# readelf -h lib/libprotobuf.so.8.0.0
ELF 头:
  Magic:  7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  类别:                              ELF64
  数据:                              2 补码,小端序 (little endian)
  版本:                              1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              DYN (共享目标文件)
  系统架构:                          AArch64
  版本:                              0x1
  入口点地址:              0x4e860
  程序头起点:              64 (bytes into file)
  Start of section headers:          10016400 (bytes into file)
  标志:             0x0
  本头的大小:       64 (字节)
  程序头大小:       56 (字节)
  Number of program headers:         7
  节头大小:         64 (字节)
  节头数量:         36
  字符串表索引节头: 35

编译测试

syntax = "proto2";

package com.example.protobuf.demo.proto;
option java_multiple_files = true;

message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3;
}

定义一个名为demo.proto的文件,然后通过aarch64平台下编译成功的protoc进行生成java文件:

[root@workstation bin]# ./protoc src/demo.proto --java_out target/
[root@workstation bin]# tree -L 7
.
├── protoc
├── src
│   └── demo.proto
└── target
    └── com
        └── example
            └── protobuf
                └── demo
                    └── proto
                        ├── Demo.java
                        ├── SearchRequest.java
                        └── SearchRequestOrBuilder.java

7 directories, 5 files

编译成功,至此开发环境可以交付。

声明
1.本网站名称: 盲盒博客
2.本站永久网址:https://exakit.com
3.本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长support@exakit.com
4.本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责
5.本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
6.本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新