[Android 基础] -- 把 apk、so 等文件,打包到 system.img 的方法 —— PRODUCT_PACKAGES 与 PRODUCT_COPY_FILES

本文说的打包是指在 aosp 中用 make -j8 编译后,把自己需要的文件打包到 system.img 中。

这里有两种情况,第一种是 apk、so 是第三方提供的,已经编译好了,只要打包到 system.img 即可;第二种是有 apk、so 的源码,并且需要放在 aosp 中编译。

一、第一种情况 —— PRODUCT_COPY_FILES

可以修改 device.mk 中的 PRODUCT_COPY_FILES,这里用 android4.0 中自带的 device/ti/panda 来修改。

在 device/ti/panda 增加已经自己的文件夹,并且把需要打包的文件,拷贝到文件夹下:

root@xxx:/mnt/ics-android/ics-src/device/ti/panda# ls my/*
my/app:
my.apk
 
my/bin:
my.sh
 
my/fonts:
 
my/lib:
libmy.so

这里在 device/ti/panda 下增加了一个文件夹 my,并且在 my 下面增加了 app、bin、fonts、lib,对应 out/target/product/panda/system 下面的目录,在 device.mk 的最后增加:

PRODUCT_COPY_FILES += \
        device/ti/panda/my/app/my.apk:system/app/my.apk \
        device/ti/panda/my/bin/my.sh:system/bin/my.sh \
        device/ti/panda/my/lib/libmy.so:system/lib/libmy.so

二、第二种情况 —— PRODUCT_PACKAGES

同样需要修改 device.mk,把需要打包的文件添加到变量 PRODUCT_PACKAGES 中:

PRODUCT_PACKAGES += \
    libmy \
    my

注意这里的名字要求和模块的 Android.mk 中,指定生成的文件名称相同,例如:

LOCAL_MODULE := libmy

或者

LOCAL_PACKAGE_NAME := my

同时,还要求模块的 Android.mk 中变量 LOCAL_MODULE_TAGS 值为 optional

LOCAL_MODULE_TAGS := optional

在 aosp 的 build 目录下有多处指定打包文件的地方,可以参考下:

root@xxx:/ics-android/ics-src/build# grep PRODUCT_PACKAGES * -rn
core/main.mk:614:                       $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES))
core/Makefile:315:      $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES) \
core/product.mk:68:    PRODUCT_PACKAGES \
core/base_rules.mk:93:    $(warning *    into the PRODUCT_PACKAGES section of product)
core/base_rules.mk:99:    $(warning * PRODUCT_PACKAGES section of)
target/product/large_emu_hw.mk:22:PRODUCT_PACKAGES := \
target/product/sdk.mk:20:PRODUCT_PACKAGES := \
target/product/sdk.mk:71:PRODUCT_PACKAGES += \
target/product/sdk.mk:91:PRODUCT_PACKAGES += \
target/product/sdk.mk:132:PRODUCT_PACKAGES += \
target/product/core.mk:25:PRODUCT_PACKAGES := \
target/product/core.mk:111:    PRODUCT_PACKAGES += \
target/product/full_x86.mk:29:PRODUCT_PACKAGES := \
target/product/full_x86.mk:36:PRODUCT_PACKAGES += \
target/product/full.mk:22:PRODUCT_PACKAGES := \
target/product/generic_no_telephony.mk:22:PRODUCT_PACKAGES := \
target/product/generic_no_telephony.mk:48:PRODUCT_PACKAGES += \
target/product/generic_no_telephony.mk:51:PRODUCT_PACKAGES += \
target/product/generic_no_telephony.mk:57:PRODUCT_PACKAGES += \
target/product/telephony.mk:20:PRODUCT_PACKAGES := \
target/product/full_base_telephony.mk:22:PRODUCT_PACKAGES := \
target/product/full_base.mk:22:PRODUCT_PACKAGES := \
target/board/generic/device.mk:29:PRODUCT_PACKAGES := \

扩展:

关于预置的方法,具体可参考另一篇博文:Android定制:预置应用程序

