当前位置: 移动技术网 > IT编程>移动开发>Android > Android源码分析(一)-----如何快速掌握Android编译文件

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

2019年05月21日  | 移动技术网IT编程  | 我要评论

李菁何云伟相声,爱情呀爱情,爱说不出口by秋至水

一 : android.mk文件概述

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

- apk程序:一般的android程序,编译打包生成apk文件。
- java库:java类库,编译打包生成jar包文件。
- c\c++应用程序:可执行的c/c++应用程序。
- c\c++静态库:编译生产c/c++静态库,并打包成.a文件。
- c\c++共享库:编译生成共享库,并打包成.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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网