1

为 Android 交叉编译 GSL

我正在尝试使用 Autotools 交叉编译适用于 Android 4.1 的 GNU Scientific Library (GSL)。我的构建和主机如下:

build="i386-apple-darwin10.8.0"
host="arm-linux-androideabi"

自动工具版本:

GNU Automake version 1.11.3
GNU Autoconf version 2.68
GNU Libtool version 2.4.2

我的目标是编译一个可执行文件,我可以从模拟设备上的 shell 运行它。到目前为止,我已经使用我使用 Android Native Development Kit (NDK) 生成的工具链编译了 GSL 和我的可执行文件。然后我将共享库“libgsl.so.0”和“libgslcblas.so.0”(两者都列在我的可执行文件的动态部分中)推送到“/system/lib”并将可执行文件推送到设备。

这是 arm-linux-androideabi-readelf -d issm.exe 的输出

Dynamic section at offset 0x26a2a4 contains 26 entries:
Tag        Type                         Name/Value
0x00000001 (NEEDED)                     Shared library: [libgsl.so.0]
0x00000001 (NEEDED)                     Shared library: [libgslcblas.so.0]
0x00000001 (NEEDED)                     Shared library: [libm.so]
0x00000001 (NEEDED)                     Shared library: [libc.so]
0x00000001 (NEEDED)                     Shared library: [libdl.so]
0x0000000f (RPATH)                      Library rpath: [/Users/gperez/issm/issm-uci/trunk-jpl/externalpackages/gsl/install/lib]
0x00000020 (PREINIT_ARRAY)              0x26d000
0x00000021 (PREINIT_ARRAYSZ)            0x8
0x00000019 (INIT_ARRAY)                 0x26d008
0x0000001b (INIT_ARRAYSZ)               1100 (bytes)
0x0000001a (FINI_ARRAY)                 0x26d454
0x0000001c (FINI_ARRAYSZ)               8 (bytes)
0x00000004 (HASH)                       0x8128
0x00000005 (STRTAB)                     0x96a0
0x00000006 (SYMTAB)                     0x87f0
0x0000000a (STRSZ)                      3588 (bytes)
0x0000000b (SYMENT)                     16 (bytes)
0x00000015 (DEBUG)                      0x0
0x00000003 (PLTGOT)                     0x27239c
0x00000002 (PLTRELSZ)                   960 (bytes)
0x00000014 (PLTREL)                     REL
0x00000017 (JMPREL)                     0xa7ec
0x00000011 (REL)                        0xa4a4
0x00000012 (RELSZ)                      840 (bytes)
0x00000013 (RELENT)                     8 (bytes)
0x00000000 (NULL)                       0x0

我意识到 RPATH 不正确,但如果我正确理解了动态链接器,那么它应该无法在 RPATH 中找到所需的库,然后继续检查所有库所在的 LD_LIBRARY_PATH。

然后我继续运行我的可执行文件,但我惊讶地发现以下链接错误:

link_image[1936]:   468 could not load needed library 'libgsl.so.0' for './issm.exe' (reloc_library[1285]:   468 cannot locate 'cblas_ctrmv'...
)CANNOT LINK EXECUTABLE

这个错误导致我检查'libgsl.so.0'的内容如下:

Relocation section '.rel.plt' at offset 0x36014 contains 161 entries:
Offset     Info    Type            Sym.Value  Sym. Name
00201c54  00002316 R_ARM_JUMP_SLOT   00000000   cblas_ctrmv
00201c58  00002f16 R_ARM_JUMP_SLOT   00000000   cblas_zswap
00201c5c  00003816 R_ARM_JUMP_SLOT   00000000   cblas_zsymm
00201c60  00005016 R_ARM_JUMP_SLOT   00000000   cblas_cgeru
00201c64  00009216 R_ARM_JUMP_SLOT   00000000   cblas_sgemm
00201c68  00009c16 R_ARM_JUMP_SLOT   00000000   cblas_ctrsv
00201c6c  0000c316 R_ARM_JUMP_SLOT   00000000   cblas_sgemv
...

