【翻译】(13)Prebuilts
-----------------
英文文档见android-ndk-r5b的documentation.html
属于Android Native Development Kit (NDK)的一部分
见http://developer.android.com/sdk/ndk/(需要代理)
翻译仅个人见解
-----------------
NDK Prebuilt library support:
?
NDK 预构建库支持:
-----------------------------
?
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.
?
Android NDK r5引入预构建库(动态和静态)的支持,即在你的应用程序中包含和使用库的预构建版本。
?
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.
?
1、你想发布你自己的库给第三方NDK开发者而不分发你的源代码。
?
2/ You want to use a prebuilt version of your own libraries to speed up your build.
?
2、你想使用你自己的库的预构建版本以加速你的构建。
?
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:
?
每个预构建库必须向构建系统声明为一个单一独立模块。这里有个小示例,我们假设文件libfoo.so位于以下Android.mk相同的目录中。
?
?? 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.
?
1. 给模块一个名称(这里是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.
?
2. 把你提供的预构建库的路径赋给LOCAL_SRC_FILES。通常路径相对于你的LOCAL_PATH
?
?? IMPORTANT: You *must* ensure that the prebuilt library corresponds to the target ABI you are using. More on this later.
?
?? 重要:你必须确保预构建库对应你正在使用的目标ABI(注:应用程序二进制接口,即操作系统开放给应用程序的接口)。更多相关信息见后。
?
3. Include PREBUILT_SHARED_LIBRARY, instead of BUILD_SHARED_LIBRARY, if you are providing a shared, library. For static ones, use PREBUILT_STATIC_LIBRARY.
?
3. 包含PREBUILT_SHARED_LIBRARY,而非BUILD_SHARED_LIBRARY,如果你提供的是一个动态库。对于静态库,请使用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>.
?
一个预构建模块不编译任何东西。然而,你的预构建动态库的副本将被复制到$PROJECT/obj/local,而另一个副本将被复制并裁剪进$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.
?
在依赖于你的构建模块的所有模块的Android.mk的LOCAL_STATIC_LIBRARIES或LOCAL_SHARED_LIBRARIES的声明中简单列出这些预构建模块的名称。
?
For example, a naive example of a module using libfoo.so would be:
?
例如,一个使用libfoo.so的模块的单纯例子将是:
?
?? ?include $(CLEAR_VARS)
?? ?LOCAL_MODULE := foo-user
?? ?LOCAL_SRC_FILES := foo-user.c
?? ?LOCAL_SHARED_LIBRARY := 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").
?
上面的例子被称为“单纯”是因为,实际上,foo-user.c的代码将依赖于特定的声明,那些声明通常在预构建库分发的头文件中找到(例如,foo.h)
?
In other words, foo-user.c is going to have a line like:
?
换句话说,foo-user.c将有类似的一行:
?
??#include <foo.h>
?
And you need to provide the header and its include path to the compiler when building the foo-user module.
?
而你需要在构建foo-user模块时提供头文件和它的编译器包含目录。
?
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:
?
一个简单处理方法是在预构建模块定义中使用导出。例如,假设一个foo.h文件位于相对于预构建模块的include目录下,我们可以这样写:
?
?? 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.
?
这里LOCAL_EXPORT_C_INCLUDES的定义确保任何依赖于预构建模块的模块将自动拥有带预构建库包含目录为前置值的LOCAL_C_INCLUDES,而它将能够找到包含其中的头文件。
?
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.
?
我们建议你提供包含调试符号的预构建共享库。安装进$PROJECT/libs/<abi>/的版本常常是被NDK构建系统裁剪过(注:ndk提供的工具链中包含了strip工具,它应该是用来优化生成文件的大小),但调试版本将可以供ndk-gdb使用以达到调试目的。
?
V. ABI Selection of prebuilt binaries:
?
五、预构建二进制文件的ABI选择:
--------------------------------------
?
As said previously, it is crucial to provide a prebuilt shared library that is compatible with the targetted ABI during the build. To do that, check for the value of TARGET_ARCH_ABI, its value will be:
?
正如前面所说,关键问题是在构建期间提供一个兼容于目标ABI的预构建动态库(注:开源是好事啊)。为了做到那点,检查TARGET_ARCH_ABI的值,它的值将是:
?
?? armeabi ? ? => when targetting ARMv5TE or higher CPUs
?
?? armeabi ? ? => 目标为ARMv5TE或更高的CPU
?
?? armeabi-v7a => when targetting ARMv7 or higher CPUs
?
?? armeabi-v7a => 目标为ARMv7或更高的CPU
?
?? x86 ? ? ? ? => when targetting x86 CPUs
?
?? x86 ? ? ? ? => 目标为x86 CPU。
?
Note that armeabi-v7a systems can run armeabi binaries just fine.
?
注意armeabi-v7a系统可以很好地运行armeabi的二进制文件。
?
Here's an example where we provide two versions of a prebuilt library and select which one to copy based on the target ABI:
?
这里有一个例子,我们提供两个版本的预构建库并且基于目标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
?
?? ?Android.mk ? ? ? ? ? ?--> 上面的文件 ? ?
?
?? ?armeabi/libfoo.so ? ? --> the armeabi prebuilt shared library
?
?? ?armeabi/libfoo.so ? ? --> armeabi预构建动态库
?
?? ?armeabi-v7a/libfoo.so --> the armeabi-v7a prebuilt shared library
?
?? ?armeabi-v7a/libfoo.so --> armeabi-v7a预构建动态库
?
?? ?include/foo.h ? ? ? ? --> the exported header file
?
?? ?include/foo.h ? ? ? ? --> 导出的头文件
?
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.
?
注意:记住你不需要提供一个armeabi-v7a预构建库,因为armeabi版本可以更容易地运行在相应的设备上。