zoukankan      html  css  js  c++  java
  • 理解 Android Build 系统

    在配置了以上的文件之后,便可以编译出我们新添加的设备的系统镜像了。

    首先,调用“source build/envsetup.sh”该命令的输出中会看到 Build 系统已经引入了刚刚添加的 vendorsetup.sh 文件。

    然后再调用“lunch”函数,该函数输出的列表中将包含新添加的 vendorsetup.sh 中添加的条目。然后通过编号或名称选择即可。

    最后,调用“make -j8”来执行编译即可。

    添加新的模块

    关于“模块”的说明在上文中已经提到过,这里不再赘述。

    在 源码树中,一个模块的所有文件通常都位于同一个文件夹中。为了将当前模块添加到整个 Build 系统中,每个模块都需要一个专门的 Make 文件,该文件的名称为“Android.mk”。Build 系统会扫描名称为“Android.mk”的文件,并根据该文件中内容编译出相应的产物。

    需 要注意的是:在 Android Build 系统中,编译是以模块(而不是文件)作为单位的,每个模块都有一个唯一的名称,一个模块的依赖对象只能是另外一个模块,而不能是其他类型的对象。对于已经 编译好的二进制库,如果要用来被当作是依赖对象,那么应当将这些已经编译好的库作为单独的模块。对于这些已经编译好的库使用 BUILD_PREBUILT 或 BUILD_MULTI_PREBUILT。例如:当编译某个 Java 库需要依赖一些 Jar 包时,并不能直接指定 Jar 包的路径作为依赖,而必须首先将这些 Jar 包定义为一个模块,然后在编译 Java 库的时候通过模块的名称来依赖这些 Jar 包。

    下面,我们就来讲解 Android.mk 文件的编写:

    Android.mk 文件通常以以下两行代码作为开头:

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)


    这两行代码的作用是:

       设置当前模块的编译路径为当前文件夹路径。
       清理(可能由其他模块设置过的)编译环境中用到的变量。

    为了方便模块的编译,Build 系统设置了很多的编译环境变量。要编译一个模块,只要在编译之前根据需要设置这些变量然后执行编译即可。它们包括:

       LOCAL_SRC_FILES:当前模块包含的所有源代码文件。
       LOCAL_MODULE:当前模块的名称,这个名称应当是唯一的,模块间的依赖关系就是通过这个名称来引用的。
       LOCAL_C_INCLUDES:C 或 C++ 语言需要的头文件的路径。
       LOCAL_STATIC_LIBRARIES:当前模块在静态链接时需要的库的名称。
       LOCAL_SHARED_LIBRARIES:当前模块在运行时依赖的动态库的名称。
       LOCAL_CFLAGS:提供给 C/C++ 编译器的额外编译参数。
       LOCAL_JAVA_LIBRARIES:当前模块依赖的 Java 共享库。
       LOCAL_STATIC_JAVA_LIBRARIES:当前模块依赖的 Java 静态库。
       LOCAL_PACKAGE_NAME:当前 APK 应用的名称。
       LOCAL_CERTIFICATE:签署当前应用的证书名称。
       LOCAL_MODULE_TAGS:当前模块所包含的标签,一个模块可以包含多个标签。标签的值可能是 debug, eng, user,development 或者 optional。其中,optional 是默认标签。标签是提供给编译类型使用的。不同的编译类型会安装包含不同标签的模块,关于编译类型的说明如表 7 所示:

    表 3 中的文件已经定义好了各种类型模块的编译方式。所以要执行编译,只需要引入表 3 中对应的 Make 文件即可(通过常量的方式)。例如,要编译一个 APK 文件,只需要在 Android.mk 文件中,加入“include $(BUILD_PACKAGE)

    除此以外,Build 系统中还定义了一些便捷的函数以便在 Android.mk 中使用,包括:

    $(call my-dir):获取当前文件夹路径。

    $(call all-java-files-under, <src>):获取指定目录下的所有 Java 文件。

    $(call all-c-files-under, <src>):获取指定目录下的所有 C 语言文件。

    $(call all-Iaidl-files-under, <src>):获取指定目录下的所有 AIDL 文件。

    $(call all-makefiles-under, <folder>):获取指定目录下的所有 Make 文件。

    $(call intermediates-dir-for, <class>, <app_name>, <host or target>, <common?> ):获取 Build 输出的目标文件夹路径。

    清单 2 和清单 3 分别是编译 APK 文件和编译 Java 静态库的 Make 文件示例:


    清单 2. 编译一个 APK 文件

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    # 获取所有子目录中的 Java 文件
    LOCAL_SRC_FILES := $(call all-subdir-java-files)         
    # 当前模块依赖的静态 Java 库,如果有多个以空格分隔
    LOCAL_STATIC_JAVA_LIBRARIES := static-library
    # 当前模块的名称
    LOCAL_PACKAGE_NAME := LocalPackage
    # 编译 APK 文件
    include $(BUILD_PACKAGE)

    清单 3. 编译一个 Java 的静态库

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
          
    # 获取所有子目录中的 Java 文件
    LOCAL_SRC_FILES := $(call all-subdir-java-files)
          
    # 当前模块依赖的动态 Java 库名称
    LOCAL_JAVA_LIBRARIES := android.test.runner
          
    # 当前模块的名称
    LOCAL_MODULE := sample
          
    # 将当前模块编译成一个静态的 Java 库
    include $(BUILD_STATIC_JAVA_LIBRARY)

    结束语

    整个 Build 系统包含了非常多的内容,由于篇幅所限,本文只能介绍其中最主要内容。

    由于 Build 系统本身也是在随着 Android 平台不断的开发过程中,所以不同的版本其中的内容和定义可能会发生变化。网络上关于该部分的资料很零碎,并且很多资料中的一些内容已经过时不再适用,再加上缺少官方文档,所以该部分的学习存在一定的难度。

    这就要求我们要有很强的代码阅读能力,毕竟代码是不会说谎的。要知道,对于我们这些开发人员来说,源代码就是我们最忠实的朋友。 Use the Source,Luke!

  • 相关阅读:
    解决UITableView中Cell重用机制导致内容出错的方法总结
    Hdu 1052 Tian Ji -- The Horse Racing
    Hdu 1009 FatMouse' Trade
    hdu 2037 今年暑假不AC
    hdu 1559 最大子矩阵
    hdu 1004 Let the Balloon Rise
    Hdu 1214 圆桌会议
    Hdu 1081 To The Max
    Hdu 2845 Beans
    Hdu 2955 Robberies 0/1背包
  • 原文地址:https://www.cnblogs.com/wangzehuaw/p/4269138.html
Copyright © 2011-2022 走看看