'libgslcblas.so.0' 对应的 '.dynsym':

Symbol table '.dynsym' contains 233 entries:
Num:    Value  Size Type    Bind   Vis      Ndx Name
...
218: 0004e148    64 FUNC    GLOBAL DEFAULT    7 __aeabi_f2d
219: 00050314     0 NOTYPE  GLOBAL DEFAULT   12 __data_start
220: 0000d69c  1604 FUNC    GLOBAL DEFAULT    7 cblas_dgbmv
221: 0002e008  3540 FUNC    GLOBAL DEFAULT    7 cblas_ctrmv
222: 00042c34  4184 FUNC    GLOBAL DEFAULT    7 cblas_ztbmv
223: 0004de4c   688 FUNC    GLOBAL DEFAULT    7 __subdf3
224: 00003dc4   284 FUNC    GLOBAL DEFAULT    7 cblas_snrm2
...

由于重定位部分“.rel.plet”中的第一个条目导致链接失败,因此问题很可能与所有“cblas”符号有关。然后我决定查看“libgsl.so.0”的动态部分

Dynamic section at offset 0x200b60 contains 25 entries:
Tag        Type                         Name/Value
0x00000001 (NEEDED)                     Shared library: [libm.so]
0x00000001 (NEEDED)                     Shared library: [libc.so]
0x00000001 (NEEDED)                     Shared library: [libdl.so]
0x0000000e (SONAME)                     Library soname: [libgsl.so.0]
0x00000010 (SYMBOLIC)                   0x0
0x0000000f (RPATH)                      Library rpath: [:/Users/gperez/issm/issm-uci/trunk-jpl/externalpackages/gsl/install/lib]
0x00000019 (INIT_ARRAY)                 0x200c68
0x0000001b (INIT_ARRAYSZ)               8 (bytes)
0x0000001a (FINI_ARRAY)                 0x200c70
0x0000001c (FINI_ARRAYSZ)               12 (bytes)
0x00000004 (HASH)                       0xb4
0x00000005 (STRTAB)                     0x19b1c
0x00000006 (SYMTAB)                     0x860c
0x0000000a (STRSZ)                      107542 (bytes)
0x0000000b (SYMENT)                     16 (bytes)
0x00000003 (PLTGOT)                     0x201c48
0x00000002 (PLTRELSZ)                   1288 (bytes)
0x00000014 (PLTREL)                     REL
0x00000017 (JMPREL)                     0x36014
0x00000011 (REL)                        0x33f34
0x00000012 (RELSZ)                      8416 (bytes)
0x00000013 (RELENT)                     8 (bytes)
0x00000016 (TEXTREL)                    0x0
0x6ffffffa (RELCOUNT)                   1051
0x00000000 (NULL)                       0x0

在这里,我发现该库具有引用“cblas”条目的重定位符号非常有趣,但“libgslcblas.so.0”未在动态部分中列出。这对我来说感觉不对,但我没有专业知识可以这么明确地说出来。任何人都可以帮忙吗?

我正在继续调查,但我非常感谢任何建议、更正或输入或任何形式!

问题

  1. 鉴于“libgsl.so.0”在其重定位部分对 cblas 结构的引用,“libgslcblas.so.0”是否应该在“libgsl.so.0”的动态部分中?
  2. 设置不正确的 RPATH 会是这一切的根源吗?
4

1 回答 1

0

我建议使用 AOSP 而不是 autotools。

通过将 GSL 源代码包装到 Android make 文件中,可以将 GSL 集成到 Android 中。然后,您可以使用此 Android make 文件中定义的模块来访问 GSL 的功能。

但是,这仅提供对在 AOSP 中编译的应用程序的访问。

于 2015-08-10T11:24:33.953 回答