交叉编译ARM:./.libs/libproc.so的协议时出错:错误:未定义对'描述符的引用

Make error when cross compiling protobuf for ARM:./.libs/libprotoc.so: error: undefined reference to #39;descriptor(交叉编译ARM:./.libs/libproc.so的协议时出错:错误:未定义对#39;描述符的引用)

本文介绍了交叉编译ARM:./.libs/libproc.so的协议时出错:错误:未定义对'描述符的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

交叉编译ARM协议时出错

编译的脚本:

  1 #!/bin/sh
  2 
  3 export PREFIX=$HOME/soft/protobuf_arm/
  4 CLANG_TOOLCHAIN=$HOME/soft/arm-29-toolchain-clang
  5 export PATH=$CLANG_TOOLCHAIN/bin:$PATH
  6 export SYSROOT=$CLANG_TOOLCHAIN/sysroot
  7 export CC="armv7a-linux-androideabi29-clang --sysroot $SYSROOT"
  8 export CXX="armv7a-linux-androideabi29-clang++ --sysroot $SYSROOT"
  9 
 10 cd $HOME/github/c++/protobuf
 11 make clean
 12 ./autogen.sh
 13 ./configure --prefix=$PREFIX 
 14 --host=armv7a-linux-androideabi29 
 15 --with-sysroot="${SYSROOT}" 
 16 --enable-shared 
 17 --enable-cross-compile 
 18 --with-protoc=$HOME/soft/protobuf_linux/protoc 
 19 CFLAGS="-march=armv7-a -D__ANDROID_API__=29" 
 20 CXXFLAGS="-frtti -fexceptions -march=armv7-a -D__ANDROID_API__=29" 
 21 LIBS="-llog -lz -lc++_static"
 22 make -j 12
 23 make install

配置中没有错误,make中出错:

In file included from google/protobuf/compiler/csharp/csharp_source_generator_base.cc:39:
./google/protobuf/compiler/csharp/csharp_source_generator_base.h:62:25: warning: private field 'descriptor_' is not used [-Wunused-private-field]
  const FileDescriptor* descriptor_;
                        ^
1 warning generated.
  CXXLD    libprotoc.la
clang90++: warning: argument unused during compilation: '-pthread' [-Wunused-command-line-argument]
clang90++: warning: argument unused during compilation: '-pthread' [-Wunused-command-line-argument]
  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'
clang90++: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Makefile:3883: protoc] Error 1
make[2]: Leaving directory '/home/sen/github/c++/protobuf/src'
make[1]: *** [Makefile:1866: all-recursive] Error 1
make[1]: Leaving directory '/home/sen/github/c++/protobuf'
make: *** [Makefile:1773: all] Error 2

环境

Linux x 5.6.15-arch1-1
GNU Make 4.3
NDK (Side by side) 21.1.6352462
protobuf v3.13.0

有趣的是,虽然报告了错误,但在协议buf/src/.libs下获得了.so等库文件。

推荐答案

简略回答

这可能有点复杂,但可以简单到:

  • -fuse-ld=bfd添加到CFLAGS
  • -fuse-ld=bfd添加到CXXFLAGS

如果这样做不能解决问题,则您可能还需要:

  • ./autogen.sh之后但在./configure补丁程序ltmain.sh之前,允许使用-fuse-ld=bfd(下面的补丁程序文件)

补丁文件(ltmain.sh.patch):

--- a/ltmain.sh 2015-02-16 04:15:37.000000000 +1100
+++ b/ltmain.sh 2021-05-23 18:18:46.000000000 +1000
@@ -7273,9 +7273,11 @@
       # --sysroot=*          for sysroot support
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       # -stdlib=*            select c++ std lib with clang
+      # -fuse-ld=*           Linker select flags for GCC
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| 
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| 
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| 
+      -fuse-ld=*)
         func_quote_for_eval "$arg"
    arg=$func_quote_for_eval_result
         func_append compile_command " $arg"

补丁命令:

patch -p1 < path/to/ltmain.sh.patch

详细答案

该问题是由于src/.libs/libprotobuf.so中的符号弱导出造成的,这与src/libprotobuf.map中提供的映射配置相冲突。此配置指定应强烈导出与模式*google*匹配的所有符号(因此可用于链接到protoc),而应隐藏所有其他符号。

但是,在运行armv7a-linux-androideabi29-clang++时使用的默认链接器(GOLD)中有一个bug,它忽略extern "C++"挡路中的任何映射指令。在NDK中提供了三个链接器:

  • ld
  • ld.bfd
  • ld.gold

BFD链接器没有相同的问题,因此前进的路径是将armv7a-linux-androideabi29-clang++配置为使用BFD链接器,这就是-fuse-ld=bfd选项执行的操作。

不幸的是,这可能不是很简单,因为Protobuf源代码是使用libtool构建的,而最新发布的版本不能识别-fuse-ld参数。因此,如果您的发行版libtool尚未将补丁应用到其打包版本,我们需要应用更改以允许它这样做(部分取自development commit)。这样做的侵入性最小的方法是等待必要的文件(ltmain.sh)作为./autogen.sh命令的一部分复制到源中,然后修补它,以便在处理该文件(作为./configure命令的一部分)时,更改会传播到创建的libtool文件中。

aarch64-linux-android29怎么办?

使用aarch64-linux-android29-clang++构建时,默认链接器已更改为BFD链接器,因此对于诸如protocol buf这样的代码库,此问题不会发生。使用上面的相同修补程序,您可以使用-fuse-ld=gold复制该问题。

这篇关于交叉编译ARM:./.libs/libproc.so的协议时出错:错误:未定义对&#39;描述符的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:交叉编译ARM:./.libs/libproc.so的协议时出错:错误:未定义对&#39;描述符的引用

基础教程推荐