This page describes a suggested standard way of packaging Android libraries.
If you wish to use such a packed library, please refer to Best Practices for users of libraries.
Why this document ?Before we end up with the autoconf nightmare all over again, I would like to propose a unified way of packaging libraries so that FOSS softwares are easier to build for the Android platform.
Basically, these simple conventions use the existing mecanisms in the Android NDK to provide fonctionalities similar to those of pkg-config on regular Linux systems.
Suggested way of distributing Android LibrariesVersioningPlease choose an "API version number" such that you guarantee that if the API version does not change, softwares that used to build with previous releases will still build. If you do not wish to make such a guarantee, you can use the library version number as the API version number.
Consider an imaginary library libfoo version 2.3.4 . If my API version is 2.3, then when the 2.3.5 version is released, people can update and know their code will still build. It is OK to use 2.3.4 as the API version number, thus providing no guarantee.
Choosing a build systemYou basically have two possibilities : you can either keep your existing build system (be it cmake, scons or whatever) or you can rely on the Android NDK build system (which is itself based on GNU Make).
A middle way would be to use a traditional build system to generate the makefiles used by the Android NDK build system. As of today, I have not investigated the ways of doing that, but believe it to be possible. If you do that, I would like to suggest that you distribute those generated Makefiles with the released source code.
Building with the Android NDK build systemIf possible, I recommend using the Android build system is used to build the libraries, for reasons mentioned above.The theoryPlease feel free to skip this section and to refer to the example which follows. Released source code archive that are to be built by the NDK build system should contain an Android.mk file as per the ANDROID-MK.html of the NDK. This Android.mk file should be placed at the root directory. It should define a module called "library-API_version_number" where the API version number is as described above. It should also export its headers by setting the The file should not refer to files outside of the library archive, and should instead use the NDK module system. It should not make assumptions on the architecture. In particular, it must not optimise for certain CPUs without checking if the build targets this CPU. It should not enable generic-purpose optimizations or debug options as those are to be enabled project-wide by the Application.mk file. ExampleConsidering an imaginary library libfoo version 2.3.4 whose "API version number" (as described above) is 2.3 . libfoo depends on libbar and libwiz. The source code archive should contain an Android.mk along those lines: # Source code root. # All paths should be contain to this variable, with the exception # of LOCAL_SRC_FILES .
LOCAL_PATH := $(call my-dir)
# Needed by the NDK build system include $(CLEAR_VARS)
# Name your library with its API version number (described above). LOCAL_MODULE := libfoo-2.3
# This indicates the path to the headers that users # of your library wants (like libfoo.h) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/headers-are-here \ $(LOCAL_PATH)/headers-are-there
# Those are the libraries we are using. # Android.mk will setup linking and includes for you ! LOCAL_SHARED_LIBRARIES := wiz-1.0 bar-2.1
LOCAL_STATIC_LIBRARIES := wuz-2.3
# This is a path to headers you do not wish to expose. # Please do not put relative paths to the headers of your dependencies here .# Instead, please add the dependencies, to LOCAL_SHARED_LIBRARIES and rely
# on the dependencies to set their LOCAL_EXPORT_C_INCLUDES .
LOCAL_C_INCLUDES := $(LOCAL_PATH)/private-headers/
# Please do not add GCC optimisation or "-g" flags here, as they should # be set project-wise by the user # Please do not set include paths here (see LOCAL_C_INCLUDES).# Please do not add ARM-specific defines here (but see below).
LOCAL_CFLAGS := -DENABLE_MAGIC # If you want to add ARM-specific defines, please do it this way
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -DENABLE_ARM_SPECIFIC_MAGIC
endif
# You can either use this or explicitely list the source code files
LOCAL_SRC_FILES := $(notdir $(wildcard $(LOCAL_PATH)/*.c))
# If you explicitely list source files, you do not need to repeat $(LOCAL_PATH)
# Use this only when linking with system libraries that are part # of the Android ABI. # For the other libraries, please use LOCAL_SHARED_LIBRARIES# and LOCAL_STATIC_LIBRARIES as demonstrated above.
LOCAL_LDLIBS := -lz
# This enables the build of your library as a shared library. # Please do so, if possible, as you would on a GNU/Linux system. include $(BUILD_SHARED_LIBRARY) #include $(BUILD_STATIC_LIBRARY)
Building with your custom build systemAfter adapting your custom build system so that it produces binaries for the android platform, you need to create a short file that will expose the generated files to the NDK. Considering an imaginary library libfoo version 2.3.4 whose "API version number" (as described above) is 2.3 . libfoo depends on libbar and libwiz. The source code archive should contain an Android.mk along those lines:
|