soong: Add mkdir module

Co-authored-by: LuK1337 <priv.luk@gmail.com>
Change-Id: I7b98cf5b120817a271036fca3aa0582d77861993
Signed-off-by: Jackeagle <jackeagle102@gmail.com>
diff --git a/build/core/mkdir.mk b/build/core/mkdir.mk
new file mode 100644
index 0000000..01ab1f3
--- /dev/null
+++ b/build/core/mkdir.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2025 The LineageOS 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.
+
+ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK))
+$(call pretty-error,mkdir.mk may only be used from Soong)
+endif
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_SOONG_INSTALL_DIR):
+	@mkdir -p $@
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_SOONG_INSTALL_DIR) $(LOCAL_ADDITIONAL_DEPENDENCIES)
+	@mkdir -p $(dir $@)
+	@touch $@
+
+ifneq ($(filter $(LOCAL_MODULE),$(PRODUCT_PACKAGES)),)
+ALL_DEFAULT_INSTALLED_MODULES += $(LOCAL_SOONG_INSTALL_DIR)
+endif
diff --git a/build/soong/Android.bp b/build/soong/Android.bp
index 5ac776c..b69ab4b 100644
--- a/build/soong/Android.bp
+++ b/build/soong/Android.bp
@@ -42,6 +42,22 @@
     ],
 }
 
+bootstrap_go_package {
+    name: "soong-bliss-mkdir",
+    pkgPath: "bliss/soong/mkdir",
+    deps: [
+        "blueprint",
+        "blueprint-pathtools",
+        "soong",
+        "soong-android",
+    ],
+    srcs: [
+        "mkdir/init.go",
+        "mkdir/mkdir.go",
+    ],
+    pluginFor: ["soong_build"],
+}
+
 cc_defaults {
     name: "generated_kernel_header_defaults",
     generated_headers: ["generated_kernel_includes"],
diff --git a/build/soong/mkdir/init.go b/build/soong/mkdir/init.go
new file mode 100644
index 0000000..5c17507
--- /dev/null
+++ b/build/soong/mkdir/init.go
@@ -0,0 +1,29 @@
+// Copyright 2025 The LineageOS 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 mkdir
+
+import (
+	"android/soong/android"
+)
+
+var pctx = android.NewPackageContext("bliss/soong/mkdir")
+
+func init() {
+	RegisterBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterBuildComponents(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("mkdir", MkdirFactory)
+}
diff --git a/build/soong/mkdir/mkdir.go b/build/soong/mkdir/mkdir.go
new file mode 100644
index 0000000..f4bea63
--- /dev/null
+++ b/build/soong/mkdir/mkdir.go
@@ -0,0 +1,68 @@
+// Copyright 2025 The LineageOS 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 mkdir
+
+import (
+	"android/soong/android"
+
+	"path/filepath"
+)
+
+func MkdirFactory() android.Module {
+	module := &Mkdir{}
+	module.AddProperties(&module.properties)
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+	return module
+}
+
+type MkdirProperties struct {
+	Dir string `android:"arch_variant"`
+}
+
+type Mkdir struct {
+	android.ModuleBase
+
+	properties MkdirProperties
+
+	installDir android.InstallPath
+	output android.ModuleOutPath
+}
+
+func (this *Mkdir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	if filepath.Clean(this.properties.Dir) != this.properties.Dir {
+		ctx.PropertyErrorf("dir", "Should be a clean filepath")
+		return
+	}
+
+	out := android.PathForModuleOut(ctx, "out.txt")
+	android.WriteFileRuleVerbatim(ctx, out, "")
+	this.output = out
+
+	this.installDir = android.PathForModuleInstall(ctx, "", this.properties.Dir)
+}
+
+func (this *Mkdir) AndroidMkEntries() []android.AndroidMkEntries {
+	return []android.AndroidMkEntries{{
+		Class: "FAKE",
+		// Need at least one output file in order for this to take effect.
+		OutputFile: android.OptionalPathForPath(this.output),
+		Include: "vendor/bliss/build/core/mkdir.mk",
+		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+				entries.SetString("LOCAL_SOONG_INSTALL_DIR", this.installDir.String())
+			},
+		},
+	}}
+}