のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

一つの共有ライブラリを、複数のアプリで使用する方法

($NDK_ROOT)\docs\PREBUILTS.htmlより引用

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.

1.自分のライブラリを他社のNDK開発者へソース無しに配布したい人。<=こっち

2.プレビルド版の自分のライブラリを使って、ビルドを速くしたい人。

#プレビルド版のライブラルのモジュールを宣言する。
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.

  #モジュール名をここで、'foo-prebuilt'とする。
   #プレビルド版ライブラリ自身の名前と一致する必要はない.

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 <=ABI切り替え
    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.

LOCAL_PATH?:= $(call my-dir)

# libpng用
include $(CLEAR_VARS)
LOCAL_MODULE ?:= prebuild-libpng
LOCAL_SRC_FILES?:= external/lib/libpng.so
include $(PREBUILT_SHARED_LIBRARY)

# NdkGLRenderer用
include $(CLEAR_VARS)
LOCAL_MODULE ?:= NdkGLRenderer
LOCAL_SRC_FILES ?:= NdkGLRenderer.cpp
LOCAL_LDLIBS ?:= -lGLESv1_CM -llog
LOCAL_SHARED_LIBRARIES?:= prebuild-libpng
LOCAL_C_INCLUDES ?:= external/include
include $(BUILD_SHARED_LIBRARY)

PREBUILT_SHARED_LIBRARY 配布用、ビルド高速化などで使うために事前にビルドされたshard libraryを取り込む、prebuiltするときにLOCAL_SRC_FILESにはとりこむバイナリファイルを指定する(アーキテクチャに合わせて適切なバイナリモジュールを選ぶ必要がある、TARGET_ARCH_ABIを使ってパスを指定するのが良い)。他のモジュールからはLOCAL_SHARED_LIBRARYで読み込める。ヘッダを公開するときはLOCAL_EXPORT_C_INCLUDES を使う。