Convert oemaids_headers / passwd / group to Soong

Bug: 118089258
Test: m oemaids_header_gen oemaids_headers passwd group
Change-Id: Ie3b92a499b44391e0692da5d9ad067089a62aabb
diff --git a/core/board_config.mk b/core/board_config.mk
index 6f04fb3..cc989b5 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -44,6 +44,7 @@
   TARGET_BOARD_PLATFORM \
   TARGET_BOARD_PLATFORM_GPU \
   TARGET_BOOTLOADER_BOARD_NAME \
+  TARGET_FS_CONFIG_GEN \
   TARGET_NO_BOOTLOADER \
   TARGET_NO_KERNEL \
   TARGET_NO_RECOVERY \
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 0275de6..c01fc98 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -165,6 +165,8 @@
 $(call add_json_list, ProductHiddenAPIStubsSystem,       $(PRODUCT_HIDDENAPI_STUBS_SYSTEM))
 $(call add_json_list, ProductHiddenAPIStubsTest,         $(PRODUCT_HIDDENAPI_STUBS_TEST))
 
+$(call add_json_str,  TargetFSConfigGen,                 $(TARGET_FS_CONFIG_GEN))
+
 $(call add_json_map, VendorVars)
 $(foreach namespace,$(SOONG_CONFIG_NAMESPACES),\
   $(call add_json_map, $(namespace))\
diff --git a/tools/fs_config/Android.bp b/tools/fs_config/Android.bp
index 19a4624..d6fae2d 100644
--- a/tools/fs_config/Android.bp
+++ b/tools/fs_config/Android.bp
@@ -12,6 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+bootstrap_go_package {
+    name: "soong-fs_config",
+    pkgPath: "android/soong/fs_config",
+    deps: [
+        "soong-android",
+        "soong-genrule",
+    ],
+    srcs: [
+        "fs_config.go"
+    ],
+    pluginFor: ["soong_build"],
+}
+
 cc_binary_host {
     name: "fs_config",
     srcs: ["fs_config.c"],
@@ -21,3 +34,64 @@
     ],
     cflags: ["-Werror"],
 }
+
+target_fs_config_gen_filegroup {
+    name: "target_fs_config_gen",
+}
+
+genrule {
+    name: "oemaids_header_gen",
+    tool_files: ["fs_config_generator.py"],
+    cmd: "$(location fs_config_generator.py) oemaid --aid-header=$(location :android_filesystem_config_header) $(location :target_fs_config_gen) >$(out)",
+    srcs: [
+        ":target_fs_config_gen",
+        ":android_filesystem_config_header",
+    ],
+    out: ["generated_oem_aid.h"],
+}
+
+cc_library_headers {
+    name: "oemaids_headers",
+    generated_headers: ["oemaids_header_gen"],
+    export_generated_headers: ["oemaids_header_gen"],
+}
+
+// Generate the vendor/etc/passwd text file for the target
+// This file may be empty if no AIDs are defined in
+// TARGET_FS_CONFIG_GEN files.
+genrule {
+    name: "passwd_gen",
+    tool_files: ["fs_config_generator.py"],
+    cmd: "$(location fs_config_generator.py) passwd --required-prefix=vendor_ --aid-header=$(location :android_filesystem_config_header) $(location :target_fs_config_gen) >$(out)",
+    srcs: [
+        ":target_fs_config_gen",
+        ":android_filesystem_config_header",
+    ],
+    out: ["passwd"],
+}
+
+prebuilt_etc {
+    name: "passwd",
+    vendor: true,
+    src: ":passwd_gen",
+}
+
+// Generate the vendor/etc/group text file for the target
+// This file may be empty if no AIDs are defined in
+// TARGET_FS_CONFIG_GEN files.
+genrule {
+    name: "group_gen",
+    tool_files: ["fs_config_generator.py"],
+    cmd: "$(location fs_config_generator.py) group --required-prefix=vendor_ --aid-header=$(location :android_filesystem_config_header) $(location :target_fs_config_gen) >$(out)",
+    srcs: [
+        ":target_fs_config_gen",
+        ":android_filesystem_config_header",
+    ],
+    out: ["group"],
+}
+
+prebuilt_etc {
+    name: "group",
+    vendor: true,
+    src: ":group_gen",
+}
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index 0e0b1da..96db0f3 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -382,67 +382,6 @@
 	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
 endif
 
