跳至主要內容

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里,加载速度会比较快,体积会大一点点。