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. 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.

Android NDK r5版本引入了引用二进制库(提前编译好的共享和静态库)的能力,可以在应用中包含和使用提前编译好的库。这个功能使以下两件事有帮助:

1/ 你需要分发你自己的库给第三方的NDK开发者,但是不想分发源码。

2/你需要引入自己的库文件,加快构建速度。

这篇文档将解释上面的两种情况是如何实现的。

I. Declaring a prebuilt library module:

I. 定义一个预先编译好的二进制库模块:

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位于同一个路径,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. 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>.

注意,为了定义这样一个模块,你只需要做以下事情:

1. 给这个模块命名(这里是“foo-prebuild”),这不需要和库文件名字本身一样

2.给 LOCAL_SRC_FILES 赋值,指向你的预编译好的库所在的路径。像其他一样,提供和LOCAL_PATH对于的相对路径。注意,必须保证预编译库的版本和目标ABI移植。

3.如果包含的是共享库,应写成PREBUILT_SHARED_LIBRARY,而不是BUILD_SHARED_LIBRARY。如果是静态库,就是PREBUILT_STATIC_LIBRARY。预编译的模块不会出发构建过程。只是把预编译的共享库拷贝到$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. 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)

II.在其他模块中引用预编译的库:

简单的在依赖库的应用的Android.mk里LOCAL_STATIC_LIBRARIES或LOCAL_SHARED_LIBRARIES中列出预编译的模块的名字就可以了。例如,一个简单的应用使用libfoo.so应该是:

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:

III. 导出预编译库的头文件:

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.

上面的例子之所以说“简单”,是因为实际上foo-user.c里面的代码会依赖预编译库配套的头文件(如“foo.h”)中的定义。换句话说,foo-user.c需要有一行类似于下面的代码 #include <foo.h> ,而且你在构建时应该提供他引用的头文件并放置在编译器能访问的路径下。一个简单的处理方法是在预编译的库的定义中中使用exports。例如,假设"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)

IV. Debugging prebuilt binaries:

IV. 调试预编译的库

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-gdb用于调试目的。

V. ABI Selection of prebuilt binaries:

V. 预编译库的ABI适配

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.

就像前面说的,提供一个与目标ABI版本匹配的预编译的库非常重要。检查TARGET_ARCH_ABI的值,如果目标版本为ARMv5TE或更高,值应该是 armeabi 。目标是ARMv7或更高,值应该是armeabi-v7a。目标是x86时值为x86;目标是MIPS系列CPU时,值为mips。注意armeabi-v7a系统能运行armeabi的文件。下面是一个例子,我们提供两个版本的预编译库,并根据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)


我们假设需要拷贝的预编译库在以下目录中:

Android.mk --> 上面的make文件

armeabi/libfoo.so--> armeabi 版本库

armeabi-v7a/libfoo.so --> armeabi-v7a 版本库

include/foo.h --> 导出头文件

注意:记住你不是必须要提供一个armeabi-v7a版本的预编译库,因为armeabi版本就可以在相关设备商跑的很好。

NDK使用二进制库方法(翻译)

时间: 2024-10-10 11:18:09

NDK使用二进制库方法(翻译)的相关文章

如何使用Eclipse的NDK开发动态库,静态库

============问题描述============ 如何使用Eclipse的NDK开发动态库,静态库? Eclipse中已经安装了NDK,CDT和Esequoyah并配置(是在网上查的). 我是做C++的,公司业务需要自学Android,对Java也是知道一点皮毛. 在网上查了一些资料,我都没有成功做出最简单的动态库或静态库,郁闷啊! 有没有详细指导? ============解决方案1============ 你去搜一下Android的jni开发,就知道了,一点都不难,不过一般开发ndk

python 解析html基础 HTMLParser库,方法,及代码实例

HTMLParser, a simple lib as html/xhtml parser 官方解释: This module defines a class HTMLParser which serves as the basis for parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML.Unlike the parser in htmllib, this parser is not base

