28

Background

I've recently started to develop some code using the NDK, and I've thought of a possible portability problem that could occur while developing using NDK.

The problem

Since NDK uses native code, it needs to be compiled per CPU architecture. This is a problem since the user needs to run the app no matter what CPU the device has.

Possible solutions I've found so far

I've noticed I can modify the file "jni/Application.mk" and use:

APP_ABI := armeabi armeabi-v7a x86

however, I don't know what I should do from this step on. Will the app contain all of the compiled code for each of the CPU architectures and automatically choose the correct one when running itself?

Also, what if there will be another CPU architecture that is unknown?

What will happen if I try to run the app on Google TV, which according to what I remember doesn't support the NDK at all?

Another solution I've found is the multi-apk support. However, I'm not sure I understand it. Does it all mean that you create the same APK, each time with a different configuration? No special automation tool from ADT to help with that?

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • 2
    "will the app contain all of the compiled code for each of the CPU architectures and automatically choose the correct one when running itself?" -- yes. – CommonsWare Jan 20 '13 at 00:16
  • "no special automation tool from ADT to help with that?" -- no, because the assumption is that you need different code to handle the different environments. If you do *not* need different code, you do not need multiple APKs, in all likelihood. – CommonsWare Jan 20 '13 at 00:17
  • nice . why didn't you put the answers in a real post ? also , can you please answer the other questions ? this is interesting . – android developer Jan 20 '13 at 06:57
  • 1
    Did you try and run `ndk-build` with `APP_ABI := armeabi armeabi-v7a x86` defined for a library? I can only get it to build `armeabi`. `ndk-build` ignores the other architectures. – jww Sep 06 '14 at 16:29
  • I just used what is written on the chosen answer, and it worked fine for me: APP_ABI := all – android developer Sep 06 '14 at 16:42

2 Answers2

33

If you don't set APP_ABI at all, or use

APP_ABI := all

in your Application.mk, then ndk-build will build for all architectures supported by your version of NDK. The latest one, to date r8d, will in addition to armeabi armeabi-v7a x86 build also for mips. When another architecture will be released, you will hopefully automatically get the APK built to support it.

When you application is installed on an Android device, the system will automatically choose the matching ABI version and install the correct shared libraries from the APK.

One drawback of this approach is that if the native libraries are big, your "monolithic" APK file may become huge. You can use the multi-APK approach to make user downloads smaller. The official site recommends: You should generally use multiple APKs to support different device configurations only when your APK is too large (greater than 50MB). You should carefully follow the version code guildlines if you choose this route.

Unfortunately, there are no trustworthy prophecies regarding NDK support on Google TV, but there seem to be no technical justification for its current unavailability. If and when it arrives, your ndk-build will take care of it automatically.

UPDATE Here is a simple process to maintain split APK. And by the way, the new Android TV does support NDK.

