| <html><body><pre>NDK Prebuilt library support: |
| ----------------------------- |
| |
| Android NDK r5 introduced support for prebuilt libraries (shared and |
| static), i.e. the ability to include and use, in your applications, |
| prebuilt version of libraries. |
| |
| This feature can be useful for two things: |
| |
| 1/ You want to distribute your own libraries to third-party NDK developers |
| without distributing your sources. |
| |
| 2/ You want to use a prebuilt version of your own libraries to speed up |
| your build. |
| |
| This document explains how this support works. |
| |
| |
| I. Declaring a prebuilt library module: |
| --------------------------------------- |
| |
| Each prebuilt library must be declared as a *single* independent module to |
| the build system. Here is a trivial example where we assume that the file |
| "libfoo.so" is located in the same directory than the Android.mk below: |
| |
| LOCAL_PATH := $(call my-dir) |
| |
| include $(CLEAR_VARS) |
| LOCAL_MODULE := foo-prebuilt |
| LOCAL_SRC_FILES := libfoo.so |
| include $(PREBUILT_SHARED_LIBRARY) |
| |
| Notice that, to declare such a module, you really only need the following: |
| |
| 1. Give the module a name (here 'foo-prebuilt'). This does not need to |
| correspond to the name of the prebuilt library itself. |
| |
| 2. Assign to LOCAL_SRC_FILES the path to the prebuilt library you are |
| providing. As usual, the path is relative to your LOCAL_PATH. |
| |
| IMPORTANT: You *must* ensure that the prebuilt library corresponds |
| to the target ABI you are using. More on this later. |
| |
| 3. Include PREBUILT_SHARED_LIBRARY, instead of BUILD_SHARED_LIBRARY, if |
| you are providing a shared, library. For static ones, use |
| PREBUILT_STATIC_LIBRARY. |
| |
| A prebuilt module does not build anything. However, a copy of your prebuilt |
| shared library will be copied into $PROJECT/obj/local, and another will be |
| copied and stripped into $PROJECT/libs/<abi>. |
| |
| II. Referencing the prebuilt library in other modules: |
| ------------------------------------------------------ |
| |
| Simply list your prebuilt module's name in the LOCAL_STATIC_LIBRARIES or |
| LOCAL_SHARED_LIBRARIES declaration in the Android.mk of any module that |
| depends on them. |
| |
| For example, a naive example of a module using libfoo.so would be: |
| |
| include $(CLEAR_VARS) |
| LOCAL_MODULE := foo-user |
| LOCAL_SRC_FILES := foo-user.c |
| LOCAL_SHARED_LIBRARIES := foo-prebuilt |
| include $(BUILD_SHARED_LIBRARY) |
| |
| |
| III. Exporting headers for prebuilt libraries: |
| ---------------------------------------------- |
| |
| The example above was called 'naive' because, in practice, the code in |
| foo-user.c is going to depend on specific declarations that are normally |
| found in a header file distributed with the prebuilt library (e.g. "foo.h"). |
| |
| In other words, foo-user.c is going to have a line like: |
| |
| #include <foo.h> |
| |
| And you need to provide the header and its include path to the compiler |
| when building the foo-user module. |
| |
| A simple way to deal with that is to use exports in the prebuilt module |
| definition. For example, assuming that a file "foo.h" is located under |
| the 'include' directory relative to the prebuilt module, we can write: |
| |
| include $(CLEAR_VARS) |
| LOCAL_MODULE := foo-prebuilt |
| LOCAL_SRC_FILES := libfoo.so |
| LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include |
| include $(PREBUILT_SHARED_LIBRARY) |
| |
| The LOCAL_EXPORT_C_INCLUDES definition here ensures that any module that |
| depends on the prebuilt one will have its LOCAL_C_INCLUDES automatically |
| prepended with the path to the prebuilt's include directory, and will thus |
| be able to find headers inside that. |
| |
| |
| IV. Debugging prebuilt binaries: |
| -------------------------------- |
| |
| We recommend you to provide prebuilt shared libraries that contain debug |
| symbols. The version that is installed into $PROJECT/libs/<abi>/ is always |
| stripped by the NDK build system, but the debug version will be used for |
| debugging purposes with ndk-gdb. |
| |
| |
| V. ABI Selection of prebuilt binaries: |
| -------------------------------------- |
| |
| As said previously, it is crucial to provide a prebuilt shared library |
| that is compatible with the targeted ABI during the build. To do that, |
| check for the value of TARGET_ARCH_ABI, its value will be: |
| |
| armeabi => when targeting ARMv5TE or higher CPUs |
| armeabi-v7a => when targeting ARMv7 or higher CPUs |
| x86 => when targeting x86 CPUs |
| mips => when targeting MIPS CPUs |
| |
| Note that armeabi-v7a systems can run armeabi binaries just fine. |
| |
| Here's an example where we provide two versions of a prebuilt library |
| and select which one to copy based on the target ABI: |
| |
| include $(CLEAR_VARS) |
| LOCAL_MODULE := foo-prebuilt |
| LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so |
| LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include |
| include $(PREBUILT_SHARED_LIBRARY) |
| |
| Here. we assume that the prebuilt libraries to copy are under the |
| following directory hierarchy: |
| |
| Android.mk --> the file above |
| armeabi/libfoo.so --> the armeabi prebuilt shared library |
| armeabi-v7a/libfoo.so --> the armeabi-v7a prebuilt shared library |
| include/foo.h --> the exported header file |
| |
| NOTE: Remember that you don't need to provide an armeabi-v7a prebuilt |
| library, since an armeabi one can easily run on the corresponding |
| devices. |
| </pre></body></html> |