1

I need to filter my 3-rd party native libraries and allow only "armeabi" for all of them. With one exception! - a specific library must be included in its "armeabi-v7a" variant.

How can I filter my 3rd party native libraries differently depending on the library? (or on the app module)

What I want in my APK in the end is:

  • armeabi / lib-1.so
  • armeabi / lib-2.so
  • armeabi / lib-3.so
  • armeabi-v7a / special-lib.so

The full story:

I have an app built in a couple of modules. It uses a few 3rd party native libraries. Until now, we were only using "armeabi" versions of all libraries, since they are most compatible, and since we aim for low app size (without multiple APK's). However, now we need to include a new 3rd party library that is only available in "armeabi-v7a" form.

We've been using the filter:

productFlavors {
        app {
            ndk {
                abiFilters "armeabi"
}}}

It's located in the main app module. It filters all native libraries from all modules and libraries. Now we are forced to use this filter:

productFlavors {
        app {
            ndk {
                abiFilters "armeabi", "armeabi-v7a"
}}}

Which makes the app work but also increases its size significantly. We don't want to use it. It allows the armeabi-v7a version of the new library, but it also allows the armeabi-v7a versions of a few other libraries that we don't want to include.

The question: We want to allow "armeabi-v7a" only for one specific library which resides in one of our app modules. Can we achieve that by ABI filters or some other way?

Note about 64-bit: I know that in case you have ANY 64 bit native libraries, you need to have all of them (cause if the app finds one 64-bit lib, it will start in 64-bit mode and will not be able to use the 32-bit libs). However, in the case of armeabi vs armeabi-v7a there is no such problem and you don't have to supply both versions of each lib.

JoshDM
  • 4,939
  • 7
  • 43
  • 72
Stan
  • 2,151
  • 1
  • 25
  • 33

1 Answers1

3

Regarding your last point about having to supply both versions of each lib - no, that still also goes for armeabi vs armeabi-v7a.

Given an APK that contains the files you listed:

  • armeabi / lib-1.so
  • armeabi / lib-2.so
  • armeabi / lib-3.so
  • armeabi-v7a / special-lib.so

If installing this on an armeabi-v7a device, the installer does not need to, and won't, install files from the armeabi directory at all. See https://developer.android.com/ndk/guides/abis.html#aen for an authoritative source saying the same. (There have been installer bugs in older Android versions, where some of the armeabi libs may have been installed, but not all, depending on which order they are packaged in the APK. See https://stackoverflow.com/a/25648943/3115956 for details on that. But that's only bugs, not intended behaviour, and only on older versions.)

Additionally, what would happen if you ran the app on an armeabi device, that doesn't support armeabi-v7a at all? In that case, you wouldn't have special-lib.so available at all - is that expected? If not, you basically already require armeabi-v7a for your app, so just ship armeabi-v7a versions of all your libs.

Community
  • 1
  • 1
mstorsjo
  • 12,983
  • 2
  • 39
  • 62
  • Thank you, I was not aware that the device will pick libs from only one folder in this case, too (well, in ANY case). I was planning to handle the situation where a device is with armeabi architecture, and disable the armeabi-v7a lib functionality. The reason why I wanted to go this way was the availability of the 3rd party libs, I simply don't have them all for a single architecture. I think it's weird. Anyone who distributes a native library should make it available in all architectures possible... – Stan Jul 27 '16 at 08:50
  • 1
    Yes, libraries should ideally be available in all architectures, to let the app developer choose which ones of them to ship. Although in practice, there may be other reasons not to provide all architectures (e.g. if the library is lowlevel, and you haven't been able to test some of the less common architectures, and you have reasons to doubt that it works out of the box). For your case, you _could_ move special-lib.so from armeabi-v7a to armeabi and pretend that it's an armeabi library, and just avoid using it if you know via runtime checks that you aren't on armeabi-v7a. – mstorsjo Jul 27 '16 at 09:23
  • 1
    Also, in practice, if you mainly target newer android versions, you lose a pretty small part of the userbase by just skipping armeabi and only providing armeabi-v7a - see e.g. http://stackoverflow.com/a/30924571/3115956. – mstorsjo Jul 27 '16 at 09:25
  • Can I move all libs from "armeabi" to "armeabi-v7a" folder? I mean the files as they are (in their armeabi version) coexisting in the same folder with real armeabi-v7a files. I tested this and it works in my case. But I am concerned of potential problems (maybe on specific devices). – Stan Aug 02 '16 at 09:23
  • 1
    Yes, you can move the libs from armeabi to armeabi-v7a, and that should work just fine, there is no issue on specific devices with that. But if you do that, I would recommend you to rebuild the libs for armeabi-v7a instead (if it is a lib that you can build yourself), since you'll get a performance benefit by doing that. – mstorsjo Aug 02 '16 at 10:00