Android NDK编程浅入深出之--Android.mk

来源:互联网 发布:网络兔子机器人 编辑:程序博客网 时间:2024/06/04 18:27

http://www.41443.com/HTML/Android/20150707/383675.html

 

Android.mk Android.mk是一个向Android NDK构建系统描述NDK项目的GUN Makefile片段。它是每一个NDK项目的必备组件。构建系统希望它出现在jni子目录中。下面是hello-jni项目中Android.mk文件的内容。 为了更好地理解它的句法,我们逐行分析。因为这个是一个GU

 

Android.mk

Android.mk是一个向Android NDK构建系统描述NDK项目的GUN Makefile片段。它是每一个NDK项目的必备组件。构建系统希望它出现在jni子目录中。下面是hello-jni项目中Android.mk文件的内容。

为了更好地理解它的句法,我们逐行分析。因为这个是一个GUN Makefile片段,所以它的句法和其他Makefile是一样的。每行都包含一个单独的指令,以“#”开头的是注释行,GUN Make 工具不处理它们。根据命名规范,变量名要大写。

注释块后的第一条指令是用来定义LOCAL_PATH变量的。根据Android构建系统的要求,Android.mk文档必须以LOCAL_PATH变量的定义开头。

  • LOCAL_PATH :=$(call my-dir)

    Android构建系统利用LOCAL_PATH来定位源文件。因为将该变量设置为硬编码值并不合适,所以Android构建系统提供了一个名为my-dir的宏功能。通过将该变量设置为my-dir 宏功能的返回值,可以将其放在当前目录下。

    Android构建系统将CLEAR_VARS变量设置为clear-vars.mk片段的位置。包含Makefile片段可以清除除了LOCAL_PATH以外的LOCAL_变量,例如LOCAL_MODULE与LOCAL_SRC_FILES等。

  • Include $(CLEAR_VARS)

    这样做是因为Android构建系统在单次执行中解析多个构建文件和模块定义,而LOCAL_是全局变量。清除它们可以避免冲突,每一个原生组件被称为一个模块。

    LOCAL_MODULE变量用来给这些模块设定一个唯一的名称。下面的代码将该模块的名称设为hello-jni:

  • LOCAL_MODULE := hello-jni

    因为模块名称也被用于给构建过程所生成的文件命名,所以构建系统给该文件添加了适当的前缀和后缀。本例中,hello-jni模块会生成一个共享库文件且构建系统会将它命名为libhello-jni.so。

    用LOCAL_SRC_FILES变量定义用来建立和组装这个模块的源文件列表。

  • LOCAL_SRC_FILES := hello-jni.c

    这里,hello-jni模块只由一个源文件生成,而LOCAL_SRC_FILES变量可以包含用空格分开的多个源文件名。

    至此,Android.mk文件中定义的构建系统变量简单描述了原生项目。编译和生成实际模块的构建系统还需要包含合适的构建系统片段,具体需要包含哪些片段取决于想要生成模块的类型。

    1. 构建共享库

    为了建立可供主应用程序使用的模块,必须将该模块变成共享库。Android NDK构建系统将BUILD_SHARED_LIBRARY变量设置成build-shared-library.mk文件的保存位置。该Makefile片段包含了将源文件构建和组装成共享库的必要过程:

  • include $(BUILD_SHARED_LIBRARY)

    hello-jni是一个简单的模块;然而,除非你的模块需要特殊处理,否则Android.mk文档将会包含一模一样的流程和指令。

     

    2. 构建多个共享库

    基于不同的应用程序的体系结构,一个单独的Android.mk文档可能产生多个共享库模块。如程序:

    在处理完这个Android.mk构建文档之后,Android NDK构建系统会产生libmodule1.so和libmodule2.so两个共享库。

    3. 构建静态库

    Android NDK构建系统也支持静态库。实际的Android应用程序并不直接使用静态库,并且应用程序包中也不包含静态库。静态库可以用来构建共享库。例如,在将第三方代码添加到现有原生项目中时,不用直接将第三方源代码包括在原生项目中,而是将第三方代码编译成静态库然后并入共享库,如程序:

    在将第三方代码模块生成静态库之后,共享库就可以通过将它的模块名添加到LOCAL_STATIC_LIBRARIES变量中来使用该模块。

    4. 用共享库共享通用模块

    静态库可以保证源代码模块化;但是,当静态库与共享库相连时,它就变成了共享库的一部分。在多个共享库的情况下,多个共享库与同一个静态库连接时,需要将通用模块的多个副本与不同共享库重复相连,这样就增加了应用程序的大小。在这种情况下,不用构建静态库,而是将通用模块作为共享库建立起来,而动态连接依赖模块以便消除重复的副本,如程序:

    5. 在多个NDK项目间共享模块

    同时使用静态库和共享库时,可以在模块间共享通用模块。但要说明的是,所有这些模块必须属于同一个NDK项目。从R5版本开始,Android NDK也允许在NDK项目间共享和重用模块。考虑前面讲过的示例,可以通过以下步骤在多个NDK项目间共享avilib模块:

    首先,将avilib源代码移动到NDK项目以外的位置,例如:C:androidshared-modules avilib。为了避免命名冲突,目录结构也可以包含模块提供者的名字,例如:C: androidshared-modules ranscodeavilib。

    注意:

    在Android NDK构建系统中,共享模块路径不能包含空格。

    作为共享模块,avilib需要自己的Android.mk文件,如程序:

    现在,可以将avilib模块从NDK项目的Android.mk文件中移除。为了使用这个共享模块,将以transcode/avilib为参数调用函数宏import-module部分添加在构建文档的末尾。为了避免构建系统的冲突,应该将import-module函数宏调用放在Android.mk文档的末尾。如程序:

    import-module函数宏需要先定位共享模块,然后再将它导入到NDK项目中。默认情况下,import-module函数宏只搜索/sources目录。为了搜索c:androidshared-modules目录,定义一个名为NDK_MODULE_PATH的新环境变量并将它设置成共享模块的根目录,例如:c:androidshared-modules。

    6. 用Prebuilt库

    使用共享模块要求有共享模块的源代码,Android NDK构建系统简单地把这些源文件包含在NDK项目中并每次构建它们。自R5版本以后,Android NDK也提供对Prebuilt库的支持。在下面的情况下,Prebuilt库是非常有用的:

    想在不发布源代码的情况下将你的模块发布给他人。

    想使用共享模块的预建版来加速构建过程。

    尽管已经被编译了,但预建模块仍需要一个Android.mk构建文档,如程序:

    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库了。

    7. 构建独立的可执行文件

    (责任编辑:幽灵学院)
  •  

     

    0 0
    原创粉丝点击