Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af725834 authored by Spandan Das's avatar Spandan Das
Browse files

Generate a ndk_sysroot target in bp2build

This target will have a dependency edge to every bp2build equivalent of
Soong's ndk_headers. In b builds, sdk variants will compile against this
aggregated CcInfo providing target

A non monolithic alternative was discarded after conversations in
b/300504837#comment1-5

Contents of bp2build generated target: https://paste.googleplex.com/6643820291686400

Implementation details
- Since there is no equivalent Soong module for ndk_sysroot, hardcode
  bp2build/build_conversion.go to collect all ndk_headers soong modules.
  Add them to `deps` of a ndk_sysroot target
- Create `ndk_sysroot` in build/bazel/rules/cc/BUILD.bazel. This is
  expected to be a temporary location. This will use the
  cc_library_headers macro
- Update SetStubsForDynamicDeps so that sdk variant of rdeps depends on
  //build/bazel/rules/cc:ndk_sysroot. This will provide a CcInfo during
  compilation. Since ndk_sysroot is of type cc_library_headers, it will
  not get packaged into the apk.
- Refactor `goBazelTarget` to a generic `bTarget` so that it is
  representative of the expanded usage by ndk_sysroot

Test: b build //build/bazel/examples/android_app/java/com/app:app_with_sdk_variant_of_jni_deps --config=android (with aosp/2755284)

Bug: 300504837

Change-Id: Ifa427dd78115703ab251b0e1a0b71d3f19e91008
parent b95a8b33
Loading
Loading
Loading
Loading
+70 −23
Original line number Diff line number Diff line
@@ -287,9 +287,9 @@ func (r conversionResults) BuildDirToTargets() map[string]BazelTargets {
	return r.buildFileToTargets
}

