Android module paths: NDK官方文档,module相关说明文档
2015-05-20 12:44
417 查看
Android module paths (sharing code made easy): Starting from r5, the Android NDK comes with a cool feature that allows you to share and reuse other people's modules more easily. I. Overview: The main idea behind this feature are: - You can install NDK modules outside of your main project source tree. - You can easily 'import' them into your project with a one-line command. In practice, here's how this works: 1. Your NDK_MODULE_PATH environment variable will contain a list of search paths on your system to lookup for modules. It is up to you to set the variable, and to copy other modules to the directories you listed in it. 2. To import a module, place a line like the following to, preferably at the *end* of, your Android.mk: $(call import-module,<tag>) This will look for <tag>/Android.mk under any of the directories listed in your NDK_MODULE_PATH. (The reason why it must be at the end is to avoid messing with the results of the 'my-dir' function. See its description in docs/ANDROID-MK.html for details). 3. Declare that your project's modules depend on the imported one by listing them in either your LOCAL_STATIC_LIBRARIES or LOCAL_SHARED_LIBRARIES. For example: LOCAL_STATIC_LIBRARIES += <tag> 4. Rebuild! Remember that NDK r5 also added the ability for a module to "export" declarations to other modules that depend on it (for example, see the definition of LOCAL_EXPORT_CFLAGS in docs/ANDROID-MK.html). A well-written module will correctly export all the things its dependees need, et voila. Now for the full details: I. NDK_MODULE_PATH: The NDK_MODULE_PATH variable must contain a list of directories. * Due to GNU Make limitations, NDK_MODULE_PATH must not contain any space. The NDK will complain if this is not the case. * Use ':' as the path separator. * On Windows, use '/' as the directory separator. The directories of NDK_MODULE_PATH will be searched in order. The first <path>/<tag>/Android.mk file that is found during the lookup will be included automatically. As a convenience, $NDK/sources is appended to your NDK_MODULE_PATH definition by the NDK build system. This allows you to easily import the helper libraries that come with it (see docs/CPU-FEATURES.html for a practical example). II. Writing an import module: Writing an import module is trivial and very similar to what you do when writing project modules: 1. Create a sub-directory from one of your NDK_MODULE_PATH directories. For example, if NDK_MODULE_PATH is defined to /home/user/ndk-modules, then create the directory /home/user/ndk-modules/my-module/ 2. Place an Android.mk and eventual source code there. Just like you would for a project module, where these files normally go to $PROJECT_PATH/Android.mk. In the example above, this would go to /home/user/ndk-modules/my-module/Android.mk NOTE: Any Application.mk file here will be ignored. 3. Any module that depends on your new module, would import by calling the import-module function. For example: $(call import-module,my-first-module) Import modules *can* import other modules, but circular dependencies are not permitted and will be detected. Dependencies are transitive and the build system will compute all the things that need to be built for you. The NDK build system will not place object files or executables in your import module directory (they will all be placed under the project's build directory, e.g. $PROJECT_PATH/obj/). You can however distribute prebuilt binaries in your import module with the new PREBUILT_STATIC_LIBRARIES or PREBUILT_SHARED_LIBRARIES feature (see docs/ANDROID-MK.html). This makes it easy to package and redistribute your import module directory to third-parties. III. Naming an import module: It is important to understand a few things related to the naming of your import module: - What 'import-module' does is really search for a file named Android.mk using the list provided by NDK_MODULE_PATH, then include while performing very little bit of house-keeping. Your imported Android.mk can define any number of modules, with any name. As a consequence, there is no direct relationship between <name> in the following line: $(call import-module,<tag>/<name>) And the names of the modules defined under <tag>/<name>/Android.mk. IN CASE OF DOUBT, KEEP IT SIMPLE! If you only plan to provide one import module, just name it like the base import directory. On the other hand, you may want to provide a static and a shared version of your module: use distinct names under the same top-level Android.mk. Consider the following build script: $NDK_MODULE_PATH/foo/bar/Android.mk: LOCAL_PATH := $(call my-dir) # Static version of the library is named 'bar_static' include $(CLEAR_VARS) LOCAL_MODULE := bar_static LOCAL_SRC_FILES := bar.c # Ensure our dependees can include <bar.h> too LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) include $(BUILD_STATIC_LIBRARY) # Shared version of the library is named 'bar_shared' LOCAL_MODULE := bar_shared LOCAL_SRC_FILES := bar.c LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) include $(BUILD_SHARED_LIBRARY) Another module would refer to it by doing the following: 1. Import 'foo/bar', as in: $(call import-module,foo/bar) 2. To use the static library: ... LOCAL_STATIC_LIBRARIES := bar_static 3. Or to use the shared library: ... LOCAL_SHARED_LIBRARIES := bar_shared - The module namespace is flat, so try to give your modules names that are likely to not collide with other. Note that your can use LOCAL_MODULE_FILENAME to give the name of your module's binary file, independently from its LOCAL_MODULE (see docs/ANDROID-MK.html for definition and usage). For example: include $(CLEAR_VARS) LOCAL_MODULE := super_foo LOCAL_MODULE_FILENAME := foo # will give libfoo.so LOCAL_SRC_FILES := foo-src.c LOCAL_CFLAGS := -DVOLUME=11 include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := normal_foo LOCAL_MODULE_FILENAME := foo # will also give libfoo.so LOCAL_SRC_FILES := foo-src.c include $(BUILD_SHARED_LIBRARY) Defines two modules named "super_foo" and "normal_foo" which both produce a shared library named 'libfoo.so' As a consequence, only one of them can be used by your project or a conflict will happen at build time. This allows you to select either the normal or optimized version in your NDK build scripts, while keeping the same simple loading instruction in your Java sources as: static { System.loadLibrary("foo"); } IV. Tips & Recommendations: * You don't need to import a module before you can reference it! * Use import-module at the *end* of your Android.mk to avoid messing with the result of 'my-dir'. See the description of this function in docs/ANDROID-MK.html to understand why. * It is *strongly* suggested to use a subdirectory for your import tags, that describes its origin, as in: $(call import-module,gtk/glib) or something like: $(call import-module,com.example/awesomelib) IMPORTANT: THE 'android' IMPORT DIRECTORY, AND ANY OF ITS SUB-DIRECTORIES IS *RESERVED* FOR NDK USAGE. FEEL FREE TO ORGANIZE YOUR OTHER IMPORT MODULES AS YOU WANT OTHERWISE.
原文地址:http://www.kandroid.org/ndk/docs/IMPORT-MODULE.html
相关文章推荐
- Bluetooth Low Energy for Android --- Google官方说明文档(英文)
- #android-ndk-r8d 使用 独立 编译 工具链 官方文档 中英文 对照
- Android 线性布局(LinearLayout)相关官方文档 - 布局参数部分
- 使用Android Studio进行NDK开发和调试(gradle-experimental之官方文档的翻译说明)
- Android官方开发文档Training系列课程中文版:Android的JNI相关
- Android官方开发文档Training系列课程中文版:Android的JNI相关
- Android中使用官方提供好的功能使用说明(比如系统图库获取),也作为延生学习的学习文档
- 摩托罗拉三防智能DEFY ME525 官方Android 2.3升级文档、说明及教程
- 关于 Android Fragment的官方说明文档
- Android 线性布局(LinearLayout)相关官方文档 - 布局參数部分
- android官方文档关于oncreate()的参数说明
- Android 线性布局(LinearLayout)相关官方文档 - 参考部分
- #android-ndk-r8d 使用 独立 编译 工具链 官方文档 中文版
- Android 线性布局(LinearLayout)相关官方文档 - 指南部分
- android多屏幕适配相关知识和官方翻译文档
- Android官方开发文档Training系列课程中文版:如何避免ANR?
- Android File类 根据官方文档理解
- Caching Bitmaps缓存bitmaps(Android官方文档翻译三)