NDK开发之Android.mk文件初探

NDK开发之Android.mk文件初探


Android.mk文件概述

  • Android.mk是一个向Android NDK 构建系统描述NDK 项目的GUN Makefile片段.

  • Android.mk是NDK项目的必备组件.

  • NDK构建系统要求将Android.mk放置在jni子目录中.

  • Android.mk是一个GUN Makefile片段,所以语法和其他的Makefile一样, 每一行都包含一个指令.

  • Makefile文件使用 #作为指令注解的开头, GUN Make工具不处理注解行.

  • 根据GUN Make 的命名规范, 变量名要大写.


Android.mk内容详解

  • 声明 LOCLA_PATH 变量

    LOCLA_PATH := $(call my-dir)

    根据Android构建系统的要求,Android.mk文档必须以 LOCAL_PATH 变量的定义开头.

    Android构建系统利用LOCAL_PATH来定位源文件.

    由于LOCAL_PATH设置为硬编码并不合适, 所以构建系统提供 my-dir 的宏功能.

    通过将该变量设置为 my-dir 的宏的返回值, 可以将其放置在当前目录下.

  • 引入 CLEAR_VARS 指令

    Include $(CLEAR_VARS)

    Android 构建系统将 CLEAR_VARS 变量设置在 clear-vars.mk片段, 其作用是, 引入的Makefile 片段可以清除除了 LOCAL_PATH 以外的 LOCAL_ 的变量.

    eg: LOCAL_MODULE, LOCAL_SRC_FILES等.

    每一个原生组件被成为一个模块, Android构建系统在单次执行中解析多个构建文件和模块定义, 而LOCAL_ 是全局变量, 执行清除指令可以避免冲突.

  • 声明 LOCAL_MODULE 变量

    LOCAL_MODULE := hello-jni

    LOCAL_MODULE变量用来给模块设定唯一的名称, 以上则为设定该模块的名称为: hello-jni.

    模块名称也被用于构建系统生成的文件命名, 所以构建系统给该文件添加了适当的前缀和后缀.

    上面的hello-jni模块会生成一个共享库文件且构建系统会将他命名为: libhello-jni.so.

  • 声明 LOCAL_SRC_FILES 变量

    LOCAL_SRC_FILES := hello.c

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

    eg: LOCAL_SRC_FILES := subDir<name>/.../hello.c

    LOCAL_SRC_FILES 可以包含用空格分开的多个源文件名, 如果jni下有多级子目录则如下.

    可以使用: ‘空格 + \’ 进行换行.

    eg: 
    LOCAL_SRC_FILES := \
    hello.c \
    ... \
    world.c

    多级子目录

    eg: 
    LOCAL_SRC_FILES := \    
    LOCAL_SRC_FILES := \
    subDir<name>/.../hello.c \
    ... \
    subDir<name>/.../world.c
  • 引入 BUILD_SHARED_LIBRARY 指令 # 构建共享库

    include $(BUILD_SHARED_LIBRARY)

    为建立可供主程序使用的模块, 必须将模块变成共享库.

    Android NDK 构建系统将 BULID_SHARED_LIBRARY 变量设置为 build-shared-library.mk文件的保存位置, 改Makefile片段包含了将源文件构建和组装成为共享库的必要过程.

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

    eg: 
    
    # 模块1 开始
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := <module1_name>
    LOCAL_SRC_FILES := <module1.xx.c ...> # 可有多个
    
    include $(BUILD_SHARED_LIBRARY)
    
    # 模块1 结束
    
    
    
    # 模块2 开始
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := <module2_name>
    LOCAL_SRC_FILES := <module2.xx.c ...> # 可有多个
    
    include $(BUILD_SHARED_LIBRARY)
    
    # 模块2 结束
    
    
    .... # 可以有多个模块
    
    
    # 处理完Android.mk构建文档后, Android NDK 构建系统会产生 lib<module1_name>.so 和 lib<module2_name>.so     对应个共享库.
    
  • 引入 BUILD_STATIC_LIBRARY 指令

    incline $(BUILD_STATIC_LIBRARY) # 构建静态库

    静态库可以保证源代码模块化, 当静态库和共享库连接时, 他就变成共享库的一部分.在多个共享库于同一个静态库连接时, 需要将多个副本和不同的共享库重复链接, 这样就增加了应用程序的大小.

    Android NDK 构建系统支持链接静态库.

    实际的应用并不直接使用 静态库, 且应用程序包中不包含静态库, 静态库用来构建共享库.

    在将第三方代码添加到现有原生项目中时, 不直接将三方源码包含在原生项目中, 而是将第三方代码编译成静态库并入到共享库.

    eg: 
    
    # 程序清单
    
    LOCAL_PATH := $(call my-dir)
    
    
    # 三方AVI库
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := vailib
    LOCAL_SRC_FILES := avilib.c platform.c
    
    
    # 引入静态库指令
    
    include $(BUILD_STATIC_LIBRARY) 
    
    # 三方库配置完成
    
    
    
    # 原生模块
    
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := <module_name>
    LOCAL_SRC_FILES := <srcxxx>.c ...
    
    
    # 声明静态库变量, 指向 三方静态库 vailib
    
    LOCAL_STATIC_LIBRARIES := vailib
    
    include $(BUILE_SHARED_LIBRARY)
    
    # 原生模块配置完成
    
    
    
    # 说明: 在将三方代码模块生成静态库之后, 共享库就可以通过他的模块名添加到 LOCAL_STATIC_LIBRARY     变量中来使用该模块
    
  • 用共享库共享通用模块

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

    eg: 
    LOCAL_PATH := #(call my-dir)
    
    
    # 将三方通用模块作为共享库
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := vailib
    LOCAL_SRC_FILES := vai.c vai-xx.c
    
    include $(BUILD_SHARED_LIBRARY)
    
    
    # 原生模块1, 链接vailib模块
    
    
    #include $(CLEAR_VARS)
    
    
    LOCAL_MODULE    := module1
    LOCAL_SRC_FILES := module1.c
    
    LOCAL_SHARED_LIBRARIES := vailib
    include $(BUILD_SHARED_LIBRARY)
    
    # 原生模块1 结束
    
    
    
    # 原生模块2, 也链接到 vailib模块
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := module2
    LOCAL_SRC_FILES := module2.c
    
    LOCAL_SHARDE_LIBRARIES := vailib
    include $(BUILD_SHARED_LIBRARY)
  • 在多个NDK项目间共享模块

    同时使用静态库和共享库, 可以在模块间共享通用模块, 但这都是在同一个NDK项目中. 从R5版本开始, Android NDK 开始允许在NDK项目间共享和重用模块.

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

    以上面的vailib为例 具体如下

    1. 将avilib的源代码移到NDK 项目以外的位置, 为避免命名冲突, 目录结构可以包含模块提供者.
    eg: C:/android\shared-modules\transcode\avilib
    1. 作为共享模块, vailib需要有自己的Android.mk文件, 清单如下:
    
    # vailib 模块配置清单
    
    
    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE     := vailib
    LOCAL_SRC_FILES := valib.c
    
    include $(BUILD_SHARED_LIBRARY)
    1. 将vailib模块的配置信息在原生项目中移除, 为了使用这个共享模块, 将以transcode/vailib为参数调用函数宏 import-module 部分增加在构建文档的末尾.

    为避免构建系统冲突, 应将 import-module 函数宏放在Android.mk文档的末尾.

    
    # 原生模块配置清单
    
    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := module
    LOCAL_SRC_FILES := module.c
    
    include $(BUILD_SHARED_LIBRARY)
    
    $(call import-module, transcode/vailib)
    1. import-module函数宏需要先定位共享模块, 然后再将其导入 NDK 项目中.

    2. 默认 import-module 函数宏只搜索/sources 目录下的模块, 为了能够搜索 C:/android\shared-modules\transcode\avilib 目录, 需要定义一个名为: NDK_MODULE_PATH 的环境变量, 并将其设置为共享模块的根目录 如上中: C:/android\shared-modules\


声明: 此笔记为 << Android C++高级编程:使用NDK >>这本书的学习笔记.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值