Android 编译如何跳过生成ota package过程?

通常来说,OTA是用户比较接受的升级方式,但对于开放性比较高的ROM却不适用,因为OTA从原理上讲,是利用现有文件进行补丁升级,因此需要系统文件严格保持完整性才能正确应用更新。而LineageOS和RROS的编译系统,似乎也不能正确生成OTA更新包,而且同样会占用较长的编译时间(对于我的笔记本来说,10min左右),因此可以选择关闭本功能。

如何禁用OTA更新包生成?

AOSP从Android Oreo版本开始引进ninja编译管理系统,因此对于刚刚入门的编译者可能无从下手,但是实际上这种改变也仅仅是部分的将原有的Makefile(Android.mk)升级为blueprint(Android.bp)格式,此外也依然兼容原有Makefile编译系统(本质上依然使用make命令进行实际编译),而且项目的基本结构是未发生任何变化的,所以其实还是考验编译维护者对系统的熟悉程度。

解决方案

在所选用的device中BoardConfig.mk文件,修改或者增加一行TARGET_SKIP_OTA_PACKAGE := true 即可在构建时不生成ota更新包。

下面是找解决方法中的一些碎碎念,可以选择性忽略...当然看看也是不错哒

解决思路

首先我们知道编译时的生成文件是类似下面这样的:


make ota package

那么我们要做的就是,找到这个编译目标,这可以通过看详细日志来解决,也可以通过搜索文件全文来查找。

通过查找关键字,可以找到:

$ grep -arnw "otapackage" .
./build/make/core/Makefile:4317:.PHONY: otapackage
./build/make/core/Makefile:4318:otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
./build/make/core/Makefile:4344:otapackage otardppackage: $(INTERNAL_OTA_RETROFIT_DYNAMIC_PARTITIONS_PACKAGE_TARGET)

也就是定义在 ./build/make/core/Makefile: 4317 附近的一个伪目标,进一步打开这个文件,可以看到其中有这样一段代码:

.PHONY: target-files-package
target-files-package: $(BUILT_TARGET_FILES_PACKAGE)

ifneq ($(filter $(MAKECMDGOALS),target-files-package),)
$(call dist-for-goals, target-files-package, $(BUILT_TARGET_FILES_PACKAGE))
endif

# -----------------------------------------------------------------
# NDK Sysroot Package
NDK_SYSROOT_TARGET := $(PRODUCT_OUT)/ndk_sysroot.tar.bz2
$(NDK_SYSROOT_TARGET): $(SOONG_OUT_DIR)/ndk.timestamp
    @echo Package NDK sysroot...
    $(hide) tar cjf $@ -C $(SOONG_OUT_DIR) ndk

$(call dist-for-goals,sdk,$(NDK_SYSROOT_TARGET))

ifeq ($(build_ota_package),true)
# -----------------------------------------------------------------
# OTA update package

# $(1): output file
# $(2): additional args
define build-ota-package-target
PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
   build/make/tools/releasetools/ota_from_target_files -v \
   --block \
   --extracted_input_target_files $(patsubst %.zip,%,$(BUILT_TARGET_FILES_PACKAGE)) \
   -p $(HOST_OUT) \
   --backup=$(backuptool) \
   $(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
   $(2) \
   $(BUILT_TARGET_FILES_PACKAGE) $(1)
endef

name := $(TARGET_PRODUCT)
ifeq ($(TARGET_BUILD_TYPE),debug)
  name := $(name)_debug
endif
name := $(name)-ota-$(FILE_NAME_TAG)

INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip

INTERNAL_OTA_METADATA := $(PRODUCT_OUT)/ota_metadata

$(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)

ifeq ($(AB_OTA_UPDATER),true)
$(INTERNAL_OTA_PACKAGE_TARGET): $(BRILLO_UPDATE_PAYLOAD)
else
$(INTERNAL_OTA_PACKAGE_TARGET): $(BROTLI)
endif

ifeq ($(TARGET_OTA_ASSERT_DEVICE),)
    OTA_SCRIPT_OVERRIDE_DEVICE := auto
else
    OTA_SCRIPT_OVERRIDE_DEVICE := $(TARGET_OTA_ASSERT_DEVICE)
endif

ifneq ($(RR_BUILD),)
    $(INTERNAL_OTA_PACKAGE_TARGET): backuptool := true
else
    $(INTERNAL_OTA_PACKAGE_TARGET): backuptool := false
endif

$(INTERNAL_OTA_PACKAGE_TARGET): .KATI_IMPLICIT_OUTPUTS := $(INTERNAL_OTA_METADATA)

$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) \
        build/make/tools/releasetools/ota_from_target_files
    @echo "Package OTA: $@"
    $(call build-ota-package-target,$@,-k $(KEY_CERT_PAIR) --output_metadata_path $(INTERNAL_OTA_METADATA))

