我正在寻找开发和打包具有不同编译设置的库的不同变体的最佳方法,但是对于相同的ABI,然后在运行时选择最佳匹配。更具体地说,我想要一个NEON和非NEON armeabi-v7a构建。
本机库具有第三方链接到的公共C接口。他们似乎需要链接到其中一个变体以防止链接错误,但我想在运行时加载替代变量,如果它更适合设备,并让运行时加载程序执行正确的重定位。
从我到目前为止看来,似乎我需要为两个变体提供相同的文件名,因此需要将它们放在不同的文件夹中。 abi文件夹下的子文件夹似乎没有被包安装过程复制,因此该方法不起作用。到目前为止,我看到的最好的建议是手动将res文件夹中的一个变体复制到已知的设备路径,并使用完整路径调用System.loadLibrary()。参考:https://groups.google.com/forum/#!topic/android-ndk/zu_dmcmUlMo
我假设使用二进制转换的设备上的cpufeatures不会将cpu系列报告为ARM,因此我提出的解决方案是以正常方式构建标准的armeabi-v7a库(我想这将得到二进制翻译) ,并在res / raw中运送一个支持NEON的库。然后在运行时,如果cpufeatures报告具有NEON支持的ARM CPU,则复制该库并使用完整路径调用loadLibrary。任何人都可以看到这种方法有任何问题吗?
答案 0 :(得分:1)
如果你明确想要有一个lib的两个不同版本,那么是的,这可能是最好的妥协。
首先请注意,许多可以使用NEON的库可以使用运行时启用的那些部分构建,这样您就可以拥有一个正常的ARMv7构建,它不严格要求NEON,但如果检测到,则可以在运行时启用这些代码路径 - 例如libav / FFmpeg这样做,对于许多其他类似的库也是如此。这允许您使用一个单独的ARMv7二进制文件,在适用的情况下充分利用NEON,同时仍然可以在没有NEON的少数ARMv7设备上运行。
如果您正在尝试使用编译器自动向量化,或者这是一个库,其中NEON例程不容易局限于在运行时启用的受限制部分(或希望通过使用NEON构建整个库来获得额外性能启用),你的方法听起来很健全。
请记住,您希望至少有一个“正常”打包的本机库(您似乎已经拥有,但这在例如https://stackoverflow.com/a/29329413/3115956中是一个问题)。在安装时,安装程序会选择捆绑体系结构的最佳匹配,并仅从该体系结构中提取lib,并以该模式运行该进程。在具有多个ABI(32位和64位)的设备上,这是必不可少的,因为如果以不同的模式启动进程,则在尝试以不同的形式加载库时切换模式为时已晚。
在模拟ARM二进制文件的x86设备上,如果进程在ARM模式下运行,则至少cpufeatures
库将返回ARM。如果您使用系统属性来查找主要和次要ABI,您将不知道当前进程正在使用哪些ABI。