2.4.1 Android.mk(3)
5. 在多个NDK项目间共享模块
同时使用静态库和共享库时,可以在模块间共享通用模块。但要说明的是,所有这些模块必须属于同一个NDK项目。从R5版本开始,Android NDK也允许在NDK项目间共享和重用模块。考虑前面讲过的示例,可以通过以下步骤在多个NDK项目间共享avilib模块:
首先,将avilib源代码移动到NDK项目以外的位置,例如:C:\android\shared-modules\ avilib。为了避免命名冲突,目录结构也可以包含模块提供者的名字,例如:C:\ android\shared-modules \transcode\avilib。
注意:
在Android NDK构建系统中,共享模块路径不能包含空格。
作为共享模块,avilib需要自己的Android.mk文件,如程序清单2-5所示。
程序清单2-5 共享avilib模块的Android.mk文件
- LOCAL_PATH := $(call my-dir)
-
- #
- #第三方AVI库
- #
- include $(CLEAR_VARS)
-
- LOCAL_MODULE := avilib
- LOCAL_SRC_FILES := avilib.c platform_posix.c
-
- include $(BUILD_SHARED_LIBRARY)
现在,可以将avilib模块从NDK项目的Android.mk文件中移除。为了使用这个共享模块,将以transcode/avilib为参数调用函数宏import-module部分添加在构建文档的末尾,如程序清单2-6所示。为了避免构建系统的冲突,应该将import-module函数宏调用放在Android.mk文档的末尾。
程序清单2-6 使用共享模块的 NDK 项目
- #
- # 原生模块
- #
- include $(CLEAR_VARS)
-
- LOCAL_MODULE := module
- LOCAL_SRC_FILES := module.c
- LOCAL_SHARED_LIBRARIES := avilib
-
- include $(BUILD_SHARED_LIBRARY)
-
- $(call import-module,transcode/avilib)
import-module函数宏需要先定位共享模块,然后再将它导入到NDK项目中。默认情况下,import-module函数宏只搜索<Android NDK>/sources目录。为了搜索c:\android\shared-modules目录,定义一个名为NDK_MODULE_PATH的新环境变量并将它设置成共享模块的根目录,例如:c:\android\shared-modules。
6. 用Prebuilt库
使用共享模块要求有共享模块的源代码,Android NDK构建系统简单地把这些源文件包含在NDK项目中并每次构建它们。自R5版本以后,Android NDK也提供对Prebuilt库的支持。在下面的情况下,Prebuilt库是非常有用的:
想在不发布源代码的情况下将你的模块发布给他人。
想使用共享模块的预建版来加速构建过程。
尽管已经被编译了,但预建模块仍需要一个Android.mk构建文档,如程序清单2-7所示。
程序清单2-7 预构建共享模块的Android.mk 文件
- LOCAL_PATH := $(call my-dir)
-
- #
- # 第三方预构建AVI库
- #
- include $(CLEAR_VARS)
-
- LOCAL_MODULE := avilib
- LOCAL_SRC_FILES := libavilib.so
-
- include $(PREBUILT_SHARED_LIBRARY)
LOCAL_SRC_FILES变量指向的不是源文件,而是实际Prebuilt库相对于LOCAL_PATH的位置。
注意:
Prebuilt库定义中不包含任何关于该库所构建的实际机器体系结构的信息。开发人员需要确保Prebuilt库是为与NDK项目相同的机器体系结构而构建的。
PREBUILT_SHARED_LIBRARY变量指向prebuilt-shared-library.mk Makefile片段。它什么都没有构建,但是它将Prebuilt库复制到了NDK项目的libs目录下。通过使用PREBUILT_STATIC_LIBRARY变量,静态库可以像共享库一样被用作Prebuilt库,NDK项目可以像普通共享库一样使用Prebuilt库了。
- ...
- LOCAL_SHARED_LIBRARIES :=avilib
- …
7. 构建独立的可执行文件
在Android平台上使用原生组件的推荐和支持的方法是将它们打包成共享库。但是,为了方便测试和进行快速原型设计,Android NDK也支持构建独立的可执行文件。这些独立的可执行文件是不用打包成APK文件就可以复制到Android设备上的常规Linux应用程序,而且它们可以直接执行,而不通过Java应用程序加载。生成独立可执行文件需要在Android.mk构建文档中导入BUILD_EXECUTABLE变量,而不是导入BUILD_SHARED_ LIBRARY变量,如程序清单2-8所示。
程序清单2-8 独立可执行模块的Android.mk文件
- #
- # 独立的可执行的原生模块
- #
- include $(CLEAR_VARS)
-
- LOCAL_MODULE := module
- LOCAL_SRC_FILES := module.c
-
- LOCAL_STATIC_LIBRARIES := avilib
-
- include $(BUILD_EXECUTABLE)
BUILD_EXECUTABLE变量指向build-executable.mk Makefile片段,该片段包含了在Android平台上生成独立可执行文件的必要步骤。独立可执行文件以与模块相同的名称被放在libs/<machine architecture>目录下。尽管放在该目录下,但在打包阶段它并没有被包含在APK文件中。
喜欢的朋友可以添加我们的微信账号:
51CTO读书频道二维码

51CTO读书频道活动讨论群:342347198