这个东西好,但又不完全好

基操

解决了什么问题?

soong 命名空间的诞生是为了解决模块名称重复的问题,两个同名模块,只要位于编译系统的不同命名空间中,就不会报错

它在哪个命名空间?

soong 命名空间采用向上级目录寻找,直到有声明命名空间为止的机制
而命名空间的创建方式,只需要在Android.bp中声明

soong_namespace {
}

这样一个空的东西就可以了。。。

比如说,模块C位于B目录下,但是B目录下并没有Android.bp文件,那么就继续往上级目录找,发现父目录A中有Android.bp文件且声明了soong_namespace,那么模块C就位于命名空间A

如果B中有Android.bp文件,且声明了soong_namespace,那么模块C就位于命名空间A/B

命名空间采用“最小命名空间”的机制,也就是说,会向上寻找最近的那个命名空间定义作为模块所在的命名空间
而命名空间的名字,就是从项目根目录开始到声明命名空间的Android.bp文件 的(文件夹)路径
A/B/C/D/Android.bp -> 命名空间 A/B/C/D

当模块不位于任何一个命名空间时,默认它在隐式全局命名空间

使用命名空间 (Android.bp)

只需要在声明命名空间的时候引入别的命名空间即可

soong_namespace {
    imports: ["A/B/C", "D/E/F"],
}

之后就可以使用这些命名空间里的模块了,模块采用从前到后搜索的顺序,从引入的第一个命名空间开始搜索到最后一个,之后再去全局命名空间里搜索

也可以在使用模块时指定模块的全路径//path/to/namespace:modulename

使用命名空间(Android.mk)

只需要在Makefile中

PRODUCT_SOONG_NAMESPACES += path/to/namespace

即可

兼容性

省流助手:很烂

众所周知,Android编译系统还位于从make到soong的迁移过程中,整整五年过去了,迁移还是没有完成
这不经让我怀疑华为掏空安卓究竟要几年

以下仅针对Makefile

无法override

假如全局命名空间和某个命名空间中有同名模块,在Makefile中是无法通过PRODUCT_SOONG_NAMESPACES +=来实现模块覆盖的,不报错模块定义重复就已经是谢天谢地了,而在soong中,因为include path是按顺序搜索的,因此模块覆盖是可以实现的

这也就意味着,Makefile中,namespace的使用范围被限制在了类似
hardware/qcomhardware/google同名模块二选一的这种情况

全局性

PRODUCT_SOONG_NAMESPACES +=之后,命名空间将会被平等的暴露给整个make系统,而非仅暴露所需的模块 抑或是 暴露给make系统的一部分

这就造成了上面所说的,使用多个命名空间时,很容易报错模块重复定义,并且也没法知道指定的模块在哪个命名空间

无法指定命名空间下的模块

PRODUCT_PACKAGES += //path/to/namespace:modulename这种形式是不合法的,无法被识别
也就是说,如果要使用某个命名空间下的某个模块,要么把整个命名空间包含进去,要么单独把那个模块拷出来。。。

别致的变量assgin时间

在AOSP中
PRODUCT_SOONG_NAMESPACES只能在编译系统的早期被访问,这意味着在某些Makefile中对其赋值是非法的
而在makefile的调用顺序中,device.mk早于BoardConfig.mk,且$(call readonly-product-vars)在它们被include的之间被调用,这意味着PRODUCT_SOONG_NAMESPACES只能在device.mk这种早期被调用的Makefile中被赋值,否则

In file included from build/make/core/config.mk:297:
In file included from build/make/core/envsetup.mk:277:
In file included from build/make/core/board_config.mk:142:
In file included from device/oneplus/kebab/BoardConfig.mk:18:
device/oneplus/sm8250-common/BoardConfigCommon.mk:24: error: cannot assign to readonly variable:
 PRODUCT_SOONG_NAMESPACES

甚至

In file included from build/make/core/config.mk:304:
In file included from vendor/aosp/config/BoardConfig.mk:4:
vendor/aosp/config/BoardConfigQcom.mk:138: error: cannot assign to readonly variable: PRODUCT_SO
ONG_NAMESPACES

第三方系统为了各种操作方便,把readonly限制进行了推迟以解决这一问题

diff --git a/core/product.mk b/core/product.mk
index 4b5c805746..c212768bbf 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -490,9 +490,11 @@ _readonly_late_variables := \
 
 # Modified internally in the build system
 _readonly_late_variables += \
   PRODUCT_COPY_FILES \
   PRODUCT_DEX_PREOPT_NEVER_ALLOW_STRIPPING \
   PRODUCT_DEX_PREOPT_BOOT_FLAGS \
+  PRODUCT_SOONG_NAMESPACES
 
 _readonly_early_variables := $(filter-out $(_readonly_late_variables),$(_product_var_list))