Android NDK ARM构建设置以在大多数设备上运行?

3
我有几个Android NDK应用程序,但人们抱怨我的应用程序在他们的手机上无法正常工作。我想知道的是,哪些编译设置将支持市场上大多数,如果不是所有ARM设备?我的问题似乎是armeabi-v7a设备对VFP、NEON等的支持程度不同。我正在寻找一种解决方案,可以构建运行于最多平台上的应用程序,即使这样会牺牲优化成本。我使用了默认的NDK构建脚本来指定armeabi和armeabi-v7a,如下所示:-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3。但这在某些设备上无效,例如Acer A500(CPU Nvidia Tegra2(双核Cortex A9))。从这里http://wiki.debian.org/ArmHardFloatPort/VfpComparison学到,该CPU没有实现NEON。具体而言,崩溃是这样的:
F/libc    (15549): Fatal signal 4 (SIGILL) at 0x5bfd9260 (code=1)
...(snip)...
I/DEBUG   (   81): #00 pc 0005b260 /data/data/com.burnsmod.oscpad/lib/libapplication.so (tanf)

看 libapplication.so,我发现 tanf 生成为:

0005b25c <tanf>:
5b25c:       ee070a90        fmsr    s15, r0
5b260:       eef70ae7        fcvtds  d16, s15
5b264:       e92d4010        push    {r4, lr}
5b268:       ec510b30        vmov    r0, r1, d16
5b26c:       ebff4b6c        bl      2e024 <_ZN15ButtonUIHandler10FreeImagesEv-0x6ac>
5b270:       ec410b30        vmov    d16, r0, r1
5b274:       eef77be0        fcvtsd  s15, d16
5b278:       ee170a90        fmrs    r0, s15
5b27c:       e8bd8010        pop     {r4, pc}

那么,答案是什么?vfpv2?vfp?vfpv3?vfpv3-d16?

现在,如果我使用readelf,我会发现我的应用程序库的依赖关系如下:

MacBook:armeabi-v7a tom$ arm-linux-androideabi-readelf -A libapplication.so
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "7-A"
Tag_CPU_arch: v7
Tag_CPU_arch_profile: Application
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-2
Tag_VFP_arch: VFPv3
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align8_needed: Yes
Tag_ABI_align8_preserved: Yes, except leaf SP
Tag_ABI_enum_size: int
Tag_ABI_HardFP_use: SP and DP

VFP2:使用“-mfpu=vfpv2”或“-mfpu=vfp2”编译是不支持在NDK 7中的,两者都会返回错误消息。


通常情况下,当兼容性比优化更重要时,您应该以最低公共分母为目标。 - Seva Alekseyev
@Seva 当然。那么它是什么?VFP被提到为“过时的”,所以它是VFPv2吗? - gravitron
2个回答

3
原来我的问题在于我使用的是 NDK r7b 版本,其中一些核心库中包含 VFPv3 代码的错误。

http://code.google.com/p/android/issues/detail?id=26199

这个问题在r7c版本中已经被修复,升级到r8b版本后,看起来我已经解决了这个问题。


1
通过构建一个普通版本和一个armv7优化库(armeabi和armeabi-v7a),您可以覆盖armv7和非armv7的情况,因为当用户安装您的应用程序时,包管理器将选择适当的库。
在armv7优化库中,您可以使用android_getCpuFeatures()来检测对VFPv3-D16和NEON的支持,并根据此选择适当的代码路径。也就是说,如果设置了ANDROID_CPU_ARM_FEATURE_VFPv3,则可以执行任何VFPv3-D16优化代码,如果设置了ANDROID_CPU_ARM_FEATURE_NEON,则可以执行任何NEON/VFPv3-D32优化代码(假设没有设备虚报其支持的内容)。

谢谢提供信息,但我并没有编写基于VFPv3 / NEON的代码。这是在编译期间为我选择的(例如,tanf是基于vfpv3生成的)。 - gravitron
在这种情况下,如果您真的想支持基于Tegra 2的设备并且不想拥有Tegra 2特定版本的应用程序,那么您最好的选择可能是使用-mfpu=vfpv3编译armeabi-v7a库。 - Michael
1
实际上,Tegra2仅支持vfpv3-d16。我已经向那些抱怨崩溃的人发送了一个使用该版本构建的应用程序副本,希望它能解决问题,让我可以回到高效编码中。 - gravitron
1
是的,抱歉,我想说的是vfpv3-d16(复制粘贴错误)。另一个可能性是构建多个armeabi-v7a版本的库 - 例如,一个带有neon优化,一个带有vfpv3-d16优化 - 并根据getCpuFeatures返回的结果在运行时决定加载哪个版本(我自己没有尝试过这种方法,所以无法对其实用性发表评论)。 - Michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接