<think>好的,我现在需要解决用户在Android 11编译时遇到的“Prebuilt apk found in PRODUCT_COPY_FILES”错误。首先,我得回忆一下相关的知识,并结合提供的引用内容来分析问题。 根据用户提供的引用内容,尤其是引用[2]和[3],问题出现在使用PRODUCT_COPY_FILES来拷贝APK文件时,系统检测到预构建的APK,而正确的做法是使用BUILD_PREBUILT或者类似的机制来处理。Android的编译系统在较新版本中可能加强了对PRODUCT_COPY_FILES的检查,禁止直接拷贝APK文件,因为这应该通过预构建模块来处理,以确保正确的依赖管理和构建步骤。 首先,用户遇到的错误信息明确指出在PRODUCT_COPY_FILES中发现了预构建的APK,建议改用BUILD_PREBUILT。这说明用户可能在某个.mk文件或产品配置中使用了类似PRODUCT_COPY_FILES += path/to/apk:system/path/to/dest这样的语句,而这样的用法在新版本中不被允许。 根据引用[2],解决方法是修改build/core/Makefile,注释掉check-product-copy-files的相关检查。不过这种方法可能属于临时规避,不是最佳实践,且可能影响其他部分的正确性。引用[3]提到PRODUCT_COPY_FILES不能在Android.mk中添加新的拷贝项,而应该使用预构建模块。因此,正确的解决方案应该是将APK文件声明为预构建模块,使用BUILD_PREBUILT或Android.mk中的模块定义。 接下来,我需要给出具体的解决步骤。首先,建议用户检查他们的产品配置文件(通常是device/.../product.mk或类似的地方),找到所有PRODUCT_COPY_FILES中包含.apk的行,并将其移除。然后,为每个APK创建对应的预构建模块。例如,在Android.mk中添加相应的模块,使用LOCAL_MODULE、LOCAL_MODULE_CLASS、LOCAL_SRC_FILES等变量来定义,并包含$(BUILD_PREBUILT)。这样,编译系统会正确处理这些APK文件,避免触发错误。 此外,需要注意预构建模块的路径和权限设置是否正确,确保安装到正确的分区(如system/app或vendor/app等)。如果用户不熟悉如何编写Android.mk文件,可能需要提供示例代码,指导他们如何结构化这些模块。 最后,提醒用户如果必须临时绕过检查,可以修改Makefile,但需谨慎,因为这可能影响其他部分的编译检查,导致潜在的问题被忽略。正确的长期解决方案还是遵循Google的推荐做法,使用预构建模块来处理APK文件的拷贝。 总结步骤: 1. 查找并移除PRODUCT_COPY_FILES中的APK引用。 2. 为每个APK创建预构建模块。 3. 调整模块定义,确保路径和权限正确。 4. (可选)临时修改Makefile注释检查,但不推荐。 现在需要将这些步骤以清晰的中文回答呈现,并引用提供的参考资料,同时生成相关问题。</think>### Android 11编译时"Prebuilt apk in PRODUCT_COPY_FILES"错误解决方案 #### 问题原因 在Android 11及以上版本中,编译系统禁止通过$PRODUCT_COPY_FILES$直接拷贝预编译的APK文件[^2][^3]。该机制要求使用预构建模块声明(如$BUILD_PREBUILT$)替代直接拷贝,以确保依赖关系和安装路径的正确性。 --- #### 分步解决方案 ##### 1. 移除非法配置 检查所有涉及$PRODUCT_COPY_FILES$的配置文件(通常位于`device/[厂商]/[产品名]/`目录下),删除包含.apk的配置项: ```makefile # 原错误配置示例(需删除) PRODUCT_COPY_FILES += vendor/apps/MyApp.apk:system/app/MyApp/MyApp.apk ``` ##### 2. 创建预编译模块 在对应目录(如`device/[厂商]/[产品名]/prebuilts/`)创建Android.mk文件,声明APK为预编译模块: ```makefile # Android.mk示例 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := MyApp LOCAL_MODULE_CLASS := APPS LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := prebuilts/MyApp.apk LOCAL_MODULE_SUFFIX := .apk LOCAL_CERTIFICATE := platform # 若需要系统签名 LOCAL_MODULE_PATH := $(TARGET_OUT_SYSTEM_APP)/MyApp include $(BUILD_PREBUILT) ``` ##### 3. 声明模块依赖 在设备配置文件中添加模块声明: ```makefile # 产品配置文件.mk) PRODUCT_PACKAGES += MyApp ``` ##### 4. (临时方案)修改编译检查 **(不推荐长期使用)** 修改编译系统文件: ```diff # build/core/Makefile - define check-product-copy-files + #define check-product-copy-files ``` 此操作会跳过APK文件检查,但可能导致其他潜在问题被忽略[^2]。 --- #### 关键验证点 1. **路径匹配**:确保$LOCAL_MODULE_PATH$原始配置的目标路径一致 2. **权限配置**:系统级APK需添加$LOCAL_PRIVILEGED_MODULE := true$或指定$LOCAL_MODULE_PATH$ 3. **签名验证**:系统APK需使用平台签名($LOCAL_CERTIFICATE := platform$) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值