Community
  • 1
  • 1
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • i see. does the multi-apk approach have a built in tool to create the apks , all at the same time ? also , is intel also supported when compiling ? – android developer Jan 20 '13 at 09:13
  • @Alex Cohn: vs the technical justification regarding the NDK unavailability on Google TV, this [blog post](http://spurint.org/journal/2012/10/google-tv-and-native-libraries/) gives some details: *I've learned that the Sony GTV is running a EGlibc 2.12.2, and probably a mostly-unmodified version of it. Someone with an [AT] google.com email address stated that the reason for this was that they couldn't get Chrome running against the Honeycomb version of Bionic*. – deltheil Jan 20 '13 at 11:50
  • @androiddeveloper: no, there are no automation tools, mainly (IMHO) because Google don't want to encourage this approach. All the rules for version codes, etc. make multiple APKs a pain in the neck. – Alex Cohn Jan 20 '13 at 15:26
  • @deltheil: Yes, I am aware of this excuse. There is since long a version of Chrome running on AOSP (ICS and higher). It's true that OTA upgrade may be hard for GTV, but mainly Sony has little incentive in preparing such an upgrade. – Alex Cohn Jan 20 '13 at 15:32
  • are you saying that all google TVs still use honeycomb ? not even one uses ICS and above ? if not , do they support NDK ? also , about the multiple APK , google has talked about it on one of their google IO lectures , and the lecturers were surprised to see that developers actually wanted this feature for a long time. this is quite problematic since i think there should be a difference.for example, many apps have both "normal" and "hd" versions , which is silly . using a single apk would take a lot of space but having 2 apps instead of one is also silly . – android developer Jan 20 '13 at 15:50
  • @androiddeveloper: yes, [some GTV devices](http://www.techradar.com/news/television/in-pictures-worlds-first-ice-cream-sandwich-tv-1052616) run ICS. Unfortunately, I don't have access to it to check if it has bionic or which ABI it reports. GTV site explicitly mentiones x86 (Intel) NDK as _not supported_. – Alex Cohn Jan 20 '13 at 16:17
  • @androiddeveloper: please don't blame the messenger. I empathize with your preference of slime packages. Google themselves put the threshold at 50 MByte. Is your expected APK much heavier? – Alex Cohn Jan 20 '13 at 16:20
  • @AlexCohn , no . i just think google could make it much better . even before we had such great devices , we had both smartphones and tablets , and we could target which resources should be used for each of them (in any way you decide) , but in the end , what the user downloads will always be larger than what is meant for his current device . the play store could easily check what is the device that downloads from it , and decide what to upload to it . even the expansion library doesn't support it . – android developer Jan 20 '13 at 17:40
  • @androiddeveloper: maybe I am missing something... Building multi-APK for different DPI/ OpenGL/ ABI/ SDK_VERSION variants is supported, and the Play Store will download the matching package. It's only not encouraged by Google. – Alex Cohn Jan 20 '13 at 18:24
  • yes , i know that . but it has many disadvantages : not comfortable . need to compile&upload for each configuration ,harder to manage... i would suggest having a single apk that somewhere in the xml it will tell google play what to use for each of the configurations . then google play will upload only the needed content (images,sounds,source,xml,...) from the original apk and to the end user , since the app promised it that it won't be needing the rest of the content . for some cases , google play could even decide on itself (for example image scaling) . – android developer Jan 20 '13 at 18:30
  • The current model assumes APK to be a package digitally signed by dev's private key. Your proposals don't fit in thos model. But youcan easily download resources or even shared libs "on the fly" – Alex Cohn Jan 20 '13 at 21:19
  • sure, but for this i have to set up a server, and this is sad since google play can already store a lot of space for each app . – android developer Jan 21 '13 at 08:12
  • @AlexCohn i've recently found out that new JNI projects for android do not even contain the file "Application.mk" , only "Android.mk". are they the same and only changed their names? should i be worry or take special actions (especially for targeting multiple architectures ) ? – android developer Aug 15 '13 at 10:52
5

For the latest version (now r9) you have to specify in "jni/Application.mk"

APP_ABI := all

or

APP_ABI := armeabi armeabi-v7a x86 mips

without ./ndk_build will only build 'armeabi'

hannes ach
  • 16,247
  • 7
  • 61
  • 84
  • that's what the other answer has already written: http://stackoverflow.com/a/14423013/878126 – android developer Feb 14 '14 at 10:17
  • not exactly, not specify it at all, will build for all is not true "If you don't set APP_ABI at all, or use APP_ABI := all in your Application.mk, then ndk-build will build for all architectures supported by your version of NDK" – hannes ach Feb 15 '14 at 10:40
  • 2
    I don't understand. are you saying that adding "APP_ABI := all" isn't enough? if that's true, then what should be done? – android developer Feb 15 '14 at 11:28
  • 3
    I have APP_ABI := armeabi armeabi-v7a x86 mips in my mk file and I still only get armeabi in the output. what else is missing? – tatmanblue Jun 08 '15 at 19:03
  • 1
    I have the same problem. It only builds for armeabi – André Fratelli Sep 14 '15 at 04:23
  • 3
    Some people put that line to Android.mk and complain it didnt work. You must create a file named Application.mk instead – damphat Sep 16 '15 at 04:08