Android 11 unexpected LOCAL_MODULE_CLASS for prebuilts: FAKE

本文介绍了一种在Android 11编译环境中遇到的错误——预编译不支持FAKE类型的LOCAL_MODULE_CLASS,并提供了解决方案。通过将FAKE替换为ETC,成功解决了编译错误。

 unexpected LOCAL_MODULE_CLASS for prebuilts: FAKE


引言

  又有好久没有写点偏重实战类型的博客了,最近一直都在捣鼓源码分析和项目相关事情,是时候来点偏重实战类型的博客了。捯饬点啥实战的呢,正好最近在迁移项目到Android 11上面,发现了一些不少Android 11相较于以前Android版本的一些特性,这里我就分析一个在Android 11上面预编译不支持错误的解决小实战。其错误吗如下:

build/make/core/main.mk:368: warning: "Compile using modified AOSP tree supporting full vendor value-adds"
[ 75% 1088/1440] including FAKE_TEST/Android.mk ...
FAILED: 
In file included from out/soong/Android-bengal.mk:1047859:
In file included from FAKE_TEST/Android.mk:9:
In file included from build/make/core/prebuilt.mk:26:
build/make/core/prebuilt_internal.mk:62: error: fake_out : unexpected LOCAL_MODULE_CLASS for prebuilts: FAKE.
09:23:43 ckati failed with: exit status 1

注意:本篇的介绍是基于Android 11平台为基础的!




一.怎么解决

  也许读者看到这里就会心里想了,既然Android 11不支持LOCAL_MODULE_CLASS为FAKE类型的,那不用它不就是了换一个方式实现吗,譬如PRODUCT_COPY_FILES关键词来实现不就好了,读者提出了这个解决方法那么证明是对Android的编译是有一定理解的。但是由于历史原因(我们的一套代码需要适配从Android 4.2到Android 11的整个编译环境),且由于我们的很多地方都使用到了FAKE的这种LOCAL_MODULE_CLASS所以此种办法不能采纳。那么我是怎么解决的呢!让我为大家徐徐展开慢慢分析!


1.1 错误的产生

由于源码牵涉到公司,所以这里我自己编写了一个非常简单的Android.mk来还原现场(不要问我为啥不用Android.bp历史包袱啊),其Android.mk定义如下:

LOCAL_PATH := $(call my-dir)

