Android编译控制mk文件
m和mm以及mmm的区别?
m=make
mm编译当前目录下的模块,不包含所依赖的模块
mmm 后面指定模块目录
Android.mk文件的结构
在学习这个玩意之前,如要你直接把头扎进去看每一行什么意思,那你只能一行一行地学习。
但是,作为聪明的程序员,肯定会找规律的。
我们观察各种Android.mk文件,就会发现规律了。
Android.mk文件规律
我们可以发现,第一句都是
LOCAL_PATH:= $(call my-dir)
然后就是:
include $(CLEAR_VARS)
接着,就是设置各种变量了:LOCAL_XXXX
设置完变量以的事,就开始去调用构建方法了,到底要编译成什么东西.
比如说,编译成apk
include $(BUILD_PACKAGE)
比如说,遍成可执行程序
include $(BUILD_EXECUTABLE)
比如说编译成jar包
include $(BUILD_STATIC_JAVA_LIBRARY)
最后,礼貌性地调用一下子mk,或者清除变量。
Android.mk可视化
嗯哈哈
这只是编译一个模块,如果想我编译多个模块,是可以有多次BUILD_XXX的.
清除变量,重新设置即可。
接下来,我们就分来开去了解里面的内容。
Android.mk变量部分LOCAL_XXX
#设置LOCAL_PATH为当前Android.mk所在的目录地址
LOCAL_PATH := $(call my-dir)
#清除变量
include $(CLEAR_VARS)
#模块名称(其他模块使用,比如说jar包,比如说so库之类的)
LOCAL_MODULE := XXX
#依赖的jar包模块,注意:先编译被依赖的模块,否则找不到
LOCAL_JAVA_LIBRARIES := jar的模块名称
#依赖的jar静态包
LOCAL_STATIC_JAVA_LIBRARIES := XXXXX
#编译出来的名称(apk使用)
LOCAL_PACKAGE_NAME := XXX
#什么版本下编译:选项有:user/debug/test/optional
#optional为任何版本都编译
LOCAL_MODULE_TAGS := optional
#资源文件
LOCAL_JAVA_RESOURCE_FILES := $(LOCAL_PATH)/src/main/res
#清单文件
LOCAL_MANIFEST_FILE := $(LOCAL_PATH)/src/main/AndroidManifest.xml
#源码的地址
LOCAL_SRC_FILES := $(call all-java-files-under, src)
#混淆规则文件
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
#覆盖其他模块,比如说你编译Launcher3的时候,覆盖掉Laucher2
LOCAL_OVERRIDES_PACKAGES := 要覆盖的模块名称,前面的LOCAL_MODULE
#编译为apk
include $(BUILD_PACKAGE)
#如果有子Android.mk文件,会被调用
include $(call all-makefiles-under,$(LOCAL_PATH))
#签名,默认为:testkey,测试签名
#platform 平台签名,一般系统级应用会用此签名
#shared 该APK需要和home/contacts进程共享数据
#media:该APK是media/download系统中的一环
LOCAL_CERTIFICATE := testkey
更多请查看Android.mk常见的变量含义这篇笔记
BUILD_JAVA_LIBRARY 和 BUILD_STATIC_JAVA_LIBRARY的区别是啥?
- BUILD_JAVA_LIBRARY 编译出来的是共享库(动态库)
- BUILD_STATIC_JAVA_LIBRARY 静态库
SobLogDemo,如果是以static依赖,把这个jar包,也会编译到自己的文件里
如果动态库的方式依赖,就不会编译到自己的apk里,加载的时候,会动态从系统中加载。
BUILD_STATIC_JAVA_LIBRARY编译数据
target Java: SobLog (out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/classes)
Copying: out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/emma_out/lib/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/classes.jar
target Static Jar: SobLog (out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/javalib.jar)
make: Leaving directory '/home/aosp/android5.1'
BUILD_JAVA_LIBRARY的编译输出
============================================
target Java: SobLog (out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/classes)
Copying: out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/emma_out/lib/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/classes.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/noproguard.classes.jar
target Dex: SobLog
Copying: out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/classes.dex
target Jar: SobLog (out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/javalib.jar)
Install: out/target/product/generic_x86/system/framework/SobLog.jar
Dexpreopt Jar: SobLog (out/target/product/generic_x86/obj/JAVA_LIBRARIES/SobLog_intermediates/x86/javalib.odex)
dex2oatd I 32012 32012 art/dex2oat/dex2oat.cc:1329] out/host/linux-x86/bin/dex2oatd --runtime-arg -Xms64m --runtime-arg -Xmx512m --boot-image=out/target/product/generic_x86/dex_bootjars/system/framework/boot.art --dex-file=out/target/common/obj/JAVA_LIBRARIES/SobLog_intermediates/javalib.jar --dex-location=/system/framework/SobLog.jar --oat-file=out/target/product/generic_x86/obj/JAVA_LIBRARIES/SobLog_intermediates/x86/javalib.odex --android-root=out/target/product/generic_x86/system --instruction-set=x86 --instruction-set-features=default --include-patch-information --runtime-arg -Xnorelocate --no-include-debug-symbols
dex2oatd I 32012 32012 art/dex2oat/dex2oat.cc:276] dex2oat took 62.794ms (threads: 16) arena alloc=53KB java alloc=4KB native alloc=132KB free=2MB
dex2oatd I 32012 32012 art/dex2oat/dex2oat.cc:276] Code dedupe: 0 collisions, 0 max bucket size, 1699 ns hash time
dex2oatd I 32012 32012 art/dex2oat/dex2oat.cc:276] Mapping table dedupe: 0 collisions, 0 max bucket size, 597 ns hash time
dex2oatd I 32012 32012 art/dex2oat/dex2oat.cc:276] Vmap table dedupe: 0 collisions, 0 max bucket size, 446 ns hash time
dex2oatd I 32012 32012 art/dex2oat/dex2oat.cc:276] GC map dedupe: 0 collisions, 0 max bucket size, 561 ns hash time
dex2oatd I 32012 32012 art/dex2oat/dex2oat.cc:276] CFI info dedupe: 0 collisions, 0 max bucket size, 515 ns hash time
Install: out/target/product/generic_x86/system/framework/x86/SobLog.odex
make: Leaving directory '/home/aosp/android5.1'
#### make completed successfully (1 seconds) ####
验证Case
通过编译apk和jar包的不同方式来验证前面的说法
编译相关的:
- jar包以共享的方式编译,而apk以静态库的方式依赖,就找不到相关的类
- jar包以静态方式编译输出,而apk以共享的方式添加依赖(可以编译通过,但是运行是有问题的,找不到对应的类)
运行时:
- jar包以静态方式编译输出,而apk以共享的方式添加依赖(可以编译通过,但是运行是有问题的,找不到对应的类)
当我们编译的jar包是静态的,那apk应该是静态依赖,这样子apk内部就有一份。
如果是共享的,那么就以共享的方式依赖,apk内部没有,但是加载的时候会去系统里头找。
拆包,拆apk
- 静态依赖的编译的apk,包含jar包(拆包确定)
- 共享库方式依赖的apk,则不包含
什么时候把jar包编译成静态库,什么时候编译成共享库
- 共享库在使用的时候加载,减小体积
- 静态库是编译到apk里,加载速度会比较快,体积会大一点点。