以前在android系统控制编译的Android.mk不是纯文本形式,里面还有流控制,而Android.bp是类似JSON的纯文本形式. 对于Android.mk里面流控制部分,在Android.bp里要借助使用go语言文件去进行控制.
Android在7.0引入 ninja 编译系统,8.0引入Android.bp替代Android.mk,9.0强制使用Android.bp作为编译配置。
Google称之为soong, 具体可以参考:
https://android.googlesource.com/platform/build/soong
一、无流控制的宏开关
1 在已有的Android.bp中添加宏
首先找要添加的Android.bp文件中是否有cppflags或者’cflags’,基本上都是有的,例如:
cc_defaults {
name: "fs_mgr_defaults",
defaults: ["BBB"],// new add
sanitize: {
misc_undefined: ["integer"],
},
local_include_dirs: ["include/"],
cppflags: ["-Werror", "-DMTK_FSTAB_FLAGS"],
}
例如要添加的宏:
LOCAL_CFLAGS += -DTEST1
LOCAL_CFLAGS += -DTEST2=1
将上面的宏补在原有的’cc_defaults’里面的’cppflags’后面:
cc_defaults {
name: "fs_mgr_defaults",
sanitize: {
misc_undefined: ["integer"],
},
local_include_dirs: ["include/"],
cppflags: ["-Werror",
"-DMTK_FSTAB_FLAGS",
"-DTEST1",
"-DTEST2=1"],
}
1.2 androidmk命令
如果要转化的Android.mk内容没有流控制,可以使用Androidmk命令直接转换. 该命令在:out/soong/host/linux-x86/bin/androidmk,使用方法:
androidmk Android.mk > Android.bp
如果要转换的Android.mk里面没有复杂结构,就可以转换成功,如果报错就可能有复杂结构.需要手动转换.
二、有流控制的宏开关
在Android.mk中添加的宏开关:
ifeq ($(LANTONDA_S51NM_PROJECT_SUPPORT),yes)
LOCAL_CFLAGS += -DS51NM_PROJECT_SUPPORT
endif
如果要将以上的宏开关添加到Android.bp中去要通过使用go语言书写一个新文件。
Android.bp实际上是一个纯粹的json配置文件,没有条件、分支等流程结构,因此即便使用自带的androidmk工具想要将Android.mk快速转成Android.bp,也会发现流程语句并不起效果。为了解决此问题,google将条件编译进行分家,Android.bp负责纯粹配置,引入Go文件负责进行流程结构判断。
使用Android.bp编译时, 目前还存在一些问题:
1.对C/C++代码, 如果需要使用宏开关时, 由于android整个编译系统还没完全切换过来, 导致 在项目mk文件定义的开关, 还不能生效.
2.对于条件编译, 需要添加go文件进行控制.
对于问题1, 一是通过export命令, 把相应的开关设置到环境变量, go文件就能读取到了.
二是, 把开关集中放到某一个文件中, 然后在go文件中直接读取这个文件.
对于问题2, 下面会通过例子给出一个说明.
1. 法一:
实际测试:如果ProjectConfig.mk中,设置LANTONDA_S51NM_PROJECT_SUPPORT = yes,在frameworks_base_core_jni.go中打印LANTONDA_S51NM_PROJECT_SUPPORT:false,即宏不能传过来。如果设置export LANTONDA_S51NM_PROJECT_SUPPORT=yes,在frameworks_base_core_jni.go中打印LANTONDA_S51NM_PROJECT_SUPPORT:true,即宏可以传过来。而且在vc_cfg_data.h中也能正常使用宏。
如果在frameworks/base/core/jni目录下添加,方法如下:
diff --git a/frameworks/base/core/jni/Android.bp b/frameworks/base/core/jni/Android.bp
index 0e31ab9..aee5bcf 100644
--- a/frameworks/base/core/jni/Android.bp
+++ b/frameworks/base/core/jni/Android.bp
@@ -1,3 +1,26 @@
+// Android.bp condition compilation start
+bootstrap_go_package {
+ // name and pkgPath need to according to your module
+ name: "soong-frameworks_base_core_jni",
+ pkgPath: "android/soong/frameworks_base_core_jni",
+ deps: [
+ "blueprint",
+ "blueprint-pathtools",
+ "soong",
+ "soong-android",
+ "soong-cc",
+ "soong-genrule",
+ ],
+ srcs: [
+ "frameworks_base_core_jni.go", // include new add .go file
+ ],
+ pluginFor: ["soong_build"],
+}
+
+frameworks_base_core_jni_defaults { // frameworks_base_core_jni_defaults is a module
+ name: "frameworks_base_core_jni_selinux_cflags_mod",
+}
+// Android.bp condition compilation end
genrule {
name: "android_util_StatsLogInternal.cpp",
@@ -10,6 +33,7 @@ genrule {
cc_library_shared {
name: "libandroid_runtime",
+ defaults: ["frameworks_base_core_jni_selinux_cflags_mod"], // Android.bp condition compilation
cflags: [
"-Wno-unused-parameter",
diff --git a/frameworks/base/core/jni/xunfei/vc_cfg_data.h b/frameworks/base/core/jni/xunfei/vc_cfg_data.h
#ifdef S51NM_PROJECT_SUPPORT
const uint32_t g_work_mode_gain_ver5[WORK_MODE_MAX_V5][2] = {
{0x2929001E, 0x33293329},//0,默认
{0x2929001E, 0x33293329},//1,无源麦克风参考值
{0x2929001E, 0x33293329},//2,有源麦克风参考值
{0x2121001E, 0x2B212B21},//3,蓝牙通话参考值
};
#else
const uint32_t g_work_mode_gain_ver5[WORK_MODE_MAX_V5][2] = {
{0x2929001E, 0x33293329},//0,默认
{0x2929001E, 0x33293329},//1,无源麦克风参考值
{0x2929001E, 0x33293329},//2,有源麦克风参考值
{0x2121001E, 0x2B212B21},//3,蓝牙通话参考值
};
#endif
diff --git a/frameworks/base/core/jni/frameworks_base_core_jni.go b/frameworks/base/core/jni/frameworks_base_core_jni.go
new file mode 100644
index 0000000..28585cd
--- /dev/null
+++ b/frameworks/base/core/jni/frameworks_base_core_jni.go
@@ -0,0 +1,32 @@
+package frameworks_base_core_jni
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+ "fmt"
+)
+
+func init() {
+ fmt.Println("according to enable or disable selinux, resister the modules")
+ android.RegisterModuleType("frameworks_base_core_jni_defaults", selinuxDefaultsFactory)
+}
+
+func selinuxDefaultsFactory() (android.Module) {
+ module := cc.DefaultsFactory()
+ android.AddLoadHook(module, selinuxDefaults)
+ return module
+}
+
+func selinuxDefaults(ctx android.LoadHookContext) {
+ type props struct {
+ Cflags []string
+ }
+ p := &props{}
+ fmt.Println("according to enable or disable selinux, mod cflags")
+ fmt.Println("LANTONDA_S51NM_PROJECT_SUPPORT: ", ctx.AConfig().IsEnvTrue("LANTONDA_S51NM_PROJECT_SUPPORT"))
+ if ctx.AConfig().IsEnvTrue("LANTONDA_S51NM_PROJECT_SUPPORT") {
+ p.Cflags = append(p.Cflags, "-DS51NM_PROJECT_SUPPORT")
+ }
+
+ ctx.AppendProperties(p)
+}
如果在system/core/adb下添加,方法如下:
diff --git a/system/core/adb/Android.bp b/system/core/adb/Android.bp
index 01e00dd..296d21d 100644
--- a/system/core/adb/Android.bp
+++ b/system/core/adb/Android.bp
@@ -12,9 +12,33 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// Android.bp condition compilation start
+bootstrap_go_package {
+ // name and pkgPath need to according to your module
+ name: "soong-system_core_adb",
+ pkgPath: "android/soong/system_core_adb",
+ deps: [
+ "blueprint",
+ "blueprint-pathtools",
+ "soong",
+ "soong-android",
+ "soong-cc",
+ "soong-genrule",
+ ],
+ srcs: [
+ "system_core_adb.go", // include new add .go file
+ ],
+ pluginFor: ["soong_build"],
+}
+
+system_core_adb_defaults { // system_core_adb_defaults is a module
+ name: "system_core_adb_selinux_cflags_mod",
+}
+// Android.bp condition compilation end
+
cc_defaults {
name: "adb_defaults",
-
+ defaults: ["system_core_adb_selinux_cflags_mod"], // Android.bp condition compilation
cflags: [
"-Wall",
"-Wextra",
diff --git a/system/core/adb/daemon/main.cpp b/system/core/adb/daemon/main.cpp
index e5a4917..64465cd 100644
--- a/system/core/adb/daemon/main.cpp
+++ b/system/core/adb/daemon/main.cpp
@@ -163,12 +163,14 @@ static void drop_privileges(int server_port) {
} else {
// minijail_enter() will abort if any priv-dropping step fails.
minijail_enter(jail.get());
-
+#ifndef KBOX_ENABLE_SELINUX_SUPPORT
+#else
if (root_seclabel != nullptr) {
if (selinux_android_setcon(root_seclabel) < 0) {
LOG(FATAL) << "Could not set SELinux context";
}
}
+#endif
std::string error;
std::string local_name =
android::base::StringPrintf("tcp:%d", server_port);
diff --git a/system/core/adb/system_core_adb.go b/system/core/adb/system_core_adb.go
new file mode 100644
index 0000000..b4daa52
--- /dev/null
+++ b/system/core/adb/system_core_adb.go
@@ -0,0 +1,32 @@
+package system_core_adb
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+ "fmt"
+)
+
+func init() {
+ fmt.Println("according to enable or disable selinux, resister the modules")
+ android.RegisterModuleType("system_core_adb_defaults", selinuxDefaultsFactory)
+}
+
+func selinuxDefaultsFactory() (android.Module) {
+ module := cc.DefaultsFactory()
+ android.AddLoadHook(module, selinuxDefaults)
+ return module
+}
+
+func selinuxDefaults(ctx android.LoadHookContext) {
+ type props struct {
+ Cflags []string
+ }
+ p := &props{}
+ fmt.Println("according to enable or disable selinux, mod cflags")
+ fmt.Println("KBOX_ENABLE_SELINUX_SUPPORT: ", ctx.AConfig().IsEnvTrue("KBOX_ENABLE_SELINUX_SUPPORT"))
+ if ctx.AConfig().IsEnvTrue("KBOX_ENABLE_SELINUX_SUPPORT") {
+ p.Cflags = append(p.Cflags, "-DKBOX_ENABLE_SELINUX_SUPPORT")
+ }
+
+ ctx.AppendProperties(p)
+}
法二、
这种方法没有验证,可以参考https://blog.csdn.net/qq_41192631/article/details/116233122调试。
1.在平台mk中,定义宏变量。(此处平台mk选择的是BoardConfig.mk, 路径:device/(厂商)/(平台)/BoardConfig.mk
# patch start
OPTIMIZE := true
# patch end
2.新增bool类型go变量。路径build/soong/android/variable.go
type productVariables struct {
……
// patch start
Optimize *bool `json:",omitempty"`
// patch end
}
3.建立go变量和mk变量的json映射关系,让go变量可以获取到mk中定义的变量值。路径build/make/core/soong_config.mk
# patch start
$(call add_json_bool, Optimize, $(filter true, $(OPTIMIZE)))
# patch end
这句等同于:
# bool Optimize = (OPTIMIZE == true)
4.定义go方法,返回go变量的值。路径:build/soong/android/config.go
# patch start
func (c *deviceConfig) Optimize() bool {
return Bool(c.config.productVariables.Optimize)
}
# patch end
完成了以上四步后,mk变量就成功映射到go文件中,并生成系统环境变量。
在编译之后可以查看out/soong/soong.variables文件,确认是否生成环境变量,赋值是否正确。
基于上一部分的成果,我们来修改一下实现,完成我们的需求:
修改customsystem.go,如下:
func custom_optimize_append_properties(ctx android.LoadHookContext) {
type props struct {
Srcs []string
}
p := &props{}
// 修改成自定义条件
optimize := ctx.DeviceConfig().Optimize()
fmt.Println("mk OPTIMIZE:", optimize)
if optimize {
p.Srcs = append(p.Srcs, ":custom_optimize")
} else {
p.Srcs = append(p.Srcs, ":custom_origin")
}
ctx.AppendProperties(p)
}
修改到这里,就完全结束了。现在只需要编译看看,验证效果。
参考:
[1]:https://gitee.com/kunpengcompute/Kbox/blob/AOSP10/aosp10_selinux.patch
[2]:https://blog.csdn.net/drageon_j/article/details/77336817
[3]:https://blog.csdn.net/qq_41192631/article/details/116233122