• Android源码分析(一)-----如何快速掌握Android编译文件


    一 : Android.mk文件概述

    主要向编译系统指定相应的编译规则。会被解析一次或多次。因此尽量减少源码中声明变量,因为这些变量可能会被多次定义从而影响到后面的解析。这个文件的语法会把源代码组织成模块,每个模块属于下列类型之一:

    - APK程序:一般的Android程序,编译打包生成apk文件。
    - JAVA库:java类库,编译打包生成jar包文件。
    - CC++应用程序:可执行的C/C++应用程序。
    - CC++静态库:编译生产C/C++静态库,并打包成.a文件。
    - CC++共享库:编译生成共享库,并打包成.so文件,有且只有共享库才能被安装/复制到APK包中。
    

    二 : 系统变量####

    - LOCAL_PATH:这个变量用于给出当前文件的路径,必须在Android.mk的开头定义,可以这样使用LOCAL_PATH := $(call my-dir),这样这个变量不会被$(CLEAR_VARS)清除,因为每个Android.mk只需要定义一次(即使一个文件中定义了多个模块的情况下)。
    - LOCAL_SRC_FILES:当前模块包含的所有源代码文件。
    - LOCAL_MODULE:当前模块的名称,这个名称应当是唯一的,并且不能包含空格。模块间的依赖关系就是通过这个名称来引用的。
    - LOCAL_MODULE_CLASS:标识所编译模块最后放置的位置。ETC表示放置在/system/etc.目录下,APPS表示放置在/system/app目录下,SHARED_LIBRARIES表示放置在/system/lib目录下。如果具体指定,则编译的模块不会放到编译系统中,最后会在out对应product的obj目录下的对应目录中。
    - LOCAL_SRC_FILES:这是要编译的源代码文件列表。只要列出要传递给编译器的文件即可,编译系统会自动计算依赖关系。源代码文件路径都是相相对于LOCAL_PATH的,因此可以使用相对路径进行描述。
    - LOCAL_JAVA_LIBRARIES:当前模块依赖的Java共享库,也叫Java动态库。例如framework.jar包。
    - LOCAL_STATIC_JAVA_LIBRARIES:当前模块依赖的Java静态库,在Android里,导入的jar包和引用的第三方工程都属于Java静态库。
    - LOCAL_STATIC_LIBRARIES:当前模块在运行时依赖的静态库的名称。
    - LOCAL_SHARED_LIBRARIES:当前模块在运行时依赖的动态库的名称。
    - LOCAL_C_INCLUDES:c或c++语言需要的头文件的路径。
    - LOCAL_CFLAGS:提供给C/C++编译器的额外编译参数。
    - LOCAL_PACKAGE_NAME:当前APK应用的名称。
    - LOCAL_CERTIFICATE:签署当前应用的证书名称。
    - LOCAL_MODULE_TAGS:当前模块所包含的标签,一个模块可以包含多个标签。标签的值可能是eng、user、debug、development、optional。其中,optional是默认标签。
    - LOCAL_DEX_PREOPT:apk的odex优化开关,默认是false。
    

    三 : mk文件模板####

    • 编译C/C++应用程序的模板:
         #Test Exe
         LOCAL_PATH := $(call my-dir)
         include $(CLEAR_VARS)
         LOCAL_SRC_FILES:= main.c
         LOCAL_MODULE:= test_exe
         #LOCAL_C_INCLUDES :=
         #LOCAL_STATIC_LIBRARIES :=
         #LOCAL_SHARED_LIBRARIES :=
         include $(BUILD_EXECUTABLE)
    

    BUILD_EXECUTABLE表示以一个可执行程序的方式进行编译。补充说明:include $(BUILD_PACKAGE)则是编译出一个apk,include $(BUILD_STATIC_JAVA_LIBRARY)则是编译出jar包。

    • 编译静态库的模板:
        `#Test Static Lib
         LOCAL_PATH := $(call my-dir)
         include $(CLEAR_VARS)
         LOCAL_SRC_FILES:= /
                   helloworld.c
         LOCAL_MODULE:= libtest_static
         #LOCAL_C_INCLUDES :=
         #LOCAL_STATIC_LIBRARIES :=
         #LOCAL_SHARED_LIBRARIES :=
         include $(BUILD_STATIC_LIBRARY)
    

    一般的和上面相似,BUILD_STATIC_LIBRARY表示编译一个静态库.a文件。静态库不会复制到的APK包中,但是能够用于编译共享库。

    • 编译动态库的模板:
         #Test Shared Lib
         LOCAL_PATH := $(call my-dir)
         include $(CLEAR_VARS)
         LOCAL_SRC_FILES:= /
                   helloworld.c
         LOCAL_MODULE:= libtest_shared
         TARGET_PRELINK_MODULES := false
         #LOCAL_C_INCLUDES :=
         #LOCAL_STATIC_LIBRARIES :=
         #LOCAL_SHARED_LIBRARIES :=
          include $(BUILD_SHARED_LIBRARY)
    

    一般的和上面相似,BUILD_SHARED_LIBRARY表示编译一个动态库。
    以上三者的生成结果分别在如下,generic依具体target会变:
    out/target/product/generic/obj/EXECUTABLE
    out/target/product/generic/obj/STATIC_LIBRARY
    out/target/product/generic/obj/SHARED_LIBRARY

    每个模块的目标文件夹分别为:
    可执行程序:XXX_intermediates
    静态库: XXX_static_intermediates
    动态库: XXX_shared_intermediates

    另外,在Android.mk文件中,还可以指定最后的目标安装路径,用LOCAL_MODULE_PATH和LOCAL_UNSTRIPPED_PATH来指定。不同的文件系统路径用以下的宏进行选择:

    - TARGET_ROOT_OUT:表示根文件系统out/target/product/xxxxx/root。
    - TARGET_OUT:表示system文件系统out/target/product/xxxx/system。
    - TARGET_OUT_DATA:表示data文件系统out/target/product/xxxx/data。
    - TARGET_OUT_SHARED_LIBRARIES:表示out/target/product/xxxx/system/lib
    - TARGET_OUT_APPS:表示out/target/product/xxxx/system/app
    - ANDROID_PRODUCT_OUT:out/target/product/xxxx/
    - TARGET_OUT_JAVA_LIBRARIES:out/target/product/xxxx/system/framework
    

    四 : 常用函数####

    - $(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输入的目标文件夹路径。
    

    五 : Settings模块Android.mk文件分析####

    # 当前文件的路径
    LOCAL_PATH:= $(call my-dir)
    # 清除变量
    include $(CLEAR_VARS)
    
    # 列举所有需要编译的源文件
    LOCAL_SRC_FILES := 
            $(call all-logtags-files-under, src)
    
    # 模块名称--唯一
    LOCAL_MODULE := settings-logtags
    
    #依赖的java静态库
    include $(BUILD_STATIC_JAVA_LIBRARY)
    
    # Build the Settings APK
    include $(CLEAR_VARS)
    
    #依赖的java库
    LOCAL_JAVA_LIBRARIES := bouncycastle core-oj telephony-common ims-common
    #依赖的jar包,包括系统的和第三方的(放在libs目录)jar包
    LOCAL_STATIC_JAVA_LIBRARIES := 
        android-support-v4 
        android-support-v13 
        android-support-v7-recyclerview 
        android-support-v7-preference 
        android-support-v7-appcompat 
        android-support-v14-preference 
        jsr305 
        settings-logtags
        
    #user: 指该模块只在user版本下才编译
    #eng: 指该模块只在eng版本下才编译
    #tests: 指该模块只在tests版本下才编译
    #optional:指该模块在所有版本下都编译
    LOCAL_MODULE_TAGS := optional
    
    #列举所有需要编译的源文件
    LOCAL_SRC_FILES := 
            $(call all-java-files-under, src)
    
    #列举所有需要的资源文件夹
    LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res 
        frameworks/support/v7/preference/res 
        frameworks/support/v14/preference/res 
        frameworks/support/v7/appcompat/res 
        frameworks/support/v7/recyclerview/res
    
    #打包成apk的名称--包名
    LOCAL_PACKAGE_NAME := Settings
    
    #用于指定签名时使用的KEY
    LOCAL_CERTIFICATE := platform
    
    #编译后在ROM中的安装位置
    #true,安装位置为system/priv-app
    #false,安装位置为system/app
    LOCAL_PRIVILEGED_MODULE := true
    
    #混淆文件名
    LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    
    LOCAL_AAPT_FLAGS := --auto-add-overlay 
        --extra-packages android.support.v7.preference:android.support.v14.preference:android.support.v17.preference:android.support.v7.appcompat:android.support.v7.recyclerview
    
    ifneq ($(INCREMENTAL_BUILDS),)
        LOCAL_PROGUARD_ENABLED := disabled
        LOCAL_JACK_ENABLED := incremental
        LOCAL_DX_FLAGS := --multi-dex
        LOCAL_JACK_FLAGS := --multi-dex native
    endif
    
    #包含的其他mk文件
    include frameworks/opt/setupwizard/library/common-full-support.mk
    include frameworks/base/packages/SettingsLib/common.mk
    
    #打包成apk
    include $(BUILD_PACKAGE)
    
    # Use the following include to make our test apk.
    ifeq (,$(ONE_SHOT_MAKEFILE))
    #获取当前目录下的所有Make文件
    include $(call all-makefiles-under,$(LOCAL_PATH))
    endif
    
  • 相关阅读:
    Centos设置时区和时间同步
    CentOS 安装 Docker
    Docker部署RabbitMq
    Docker部署MinIO对象存储服务
    Docker配置阿里云镜像加速
    IDEA集成Docker部署项目容器
    VMware配置静态ip
    Vue 报错 "TypeError: Cannot read property 'name' of undefined"
    持续交付-发布可靠软件的系统方法
    软件测试总结
  • 原文地址:https://www.cnblogs.com/ljx646566715/p/10893807.html
Copyright © 2020-2023  润新知