summaryrefslogtreecommitdiff
path: root/bp2build/conversion.go
diff options
context:
space:
mode:
Diffstat (limited to 'bp2build/conversion.go')
-rw-r--r--bp2build/conversion.go118
1 files changed, 118 insertions, 0 deletions
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
new file mode 100644
index 000000000..cdfb38b14
--- /dev/null
+++ b/bp2build/conversion.go
@@ -0,0 +1,118 @@
+package bp2build
+
+import (
+ "android/soong/android"
+ "reflect"
+ "sort"
+ "strings"
+
+ "github.com/google/blueprint/proptools"
+)
+
+type BazelFile struct {
+ Dir string
+ Basename string
+ Contents string
+}
+
+func CreateBazelFiles(
+ ruleShims map[string]RuleShim,
+ buildToTargets map[string][]BazelTarget) []BazelFile {
+ files := make([]BazelFile, 0, len(ruleShims)+len(buildToTargets)+numAdditionalFiles)
+
+ // Write top level files: WORKSPACE and BUILD. These files are empty.
+ files = append(files, newFile("", "WORKSPACE", ""))
+ // Used to denote that the top level directory is a package.
+ files = append(files, newFile("", "BUILD", ""))
+
+ files = append(files, newFile(bazelRulesSubDir, "BUILD", ""))
+ files = append(files, newFile(bazelRulesSubDir, "providers.bzl", providersBzl))
+
+ for bzlFileName, ruleShim := range ruleShims {
+ files = append(files, newFile(bazelRulesSubDir, bzlFileName+".bzl", ruleShim.content))
+ }
+ files = append(files, newFile(bazelRulesSubDir, "soong_module.bzl", generateSoongModuleBzl(ruleShims)))
+
+ files = append(files, createBuildFiles(buildToTargets)...)
+
+ return files
+}
+
+func createBuildFiles(buildToTargets map[string][]BazelTarget) []BazelFile {
+ files := make([]BazelFile, 0, len(buildToTargets))
+ for _, dir := range android.SortedStringKeys(buildToTargets) {
+ content := soongModuleLoad
+ targets := buildToTargets[dir]
+ sort.Slice(targets, func(i, j int) bool { return targets[i].name < targets[j].name })
+ for _, t := range targets {
+ content += "\n\n"
+ content += t.content
+ }
+ files = append(files, newFile(dir, "BUILD.bazel", content))
+ }
+ return files
+}
+
+func newFile(dir, basename, content string) BazelFile {
+ return BazelFile{
+ Dir: dir,
+ Basename: basename,
+ Contents: content,
+ }
+}
+
+const (
+ bazelRulesSubDir = "build/bazel/queryview_rules"
+
+ // additional files:
+ // * workspace file
+ // * base BUILD file
+ // * rules BUILD file
+ // * rules providers.bzl file
+ // * rules soong_module.bzl file
+ numAdditionalFiles = 5
+)
+
+var (
+ // Certain module property names are blocklisted/ignored here, for the reasons commented.
+ ignoredPropNames = map[string]bool{
+ "name": true, // redundant, since this is explicitly generated for every target
+ "from": true, // reserved keyword
+ "in": true, // reserved keyword
+ "arch": true, // interface prop type is not supported yet.
+ "multilib": true, // interface prop type is not supported yet.
+ "target": true, // interface prop type is not supported yet.
+ "visibility": true, // Bazel has native visibility semantics. Handle later.
+ "features": true, // There is already a built-in attribute 'features' which cannot be overridden.
+ }
+)
+
+func shouldGenerateAttribute(prop string) bool {
+ return !ignoredPropNames[prop]
+}
+
+func shouldSkipStructField(field reflect.StructField) bool {
+ if field.PkgPath != "" {
+ // Skip unexported fields. Some properties are
+ // internal to Soong only, and these fields do not have PkgPath.
+ return true
+ }
+ // fields with tag `blueprint:"mutated"` are exported to enable modification in mutators, etc
+ // but cannot be set in a .bp file
+ if proptools.HasTag(field, "blueprint", "mutated") {
+ return true
+ }
+ return false
+}
+
+// FIXME(b/168089390): In Bazel, rules ending with "_test" needs to be marked as
+// testonly = True, forcing other rules that depend on _test rules to also be
+// marked as testonly = True. This semantic constraint is not present in Soong.
+// To work around, rename "*_test" rules to "*_test_".
+func canonicalizeModuleType(moduleName string) string {
+ if strings.HasSuffix(moduleName, "_test") {
+ return moduleName + "_"
+ }
+
+ return moduleName
+}