-----
For English documents, see documentation.html of android-ndk-r5b.
Part of Android Native Development Kit (ndk)
See http://developer.android.com/sdk/ndk/ (Agent required)
Translation is personal opinion only
-----------------
Android module paths (sharing Code made easy ):
Android module path (easy to share)Code):
========================================================== ======
Starting from R5, the android ndk comes with a cool feature that allows you to share and reuse other people's modules more easily.
Android ndk introduced a cool feature starting with R5, allowing you to share and reuse modules of others more easily.
I. Overview:
I. Overview:
------------
The main idea behind this feature are:
The main idea behind this feature is:
-You can install ndk modules outside of your main project source tree.
-You can install the ndk module outside the source code tree of your main project.
-You can easily 'import' them into your project with a one-line command.
-You can use a single-line command to "import" them to your project.
In practice, here's how this works:
In fact, here we will introduce how it works:
1. Your ndk_module_path environment variable will contain a list of search paths on your system to lookup for modules.
1. Your ndk_module_path environment variable will contain a list of search paths for the module on your system.
It is up to you to set the variable, and to copy other modules to the directories you listed in it.
It is up to you to decide to set variables and copy other modules under the directories you listed.
2. to import a module, place a line like the following to, preferably at the * end * of, your android. mk:
2. to import a module, place the following command line at the end of your android. mk file:
$ (Call import-module, <tag>)
This will look for <tag>/Android. mk under any of the directories listed in your ndk_module_path.
This will find the <tag>/Android. mk in any directory 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 ).
(The reason it must be placed at the end is to avoid interference with the result of the my-Dir function. For more information, see descriptions in the docs/ANDROID-MK.html ).
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:
3. list them in your local_static_libraries or local_shared_libraries and declare that your project module depends on this import module. For example:
Local_static_libraries + = <tag>
4. Rebuild!
4. Build again!
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 ).
Remember that ndk R5 also adds module capabilities to "Export" Declarations to other modules dependent on it (for example, refer to 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.
A well-written module will correctly export all the things needed by the dependent person (Note: et voila is in French ).
Now for the full details:
The details are as follows:
I. ndk_module_path:
1. ndk_module_path:
-------------------
The ndk_module_path variable must contain a list of directories.
The ndk_module_path variable must contain a directory list.
* Due to GNU make limitations, ndk_module_path must not contain any space. The ndk will complain if this is not the case.
* Due to GNU make restrictions, ndk_module_path cannot contain any spaces. Ndk will explain whether it violates the requirements.
* Use ':' as the path separator.
* Use a semicolon as the path separator.
* On Windows, use '/' as the directory separator.
* In Windows, the forward slash is used as the directory separator (note: the windows-style backslash should be changed to the forward slash ).
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 encoded automatically.
The ndk_module_path directory will be searched in sequence. The first found <path>/<tag>/Android. mk file will be automatically included.
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 ).
As agreed, $ ndk/sources is added to your ndk_module_path definition by the end of the ndk build system. This allows you to easily import the secondary library generated by it (see an actual example in docs/CPU-FEATURES.html)
Ii. Writing an import module:
2. Write an import module:
-----------------------------
Writing an import module is trivial and very similar to what you do when writing project modules:
Writing an import module is small and very similar to what you do when writing an engineering module:
1. Create a sub-directory from one of your ndk_module_path directories.
1. Create a subdirectory in a directory in your ndk_module_path directory.
For example, if ndk_module_path is defined to/home/user/ndk-modules, then create the directory/home/user/ndk-modules/My-module/
For example, if ndk_module_path is defined as/home/user/ndk-modules, create the directory/home/user/ndk-modules/My-module/
2. Place an android. mk and eventual source code there.
2. Place an android. mk and the final source code there.
Just like you wocould for a project module, where these files normally go to $ project_path/android. mk. in the example above, this wocould go to/home/user/ndk-modules/My-module/android. mk
As you do for a project module, these files are usually stored in $ project_path/Android. mk. In the above example, it will concentrate on/home/user/ndk-modules/My-module/Android. mk
Note: Any application. mk file here will be ignored.
Note: Any application. mk file will be ignored.
3. Any module that depends on your new module, wocould import by calling the import-module function. For example:
3. Any module of your new module will be imported 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 import module can import other modules, but does not allow circular dependencies. It will be detected. Dependencies are thing-to-thing. The build system will calculate everything you need to build.
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 /).
The ndk build system will not place object files or executable files in the directory of your import module (they will all be placed under the build directory of the project, such as $ 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 ).
However, you can distribute pre-built binaries in your import module through 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.
This makes it easy to package and resend the directory of your import module to a third party.
Iii. naming an import module:
Iii. Name an import module:
-----------------------------
It is important to understand a few things related to the naming of your import module:
It is important to understand 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 refreshing Ming very little bit of house-keeping.
-What import-module does is to search for the file named Android. mk using the list provided by ndk_module_path, and then include it when executing a very small amount of internal work.
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:
You can define any number of modules by name when importing Android. mk. Therefore, there is no direct association between <Name> In the following command line:
$ (Call import-module, <tag>/<Name>)
And the names of the modules defined under <tag>/<Name>/Android. mk.
And the module name defined in <tag>/<Name>/Android. mk.
In case of doubt, keep it simple!
If you still don't understand it, keep it simple!
If you only plan to provide one import module, just name it like the base import directory.
If you only plan to provide an import module, you only need to name it like the import base 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:
On the other hand, you may provide static and dynamic versions of your modules: use different 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'
# The static version of the database is named bar_static.
Include $ (clear_vars)
Local_module: = bar_static
Local_src_files: = bar. c
# Ensure our dependees can include <bar. h> too
# Ensure that our dependent users can also include <bar. h>
Local_export_c_includes: =$ (local_path)
Include $ (build_static_library)
# Shared version of the library is named 'bar _ shared'
# The dynamic 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 wocould refer to it by doing the following:
Another module will reference it using the following method:
1. Import 'foo/bar', as in:
1. Import Foo/bar, as shown in the following figure:
$ (Call import-module, foo/bar)
2. To use the static Library:
2. Use a static Library:
...
Local_static_libraries: = bar_static
3. or to use the Shared Library:
3. Alternatively, use the dynamic 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:
-The module namespace is flat, so try to give your module A name that cannot conflict with other module names. Note that you can use local_module_filename to set the name of your module's binary file, independent of local_module (see Docs/ANDROID-MK.html for its definition and usage ). For example:
Include $ (clear_vars)
Local_module: = super_foo
Local_module_filename: = Foo # Will give libfoo. So # Set it to 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 # will also be set to 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'
Define two modules named super_foo and normal_foo. Both of them generate a dynamic 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:
Therefore, only one of them can be used by your project or conflict occurs during the build period. This allows you to use your ndk build script to select a normal or optimized version, and keep it in your JavaSource codeThe same and simple loading command in:
Static {
System. loadlibrary ("foo ");
}
Iv. Tips & Recommendations:
Iv. Tips and suggestions:
---------------------------
* You don't need to import a module before you can reference it!
* You do not need to import the 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.
* Use import-module at the end of your android. mk to avoid interference with the result of my-Dir. Refer to the description of this function in the 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:
* We strongly recommend that you use sub-directories for your import label to describe its source, like this:
$ (Call import-module, GTK/Glib)
Or something like:
Or something like this:
$ (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.
Important: the "android" Import directory and any of its subdirectories are retained due to the use of ndk. However, you are welcome to organize other import modules as you wish.