-##################################
-# Build the oemaid header library when fs config files are present.
-# Intentionally break build if you require generated AIDs
-# header file, but are not using any fs config files.
-ifneq ($(TARGET_FS_CONFIG_GEN),)
-include $(CLEAR_VARS)
-LOCAL_MODULE := oemaids_headers
-
-LOCAL_MODULE_CLASS := ETC
-
-# Generate the "generated_oem_aid.h" file
-oem := $(local-generated-sources-dir)/generated_oem_aid.h
-$(oem): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
-$(oem): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(oem): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(oem): PRIVATE_CUSTOM_TOOL = $(PRIVATE_LOCAL_PATH)/fs_config_generator.py oemaid --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(PRIVATE_TARGET_FS_CONFIG_GEN) > $@
-$(oem): $(TARGET_FS_CONFIG_GEN) $(LOCAL_PATH)/fs_config_generator.py
-	$(transform-generated-source)
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(dir $(oem))
-LOCAL_EXPORT_C_INCLUDE_DEPS := $(oem)
-
-include $(BUILD_HEADER_LIBRARY)
-endif
-
-##################################
-# Generate the vendor/etc/passwd text file for the target
-# This file may be empty if no AIDs are defined in
-# TARGET_FS_CONFIG_GEN files.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := passwd
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
-	@mkdir -p $(dir $@)
-	$(hide) $< passwd --required-prefix=vendor_ --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) > $@
-
-##################################
-# Generate the vendor/etc/group text file for the target
-# This file may be empty if no AIDs are defined in
-# TARGET_FS_CONFIG_GEN files.
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := group
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
-$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config)
-	@mkdir -p $(dir $@)
-	$(hide) $< group --required-prefix=vendor_ --aid-header=$(PRIVATE_ANDROID_FS_HDR) $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null) > $@
-
 system_android_filesystem_config :=
 system_capability_header :=
 fs_config_generate_extra_partition_list :=
diff --git a/tools/fs_config/fs_config.go b/tools/fs_config/fs_config.go
new file mode 100644
index 0000000..869cb3d
--- /dev/null
+++ b/tools/fs_config/fs_config.go
@@ -0,0 +1,60 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package fs_config
+
+import (
+	"android/soong/android"
+)
+
+var pctx = android.NewPackageContext("android/soong/fs_config")
+
+func init() {
+	android.RegisterModuleType("target_fs_config_gen_filegroup", targetFSConfigGenFactory)
+}
+
+// target_fs_config_gen_filegroup is used to expose the file pointed to by TARGET_FS_CONFIG_GEN to
+// genrules in Soong. If TARGET_FS_CONFIG_GEN is empty, it will export an empty file instead.
+func targetFSConfigGenFactory() android.Module {
+	module := &targetFSConfigGen{}
+	android.InitAndroidModule(module)
+	return module
+}
+
+var _ android.SourceFileProducer = (*targetFSConfigGen)(nil)
+
+type targetFSConfigGen struct {
+	android.ModuleBase
+	path android.Path
+}
+
+func (targetFSConfigGen) DepsMutator(ctx android.BottomUpMutatorContext) {}
+
+func (t *targetFSConfigGen) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	if ret := ctx.DeviceConfig().TargetFSConfigGen(); ret != nil && *ret != "" {
+		t.path = android.PathForSource(ctx, *ret)
+	} else {
+		path := android.PathForModuleGen(ctx, "empty")
+		t.path = path
+
+		rule := android.NewRuleBuilder()
+		rule.Command().Text("rm -rf").Output(path)
+		rule.Command().Text("touch").Output(path)
+		rule.Build(pctx, ctx, "fs_config_empty", "create empty file")
+	}
+}
+
+func (t *targetFSConfigGen) Srcs() android.Paths {
+	return android.Paths{t.path}
+}