一、交叉編譯protobuf
1.配置交叉編譯器
export PATH=$PATH:/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin:/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/lib
source /opt/EC20_crosstool/ql-ol-crosstool/ql-ol-crosstool-env-init
2.編譯
1.cd /home/workspace/project/arm_grpc/third_party/protobuf/cmake
2.mkdir arm_build
3.cd arm_build
4.cmake .. -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_CXX_COMPILER:FILEPATH=/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-g++ -DCMAKE_C_COMPILER:FILEPATH=/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc -DCMAKE_BUILD_TYPE:STRING=RELEASE -DCMAKE_INSTALL_PREFIX=/home/workspace/test/arm_install -DBUILD_SHARED_LIBS=ON
5.make -j8
6.make install -j8
編譯的時候報錯
原因是/usr/local/lib/libz.so是Ubuntu下編譯的,因此需要交叉編譯libz.so,在EC20編譯器中搜索到有這個庫。爲了圖省事,直接將EC20中的libz.so拷貝替換/usr/local/lib/中的libz.so。
編譯成功
二、交叉編譯grpc
1.mkdir -p cmake/arm_build
2.cd cmake/arm_build
3.cmake ../.. -DCMAKE_CXX_COMPILER:FILEPATH=/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-g++ -DCMAKE_C_COMPILER:FILEPATH=/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc -DCMAKE_BUILD_TYPE:STRING=RELEASE -DCMAKE_INSTALL_PREFIX=/home/workspace/test/arm_install -DBUILD_SHARED_LIBS=ON
執行make報錯
/home/workspace/test/grpc/third_party/boringssl-with-bazel/linux-x86_64/crypto/chacha/chacha-x86_64.S: Assembler messages:
/home/workspace/test/grpc/third_party/boringssl-with-bazel/linux-x86_64/crypto/chacha/chacha-x86_64.S:1633: Error: junk at end of line, first unrecognized character is `,'
make[2]: *** [third_party/boringssl-with-bazel/CMakeFiles/crypto.dir/linux-x86_64/crypto/chacha/chacha-x86_64.S.o] Error 1
make[1]: *** [third_party/boringssl-with-bazel/CMakeFiles/crypto.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
使用make -j8 HAS_PKG_CONFIG=false PROTOBUF_CONFIG_OPTS="–host=arm-oe-linux-gnueabi --with-protoc=/usr/local/bin/protoc" 錯誤還是一樣。
具體原因還是沒找到。放棄cmake的方式進行編譯。直接在grpc目錄下使用make的方式編譯,不通過cmake重新構造Makefile。
export GRPC_CROSS_COMPILE=true
export GRPC_CROSS_AROPTS="cr --target=elf32-little"
make clean 注意一定要先清除,不然會編譯出錯。
make -j8 HAS_PKG_CONFIG=false CC=arm-oe-linux-gnueabi-gcc CXX=arm-oe-linux-gnueabi-g++ RANLIB=arm-oe-linux-gnueabi-ranlib LD=arm-oe-linux-gnueabi-ld LDXX=arm-oe-linux-gnueabi-g++ AR=arm-oe-linux-gnueabi-ar PREFIX=/home/workspace/test/arm_install PROTOBUF_CONFIG_OPTS="--host=arm-oe-linux-gnueabi --with-protoc=/usr/local/bin/protoc"
沒辦法make install,因爲是交叉編譯,只需將libs/opt中的庫文件拷貝到設備中即可。
之前因爲沒有添加export GRPC_CROSS_COMPILE=true
export GRPC_CROSS_AROPTS=“cr --target=elf32-little”。
導致libs/opt並沒有看到交叉編譯過的grpc庫。
添加之後重新編譯,編譯成功。
說明arm版本已經編譯ok了。
還有一種比較簡單的方式判斷當前庫是交叉編譯還是gcc版本。因爲我電腦是64位,開發板是32位,所以直接使用objdump來進行判斷。例如:
objdump -a libgrpc.a
三、交叉編譯demo與設備實測
交叉編譯helloworld demo
使用make方式進行編譯。只需要交叉編譯greeter_server和greeter_client測試基本功能就好了,順便看看哪些庫可以不用拷貝到設備中。
cd /home/workspace/test/grpc/examples/cpp/helloworld
make greeter_server HAS_PKG_CONFIG=false CC=arm-oe-linux-gnueabi-gcc CXX=arm-oe-linux-gnueabi-g++ RANLIB=arm-oe-linux-gnueabi-ranlib LD=arm-oe-linux-gnueabi-ld LDXX=arm-oe-linux-gnueabi-g++ AR=arm-oe-linux-gnueabi-ar PREFIX=/home/workspace/project/grpc/arm_build PROTOBUF_CONFIG_OPTS="–host=arm-oe-linux-gnueabi --with-protoc=/usr/local/bin/protoc"
如果忘記將libs/opt中的庫拷貝到交叉編譯protobuf 安裝的目錄/home/workspace/test/arm_install中的話就會報錯。
發現只要鏈接這三個庫就可以。於是我只拷貝這幾個庫(因爲編譯出來得庫都挺大的)。而且還要修改下helloworld目錄下的makefile
修改前
修改後
交叉編譯成功
將這些庫拷貝到設備中
設置好設備的環境變量。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usrdata/grpc/lib
運行時發現,佔用空間都一致應該是同一個動態庫,因此爲了節省空間創建軟連接。
最終在EC20設備上成功運行。
但存在個問題,庫太佔用空間了。後面得想辦法裁剪一下。
過程中遇到的一些坑爹的問題,後面重頭操作幾次後,總算解決了。順便記錄下自己過程中遇到的奇奇怪怪的問題。
錯誤:
[HOSTCXX] Compiling src/compiler/cpp_generator.cc
In file included from ./src/compiler/config_protobuf.h:22:0,
from ./src/compiler/config.h:22,
from ./src/compiler/cpp_generator.h:29,
from src/compiler/cpp_generator.cc:21:
include/grpcpp/impl/codegen/config_protobuf.h:30:37: fatal error: google/protobuf/message.h: No such file or directory
#include <google/protobuf/message.h>
^
compilation terminated.
make: *** [/home/workspace/project/grpc/objs/opt/src/compiler/cpp_generator.o] Error 1
make: *** Waiting for unfinished jobs....
CXX google/protobuf/compiler/main.o
CXXLD libprotobuf-lite.la
libtool: link: warning: library `/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/../../armv7a-vfp-neon-oe-linux-gnueabi/usr/lib/libstdc++.la' was moved.
CXXLD libprotobuf.la
libtool: link: warning: library `/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/../../armv7a-vfp-neon-oe-linux-gnueabi/usr/lib/libstdc++.la' was moved.
CXXLD libprotoc.la
libtool: link: warning: `/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/../../armv7a-vfp-neon-oe-linux-gnueabi/usr/lib/libstdc++.la' seems to be moved
libtool: link: warning: library `/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/../../armv7a-vfp-neon-oe-linux-gnueabi/usr/lib/libstdc++.la' was moved.
CXXLD protoc
libtool: link: warning: library `/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/../../armv7a-vfp-neon-oe-linux-gnueabi/usr/lib/libstdc++.la' was moved.
libtool: link: warning: library `/opt/EC20_crosstool/ql-ol-crosstool/sysroots/x86_64-oesdk-linux/usr/bin/arm-oe-linux-gnueabi/../../armv7a-vfp-neon-oe-linux-gnueabi/usr/lib/libstdc++.la' was moved.
./.libs/libprotoc.so: error: undefined reference to 'descriptor_table_google_2fprotobuf_2fdescriptor_2eproto'
./.libs/libprotoc.so: error: undefined reference to 'scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto'
collect2: error: ld returned 1 exit status
make[2]: *** [protoc] Error 1
make[2]: Leaving directory `/home/workspace/project/grpc/third_party/protobuf/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/workspace/project/grpc/third_party/protobuf'
make: *** [all] Error 2
grpc_transport* grpc_create_cronet_transport(void* engine, const char* target,
^
[AR] Creating /home/workspace/project/grpc/libs/opt/libgrpc_cronet.a
[STRIP] Stripping libaddress_sorting.a
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libaddress_sorting.a(address_sorting_posix.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libaddress_sorting.a(address_sorting_windows.o)'
[STRIP] Stripping libgpr.a
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(atm.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(cpu_iphone.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(cpu_linux.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(cpu_posix.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(cpu_windows.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(env_linux.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(env_posix.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(env_windows.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(log.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(log_android.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libgpr.a(log_linux.o)'
strip: Unable to recognise the format of the input file `/home/workspace/project/grpc/libs/opt/libupb.a(upb.o)'
[INSTALL] Installing C pkg-config files
[INSTALL] Installing libaddress_sorting.a
[INSTALL] Installing libgpr.a
[INSTALL] Installing libgrpc.a
[INSTALL] Installing libgrpc_cronet.a
[INSTALL] Installing libgrpc_unsecure.a
[INSTALL] Installing libupb.a
[LD] Linking /home/workspace/project/grpc/libs/opt/libaddress_sorting.so.9.0.0
/usr/bin/ld: /home/workspace/project/grpc/objs/opt/third_party/address_sorting/address_sorting.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: /home/workspace/project/grpc/objs/opt/third_party/address_sorting/address_sorting.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: /home/workspace/project/grpc/objs/opt/third_party/address_sorting/address_sorting.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: /home/workspace/project/grpc/objs/opt/third_party/address_sorting/address_sorting.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: /home/workspace/project/grpc/objs/opt/third_party/address_sorting/address_sorting.o: Relocations in generic ELF (EM: 40)
/home/workspace/project/grpc/objs/opt/third_party/address_sorting/address_sorting.o: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make: *** [/home/workspace/project/grpc/libs/opt/libaddress_sorting.so.9.0.0] Error 1
This warning is for project developers. Use -Wno-dev to suppress it.
-- Found ZLIB: /usr/local/lib/libz.so (found version "1.2.11")
-- Using protobuf
CMake Error at CMakeLists.txt:113 (find_package):
Could not find a configuration file for package "gRPC" that is compatible
with requested version "".
The following configuration files were considered but not accepted:
/usr/local/lib/cmake/grpc/gRPCConfig.cmake, version: 1.28.0-pre3 (64bit)
[CXX] Compiling src/core/tsi/ssl_transport_security.cc
gnu-configize: 'configure.ac' or 'configure.in' is required
autoreconf: gnu-configize failed with exit status: 1
make: *** [third_party/protobuf/configure] Error 1
make: *** Waiting for unfinished jobs....
src/core/tsi/fake_transport_security.cc:498:34: warning: unused parameter 'self' [-Wunused-parameter]
const tsi_handshaker_result* self, tsi_peer* peer) {
make all-recursive
make[1]: Entering directory `/home/workspace/project/grpc/third_party/protobuf'
Making all in .
make[2]: Entering directory `/home/workspace/project/grpc/third_party/protobuf'
make[2]: Leaving directory `/home/workspace/project/grpc/third_party/protobuf'
Making all in src
make[2]: Entering directory `/home/workspace/project/grpc/third_party/protobuf/src'
CXXLD protoc
./.libs/libprotoc.so: error: undefined reference to 'descriptor_table_google_2fprotobuf_2fdescriptor_2eproto'
./.libs/libprotoc.so: error: undefined reference to 'scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto'
collect2: error: ld returned 1 exit status
make[2]: *** [protoc] Error 1
make[2]: Leaving directory `/home/workspace/project/grpc/third_party/protobuf/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/workspace/project/grpc/third_party/protobuf'
make: *** [all] Error 2
-- Found Protobuf: /usr/local/bin/protoc-3.11.2.0 (found version "3.11.2.0")
-- Using protobuf
CMake Error at CMakeLists.txt:113 (find_package):
Could not find a configuration file for package "gRPC" that is compatible
with requested version "".
The following configuration files were considered but not accepted:
/usr/local/lib/cmake/grpc/gRPCConfig.cmake, version: 1.28.0-pre3 (64bit)
-- Configuring incomplete, errors occurred!
差點整崩潰,後面幾次重新解壓源碼重新流程操作幾次與參考網上博客,總算問題解決了。
四、參考資料
交叉編譯gRPC_嵌入式_maimang1001的專欄-CSDN博客 https://blog.csdn.net/maimang1001/article/details/100561970
移植protobuf遇到的一點小問題_Johnny_nass_hu的專欄-CSDN博客 https://blog.csdn.net/Johnny_nass_hu/article/details/84138749
grpc arm 交叉編譯(ubuntu 16.04)_嵌入式_學習————-CSDN博客 https://blog.csdn.net/qq_35487883/article/details/94398728
記一次grpc arm-hisiv400-linux交叉編譯_嵌入式_vc66vcc的博客-CSDN博客 https://blog.csdn.net/vc66vcc/article/details/83614906
Arm下Grpc交叉編譯過程記錄_嵌入式_深圳趣奇多科技-CSDN博客 https://blog.csdn.net/poolooloo/article/details/97890673