一 概述
android Q build变化整体上越来越严格,语法上之前能够使用的Q上将不能使用。
二 主要变化
2.1 'USER' 弃用
‘USER’后面的值会被设置成‘nobody',android后续的修改都是围绕着去除掉不同机器不同用户的差异,使得满足要求的任何机器或者用户编译结果相同。如果必须要使用的话,可以使用’BUILD_USERNAME‘来进行替代
2.2 ’BUILD_NUMBER‘
’BUILD_NUMBER‘从Android.mk中移除
2.3 DIST_DIR
, dist_goal
, and dist-for-goals
在android.mk中DIST_DIR
and dist_goal
不能再被使用,只能使用dist-for-goals
2.4 .PHONY
伪目标规则更加严格
.PHONY使用用户交互型好的名字替代真是文件,但是使用伪目标每一此编译都被识别成dirty,需要重新编译。如果编译目标是伪目标的话无额外开销但是如果编译目标依赖于伪目标的话,可能是一笔不小的开销。
我们现在在Q上编译,如果有如下的warning的话,.PHONY目标不允许使用'/'
...mk:42: warning: PHONY target "out/.../foo" looks like a real file (contains a "/")
如果是如下错误的话,有两个原因1) .PHONY的目标不是一个真正的文件 2) 目标是一个真实文件,但是不在outpu目录下,在执行m clean的时候不能够删除它
...mk:42: warning: writing to readonly directory: "kernel-modules"
在实际使用中,用的最多的是想bootloader kernel这种不属于android编译系统的模块。他们使用伪目标的目的是在android的makefile中,不知道依赖是否有变化,因此要使用伪目标。谷歌建议此类编译最好在android系统外进行编译,以Prebuild的形式存在android的工程中。
总结下来,对于非android编译系统的编译问题,建议单独编译,如果非要添加进去的话,不要使用.PHONY
out/target/.../zImage: $(sort $(shell find -L $(KERNEL_SRCDIR)))
...
谷歌认为像kernel这样的,如果不是debug kernel的话,不要每次都重新编译,如果需要重新编译的话,可以先clean在编译。
2.5 Makefile中export
and unexport
将被弃用
export 和unexport 变量的方式不被使用,如果要使用的话,建议使用方法如下:
$(intermediates)/generated_output.img:
rm -rf $@
export MY_ENV_A="$(MY_A)"; make ...
如果要设置很多的变量的话,使用方法如下:
envsh := $(intermediates)/env.sh
$(envsh):
rm -rf $@
echo 'export MY_ENV_A="$(MY_A)"' >$@
echo 'export MY_ENV_B="$(MY_B)"' >>$@
$(intermediates)/generated_output.img: PRIVATE_ENV := $(envsh)
$(intermediates)/generated_output.img: $(envsh) a/b/c/package.sh
rm -rf $@
source $(PRIVATE_ENV); make ...
source $(PRIVATE_ENV); a/b/c/package.sh ...
2.6 Module name将不能使用'/'
举例来说
include $(CLEAR_VARS)
LOCAL_MODULE := ver1/code.bin
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware
...
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := ver2/code.bin
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware
...
include $(BUILD_PREBUILT)
上面的LOCAL_MODULE 不应该出现'/',可以将代码修改成下面这样
include $(CLEAR_VARS)
LOCAL_MODULE := ver1_code.bin
LOCAL_MODULE_STEM := code.bin
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/ver1
...
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := ver2_code.bin
LOCAL_MODULE_STEM := code.bin
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/ver2
...
include $(BUILD_PREBUILT)
在修改的同时,要将PRODUCT_PACKAGES和LOCAL_REQUIRED_MODULES对应的名字进行修改
2.7 Module 名字字符选择
Module的名字从 a-z
, A-Z
, 0-9
, and the special characters _.+-=,@~
选取
2.8 PATH Tools
android的编译正朝着可重入性发展,也就是不依赖环境。为了实现这个目标PATH会指向android工程里的工具。目前的唯一区别就是删除 host GCC工具。对于违反规则使用build server PATH中的工具和命令的话,目前只是记录到LOG中,后面限制会更加严格,可能就无法使用。
在build/soong/ui/build/paths/config.go文件中包含相关配置,包含编译中使用到的工具,如果不在这个工具列秒中,在out/soong.log文件中将有相关warning显示。
为了解决这类问题,最好的方法就是使用,将相关tools放到prebuilt下,或者在编译的时候将他编译成host tools
可以通过设置TEMPORARY_DISABLE_PATH_RESTRICTIONS=true
的方式暂时编译通过。
2.9 在envsetup.sh中弃用'/'
谷歌那边的编译是不需要运行envsetup.sh的,许多odm还是需要运行这个脚本,里面的许多变量使用了绝对路径
instead of | use |
---|---|
OUT {#OUT} | OUT_DIR |
ANDROID_HOST_OUT {#ANDROID_HOST_OUT} | HOST_OUT |
ANDROID_PRODUCT_OUT {#ANDROID_PRODUCT_OUT} | PRODUCT_OUT |
ANDROID_HOST_OUT_TESTCASES {#ANDROID_HOST_OUT_TESTCASES} | HOST_OUT_TESTCASES |
ANDROID_TARGET_OUT_TESTCASES {#ANDROID_TARGET_OUT_TESTCASES} | TARGET_OUT_TESTCASES |
上面的envsetup.sh中的变量都取自makefile为,相对路径。如果要使用绝对路径的话,下面的方法,在单条规则中export
$(PRODUCT_OUT)/gen.img: my/src/path/gen.sh
export PRODUCT_OUT=$$(cd $(PRODUCT_OUT); pwd); cd my/src/path; ./gen.sh -o $${PRODUCT_OUT}/gen.img
2.9 ANDROID_BUILD_TOP
在android.mk文件中,可以设定当前的目录为代码目录,可以使用.来替代或者直接指定文件,如果要使用绝对路径的话,请参考上节的例子。
2.10 停止使用直接使用PATH
新的soong会修改PATH变量,不建议在Makefile中读取这个变量。如果要使用的话,建议如下:
$(TARGET): myscript my/path/binary
PATH=my/path:$$PATH myscript -o $@
2.11 不要使用PYTHONPATH
跟PATH变量一样,PYTHONPATH 变量也是有变化的,不建议在Mafile频繁读取。谷歌建议将修改song python building support.这部分主要是 packages the python interpreter, libraries, and script all into one file。不过还是建议使用如下方法,更简单一点:
$(TARGET): myscript.py $(sort $(shell find my/python/lib -name '*.py'))
PYTHONPATH=my/python/lib:$$PYTHONPATH myscript.py -o $@
2.12 PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE和USE_CLANG_PLATFORM_BUILD 弃用
3 总结
android Q 主要的变化就是.PHONY伪目标使用更严格,除prebuilt下的命令使用除了config.go里面的,将不允许使用。
网友评论