##################
<think> 我们遇到的问题是在构建过程中出现的,错误信息指向 `build/make/core/prebuilt_internal.mk:57`,具体错误是: `com.fingerprints.extension : unexpected LOCAL_MODULE_CLASS for prebuilts: JAVA_LIBRARIES` 同时,ckati 退出状态为1(ckati是Android构建系统的一部分,用于解析Android.mk文件等)。 根据错误信息,问题出现在预构建模块的定义上。具体来说,模块 `com.fingerprints.extension` 被声明为预构建模块(prebuilt),但其 `LOCAL_MODULE_CLASS` 设置为 `JAVA_LIBRARIES`,而该位置期望的可能是其他类型(如APK、SHARED_LIBRARIES等)。 在Android构建系统中,`prebuilt_internal.mk` 文件用于处理各种预构建模块(预编译的库、应用等)。错误提示表明,对于预构建模块,`LOCAL_MODULE_CLASS` 的值 `JAVA_LIBRARIES` 在此上下文中不被接受。 ### 原因分析 1. **模块类型不匹配**:预构建的Java库(JAR文件)通常使用 `LOCAL_MODULE_CLASS := JAVA_LIBRARIES`,但可能当前的构建规则(在 `prebuilt_internal.mk` 中)不支持这种类型。 2. **模块声明错误**:可能在Android.mk(或类似构建文件)中,该模块被错误地声明为预构建模块,但实际类型不匹配。 ### 解决步骤 #### 1. 检查模块定义 找到定义 `com.fingerprints.extension` 模块的构建文件(可能是 `Android.mk` 或 `Android.bp`)。在该文件中,查找类似如下语句: ```makefile include $(CLEAR_VARS) LOCAL_MODULE := com.fingerprints.extension LOCAL_MODULE_CLASS := JAVA_LIBRARIES ... include $(BUILD_PREBUILT) ``` 注意:`LOCAL_MODULE_CLASS` 设置为 `JAVA_LIBRARIES`。 #### 2. 修改模块类型 根据错误提示,预构建模块在此处期望的 `LOCAL_MODULE_CLASS` 可能不是 `JAVA_LIBRARIES`。我们可以尝试将其改为其他类型,例如: - 如果这个模块是一个JAR文件,通常应该使用 `LOCAL_MODULE_CLASS := JAVA_LIBRARIES`,但构建系统在此处不允许,可能是因为这个特定的预构建规则(在 `prebuilt_internal.mk` 中)只接受某些类型。 实际上,在Android构建系统中,预构建的Java库通常使用 `BUILD_PREBUILT` 并设置 `LOCAL_MODULE_CLASS` 为 `JAVA_LIBRARIES` 是标准做法。所以出现这个错误可能是由于构建系统版本的变化或者特定设备的构建规则不同。 我们可以尝试使用另一种方式:使用 `BUILD_JAVA_LIBRARY` 来构建预构建的Java库,但这通常用于从源码构建。对于预构建的JAR,我们通常使用 `BUILD_PREBUILT`。 因此,可能需要检查构建系统是否对该类型有特殊要求。参考引用[1]中提到了 `LOCAL_PREBUILT_JNI_LIBS` 用于控制so库的集成,但这里我们处理的是Java库(JAR),所以不适用。 #### 3. 使用正确的预构建类型 根据Android构建系统的文档,预构建的Java库(JAR)应该这样定义: ```makefile include $(CLEAR_VARS) LOCAL_MODULE := com.fingerprints.extension LOCAL_MODULE_CLASS := JAVA_LIBRARIES LOCAL_SRC_FILES := $(LOCAL_MODULE).jar LOCAL_UNINSTALLABLE_MODULE := true # 如果不需要安装到系统,设置为true include $(BUILD_PREBUILT) ``` 但是,如果构建系统报错,可能是因为在 `prebuilt_internal.mk` 中,对于 `LOCAL_MODULE_CLASS` 为 `JAVA_LIBRARIES` 的预构建模块有特殊的处理,而当前配置可能触发了某种不支持的路径。 #### 4. 替代方案:使用 BUILD_JAVA_LIBRARY 如果上述方法不行,可以尝试将预构建的JAR当作一个普通的Java库来构建(尽管它是预构建的): ```makefile include $(CLEAR_VARS) LOCAL_MODULE := com.fingerprints.extension LOCAL_SRC_FILES := $(LOCAL_MODULE).jar LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := JAVA_LIBRARIES LOCAL_MODULE_SUFFIX := .jar include $(BUILD_JAVA_LIBRARY) ``` 注意:使用 `BUILD_JAVA_LIBRARY` 会期望这个JAR是作为编译的一部分(虽然已经是编译好的),构建系统可能会对其进行处理(如dex处理等)。 #### 5. 检查构建系统版本 如果问题仍然存在,可能需要检查Android构建系统的版本(如Android 10, 11, 12等),因为不同版本对预构建模块的支持可能有差异。特别是引用[1]中提到了Android 12中关于 `LOCAL_PREBUILT_JNI_LIBS` 的处理,但我们的问题是Java库,所以不直接相关。 #### 6. 错误的具体位置 查看 `prebuilt_internal.mk` 文件的第57行附近(具体行号可能因版本而异)的代码。例如,可能在该位置有一个条件判断,检查 `LOCAL_MODULE_CLASS` 的值是否在允许的列表中,而 `JAVA_LIBRARIES` 不在其中。 ### 操作步骤总结 1. 定位定义模块 `com.fingerprints.extension` 的构建文件(在项目源码树中搜索 `LOCAL_MODULE := com.fingerprints.extension`)。 2. 查看其 `LOCAL_MODULE_CLASS` 的设置,并尝试修改为其他可能的类型(例如,如果实际上是一个APK,则设置为 `APPS`;如果是共享库,则设置为 `SHARED_LIBRARIES`)。但根据模块名,它应该是一个Java库(JAR)。 3. 如果确定是Java库,尝试将构建类型从 `include $(BUILD_PREBUILT)` 改为 `include $(BUILD_JAVA_LIBRARY)`,并相应地调整其他变量(如 `LOCAL_MODULE_SUFFIX`)。 4. 如果修改后出现其他错误,可能需要进一步调试。 ### 相关问题 1. 如何正确地在 Android 构建系统中添加预构建的 Java 库 (JAR)? 2. Android 构建系统中 `LOCAL_MODULE_CLASS` 的取值有哪些?分别代表什么? 3. 在 Android 构建过程中如何处理 `ckati` 返回错误码 1 的问题? </think> ### 解决 `prebuilt_internal.mk:57` 构建错误的方法 #### 错误分析 在 Android 构建系统中出现以下错误: ``` com.fingerprints.extension: unexpected LOCAL_MODULE_CLASS for prebuilts: JAVA_LIBRARIES ckati 退出状态为 1 ``` 表明构建系统对预编译模块 `com.fingerprints.extension` 的声明存在类型冲突,核心问题在于: 1. `LOCAL_MODULE_CLASS=JAVA_LIBRARIES` 表示该模块被声明为 **Java 库** 2. 但 `prebuilt_internal.mk` 期望的是 **原生库**(SHARED_LIBRARIES/STATIC_LIBRARIES) 或 **APK** 类型[^1] 3. 这种类型不匹配导致 ckati(Android 构建解析器)异常中止 #### 解决方案 ##### 1. 修正模块类型声明 在模块定义文件(通常是 `Android.mk` 或 `Android.bp`)中修改类型声明: ```makefile # 修改前 LOCAL_MODULE := com.fingerprints.extension LOCAL_MODULE_CLASS := JAVA_LIBRARIES # 修改后(根据实际类型选择) LOCAL_MODULE_CLASS := SHARED_LIBRARIES # 如果是动态库 # 或 LOCAL_MODULE_CLASS := STATIC_LIBRARIES # 如果是静态库 ``` ##### 2. 补充必要声明 添加预编译模块必需的声明: ```makefile LOCAL_SRC_FILES := path/to/$(LOCAL_MODULE).so # 指定库文件路径 LOCAL_MODULE_SUFFIX := .so # 设置文件后缀 LOCAL_MODULE_TAGS := optional # 标记为可选模块 include $(BUILD_PREBUILT) # 包含预构建规则 ``` ##### 3. 检查依赖关系 在依赖此模块的文件中确认引用正确: ```makefile # 使用模块的Android.mk LOCAL_SHARED_LIBRARIES := com.fingerprints.extension # 需与模块名一致 ``` ##### 4. 清理构建缓存 执行完整清理后重建: ```bash make clean # 清理构建缓存 make -j8 # 重新构建(并行8线程) ``` #### 根本原因说明 `prebuilt_internal.mk` 对预编译模块有严格类型限制: ```mermaid graph LR A[预编译模块] --> B[原生库] A --> C[APK文件] A --> D[其他二进制] A --> E[Java库 - 不被支持] ``` 当系统检测到 `JAVA_LIBRARIES` 类型时会触发第57行的类型检查错误: ```python if module_class not in ["SHARED_LIBRARIES", "STATIC_LIBRARIES", "EXECUTABLES", "APPS"]: error("unexpected LOCAL_MODULE_CLASS for prebuilts") ``` #### 验证步骤 1. 使用 `mm` 命令单独编译模块: ```bash mmma path/to/module ``` 2. 检查输出文件类型: ```bash file $OUT/system/lib64/com.fingerprints.extension.so # 应显示: ELF 64-bit LSB shared object ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值