.PHONY: otapackage
otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)

ifeq ($(BOARD_BUILD_RETROFIT_DYNAMIC_PARTITIONS_OTA_PACKAGE),true)
name := $(TARGET_PRODUCT)
ifeq ($(TARGET_BUILD_TYPE),debug)
  name := $(name)_debug
endif
name := $(name)-ota-retrofit-$(FILE_NAME_TAG)

INTERNAL_OTA_RETROFIT_DYNAMIC_PARTITIONS_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip

$(INTERNAL_OTA_RETROFIT_DYNAMIC_PARTITIONS_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)

ifeq ($(AB_OTA_UPDATER),true)
$(INTERNAL_OTA_RETROFIT_DYNAMIC_PARTITIONS_PACKAGE_TARGET): $(BRILLO_UPDATE_PAYLOAD)
else
$(INTERNAL_OTA_RETROFIT_DYNAMIC_PARTITIONS_PACKAGE_TARGET): $(BROTLI)
endif

$(INTERNAL_OTA_RETROFIT_DYNAMIC_PARTITIONS_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) \
        build/make/tools/releasetools/ota_from_target_files
    @echo "Package OTA (retrofit dynamic partitions): $@"
    $(call build-ota-package-target,$@,-k $(KEY_CERT_PAIR) --retrofit_dynamic_partitions)

.PHONY: otardppackage

otapackage otardppackage: $(INTERNAL_OTA_RETROFIT_DYNAMIC_PARTITIONS_PACKAGE_TARGET)

endif # BOARD_BUILD_RETROFIT_DYNAMIC_PARTITIONS_OTA_PACKAGE

endif    # build_ota_package

重点关注前半部分,ifeq ($(build_ota_package),true),也就是说这段代码的启用条件是,设置 build_ota_packagetrue,进一步搜索可以得到:

$ grep -arnw "build_ota_package" .
./build/make/core/Makefile:3540:  # set build_ota_package, and allow opt-out below
./build/make/core/Makefile:3541:  build_ota_package := true
./build/make/core/Makefile:3543:    build_ota_package := false
./build/make/core/Makefile:3546:    build_ota_package := false
./build/make/core/Makefile:3549:    build_ota_package := false
./build/make/core/Makefile:3552:    build_ota_package := false
./build/make/core/Makefile:3555:    build_ota_package := false
./build/make/core/Makefile:3558:    build_ota_package := false
./build/make/core/Makefile:3561:    build_ota_package := false
./build/make/core/Makefile:4262:ifeq ($(build_ota_package),true)
./build/make/core/Makefile:4348:endif    # build_ota_package

依然在这个文件中,3540行附近:


# -----------------------------------------------------------------
# host tools needed to build dist and OTA packages

  # set build_ota_package, and allow opt-out below
  build_ota_package := true
  ifeq ($(TARGET_SKIP_OTA_PACKAGE),true)
    build_ota_package := false
  endif
  ifneq (,$(filter address, $(SANITIZE_TARGET)))
    build_ota_package := false
  endif
  ifeq ($(TARGET_PRODUCT),sdk)
    build_ota_package := false
  endif
  ifneq ($(filter generic%,$(TARGET_DEVICE)),)
    build_ota_package := false
  endif
  ifeq ($(TARGET_NO_KERNEL),true)
    build_ota_package := false
  endif
  ifeq ($(recovery_fstab),)
    build_ota_package := false
  endif
  ifeq ($(TARGET_BUILD_PDK),true)
    build_ota_package := false
  endif

  # set build_otatools_package, and allow opt-out below
  build_otatools_package := true
  ifeq ($(TARGET_SKIP_OTATOOLS_PACKAGE),true)
    build_otatools_package := false
  endif

也就是说,默认生成ota,但满足条件时可以禁用,对于没有内核的设备,sdk编译目标,generic目标,或者设置变量TARGET_SKIP_OTA_PACKAGEtrue的目标,是不必生成ota更新包的,那么到这里,解决方案已经很明确了,只需设置device中的BoardConfig.mk文件,修改或者增加一行TARGET_SKIP_OTA_PACKAGE := true 即可在构建时不生成ota!