// struct to store state of go bazel targets
// struct to store state of b bazel targets (e.g. go targets which do not implement android.Module)
// this implements bp2buildModule interface and is passed to generateBazelTargets
type goBazelTarget struct {
type bTarget struct {
	targetName            string
	targetPackage         string
	bazelRuleClass        string
@@ -297,26 +297,26 @@ type goBazelTarget struct {
	bazelAttributes       []interface{}
}

var _ bp2buildModule = (*goBazelTarget)(nil)
var _ bp2buildModule = (*bTarget)(nil)

func (g goBazelTarget) TargetName() string {
	return g.targetName
func (b bTarget) TargetName() string {
	return b.targetName
}

func (g goBazelTarget) TargetPackage() string {
	return g.targetPackage
func (b bTarget) TargetPackage() string {
	return b.targetPackage
}

func (g goBazelTarget) BazelRuleClass() string {
	return g.bazelRuleClass
func (b bTarget) BazelRuleClass() string {
	return b.bazelRuleClass
}

func (g goBazelTarget) BazelRuleLoadLocation() string {
	return g.bazelRuleLoadLocation
func (b bTarget) BazelRuleLoadLocation() string {
	return b.bazelRuleLoadLocation
}

func (g goBazelTarget) BazelAttributes() []interface{} {
	return g.bazelAttributes
func (b bTarget) BazelAttributes() []interface{} {
	return b.bazelAttributes
}

// Creates a target_compatible_with entry that is *not* compatible with android
@@ -421,7 +421,7 @@ func generateBazelTargetsGoTest(ctx *android.Context, goModulesMap nameToGoLibra
		Target_compatible_with: targetNotCompatibleWithAndroid(),
	}

	libTest := goBazelTarget{
	libTest := bTarget{
		targetName:            gp.name,
		targetPackage:         gp.dir,
		bazelRuleClass:        "go_test",
@@ -514,7 +514,7 @@ func generateBazelTargetsGoPackage(ctx *android.Context, g *bootstrap.GoPackage,
		Target_compatible_with: targetNotCompatibleWithAndroid(),
	}

	lib := goBazelTarget{
	lib := bTarget{
		targetName:            g.Name(),
		targetPackage:         ctx.ModuleDir(g),
		bazelRuleClass:        "go_library",
@@ -555,23 +555,35 @@ type goLibraryModule struct {
	Deps []string
}

type buildConversionMetadata struct {
	nameToGoLibraryModule nameToGoLibraryModule
	ndkHeaders            []blueprint.Module
}

type nameToGoLibraryModule map[string]goLibraryModule

// Visit each module in the graph
// Visit each module in the graph, and collect metadata about the build graph
// If a module is of type `bootstrap_go_package`, return a map containing metadata like its dir and deps
func createGoLibraryModuleMap(ctx *android.Context) nameToGoLibraryModule {
	ret := nameToGoLibraryModule{}
// If a module is of type `ndk_headers`, add it to a list and return the list
func createBuildConversionMetadata(ctx *android.Context) buildConversionMetadata {
	goMap := nameToGoLibraryModule{}
	ndkHeaders := []blueprint.Module{}
	ctx.VisitAllModules(func(m blueprint.Module) {
		moduleType := ctx.ModuleType(m)
		// We do not need to store information about blueprint_go_binary since it does not have any rdeps
		if moduleType == "bootstrap_go_package" {
			ret[m.Name()] = goLibraryModule{
			goMap[m.Name()] = goLibraryModule{
				Dir:  ctx.ModuleDir(m),
				Deps: m.(*bootstrap.GoPackage).Deps(),
			}
		} else if moduleType == "ndk_headers" {
			ndkHeaders = append(ndkHeaders, m)
		}
	})
	return ret
	return buildConversionMetadata{
		nameToGoLibraryModule: goMap,
		ndkHeaders:            ndkHeaders,
	}
}

// Returns the deps in the transitive closure of a go target
@@ -620,7 +632,7 @@ func generateBazelTargetsGoBinary(ctx *android.Context, g *bootstrap.GoBinary, g
			Deps:                   goDepLabels(transitiveDeps, goModulesMap),
			Target_compatible_with: targetNotCompatibleWithAndroid(),
		}
		libTestSource := goBazelTarget{
		libTestSource := bTarget{
			targetName:            goSource,
			targetPackage:         ctx.ModuleDir(g),
			bazelRuleClass:        "go_source",
@@ -669,7 +681,7 @@ func generateBazelTargetsGoBinary(ctx *android.Context, g *bootstrap.GoBinary, g
		ga.Srcs = goSrcLabels(ctx.Config(), ctx.ModuleDir(g), g.Srcs(), g.LinuxSrcs(), g.DarwinSrcs())
	}

	bin := goBazelTarget{
	bin := bTarget{
		targetName:            g.Name(),
		targetPackage:         ctx.ModuleDir(g),
		bazelRuleClass:        "go_binary",
@@ -700,7 +712,9 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers

	// Visit go libraries in a pre-run and store its state in a map
	// The time complexity remains O(N), and this does not add significant wall time.
	nameToGoLibMap := createGoLibraryModuleMap(ctx.Context())
	meta := createBuildConversionMetadata(ctx.Context())
	nameToGoLibMap := meta.nameToGoLibraryModule
	ndkHeaders := meta.ndkHeaders

	bpCtx := ctx.Context()
	bpCtx.VisitAllModules(func(m blueprint.Module) {
@@ -805,6 +819,39 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers
		}
	})

	// Create an ndk_sysroot target that has a dependency edge on every target corresponding to Soong's ndk_headers
	// This root target will provide headers to sdk variants of jni libraries
	if ctx.Mode() == Bp2Build {
		var depLabels bazel.LabelList
		for _, ndkHeader := range ndkHeaders {
			depLabel := bazel.Label{
				Label: "//" + bpCtx.ModuleDir(ndkHeader) + ":" + ndkHeader.Name(),
			}
			depLabels.Add(&depLabel)
		}
		a := struct {
			Deps                bazel.LabelListAttribute
			System_dynamic_deps bazel.LabelListAttribute
		}{
			Deps:                bazel.MakeLabelListAttribute(bazel.UniqueSortedBazelLabelList(depLabels)),
			System_dynamic_deps: bazel.MakeLabelListAttribute(bazel.MakeLabelList([]bazel.Label{})),
		}
		ndkSysroot := bTarget{
			targetName:            "ndk_sysroot",
			targetPackage:         "build/bazel/rules/cc", // The location is subject to change, use build/bazel for now
			bazelRuleClass:        "cc_library_headers",
			bazelRuleLoadLocation: "//build/bazel/rules/cc:cc_library_headers.bzl",
			bazelAttributes:       []interface{}{&a},
		}

		if t, err := generateBazelTarget(bpCtx, ndkSysroot); err == nil {
			dir := ndkSysroot.targetPackage
			buildFileToTargets[dir] = append(buildFileToTargets[dir], t)
		} else {
			errs = append(errs, err)
		}
	}

	if len(errs) > 0 {
		return conversionResults{}, errs
	}
+4 −0
Original line number Diff line number Diff line
@@ -159,6 +159,10 @@ cc_library {
			"min_sdk_version":    `"29"`,
			"use_version_lib":    `True`,
			"whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
			"deps": `select({
        "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
        "//conditions:default": [],
    })`,
		}),
	})
}
+4 −0
Original line number Diff line number Diff line
@@ -118,6 +118,10 @@ cc_library_headers {
    ]`,
				"sdk_version":     `"current"`,
				"min_sdk_version": `"29"`,
				"deps": `select({
        "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
        "//conditions:default": [],
    })`,
			}),
		},
	})
+8 −0
Original line number Diff line number Diff line
@@ -175,6 +175,10 @@ cc_library_shared {
    ]`,
				"sdk_version":     `"current"`,
				"min_sdk_version": `"29"`,
				"deps": `select({
        "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
        "//conditions:default": [],
    })`,
			}),
		},
	})
@@ -1642,6 +1646,10 @@ ndk_library {
    })`,
				"local_includes": `["."]`,
				"sdk_version":    `"current"`,
				"deps": `select({
        "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
        "//conditions:default": [],
    })`,
			}),
		},
	})
+4 −0
Original line number Diff line number Diff line
@@ -203,6 +203,10 @@ cc_library_static {
    ]`,
				"sdk_version":     `"current"`,
				"min_sdk_version": `"29"`,
				"deps": `select({
        "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
        "//conditions:default": [],
    })`,
			}),
		},
	})
Loading