Android.mk和Android.bp同时需要定义一个目标怎么办?

背景:

前些天有学员朋友在群里问道发现公司的源码项目中,编译某一个目标时候,发现有Android.mk和Android.bp都有同时进行定义,这个为啥?系统到底以哪个为准,mk还是bp?

test@test:~/disk2/aosp14/android_thread$ tree
.
├── Android.bp
├── Android.mk
├── thread_posix.c
└── version.go

0 directories, 4 files

比如我们写一个demo,机油Android.mk方式来编译,也有Android.bp方式。请问为啥会有这种情况的出现呢?

Android.mk和Android.bp出现背景

主要原因有如下几个:

1、一套代码可能要考虑多个aosp的版本,Android.bp属于老版本没有的,所以在系统不支持Android.bp的情况下需要用Android.mk

2、Android.bp的一些定义是在不断更新的,有一些目标可能老版本Android.bp没有,只能用Android.mk,但是新版本已经支持了。

在这里插入图片描述

所以基于要实行以上的需求背景情况,就可能需要有如下操作:
aosp版本 > 某个版本 :Android.bp定义生效,Android.mk不生效

aosp版本 < 某个版本 :Android.mk定义生效,Android.bp不生效

如果同时定义会如何?

如果Android.bp和Android.mk同时存在情况下,什么也修改,那么会怎么样呢?

In file included from out/soong/Android-sdk_phone_x86_64.mk:1911732:
In file included from android_thread/Android.mk:12:
In file included from build/make/core/executable.mk:53:
In file included from build/make/core/executable_internal.mk:29:
In file included from build/make/core/dynamic_binary.mk:34:
In file included from build/make/core/binary.mk:9:
build/make/core/base_rules.mk:342: error: android_thread: MODULE.TARGET.EXECUTABLES.linux_thread already defined by android_thread.
12:03:20 ckati failed with: exit status 1

#### failed to build some targets (47 seconds) ####

明显报错already defined ,这个其实完全可以理解,因为Android.bp和Android.mk都同时哟定义目标linux_thread。
所以Android.mk和Android.bp要同时存在的话,必要考虑解决重复定义的问题,即一套代码只能允许一个生效,要么是Android.mk生效,要么Android.bp生效。
要实现上面需求,就需要使用Android.mk和Android.bp进行条件,然后对模块编译进行开启或者不开启。

(注意:这里大家会说是不是只需要Android.mk进行条件判断不开启就行了,那样Android.bp完全不需要,但是这里注意哈,因为系统已经支持了Android.bp,但是bp可能不支持某特性,这个时候也只能用mk情况)

Android.mk端模块是否开启

mk比较简单,使用ifeq 判断PLATFORM_SDK_VERSION既可以控制是否include $(BUILD_EXECUTABLE)

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES := thread_posix.c 
	
LOCAL_MODULE := linux_thread
LOCAL_SHARED_LIBRARIES :=liblog  
	
LOCAL_PRELINK_MODULE := false
 # 小于 Android 14 才在 Android.mk 中定义模块。include $(BUILD_XXX) 才会真正定义一个模块。
ifeq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) < 34 ))" )))  
include $(BUILD_EXECUTABLE)
endif

上面就实现了版本小于Android 14时候Android.mk才会开放编译模块linux_thread

Android.bp端模块是否开启

Android.bp要进行判断是否开启,这里其实就需要前面一篇干货文章知识:
Android.bp高级用法-添加条件判断编译方式

在这里插入图片描述

上面配置完成就可以实现不同aosp版本正常编译出目标了
aosp14上编译成功
在这里插入图片描述
aosp13上编译成功
在这里插入图片描述

总结:

Android.mk和Android.bp同时需要定义一个目标是可以的,需要自己根据条件在决定是否开启,反正最后参与编译的只能有一个,如果Andorid.mk和Android.bp什么条件也不加,两个同时定义的话,立即会报错重复定义。

更多Framework实战开发干货,请关注下面“千里马学框架”。

### Android 构建配置文件 Android.mk Android.bp 的主要区别 Android 构建系统使用 `Android.mk` `Android.bp` 两种不同格式的配置文件来定义模块的构建规则。它们在语法、结构、可维护性以及未来发展趋势上存在显著差异。 #### 语法格式差异 `Android.mk` 是基于 GNU Makefile 的传统构建配置文件,采用命令式语法,依赖于变量赋值宏展开机制。这种语法风格较为冗长,且容易因环境变量或路径问题导致构建行为不一致[^3]。 ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello_aosp LOCAL_SRC_FILES := main.cpp LOCAL_SHARED_LIBRARIES := liblog include $(BUILD_EXECUTABLE) ``` 相比之下,`Android.bp` 使用 Starlark 语言的一种子集,是一种声明式的配置方式,语法更简洁、结构化更强,支持嵌套数据结构条件判断,便于大规模项目管理[^2]。 ```starlark cc_binary { name: "hello_aosp", srcs: ["main.cpp"], shared_libs: ["liblog"], } ``` #### 可维护性扩展性 由于 `Android.mk` 基于 Make 工具链,其逻辑复杂度随着模块数量增加而迅速上升,难以进行自动化分析与重构。此外,Makefile 的隐式依赖关系也增加了调试维护成本[^3]。 `Android.bp` 文件则通过扁平化的模块定义显式的依赖声明,提升了构建系统的可读性一致性。它还支持模块级别的继承与组合,使得大型项目中的配置复用更加高效[^2]。 #### 编译效率与性能 `Android.bp` 被设计为 Soong 构建系统的一部分,能够并行处理多个模块的依赖关系,从而显著提升编译速度。Soong 在解析 `Android.bp` 文件时会生成 Ninja 构建脚本,进一步优化了构建流程[^2]。 而 `Android.mk` 文件仍然依赖传统的 `make` 工具,其串行执行特性限制了多核 CPU 的利用率,导致在大型项目中构建效率较低[^3]。 #### 系统如何选择 Android.mkAndroid.bp一个目录中同时存在 `Android.mk` `Android.bp` 时,AOSP 构建系统会优先使用 `Android.bp` 来定义模块。这是因为在现代 AOSP 构建流程中,Soong(负责解析 `Android.bp`)是主构建引擎,而遗留的 `Android.mk` 文件会被自动转换为中间表示形式(Starlark 格式),以便统一处理[^1]。 #### 未来趋势 Google 官方已明确将 `Android.bp` 作为 Android 构建系统的未来发展方向。随着 AOSP 的持续演进,越来越多的模块正在从 `Android.mk` 迁移到 `Android.bp`。因此,若项目支持,建议尽早采用 `Android.bp` 以获得更好的构建性能开发体验[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值