【问题标题】:Building OpenSSL 1.0.2n for 64-bit Android with NDK r16b undefined reference to bsd_signal使用 NDK r16b 为 64 位 Android 构建 OpenSSL 1.0.2n 未定义对 bsd_signal 的引用
【发布时间】:2018-08-24 23:32:22
【问题描述】:

我正在尝试使用最新的 Android NDK r16b 构建 OpenSSL 1.0.2n。为 32 位拱门(armv7、x86)构建工作得很好,但是当我尝试为 64 位拱门(arm64、x86_64)构建时,我收到一个链接器错误,指出 bsd_signal 未定义:

shlib_target=; if [ -n "libcrypto.so.1.0.0 libssl.so.1.0.0" ]; then \
        shlib_target="linux-shared"; \
    elif [ -n "" ]; then \
      FIPSLD_CC="aarch64-linux-android-gcc"; CC=/usr/local/ssl/fips-2.0/bin/fipsld; export CC FIPSLD_CC; \
    fi; \
    LIBRARIES="-L.. -lssl  -L.. -lcrypto" ; \
    /Applications/Xcode.app/Contents/Developer/usr/bin/make -f ../Makefile.shared -e \
        APPNAME=openssl OBJECTS="openssl.o verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o ca.o pkcs7.o crl2p7.o crl.o rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o s_time.o apps.o s_cb.o s_socket.o app_rand.o version.o sess_id.o ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o" \
        LIBDEPS=" $LIBRARIES -ldl" \
        link_app.${shlib_target}
req.o: In function `req_main':
req.c:(.text+0x368): undefined reference to `bsd_signal'
ca.o: In function `ca_main':
ca.c:(.text+0xe90): undefined reference to `bsd_signal'
ecparam.o: In function `ecparam_main':
ecparam.c:(.text+0x30): undefined reference to `bsd_signal'
s_server.o: In function `s_server_main':
s_server.c:(.text+0x32c0): undefined reference to `bsd_signal'
pkcs12.o: In function `pkcs12_main':
pkcs12.c:(.text+0x1134): undefined reference to `bsd_signal'
cms.o:cms.c:(.text+0x98): more undefined references to `bsd_signal' follow
collect2: error: ld returned 1 exit status

我看到 bsd_signal 曾一度从 NDK 中省略,但在 NDK 13 (https://github.com/android-ndk/ndk/issues/160) 中又添加了回来。此外,如果它完全丢失,我预计 32 位构建也会失败。

这是我尝试用于 arm64 构建的配置(这实际上是通过一个脚本完成的,该脚本很长。为了避免在此处粘贴整个废话,这些是最终使用的值被执行):

export MACHINE=armv7
export ARCH=arm64
export CROSS_COMPILE="aarch64-linux-android-"
export ANDROID_SYSROOT="$ANDROID_NDK_ROOT/platforms/android-21/arch-arm64"
export SYSROOT="$ANDROID_SYSROOT"
export NDK_SYSROOT="$ANDROID_SYSROOT"
export ANDROID_NDK_SYSROOT="$ANDROID_SYSROOT"
export ANDROID_API=android-21

export ANDROID_DEV="$ANDROID_NDK_ROOT/platforms/android-21/arch-arm64/usr"
export HOSTCC=gcc
export ANDROID_TOOLCHAIN="$ANDROID_NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin"
export PATH="$ANDROID_TOOLCHAIN":"$PATH"

./Configure shared no-ssl2 no-ssl3 no-comp no-hw no-engine linux-generic64 --openssldir=/usr/local/ssl/android-21 -fPIE -D__ANDROID_API__=android-21 -I$ANDROID_NDK_ROOT/sysroot/usr/include -I$ANDROID_NDK_ROOT/sysroot/usr/include/aarch64-linux-android -B$ANDROID_NDK_ROOT/platforms/android-21/arch-arm64/usr/lib

make clean
make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" depend
make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" all

在这一点上我已经尝试了很多不同的东西,我什至无法开始列出它们。

有人知道我在这里缺少什么吗?

【问题讨论】:

  • 在测试用例提交 there's a function called match_unsupported 中,它似乎与所有 64 位 ABI 匹配。不过,我在提交或问题中没有看到任何解释。
  • 没有为 LP64 ABI 放回 back,因为函数调用在 LP64 ABI 上从未存在过。将它添加到 NDK 存根库可以让您构建,但是当库加载时您只会崩溃,因为设备上没有实现:)

标签: android android-ndk openssl


【解决方案1】:
  1. 我建议使用 Android NDK 附带的 ma​​ke 来构建 NDK 工具链。如果它不在您的 PATH 上,您可以在

    找到它
    $ANDROID_NDK_ROOT/prebuilt/darwin-x86_64/bin/make
    

    我认为这不是您的问题的真正原因。

  2. bsd_signal 是从platforms/android-21/arch-arm/usr/lib/libc.so 以及对应的libc.a 导出的,但不是从platforms/android-21/arch-arm64/usr/lib/libc.so 导出的。

  3. 它在统一标头中标记为 __REMOVED_IN(21),因此我希望编译器会发出有关使用未定义函数的警告。

  4. 一种可能的解决方法是提供一个虚拟的 bsd_signal,正如 Felipe Cavalcanti 建议的 on GitHub

  5. bsd_signal 的问题似乎已在 openssl 1.1 系列中得到解决。

  6. 您在命令行上有一个错误:请改用 -D__ANDROID_API__=21

【讨论】:

  • 遗憾的是,这些都不起作用。添加您链接到的 GitHub 存储库中显示的虚假 bsd_signal 实现只是导致其他奇怪的问题,并且切换到 OpenSSL 1.1 仍然有 bsd_signal 链接错误(尽管略有不同)。查看 OpenSSL 的 GitHub 项目,他们有一个 1.1.1 的开放项目以添加 arm64 支持(github.com/openssl/openssl/issues/2490)。我想我只需要等待。
  • 请注意,使用静态库而不是 libssl 和 libcrypto 的共享库更安全:在旧平台(如 android-21)上,动态链接器可能会从 /system/lib 获取副本,这可能会导致在奇怪的问题中。
  • 谢谢!编辑(#6)使事情正常进行。在虚假的bsd_signal 中存根导致它无法找到某些标头、其他不同的链接器错误以及许多其他奇怪的东西。我将它添加到apps.c,所以也许有一些东西,但是 IDK - 我并没有费心去追逐它。另外,出于这个原因,我实际上确实在我的项目中使用了静态库。 shared 标志只是原始脚本源中遗留下来的产物。
  • 是的,如果没有有效的 ANDROID_API,NDK r16 的统一标头将无法正常工作
  • 还有一个重要提示 - 如果您正在为 x86 或 x86_64 构建 OpenSSL,您必须在配置 OpenSSL 时传递 shared 选项,否则将无法获得 -fPIC作为第一个参数传递给编译器,当您尝试再次链接库时会出现链接器错误。
【解决方案2】:

这绝对看起来像是针对一个 API 级别构建并与另一个 API 级别链接的情况(或者可能是标头 ABI 与库 ABI 不匹配?)。为了排除任何配置问题(即使没有解决问题,也可以简单地构建您的版本),我建议使用standalone toolchain

【讨论】:

    猜你喜欢
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 2019-03-08
    • 2017-01-12
    相关资源
    最近更新 更多