Java 小技巧和在Java避免NullPonintException的最佳方法(翻译)

前几天就g+里面看到有人引用这篇博文,看了一下,受益颇多.所以翻译过来,希望和大家一起学习.本人英语水平有限,如果有错,请大家指正. 原文地址(需要翻墙):http://javarevisited.blogspot.com/2013/05/ava-tips-and-best-practices-to-avoid-nullpointerexception-program-application.html =============================分割线===============

cocos2dx通过ndk编译c++库

ndk编译c++库,然后通过jni调用实现重要代码封装,是安卓应用中最常用的技术,一方面可以将重要的代码实现隐藏,防止泄漏,也可以提高打包速度. ndk里面的sample文件夹中有很多实用的例子,其中hello-jni有一个编译c++的例子. 首先,创建一个jn文件夹,文件夹内放置Android.mk和Application.mk两个文件,Android.mk文件主要是 写入编译的c++代码,打包的库名,打包的库类型(静态库or动态库),引用的模块等等.Application.mk 是主要表示打

scala类型推断及库方法设计原则和==与java有何差别

scala类型推断 方法msortSwapped(abcd)(_>_) 通常,一旦有需要推断多台方法类型参数的任务时,类型推断器就只参考第一个参数列表中所有参数类型,但不会参考之后其他参数.因为方法msortSwapped是柯里化的方法,带两个参数列表,所以第二个参数(也就是说,那个函数值)将不会用来做决定方法参数的参考. 因此这种类型推断方案也隐含了如下库方法设计原则:如果需要把参数设计为若干非函数值及一个函数值的某种多态方法,需要把函数参数放在柯里化参数列表的最后面.这样一来,方法的正确类型

动态调用动态库方法 .so

关于动态调用动态库方法说明 一.       动态库概述 1.  动态库的概念 日常编程中,常有一些函数不需要进行编译或者可以在多个文件中使用(如数据库输入/输 出操作或屏幕控制等标准任务函数).可以事先对这些函数进行编译,然后将它们放置在一些特殊的目标代码文件中,这些目标代码文件就称为库.库文件中的函数 可以通过连接程序与应用程序进行链接,这样就不必在每次开发程序时都对这些通用的函数进行编译了. 动态库是一种在已经编译完毕的程序开始启动运行时,才被加载来调用其中函数的库.其加载方式与静态库截然

php的spl_autoload标准库方法

在php5中的spl_autoload方法相当于实现自己的__autoload <?php function __autoload($classname){ if(is_file($classname.'.php'){ include $classname.'.php'; } elseif(is_file($classname.'.inc'){ include $classname.'.inc'; } } 它会在注册目录下自动寻找与$classname同名的.php/.inc文件.当然,你也可以

php调用so库和a库方法

php调用so库和a库方法 分类: (一)调用so方法 (引自:http://tech.idv2.com/2007/07/06/use-local-so-in-php/) 某个功能被编译到so文件中,那么如何通过php来调用它?一个方法是写一个php模块(php extension),在php中调用该模块内的函数,再通过该模块来调用so中的函数.下面做一个简单的例子,使用的操作系统是Fedora Core 6. 首先做一个简单的so文件: /** * hello.c * To compile,

scikit-learn机器学习库介绍(翻译tutorial)

章节内容 在这一章中,我们主要介绍关于scikit-learn机器学习库的词汇,并且将给出几个例子 机器学习:问题背景 通常,一个学习问题看重数据的n个样本然后来尝试证明一些未知数据的属性.如果每一个样本超过一个单一的数值,例如多维实体,它不就是有一些属性或者特征吗? 我们能用几个大的分类来分隔学习问题: 监督学习: 在监督学习中,这些数据自带了我们想要预测的额外的属性,这个问题是下面两者中的任何一个: 分类:属于两种或者更多类别的样本,我们想从已经被标记的数据中如何预测还没有被标记的数据.一个