Merge "Support uncompressed cpio"
diff --git a/android/apex.go b/android/apex.go
index b87ff09..6bb0751 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -749,74 +749,69 @@
}
return list
}(map[string]int{
- "adbd": 30,
- "android.net.ipsec.ike": 30,
- "androidx-constraintlayout_constraintlayout-solver": 30,
- "androidx.annotation_annotation": 28,
- "androidx.arch.core_core-common": 28,
- "androidx.collection_collection": 28,
- "androidx.lifecycle_lifecycle-common": 28,
- "apache-commons-compress": 29,
- "bouncycastle_ike_digests": 30,
- "brotli-java": 29,
- "captiveportal-lib": 28,
- "flatbuffer_headers": 30,
- "framework-permission": 30,
- "framework-statsd": 30,
- "gemmlowp_headers": 30,
- "ike-internals": 30,
- "kotlinx-coroutines-android": 28,
- "kotlinx-coroutines-core": 28,
- "libadb_crypto": 30,
- "libadb_pairing_auth": 30,
- "libadb_pairing_connection": 30,
- "libadb_pairing_server": 30,
- "libadb_protos": 30,
- "libadb_tls_connection": 30,
- "libadbconnection_client": 30,
- "libadbconnection_server": 30,
- "libadbd_core": 30,
- "libadbd_services": 30,
- "libadbd": 30,
- "libapp_processes_protos_lite": 30,
- "libasyncio": 30,
- "libbrotli": 30,
- "libbuildversion": 30,
- "libcrypto_static": 30,
- "libcrypto_utils": 30,
- "libdiagnose_usb": 30,
- "libeigen": 30,
- "liblz4": 30,
- "libmdnssd": 30,
- "libneuralnetworks_common": 30,
- "libneuralnetworks_headers": 30,
- "libneuralnetworks": 30,
- "libprocpartition": 30,
- "libprotobuf-java-lite": 30,
- "libprotoutil": 30,
- "libqemu_pipe": 30,
- "libstats_jni": 30,
- "libstatslog_statsd": 30,
- "libstatsmetadata": 30,
- "libstatspull": 30,
- "libstatssocket": 30,
- "libsync": 30,
- "libtextclassifier_hash_headers": 30,
- "libtextclassifier_hash_static": 30,
- "libtflite_kernel_utils": 30,
- "libwatchdog": 29,
- "libzstd": 30,
- "metrics-constants-protos": 28,
- "net-utils-framework-common": 29,
- "permissioncontroller-statsd": 28,
- "philox_random_headers": 30,
- "philox_random": 30,
- "service-permission": 30,
- "service-statsd": 30,
- "statsd-aidl-ndk_platform": 30,
- "statsd": 30,
- "tensorflow_headers": 30,
- "xz-java": 29,
+ "adbd": 30,
+ "android.net.ipsec.ike": 30,
+ "apache-commons-compress": 29,
+ "bouncycastle_ike_digests": 30,
+ "brotli-java": 29,
+ "captiveportal-lib": 28,
+ "flatbuffer_headers": 30,
+ "framework-permission": 30,
+ "framework-statsd": 30,
+ "gemmlowp_headers": 30,
+ "ike-internals": 30,
+ "kotlinx-coroutines-android": 28,
+ "kotlinx-coroutines-core": 28,
+ "libadb_crypto": 30,
+ "libadb_pairing_auth": 30,
+ "libadb_pairing_connection": 30,
+ "libadb_pairing_server": 30,
+ "libadb_protos": 30,
+ "libadb_tls_connection": 30,
+ "libadbconnection_client": 30,
+ "libadbconnection_server": 30,
+ "libadbd_core": 30,
+ "libadbd_services": 30,
+ "libadbd": 30,
+ "libapp_processes_protos_lite": 30,
+ "libasyncio": 30,
+ "libbrotli": 30,
+ "libbuildversion": 30,
+ "libcrypto_static": 30,
+ "libcrypto_utils": 30,
+ "libdiagnose_usb": 30,
+ "libeigen": 30,
+ "liblz4": 30,
+ "libmdnssd": 30,
+ "libneuralnetworks_common": 30,
+ "libneuralnetworks_headers": 30,
+ "libneuralnetworks": 30,
+ "libprocpartition": 30,
+ "libprotobuf-java-lite": 30,
+ "libprotoutil": 30,
+ "libqemu_pipe": 30,
+ "libstats_jni": 30,
+ "libstatslog_statsd": 30,
+ "libstatsmetadata": 30,
+ "libstatspull": 30,
+ "libstatssocket": 30,
+ "libsync": 30,
+ "libtextclassifier_hash_headers": 30,
+ "libtextclassifier_hash_static": 30,
+ "libtflite_kernel_utils": 30,
+ "libwatchdog": 29,
+ "libzstd": 30,
+ "metrics-constants-protos": 28,
+ "net-utils-framework-common": 29,
+ "permissioncontroller-statsd": 28,
+ "philox_random_headers": 30,
+ "philox_random": 30,
+ "service-permission": 30,
+ "service-statsd": 30,
+ "statsd-aidl-ndk_platform": 30,
+ "statsd": 30,
+ "tensorflow_headers": 30,
+ "xz-java": 29,
})
// Function called while walking an APEX's payload dependencies.
diff --git a/android/arch.go b/android/arch.go
index abcdbbb..b277381 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -436,7 +436,7 @@
// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
// filters out non-Soong modules. Now that we've handled them, create a
// normal android.BottomUpMutatorContext.
- mctx := bottomUpMutatorContextFactory(bpctx, module, false)
+ mctx := bottomUpMutatorContextFactory(bpctx, module, false, false)
base := module.base()
@@ -576,7 +576,7 @@
// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
// filters out non-Soong modules. Now that we've handled them, create a
// normal android.BottomUpMutatorContext.
- mctx := bottomUpMutatorContextFactory(bpctx, module, false)
+ mctx := bottomUpMutatorContextFactory(bpctx, module, false, false)
base := module.base()
diff --git a/android/config.go b/android/config.go
index 8090889..e0f3a91 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1624,21 +1624,33 @@
func splitConfiguredJarPair(str string) (string, string, error) {
pair := strings.SplitN(str, ":", 2)
if len(pair) == 2 {
- return pair[0], pair[1], nil
+ apex := pair[0]
+ jar := pair[1]
+ if apex == "" {
+ return apex, jar, fmt.Errorf("invalid apex '%s' in <apex>:<jar> pair '%s', expected format: <apex>:<jar>", apex, str)
+ }
+ return apex, jar, nil
} else {
return "error-apex", "error-jar", fmt.Errorf("malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str)
}
}
-// CreateTestConfiguredJarList is a function to create ConfiguredJarList for
-// tests.
+// CreateTestConfiguredJarList is a function to create ConfiguredJarList for tests.
func CreateTestConfiguredJarList(list []string) ConfiguredJarList {
- apexes, jars, err := splitListOfPairsIntoPairOfLists(list)
+ // Create the ConfiguredJarList in as similar way as it is created at runtime by marshalling to
+ // a json list of strings and then unmarshalling into a ConfiguredJarList instance.
+ b, err := json.Marshal(list)
if err != nil {
panic(err)
}
- return ConfiguredJarList{apexes, jars}
+ var jarList ConfiguredJarList
+ err = json.Unmarshal(b, &jarList)
+ if err != nil {
+ panic(err)
+ }
+
+ return jarList
}
// EmptyConfiguredJarList returns an empty jar list.
diff --git a/android/config_test.go b/android/config_test.go
index 7bfc800..a11115d 100644
--- a/android/config_test.go
+++ b/android/config_test.go
@@ -100,6 +100,22 @@
assertStringEquals(t, "apex1:jarA", list1.String())
})
+ t.Run("create invalid - missing apex", func(t *testing.T) {
+ defer func() {
+ err := recover().(error)
+ assertStringEquals(t, "malformed (apex, jar) pair: 'jarA', expected format: <apex>:<jar>", err.Error())
+ }()
+ CreateTestConfiguredJarList([]string{"jarA"})
+ })
+
+ t.Run("create invalid - empty apex", func(t *testing.T) {
+ defer func() {
+ err := recover().(error)
+ assertStringEquals(t, "invalid apex '' in <apex>:<jar> pair ':jarA', expected format: <apex>:<jar>", err.Error())
+ }()
+ CreateTestConfiguredJarList([]string{":jarA"})
+ })
+
list2 := list1.Append("apex2", "jarB")
t.Run("append", func(t *testing.T) {
assertStringEquals(t, "apex1:jarA,apex2:jarB", list2.String())
diff --git a/android/filegroup.go b/android/filegroup.go
index 3d1bbc5..7a6cc4f 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -29,7 +29,7 @@
// https://docs.bazel.build/versions/master/be/general.html#filegroup
type bazelFilegroupAttributes struct {
Name *string
- Srcs []string
+ Srcs bazel.LabelList
}
type bazelFilegroup struct {
@@ -52,15 +52,18 @@
// TODO: Create helper functions to avoid this boilerplate.
func FilegroupBp2Build(ctx TopDownMutatorContext) {
- if m, ok := ctx.Module().(*fileGroup); ok {
- name := "__bp2build__" + m.base().BaseModuleName()
- ctx.CreateModule(BazelFileGroupFactory, &bazelFilegroupAttributes{
- Name: proptools.StringPtr(name),
- Srcs: m.properties.Srcs,
- }, &bazel.BazelTargetModuleProperties{
- Rule_class: "filegroup",
- })
+ fg, ok := ctx.Module().(*fileGroup)
+ if !ok {
+ return
}
+
+ name := "__bp2build__" + fg.base().BaseModuleName()
+ ctx.CreateModule(BazelFileGroupFactory, &bazelFilegroupAttributes{
+ Name: proptools.StringPtr(name),
+ Srcs: BazelLabelForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs),
+ }, &bazel.BazelTargetModuleProperties{
+ Rule_class: "filegroup",
+ })
}
type fileGroupProperties struct {
diff --git a/android/module.go b/android/module.go
index dcc2b84..1409d44 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2220,10 +2220,17 @@
}
var deps []dep
b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
- if aModule, _ := module.(Module); aModule != nil && aModule.base().BaseModuleName() == name {
- returnedTag := b.bp.OtherModuleDependencyTag(aModule)
+ if aModule, _ := module.(Module); aModule != nil {
+ if aModule.base().BaseModuleName() == name {
+ returnedTag := b.bp.OtherModuleDependencyTag(aModule)
+ if tag == nil || returnedTag == tag {
+ deps = append(deps, dep{aModule, returnedTag})
+ }
+ }
+ } else if b.bp.OtherModuleName(module) == name {
+ returnedTag := b.bp.OtherModuleDependencyTag(module)
if tag == nil || returnedTag == tag {
- deps = append(deps, dep{aModule, returnedTag})
+ deps = append(deps, dep{module, returnedTag})
}
}
})
diff --git a/android/mutator.go b/android/mutator.go
index 6b19dc5..15be65f 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -45,14 +45,30 @@
}
// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
-func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, bp2buildMutators []RegisterMutatorFunc) {
- mctx := ®isterMutatorsContext{}
-
- sharedMutators := []RegisterMutatorFunc{
- RegisterDefaultsPreArchMutators,
+func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, preArchMutators, depsMutators, bp2buildMutators []RegisterMutatorFunc) {
+ mctx := ®isterMutatorsContext{
+ bazelConversionMode: true,
}
- for _, f := range sharedMutators {
+ bp2buildPreArchMutators = append([]RegisterMutatorFunc{
+ RegisterNamespaceMutator,
+ RegisterDefaultsPreArchMutators,
+ // TODO(b/165114590): this is required to resolve deps that are only prebuilts, but we should
+ // evaluate the impact on conversion.
+ RegisterPrebuiltsPreArchMutators,
+ },
+ preArchMutators...)
+
+ for _, f := range bp2buildPreArchMutators {
+ f(mctx)
+ }
+
+ bp2buildDepsMutators = append([]RegisterMutatorFunc{
+ registerDepsMutatorBp2Build,
+ registerPathDepsMutator,
+ }, depsMutators...)
+
+ for _, f := range bp2buildDepsMutators {
f(mctx)
}
@@ -77,7 +93,7 @@
register(preDeps)
- mctx.BottomUp("deps", depsMutator).Parallel()
+ register([]RegisterMutatorFunc{registerDepsMutator})
register(postDeps)
@@ -88,8 +104,9 @@
}
type registerMutatorsContext struct {
- mutators []*mutator
- finalPhase bool
+ mutators []*mutator
+ finalPhase bool
+ bazelConversionMode bool
}
type RegisterMutatorsContext interface {
@@ -211,6 +228,8 @@
finalDeps = append(finalDeps, f)
}
+var bp2buildPreArchMutators = []RegisterMutatorFunc{}
+var bp2buildDepsMutators = []RegisterMutatorFunc{}
var bp2buildMutators = []RegisterMutatorFunc{}
// RegisterBp2BuildMutator registers specially crafted mutators for
@@ -219,13 +238,24 @@
//
// TODO(b/178068862): bring this into TestContext.
func RegisterBp2BuildMutator(moduleType string, m func(TopDownMutatorContext)) {
- mutatorName := moduleType + "_bp2build"
f := func(ctx RegisterMutatorsContext) {
- ctx.TopDown(mutatorName, m)
+ ctx.TopDown(moduleType, m)
}
bp2buildMutators = append(bp2buildMutators, f)
}
+// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
+// into Bazel BUILD targets that should run prior to deps and conversion.
+func PreArchBp2BuildMutators(f RegisterMutatorFunc) {
+ bp2buildPreArchMutators = append(bp2buildPreArchMutators, f)
+}
+
+// DepsBp2BuildMutators adds mutators to be register for converting Android Blueprint modules into
+// Bazel BUILD targets that should run prior to conversion to resolve dependencies.
+func DepsBp2BuildMutators(f RegisterMutatorFunc) {
+ bp2buildDepsMutators = append(bp2buildDepsMutators, f)
+}
+
type BaseMutatorContext interface {
BaseModuleContext
@@ -370,32 +400,38 @@
// variant of the current module. The value should not be modified after being passed to
// SetVariationProvider.
SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{})
+
+ // BazelConversionMode returns whether this mutator is being run as part of Bazel Conversion.
+ BazelConversionMode() bool
}
type bottomUpMutatorContext struct {
bp blueprint.BottomUpMutatorContext
baseModuleContext
- finalPhase bool
+ finalPhase bool
+ bazelConversionMode bool
}
func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module,
- finalPhase bool) BottomUpMutatorContext {
+ finalPhase, bazelConversionMode bool) BottomUpMutatorContext {
return &bottomUpMutatorContext{
- bp: ctx,
- baseModuleContext: a.base().baseModuleContextFactory(ctx),
- finalPhase: finalPhase,
+ bp: ctx,
+ baseModuleContext: a.base().baseModuleContextFactory(ctx),
+ finalPhase: finalPhase,
+ bazelConversionMode: bazelConversionMode,
}
}
func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
finalPhase := x.finalPhase
+ bazelConversionMode := x.bazelConversionMode
f := func(ctx blueprint.BottomUpMutatorContext) {
if a, ok := ctx.Module().(Module); ok {
- m(bottomUpMutatorContextFactory(ctx, a, finalPhase))
+ m(bottomUpMutatorContextFactory(ctx, a, finalPhase, bazelConversionMode))
}
}
- mutator := &mutator{name: name, bottomUpMutator: f}
+ mutator := &mutator{name: x.mutatorName(name), bottomUpMutator: f}
x.mutators = append(x.mutators, mutator)
return mutator
}
@@ -406,6 +442,13 @@
return mutator
}
+func (x *registerMutatorsContext) mutatorName(name string) string {
+ if x.bazelConversionMode {
+ return name + "_bp2build"
+ }
+ return name
+}
+
func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
f := func(ctx blueprint.TopDownMutatorContext) {
if a, ok := ctx.Module().(Module); ok {
@@ -416,7 +459,7 @@
m(actx)
}
}
- mutator := &mutator{name: name, topDownMutator: f}
+ mutator := &mutator{name: x.mutatorName(name), topDownMutator: f}
x.mutators = append(x.mutators, mutator)
return mutator
}
@@ -449,6 +492,16 @@
}
}
+func registerDepsMutator(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("deps", depsMutator).Parallel()
+}
+
+func registerDepsMutatorBp2Build(ctx RegisterMutatorsContext) {
+ // TODO(b/179313531): Consider a separate mutator that only runs depsMutator for modules that are
+ // being converted to build targets.
+ ctx.BottomUp("deps", depsMutator).Parallel()
+}
+
func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
for _, p := range props {
err := proptools.AppendMatchingProperties(t.Module().base().customizableProperties,
@@ -576,12 +629,28 @@
func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
names ...string) []blueprint.Module {
+ if b.bazelConversionMode {
+ _, noSelfDeps := RemoveFromList(b.ModuleName(), names)
+ if len(noSelfDeps) == 0 {
+ return []blueprint.Module(nil)
+ }
+ // In Bazel conversion mode, mutators should not have created any variants. So, when adding a
+ // dependency, the variations would not exist and the dependency could not be added, by
+ // specifying no variations, we will allow adding the dependency to succeed.
+ return b.bp.AddFarVariationDependencies(nil, tag, noSelfDeps...)
+ }
return b.bp.AddVariationDependencies(variations, tag, names...)
}
func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
tag blueprint.DependencyTag, names ...string) []blueprint.Module {
+ if b.bazelConversionMode {
+ // In Bazel conversion mode, mutators should not have created any variants. So, when adding a
+ // dependency, the variations would not exist and the dependency could not be added, by
+ // specifying no variations, we will allow adding the dependency to succeed.
+ return b.bp.AddFarVariationDependencies(nil, tag, names...)
+ }
return b.bp.AddFarVariationDependencies(variations, tag, names...)
}
@@ -609,3 +678,7 @@
func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{}) {
b.bp.SetVariationProvider(module, provider, value)
}
+
+func (b *bottomUpMutatorContext) BazelConversionMode() bool {
+ return b.bazelConversionMode
+}
diff --git a/android/paths.go b/android/paths.go
index 8106958..44221be 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -15,6 +15,7 @@
package android
import (
+ "android/soong/bazel"
"fmt"
"io/ioutil"
"os"
@@ -331,6 +332,115 @@
return ret
}
+// A subset of the ModuleContext methods which are sufficient to resolve references to paths/deps in
+// order to form a Bazel-compatible label for conversion.
+type BazelConversionPathContext interface {
+ EarlyModulePathContext
+
+ GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
+ OtherModuleName(m blueprint.Module) string
+ OtherModuleDir(m blueprint.Module) string
+}
+
+// BazelLabelForModuleDeps returns a Bazel-compatible label for the requested modules which
+// correspond to dependencies on the module within the given ctx.
+func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList {
+ var labels bazel.LabelList
+ for _, module := range modules {
+ bpText := module
+ if m := SrcIsModule(module); m == "" {
+ module = ":" + module
+ }
+ if m, t := SrcIsModuleWithTag(module); m != "" {
+ l := getOtherModuleLabel(ctx, m, t)
+ l.Bp_text = bpText
+ labels.Includes = append(labels.Includes, l)
+ } else {
+ ctx.ModuleErrorf("%q, is not a module reference", module)
+ }
+ }
+ return labels
+}
+
+// BazelLabelForModuleSrc returns bazel.LabelList with paths rooted from the module's local source
+// directory. It expands globs, and resolves references to modules using the ":name" syntax to
+// bazel-compatible labels. Properties passed as the paths or excludes argument must have been
+// annotated with struct tag `android:"path"` so that dependencies on other modules will have
+// already been handled by the path_properties mutator.
+func BazelLabelForModuleSrc(ctx BazelConversionPathContext, paths []string) bazel.LabelList {
+ return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil))
+}
+
+// BazelLabelForModuleSrcExcludes returns bazel.LabelList with paths rooted from the module's local
+// source directory, excluding labels included in the excludes argument. It expands globs, and
+// resolves references to modules using the ":name" syntax to bazel-compatible labels. Properties
+// passed as the paths or excludes argument must have been annotated with struct tag
+// `android:"path"` so that dependencies on other modules will have already been handled by the
+// path_properties mutator.
+func BazelLabelForModuleSrcExcludes(ctx BazelConversionPathContext, paths, excludes []string) bazel.LabelList {
+ excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil))
+ excluded := make([]string, 0, len(excludeLabels.Includes))
+ for _, e := range excludeLabels.Includes {
+ excluded = append(excluded, e.Label)
+ }
+ labels := expandSrcsForBazel(ctx, paths, excluded)
+ labels.Excludes = excludeLabels.Includes
+ return labels
+}
+
+// expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local
+// source directory, excluding labels included in the excludes argument. It expands globs, and
+// resolves references to modules using the ":name" syntax to bazel-compatible labels. Properties
+// passed as the paths or excludes argument must have been annotated with struct tag
+// `android:"path"` so that dependencies on other modules will have already been handled by the
+// path_properties mutator.
+func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes []string) bazel.LabelList {
+ labels := bazel.LabelList{
+ Includes: []bazel.Label{},
+ }
+ for _, p := range paths {
+ if m, tag := SrcIsModuleWithTag(p); m != "" {
+ l := getOtherModuleLabel(ctx, m, tag)
+ if !InList(l.Label, expandedExcludes) {
+ l.Bp_text = fmt.Sprintf(":%s", m)
+ labels.Includes = append(labels.Includes, l)
+ }
+ } else {
+ var expandedPaths []bazel.Label
+ if pathtools.IsGlob(p) {
+ globbedPaths := GlobFiles(ctx, pathForModuleSrc(ctx, p).String(), expandedExcludes)
+ globbedPaths = PathsWithModuleSrcSubDir(ctx, globbedPaths, "")
+ for _, path := range globbedPaths {
+ s := path.Rel()
+ expandedPaths = append(expandedPaths, bazel.Label{Label: s})
+ }
+ } else {
+ if !InList(p, expandedExcludes) {
+ expandedPaths = append(expandedPaths, bazel.Label{Label: p})
+ }
+ }
+ labels.Includes = append(labels.Includes, expandedPaths...)
+ }
+ }
+ return labels
+}
+
+// getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the
+// module. The label will be relative to the current directory if appropriate. The dependency must
+// already be resolved by either deps mutator or path deps mutator.
+func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string) bazel.Label {
+ m, _ := ctx.GetDirectDep(dep)
+ // TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
+ otherModuleName := ctx.OtherModuleName(m)
+ var label bazel.Label
+ if otherDir, dir := ctx.OtherModuleDir(m), ctx.ModuleDir(); otherDir != dir {
+ label.Label = fmt.Sprintf("//%s:%s", otherDir, otherModuleName)
+ } else {
+ label.Label = fmt.Sprintf(":%s", otherModuleName)
+ }
+ return label
+}
+
// OutputPaths is a slice of OutputPath objects, with helpers to operate on the collection.
type OutputPaths []OutputPath
diff --git a/android/register.go b/android/register.go
index 02fc97e..18c743f 100644
--- a/android/register.go
+++ b/android/register.go
@@ -115,7 +115,7 @@
ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
}
- RegisterMutatorsForBazelConversion(ctx.Context, bp2buildMutators)
+ RegisterMutatorsForBazelConversion(ctx.Context, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutators)
}
// Register the pipeline of singletons, module types, and mutators for
diff --git a/android/testing.go b/android/testing.go
index 5640c29..de338bf 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -56,9 +56,9 @@
type TestContext struct {
*Context
- preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc
- bp2buildMutators []RegisterMutatorFunc
- NameResolver *NameResolver
+ preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc
+ bp2buildPreArch, bp2buildDeps, bp2buildMutators []RegisterMutatorFunc
+ NameResolver *NameResolver
}
func (ctx *TestContext) PreArchMutators(f RegisterMutatorFunc) {
@@ -85,13 +85,24 @@
// RegisterBp2BuildMutator registers a BazelTargetModule mutator for converting a module
// type to the equivalent Bazel target.
func (ctx *TestContext) RegisterBp2BuildMutator(moduleType string, m func(TopDownMutatorContext)) {
- mutatorName := moduleType + "_bp2build"
f := func(ctx RegisterMutatorsContext) {
- ctx.TopDown(mutatorName, m)
+ ctx.TopDown(moduleType, m)
}
ctx.bp2buildMutators = append(ctx.bp2buildMutators, f)
}
+// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
+// into Bazel BUILD targets that should run prior to deps and conversion.
+func (ctx *TestContext) PreArchBp2BuildMutators(f RegisterMutatorFunc) {
+ ctx.bp2buildPreArch = append(ctx.bp2buildPreArch, f)
+}
+
+// DepsBp2BuildMutators adds mutators to be register for converting Android Blueprint modules into
+// Bazel BUILD targets that should run prior to conversion to resolve dependencies.
+func (ctx *TestContext) DepsBp2BuildMutators(f RegisterMutatorFunc) {
+ ctx.bp2buildDeps = append(ctx.bp2buildDeps, f)
+}
+
func (ctx *TestContext) Register() {
registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
@@ -100,7 +111,7 @@
// RegisterForBazelConversion prepares a test context for bp2build conversion.
func (ctx *TestContext) RegisterForBazelConversion() {
- RegisterMutatorsForBazelConversion(ctx.Context.Context, ctx.bp2buildMutators)
+ RegisterMutatorsForBazelConversion(ctx.Context.Context, ctx.bp2buildPreArch, ctx.bp2buildDeps, ctx.bp2buildMutators)
}
func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) {
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index fb84df8..5d00e06 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -52,6 +52,7 @@
android.hidl.safe_union@1.0(minSdkVersion:29)
android.hidl.token@1.0(minSdkVersion:29)
android.hidl.token@1.0-utils(minSdkVersion:29)
+android.net.ipsec.ike(minSdkVersion:30)
android.net.ipsec.ike(minSdkVersion:current)
android.net.ipsec.ike.xml(minSdkVersion:(no version))
androidx-constraintlayout_constraintlayout(minSdkVersion:14)
@@ -238,6 +239,7 @@
libbase(minSdkVersion:29)
libbase_headers(minSdkVersion:29)
libbinder_headers(minSdkVersion:29)
+libbinder_headers_platform_shared(minSdkVersion:29)
libbinderthreadstateutils(minSdkVersion:29)
libbluetooth-types-header(minSdkVersion:29)
libbrotli(minSdkVersion:(no version))
diff --git a/apex/apex.go b/apex/apex.go
index c897042..724a50b 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -54,6 +54,8 @@
func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
+ ctx.BottomUp("prebuilt_apex_select_source", prebuiltSelectSourceMutator).Parallel()
+ ctx.BottomUp("deapexer_select_source", deapexerSelectSourceMutator).Parallel()
}
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
diff --git a/apex/deapexer.go b/apex/deapexer.go
index 651cadf..8f4a285 100644
--- a/apex/deapexer.go
+++ b/apex/deapexer.go
@@ -78,12 +78,17 @@
return p.prebuilt.Name(p.ModuleBase.Name())
}
-func (p *Deapexer) DepsMutator(ctx android.BottomUpMutatorContext) {
- if err := p.apexFileProperties.selectSource(ctx); err != nil {
- ctx.ModuleErrorf("%s", err)
+func deapexerSelectSourceMutator(ctx android.BottomUpMutatorContext) {
+ p, ok := ctx.Module().(*Deapexer)
+ if !ok {
return
}
+ if err := p.apexFileProperties.selectSource(ctx); err != nil {
+ ctx.ModuleErrorf("%s", err)
+ }
+}
+func (p *Deapexer) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies from the java modules to which this exports files from the `.apex` file onto
// this module so that they can access the `DeapexerInfo` object that this provides.
for _, lib := range p.properties.Exported_java_libs {
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index c72a9eb..3149952 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -250,12 +250,17 @@
return name
}
-func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
- if err := p.properties.selectSource(ctx); err != nil {
- ctx.ModuleErrorf("%s", err)
+func prebuiltSelectSourceMutator(ctx android.BottomUpMutatorContext) {
+ p, ok := ctx.Module().(*Prebuilt)
+ if !ok {
return
}
+ if err := p.properties.selectSource(ctx); err != nil {
+ ctx.ModuleErrorf("%s", err)
+ }
+}
+func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies onto the java modules that represent the java libraries that are provided by
// and exported from this prebuilt apex.
for _, lib := range p.properties.Exported_java_libs {
diff --git a/bazel/properties.go b/bazel/properties.go
index 79956e1..5b98d15 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -35,3 +35,26 @@
// The target label for the bzl file containing the definition of the rule class.
Bzl_load_location string
}
+
+// Label is used to represent a Bazel compatible Label. Also stores the original bp text to support
+// string replacement.
+type Label struct {
+ Bp_text string
+ Label string
+}
+
+// LabelList is used to represent a list of Bazel labels.
+type LabelList struct {
+ Includes []Label
+ Excludes []Label
+}
+
+// Append appends the fields of other labelList to the corresponding fields of ll.
+func (ll *LabelList) Append(other LabelList) {
+ if len(ll.Includes) > 0 || len(other.Includes) > 0 {
+ ll.Includes = append(ll.Includes, other.Includes...)
+ }
+ if len(ll.Excludes) > 0 || len(other.Excludes) > 0 {
+ ll.Excludes = append(other.Excludes, other.Excludes...)
+ }
+}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 1fa3e06..2c293ea 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "android/soong/bazel"
"fmt"
"reflect"
"strconv"
@@ -177,7 +178,7 @@
panic(fmt.Errorf("Unknown code-generation mode: %s", codegenMode))
}
- buildFileToTargets[ctx.ModuleDir(m)] = append(buildFileToTargets[dir], t)
+ buildFileToTargets[dir] = append(buildFileToTargets[dir], t)
})
return buildFileToTargets
}
@@ -349,6 +350,13 @@
ret += makeIndent(indent)
ret += "]"
case reflect.Struct:
+ if labels, ok := propertyValue.Interface().(bazel.LabelList); ok {
+ // TODO(b/165114590): convert glob syntax
+ return prettyPrint(reflect.ValueOf(labels.Includes), indent)
+ } else if label, ok := propertyValue.Interface().(bazel.Label); ok {
+ return fmt.Sprintf("%q", label.Label), nil
+ }
+
ret = "{\n"
// Sort and print the struct props by the key.
structProps := extractStructProperties(propertyValue, indent)
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index df7dd17..081b0e5 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -17,6 +17,7 @@
import (
"android/soong/android"
"android/soong/genrule"
+ "strings"
"testing"
)
@@ -248,22 +249,26 @@
ctx.RegisterForBazelConversion()
_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
- android.FailIfErrored(t, errs)
+ if Errored(t, "", errs) {
+ continue
+ }
_, errs = ctx.ResolveDependencies(config)
- android.FailIfErrored(t, errs)
+ if Errored(t, "", errs) {
+ continue
+ }
bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
- t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
- }
-
- actualBazelTarget := bazelTargets[0]
- if actualBazelTarget.content != testCase.expectedBazelTarget {
- t.Errorf(
- "Expected generated Bazel target to be '%s', got '%s'",
- testCase.expectedBazelTarget,
- actualBazelTarget.content,
- )
+ t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount)
+ } else {
+ actualBazelTarget := bazelTargets[0]
+ if actualBazelTarget.content != testCase.expectedBazelTarget {
+ t.Errorf(
+ "Expected generated Bazel target to be '%s', got '%s'",
+ testCase.expectedBazelTarget,
+ actualBazelTarget.content,
+ )
+ }
}
}
}
@@ -434,13 +439,32 @@
}
func TestModuleTypeBp2Build(t *testing.T) {
+ otherGenruleBp := map[string]string{
+ "other/Android.bp": `genrule {
+ name: "foo.tool",
+ out: ["foo_tool.out"],
+ srcs: ["foo_tool.in"],
+ cmd: "cp $(in) $(out)",
+}
+genrule {
+ name: "other.tool",
+ out: ["other_tool.out"],
+ srcs: ["other_tool.in"],
+ cmd: "cp $(in) $(out)",
+}`,
+ }
+
testCases := []struct {
+ description string
moduleTypeUnderTest string
moduleTypeUnderTestFactory android.ModuleFactory
moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
+ preArchMutators []android.RegisterMutatorFunc
+ depsMutators []android.RegisterMutatorFunc
bp string
- expectedBazelTarget string
- description string
+ expectedBazelTargets []string
+ fs map[string]string
+ dir string
}{
{
description: "filegroup with no srcs",
@@ -448,14 +472,16 @@
moduleTypeUnderTestFactory: android.FileGroupFactory,
moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
bp: `filegroup {
- name: "foo",
- srcs: [],
+ name: "fg_foo",
+ srcs: [],
}`,
- expectedBazelTarget: `filegroup(
- name = "foo",
+ expectedBazelTargets: []string{
+ `filegroup(
+ name = "fg_foo",
srcs = [
],
)`,
+ },
},
{
description: "filegroup with srcs",
@@ -463,30 +489,140 @@
moduleTypeUnderTestFactory: android.FileGroupFactory,
moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
bp: `filegroup {
- name: "foo",
- srcs: ["a", "b"],
+ name: "fg_foo",
+ srcs: ["a", "b"],
}`,
- expectedBazelTarget: `filegroup(
- name = "foo",
+ expectedBazelTargets: []string{`filegroup(
+ name = "fg_foo",
srcs = [
"a",
"b",
],
)`,
+ },
+ },
+ {
+ description: "filegroup with excludes srcs",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ bp: `filegroup {
+ name: "fg_foo",
+ srcs: ["a", "b"],
+ exclude_srcs: ["a"],
+}`,
+ expectedBazelTargets: []string{`filegroup(
+ name = "fg_foo",
+ srcs = [
+ "b",
+ ],
+)`,
+ },
+ },
+ {
+ description: "filegroup with glob",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ bp: `filegroup {
+ name: "foo",
+ srcs: ["**/*.txt"],
+}`,
+ expectedBazelTargets: []string{`filegroup(
+ name = "foo",
+ srcs = [
+ "other/a.txt",
+ "other/b.txt",
+ "other/subdir/a.txt",
+ ],
+)`,
+ },
+ fs: map[string]string{
+ "other/a.txt": "",
+ "other/b.txt": "",
+ "other/subdir/a.txt": "",
+ "other/file": "",
+ },
+ },
+ {
+ description: "filegroup with glob in subdir",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ bp: `filegroup {
+ name: "foo",
+ srcs: ["a.txt"],
+}`,
+ dir: "other",
+ expectedBazelTargets: []string{`filegroup(
+ name = "fg_foo",
+ srcs = [
+ "a.txt",
+ "b.txt",
+ "subdir/a.txt",
+ ],
+)`,
+ },
+ fs: map[string]string{
+ "other/Android.bp": `filegroup {
+ name: "fg_foo",
+ srcs: ["**/*.txt"],
+}`,
+ "other/a.txt": "",
+ "other/b.txt": "",
+ "other/subdir/a.txt": "",
+ "other/file": "",
+ },
+ },
+ {
+ description: "depends_on_other_dir_module",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ bp: `filegroup {
+ name: "foobar",
+ srcs: [
+ ":foo",
+ "c",
+ ],
+}`,
+ expectedBazelTargets: []string{`filegroup(
+ name = "foobar",
+ srcs = [
+ "//other:foo",
+ "c",
+ ],
+)`,
+ },
+ fs: map[string]string{
+ "other/Android.bp": `filegroup {
+ name: "foo",
+ srcs: ["a", "b"],
+}`,
+ },
},
{
description: "genrule with command line variable replacements",
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
+ name: "foo.tool",
+ out: ["foo_tool.out"],
+ srcs: ["foo_tool.in"],
+ cmd: "cp $(in) $(out)",
+}
+
+genrule {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tools: [":foo.tool"],
cmd: "$(location :foo.tool) --genDir=$(genDir) arg $(in) $(out)",
}`,
- expectedBazelTarget: `genrule(
+ expectedBazelTargets: []string{
+ `genrule(
name = "foo",
cmd = "$(location :foo.tool) --genDir=$(GENDIR) arg $(SRCS) $(OUTS)",
outs = [
@@ -499,20 +635,39 @@
":foo.tool",
],
)`,
+ `genrule(
+ name = "foo.tool",
+ cmd = "cp $(SRCS) $(OUTS)",
+ outs = [
+ "foo_tool.out",
+ ],
+ srcs = [
+ "foo_tool.in",
+ ],
+)`,
+ },
},
{
description: "genrule using $(locations :label)",
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
+ name: "foo.tools",
+ out: ["foo_tool.out", "foo_tool2.out"],
+ srcs: ["foo_tool.in"],
+ cmd: "cp $(in) $(out)",
+ }
+
+genrule {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
tools: [":foo.tools"],
cmd: "$(locations :foo.tools) -s $(out) $(in)",
}`,
- expectedBazelTarget: `genrule(
+ expectedBazelTargets: []string{`genrule(
name = "foo",
cmd = "$(locations :foo.tools) -s $(OUTS) $(SRCS)",
outs = [
@@ -525,12 +680,83 @@
":foo.tools",
],
)`,
+ `genrule(
+ name = "foo.tools",
+ cmd = "cp $(SRCS) $(OUTS)",
+ outs = [
+ "foo_tool.out",
+ "foo_tool2.out",
+ ],
+ srcs = [
+ "foo_tool.in",
+ ],
+)`,
+ },
+ },
+ {
+ description: "genrule using $(locations //absolute:label)",
+ moduleTypeUnderTest: "genrule",
+ moduleTypeUnderTestFactory: genrule.GenRuleFactory,
+ moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
+ bp: `genrule {
+ name: "foo",
+ out: ["foo.out"],
+ srcs: ["foo.in"],
+ tool_files: [":foo.tool"],
+ cmd: "$(locations :foo.tool) -s $(out) $(in)",
+}`,
+ expectedBazelTargets: []string{`genrule(
+ name = "foo",
+ cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)",
+ outs = [
+ "foo.out",
+ ],
+ srcs = [
+ "foo.in",
+ ],
+ tools = [
+ "//other:foo.tool",
+ ],
+)`,
+ },
+ fs: otherGenruleBp,
+ },
+ {
+ description: "genrule srcs using $(locations //absolute:label)",
+ moduleTypeUnderTest: "genrule",
+ moduleTypeUnderTestFactory: genrule.GenRuleFactory,
+ moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
+ bp: `genrule {
+ name: "foo",
+ out: ["foo.out"],
+ srcs: [":other.tool"],
+ tool_files: [":foo.tool"],
+ cmd: "$(locations :foo.tool) -s $(out) $(location :other.tool)",
+}`,
+ expectedBazelTargets: []string{`genrule(
+ name = "foo",
+ cmd = "$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)",
+ outs = [
+ "foo.out",
+ ],
+ srcs = [
+ "//other:other.tool",
+ ],
+ tools = [
+ "//other:foo.tool",
+ ],
+)`,
+ },
+ fs: otherGenruleBp,
},
{
description: "genrule using $(location) label should substitute first tool label automatically",
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo",
out: ["foo.out"],
@@ -538,9 +764,9 @@
tool_files: [":foo.tool", ":other.tool"],
cmd: "$(location) -s $(out) $(in)",
}`,
- expectedBazelTarget: `genrule(
+ expectedBazelTargets: []string{`genrule(
name = "foo",
- cmd = "$(location :foo.tool) -s $(OUTS) $(SRCS)",
+ cmd = "$(location //other:foo.tool) -s $(OUTS) $(SRCS)",
outs = [
"foo.out",
],
@@ -548,16 +774,19 @@
"foo.in",
],
tools = [
- ":foo.tool",
- ":other.tool",
+ "//other:foo.tool",
+ "//other:other.tool",
],
)`,
+ },
+ fs: otherGenruleBp,
},
{
description: "genrule using $(locations) label should substitute first tool label automatically",
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo",
out: ["foo.out"],
@@ -565,9 +794,9 @@
tools: [":foo.tool", ":other.tool"],
cmd: "$(locations) -s $(out) $(in)",
}`,
- expectedBazelTarget: `genrule(
+ expectedBazelTargets: []string{`genrule(
name = "foo",
- cmd = "$(locations :foo.tool) -s $(OUTS) $(SRCS)",
+ cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)",
outs = [
"foo.out",
],
@@ -575,23 +804,26 @@
"foo.in",
],
tools = [
- ":foo.tool",
- ":other.tool",
+ "//other:foo.tool",
+ "//other:other.tool",
],
)`,
+ },
+ fs: otherGenruleBp,
},
{
description: "genrule without tools or tool_files can convert successfully",
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo",
out: ["foo.out"],
srcs: ["foo.in"],
cmd: "cp $(in) $(out)",
}`,
- expectedBazelTarget: `genrule(
+ expectedBazelTargets: []string{`genrule(
name = "foo",
cmd = "cp $(SRCS) $(OUTS)",
outs = [
@@ -601,39 +833,73 @@
"foo.in",
],
)`,
+ },
},
}
dir := "."
for _, testCase := range testCases {
- config := android.TestConfig(buildDir, nil, testCase.bp, nil)
+ fs := make(map[string][]byte)
+ toParse := []string{
+ "Android.bp",
+ }
+ for f, content := range testCase.fs {
+ if strings.HasSuffix(f, "Android.bp") {
+ toParse = append(toParse, f)
+ }
+ fs[f] = []byte(content)
+ }
+ config := android.TestConfig(buildDir, nil, testCase.bp, fs)
ctx := android.NewTestContext(config)
ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
+ for _, m := range testCase.depsMutators {
+ ctx.DepsBp2BuildMutators(m)
+ }
ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
ctx.RegisterForBazelConversion()
- _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
- android.FailIfErrored(t, errs)
+ _, errs := ctx.ParseFileList(dir, toParse)
+ if Errored(t, testCase.description, errs) {
+ continue
+ }
_, errs = ctx.ResolveDependencies(config)
- android.FailIfErrored(t, errs)
-
- bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
- if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
- t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
+ if Errored(t, testCase.description, errs) {
+ continue
}
- actualBazelTarget := bazelTargets[0]
- if actualBazelTarget.content != testCase.expectedBazelTarget {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- testCase.expectedBazelTarget,
- actualBazelTarget.content,
- )
+ checkDir := dir
+ if testCase.dir != "" {
+ checkDir = testCase.dir
+ }
+ bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir]
+ if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
+ t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
+ } else {
+ for i, target := range bazelTargets {
+ if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
+ t.Errorf(
+ "%s: Expected generated Bazel target to be '%s', got '%s'",
+ testCase.description,
+ w,
+ g,
+ )
+ }
+ }
}
}
}
+func Errored(t *testing.T, desc string, errs []error) bool {
+ t.Helper()
+ if len(errs) > 0 {
+ for _, err := range errs {
+ t.Errorf("%s: %s", desc, err)
+ }
+ return true
+ }
+ return false
+}
+
type bp2buildMutator = func(android.TopDownMutatorContext)
func TestBp2BuildInlinesDefaults(t *testing.T) {
diff --git a/cc/binary.go b/cc/binary.go
index 71c865b..999b82c 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -182,7 +182,7 @@
}
}
- if !binary.static() && inList("libc", deps.StaticLibs) {
+ if !binary.static() && inList("libc", deps.StaticLibs) && !ctx.BazelConversionMode() {
ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
"from static libs or set static_executable: true")
}
diff --git a/cc/cc.go b/cc/cc.go
index d282b6e..df38499 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1535,6 +1535,11 @@
var vndkVersion string
var nameSuffix string
if c.InProduct() {
+ if c.ProductSpecific() {
+ // If the module is product specific with 'product_specific: true',
+ // do not add a name suffix because it is a base module.
+ return ""
+ }
vndkVersion = ctx.DeviceConfig().ProductVndkVersion()
nameSuffix = productSuffix
} else {
@@ -1741,7 +1746,7 @@
func (c *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain {
if c.cachedToolchain == nil {
- c.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
+ c.cachedToolchain = config.FindToolchainWithContext(ctx)
}
return c.cachedToolchain
}
@@ -1833,6 +1838,12 @@
deps.HeaderLibs = android.LastUniqueStrings(deps.HeaderLibs)
deps.RuntimeLibs = android.LastUniqueStrings(deps.RuntimeLibs)
+ // In Bazel conversion mode, we dependency and build validations will occur in Bazel, so there is
+ // no need to do so in Soong.
+ if ctx.BazelConversionMode() {
+ return deps
+ }
+
for _, lib := range deps.ReexportSharedLibHeaders {
if !inList(lib, deps.SharedLibs) {
ctx.PropertyErrorf("export_shared_lib_headers", "Shared library not in shared_libs: '%s'", lib)
@@ -2891,12 +2902,12 @@
ccDepModule, _ := ccDep.(*Module)
isLLndk := ccDepModule != nil && ccDepModule.IsLlndk()
isVendorPublicLib := inList(libName, *vendorPublicLibraries)
- bothVendorAndCoreVariantsExist := ccDep.HasVendorVariant() || isLLndk
+ nonSystemVariantsExist := ccDep.HasNonSystemVariants() || isLLndk
- if c, ok := ccDep.(*Module); ok {
+ if ccDepModule != nil {
// Use base module name for snapshots when exporting to Makefile.
- if snapshotPrebuilt, ok := c.linker.(snapshotInterface); ok {
- baseName := c.BaseModuleName()
+ if snapshotPrebuilt, ok := ccDepModule.linker.(snapshotInterface); ok {
+ baseName := ccDepModule.BaseModuleName()
return baseName + snapshotPrebuilt.snapshotAndroidMkSuffix()
}
@@ -2907,10 +2918,10 @@
// The vendor module is a no-vendor-variant VNDK library. Depend on the
// core module instead.
return libName
- } else if c.UseVndk() && bothVendorAndCoreVariantsExist {
- // The vendor module in Make will have been renamed to not conflict with the core
- // module, so update the dependency name here accordingly.
- return libName + c.getNameSuffixWithVndkVersion(ctx)
+ } else if ccDep.UseVndk() && nonSystemVariantsExist && ccDepModule != nil {
+ // The vendor and product modules in Make will have been renamed to not conflict with the
+ // core module, so update the dependency name here accordingly.
+ return libName + ccDepModule.Properties.SubName
} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
return libName + vendorPublicLibrarySuffix
} else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 7288cc4..6403547 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2712,6 +2712,14 @@
system_shared_libs : [],
}
cc_library {
+ name: "libproduct_vendor",
+ product_specific: true,
+ vendor_available: true,
+ no_libcrt : true,
+ nocrt : true,
+ system_shared_libs : [],
+ }
+ cc_library {
name: "libcore",
runtime_libs: ["liball_available"],
no_libcrt : true,
@@ -2728,7 +2736,7 @@
cc_library {
name: "libvendor2",
vendor: true,
- runtime_libs: ["liball_available", "libvendor1"],
+ runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
no_libcrt : true,
nocrt : true,
system_shared_libs : [],
@@ -2751,7 +2759,7 @@
cc_library {
name: "libproduct2",
product_specific: true,
- runtime_libs: ["liball_available", "libproduct1"],
+ runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
no_libcrt : true,
nocrt : true,
system_shared_libs : [],
@@ -2781,7 +2789,7 @@
checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1"}, module)
+ checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
// runtime_libs for product variants have '.product' suffixes if the modules have both core
// and product variants.
@@ -2791,7 +2799,7 @@
checkRuntimeLibs(t, []string{"liball_available.product"}, module)
module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1"}, module)
+ checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
}
func TestExcludeRuntimeLibs(t *testing.T) {
@@ -2817,10 +2825,10 @@
checkRuntimeLibs(t, []string{"liball_available"}, module)
module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available", "libvendor1"}, module)
+ checkRuntimeLibs(t, []string{"liball_available", "libvendor1", "libproduct_vendor"}, module)
module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available", "libproduct1"}, module)
+ checkRuntimeLibs(t, []string{"liball_available", "libproduct1", "libproduct_vendor"}, module)
}
func checkStaticLibs(t *testing.T, expected []string, module *Module) {
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 35dd10f..71c7626 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -142,6 +142,9 @@
// Nested and array designated initialization is nice to have.
"-Wno-c99-designator",
+ // Warnings from clang-12
+ "-Wno-gnu-folding-constant",
+
// Calls to the APIs that are newer than the min sdk version of the caller should be
// guarded with __builtin_available.
"-Wunguarded-availability",
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index db9092d..59c0422 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -32,12 +32,42 @@
toolchainFactories[os][arch] = factory
}
+type toolchainContext interface {
+ Os() android.OsType
+ Arch() android.Arch
+}
+
+type conversionContext interface {
+ BazelConversionMode() bool
+}
+
+func FindToolchainWithContext(ctx toolchainContext) Toolchain {
+ t, err := findToolchain(ctx.Os(), ctx.Arch())
+ if err != nil {
+ if c, ok := ctx.(conversionContext); ok && c.BazelConversionMode() {
+ // TODO(b/179123288): determine conversion for toolchain
+ return &toolchainX86_64{}
+ } else {
+ panic(err)
+ }
+ }
+ return t
+}
+
func FindToolchain(os android.OsType, arch android.Arch) Toolchain {
+ t, err := findToolchain(os, arch)
+ if err != nil {
+ panic(err)
+ }
+ return t
+}
+
+func findToolchain(os android.OsType, arch android.Arch) (Toolchain, error) {
factory := toolchainFactories[os][arch.ArchType]
if factory == nil {
- panic(fmt.Errorf("Toolchain not found for %s arch %q", os.String(), arch.String()))
+ return nil, fmt.Errorf("Toolchain not found for %s arch %q", os.String(), arch.String())
}
- return factory(arch)
+ return factory(arch), nil
}
type Toolchain interface {
diff --git a/cc/linkable.go b/cc/linkable.go
index ab5a552..58919a0 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -106,6 +106,8 @@
IsVndkExt() bool
IsVndkPrivate() bool
HasVendorVariant() bool
+ HasProductVariant() bool
+ HasNonSystemVariants() bool
InProduct() bool
SdkVersion() string
diff --git a/cc/linker.go b/cc/linker.go
index ff07224..6d0d416 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -328,7 +328,9 @@
}
deps.SystemSharedLibs = linker.Properties.System_shared_libs
- if deps.SystemSharedLibs == nil {
+ // In Bazel conversion mode, variations have not been specified, so SystemSharedLibs may
+ // inaccuarately appear unset, which can cause issues with circular dependencies.
+ if deps.SystemSharedLibs == nil && !ctx.BazelConversionMode() {
// Provide a default system_shared_libs if it is unspecified. Note: If an
// empty list [] is specified, it implies that the module declines the
// default system_shared_libs.
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 9dcb5f3..c17e23d 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -100,7 +100,7 @@
if bazelConversionRequested(configuration) {
// Run the alternate pipeline of bp2build mutators and singleton to convert Blueprint to BUILD files
// before everything else.
- runBp2Build(configuration, extraNinjaDeps)
+ runBp2Build(srcDir, configuration)
// Short-circuit and return.
return
}
@@ -162,7 +162,7 @@
// Run Soong in the bp2build mode. This creates a standalone context that registers
// an alternate pipeline of mutators and singletons specifically for generating
// Bazel BUILD files instead of Ninja files.
-func runBp2Build(configuration android.Config, extraNinjaDeps []string) {
+func runBp2Build(srcDir string, configuration android.Config) {
// Register an alternate set of singletons and mutators for bazel
// conversion for Bazel conversion.
bp2buildCtx := android.NewContext(configuration)
@@ -172,7 +172,20 @@
configuration.SetStopBefore(bootstrap.StopBeforePrepareBuildActions)
bp2buildCtx.SetNameInterface(newNameResolver(configuration))
- // Run the loading and analysis pipeline.
+ // The bp2build process is a purely functional process that only depends on
+ // Android.bp files. It must not depend on the values of per-build product
+ // configurations or variables, since those will generate different BUILD
+ // files based on how the user has configured their tree.
+ bp2buildCtx.SetModuleListFile(bootstrap.ModuleListFile)
+ extraNinjaDeps, err := bp2buildCtx.ListModulePaths(srcDir)
+ if err != nil {
+ panic(err)
+ }
+ extraNinjaDepsString := strings.Join(extraNinjaDeps, " \\\n ")
+
+ // Run the loading and analysis pipeline to prepare the graph of regular
+ // Modules parsed from Android.bp files, and the BazelTargetModules mapped
+ // from the regular Modules.
bootstrap.Main(bp2buildCtx.Context, configuration, extraNinjaDeps...)
// Run the code-generation phase to convert BazelTargetModules to BUILD files.
@@ -195,7 +208,6 @@
ninjaFileName := "build.ninja"
ninjaFile := android.PathForOutput(codegenContext, ninjaFileName)
ninjaFileD := android.PathForOutput(codegenContext, ninjaFileName+".d")
- extraNinjaDepsString := strings.Join(extraNinjaDeps, " \\\n ")
// A workaround to create the 'nothing' ninja target so `m nothing` works,
// since bp2build runs without Kati, and the 'nothing' target is declared in
// a Makefile.
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 8c84368..7658154 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -51,6 +51,9 @@
// Type of the filesystem. Currently, ext4, cpio, and compressed_cpio are supported. Default
// is ext4.
Type *string
+
+ // file_contexts file to make image. Currently, only ext4 is supported.
+ File_contexts *string `android:"path"`
}
// android_filesystem packages a set of modules and their transitive dependencies into a filesystem
@@ -147,6 +150,16 @@
return output
}
+func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.OutputPath {
+ builder := android.NewRuleBuilder(pctx, ctx)
+ fcBin := android.PathForModuleOut(ctx, "file_contexts.bin")
+ builder.Command().BuiltTool("sefcontext_compile").
+ FlagWithOutput("-o ", fcBin).
+ Input(android.PathForModuleSrc(ctx, proptools.String(f.properties.File_contexts)))
+ builder.Build("build_filesystem_file_contexts", fmt.Sprintf("Creating filesystem file contexts for %s", f.BaseModuleName()))
+ return fcBin.OutputPath
+}
+
func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) {
type prop struct {
name string
@@ -193,6 +206,10 @@
addStr("partition_name", f.Name())
}
+ if proptools.String(f.properties.File_contexts) != "" {
+ addPath("selinux_fc", f.buildFileContexts(ctx))
+ }
+
propFile = android.PathForModuleOut(ctx, "prop").OutputPath
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().Text("rm").Flag("-rf").Output(propFile)
@@ -212,6 +229,10 @@
"Consider adding this to bootimg module and signing the entire boot image.")
}
+ if proptools.String(f.properties.File_contexts) != "" {
+ ctx.PropertyErrorf("file_contexts", "file_contexts is not supported for compressed cpio image.")
+ }
+
zipFile := android.PathForModuleOut(ctx, "temp.zip").OutputPath
f.CopyDepsToZip(ctx, zipFile)
diff --git a/genrule/genrule.go b/genrule/genrule.go
index ddfb459..62aa7f8 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -47,9 +47,14 @@
ctx.BottomUp("genrule_tool_deps", toolDepsMutator).Parallel()
})
+ android.DepsBp2BuildMutators(RegisterGenruleBp2BuildDeps)
android.RegisterBp2BuildMutator("genrule", GenruleBp2Build)
}
+func RegisterGenruleBp2BuildDeps(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("genrule_tool_deps", toolDepsMutator)
+}
+
var (
pctx = android.NewPackageContext("android/soong/genrule")
@@ -776,9 +781,9 @@
type bazelGenruleAttributes struct {
Name *string
- Srcs []string
+ Srcs bazel.LabelList
Outs []string
- Tools []string
+ Tools bazel.LabelList
Cmd string
}
@@ -795,45 +800,63 @@
}
func GenruleBp2Build(ctx android.TopDownMutatorContext) {
- if m, ok := ctx.Module().(*Module); ok {
- name := "__bp2build__" + m.Name()
- // Bazel only has the "tools" attribute.
- tools := append(m.properties.Tools, m.properties.Tool_files...)
-
- // Replace in and out variables with $< and $@
- var cmd string
- if m.properties.Cmd != nil {
- cmd = strings.Replace(*m.properties.Cmd, "$(in)", "$(SRCS)", -1)
- cmd = strings.Replace(cmd, "$(out)", "$(OUTS)", -1)
- cmd = strings.Replace(cmd, "$(genDir)", "$(GENDIR)", -1)
- if len(tools) > 0 {
- cmd = strings.Replace(cmd, "$(location)", fmt.Sprintf("$(location %s)", tools[0]), -1)
- cmd = strings.Replace(cmd, "$(locations)", fmt.Sprintf("$(locations %s)", tools[0]), -1)
- }
- }
-
- // The Out prop is not in an immediately accessible field
- // in the Module struct, so use GetProperties and cast it
- // to the known struct prop.
- var outs []string
- for _, propIntf := range m.GetProperties() {
- if props, ok := propIntf.(*genRuleProperties); ok {
- outs = props.Out
- break
- }
- }
-
- // Create the BazelTargetModule.
- ctx.CreateModule(BazelGenruleFactory, &bazelGenruleAttributes{
- Name: proptools.StringPtr(name),
- Srcs: m.properties.Srcs,
- Outs: outs,
- Cmd: cmd,
- Tools: tools,
- }, &bazel.BazelTargetModuleProperties{
- Rule_class: "genrule",
- })
+ m, ok := ctx.Module().(*Module)
+ if !ok {
+ return
}
+ name := "__bp2build__" + m.Name()
+ // Bazel only has the "tools" attribute.
+ tools := android.BazelLabelForModuleDeps(ctx, m.properties.Tools)
+ tool_files := android.BazelLabelForModuleSrc(ctx, m.properties.Tool_files)
+ tools.Append(tool_files)
+
+ srcs := android.BazelLabelForModuleSrc(ctx, m.properties.Srcs)
+
+ var allReplacements bazel.LabelList
+ allReplacements.Append(tools)
+ allReplacements.Append(srcs)
+
+ // Replace in and out variables with $< and $@
+ var cmd string
+ if m.properties.Cmd != nil {
+ cmd = strings.Replace(*m.properties.Cmd, "$(in)", "$(SRCS)", -1)
+ cmd = strings.Replace(cmd, "$(out)", "$(OUTS)", -1)
+ cmd = strings.Replace(cmd, "$(genDir)", "$(GENDIR)", -1)
+ if len(tools.Includes) > 0 {
+ cmd = strings.Replace(cmd, "$(location)", fmt.Sprintf("$(location %s)", tools.Includes[0].Label), -1)
+ cmd = strings.Replace(cmd, "$(locations)", fmt.Sprintf("$(locations %s)", tools.Includes[0].Label), -1)
+ }
+ for _, l := range allReplacements.Includes {
+ bpLoc := fmt.Sprintf("$(location %s)", l.Bp_text)
+ bpLocs := fmt.Sprintf("$(locations %s)", l.Bp_text)
+ bazelLoc := fmt.Sprintf("$(location %s)", l.Label)
+ bazelLocs := fmt.Sprintf("$(locations %s)", l.Label)
+ cmd = strings.Replace(cmd, bpLoc, bazelLoc, -1)
+ cmd = strings.Replace(cmd, bpLocs, bazelLocs, -1)
+ }
+ }
+
+ // The Out prop is not in an immediately accessible field
+ // in the Module struct, so use GetProperties and cast it
+ // to the known struct prop.
+ var outs []string
+ for _, propIntf := range m.GetProperties() {
+ if props, ok := propIntf.(*genRuleProperties); ok {
+ outs = props.Out
+ break
+ }
+ }
+
+ // Create the BazelTargetModule.
+ ctx.CreateModule(BazelGenruleFactory, &bazelGenruleAttributes{
+ Name: proptools.StringPtr(name),
+ Srcs: srcs,
+ Outs: outs,
+ Cmd: cmd,
+ Tools: tools,
+ }, &bazel.BazelTargetModuleProperties{
+ Rule_class: "genrule",
+ })
}
func (m *bazelGenrule) Name() string {
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index da62100..29c73c1 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -129,8 +129,6 @@
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
- buildPath := android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath
-
providesUsesLib := ctx.ModuleName()
if ulib, ok := ctx.Module().(ProvidesUsesLib); ok {
name := ulib.ProvidesUsesLib()
@@ -146,7 +144,6 @@
slimDexpreoptConfig := &dexpreopt.ModuleConfig{
Name: ctx.ModuleName(),
DexLocation: dexLocation,
- BuildPath: buildPath,
EnforceUsesLibraries: d.enforceUsesLibs,
ProvidesUsesLibrary: providesUsesLib,
ClassLoaderContexts: d.classLoaderContexts,
@@ -218,7 +215,7 @@
dexpreoptConfig := &dexpreopt.ModuleConfig{
Name: ctx.ModuleName(),
DexLocation: dexLocation,
- BuildPath: buildPath,
+ BuildPath: android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath,
DexPath: dexJarFile,
ManifestPath: d.manifestFile,
UncompressedDex: d.uncompressedDex,
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 0f9ef58..27f363e 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -65,7 +65,7 @@
srcs: ["a.java"],
compile_dex: true,
}
- `, []string{":foo"}, nil)
+ `, []string{"platform:foo"}, nil)
hiddenAPI := ctx.SingletonForTests("hiddenapi")
hiddenapiRule := hiddenAPI.Rule("hiddenapi")
@@ -82,7 +82,7 @@
jars: ["a.jar"],
compile_dex: true,
}
- `, []string{":foo"}, nil)
+ `, []string{"platform:foo"}, nil)
hiddenAPI := ctx.SingletonForTests("hiddenapi")
hiddenapiRule := hiddenAPI.Rule("hiddenapi")
@@ -106,7 +106,7 @@
compile_dex: true,
prefer: false,
}
- `, []string{":foo"}, nil)
+ `, []string{"platform:foo"}, nil)
hiddenAPI := ctx.SingletonForTests("hiddenapi")
hiddenapiRule := hiddenAPI.Rule("hiddenapi")
@@ -135,7 +135,7 @@
compile_dex: true,
prefer: true,
}
- `, []string{":foo"}, nil)
+ `, []string{"platform:foo"}, nil)
hiddenAPI := ctx.SingletonForTests("hiddenapi")
hiddenapiRule := hiddenAPI.Rule("hiddenapi")
@@ -236,7 +236,7 @@
jars: ["a.jar"],
compile_dex: true,
}
- `, []string{":foo"}, &prebuiltHiddenApiDir)
+ `, []string{"platform:foo"}, &prebuiltHiddenApiDir)
expectedCpInput := prebuiltHiddenApiDir + "/hiddenapi-flags.csv"
expectedCpOutput := buildDir + "/hiddenapi/hiddenapi-flags.csv"
diff --git a/java/java.go b/java/java.go
index 78d974b..91944f6 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2687,9 +2687,10 @@
}
func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
- if ctx.Arch().ArchType == android.Common {
+ if ctx.Arch().ArchType == android.Common || ctx.BazelConversionMode() {
j.deps(ctx)
- } else {
+ }
+ if ctx.Arch().ArchType != android.Common || ctx.BazelConversionMode() {
// These dependencies ensure the host installation rules will install the jar file and
// the jni libraries when the wrapper is installed.
ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...)
diff --git a/java/proto.go b/java/proto.go
index dc5519f..652a4da 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -82,7 +82,7 @@
case "lite", "":
ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-lite")
case "full":
- if ctx.Host() {
+ if ctx.Host() || ctx.BazelConversionMode() {
ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-full")
} else {
ctx.PropertyErrorf("proto.type", "full java protos only supported on the host")
diff --git a/rust/binary.go b/rust/binary.go
index 2963a37..df48916 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -119,6 +119,7 @@
outputFile := android.PathForModuleOut(ctx, fileName)
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
@@ -132,7 +133,7 @@
return outputFile
}
-func (binary *binaryDecorator) autoDep(ctx BaseModuleContext) autoDep {
+func (binary *binaryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
// Binaries default to dylib dependencies for device, rlib for host.
if binary.preferRlib() {
return rlibAutoDep
diff --git a/rust/compiler.go b/rust/compiler.go
index c921824..586063e 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -96,7 +96,11 @@
// list of C shared library dependencies
Shared_libs []string `android:"arch_variant"`
- // list of C static library dependencies
+ // list of C static library dependencies. Note, static libraries prefixed by "lib" will be passed to rustc
+ // along with "-lstatic=<name>". This will bundle the static library into rlib/static libraries so dependents do
+ // not need to also declare the static library as a dependency. Static libraries which are not prefixed by "lib"
+ // cannot be passed to rustc with this flag and will not be bundled into rlib/static libraries, and thus must
+ // be redeclared in dependents.
Static_libs []string `android:"arch_variant"`
// crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
diff --git a/rust/fuzz.go b/rust/fuzz.go
index da8f209..6035e68 100644
--- a/rust/fuzz.go
+++ b/rust/fuzz.go
@@ -91,6 +91,6 @@
return RlibLinkage
}
-func (fuzzer *fuzzDecorator) autoDep(ctx BaseModuleContext) autoDep {
+func (fuzzer *fuzzDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
return rlibAutoDep
}
diff --git a/rust/image.go b/rust/image.go
index 5ff10ae..ac8c1b3 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -71,6 +71,15 @@
return Bool(mod.VendorProperties.Vendor_available) || Bool(mod.VendorProperties.Odm_available)
}
+// Always returns false because rust modules do not support product variant.
+func (mod *Module) HasProductVariant() bool {
+ return Bool(mod.VendorProperties.Product_available)
+}
+
+func (mod *Module) HasNonSystemVariants() bool {
+ return mod.HasVendorVariant() || mod.HasProductVariant()
+}
+
func (c *Module) InProduct() bool {
return false
}
diff --git a/rust/library.go b/rust/library.go
index 6433285..7ff13ec 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -219,13 +219,17 @@
library.MutatedProperties.VariantIsSource = true
}
-func (library *libraryDecorator) autoDep(ctx BaseModuleContext) autoDep {
+func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
if library.preferRlib() {
return rlibAutoDep
} else if library.rlib() || library.static() {
return rlibAutoDep
} else if library.dylib() || library.shared() {
return dylibAutoDep
+ } else if ctx.BazelConversionMode() {
+ // In Bazel conversion mode, we are currently ignoring the deptag, so we just need to supply a
+ // compatible tag in order to add the dependency.
+ return rlibAutoDep
} else {
panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName()))
}
@@ -439,6 +443,7 @@
}
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
if library.dylib() {
@@ -478,7 +483,6 @@
if library.rlib() || library.dylib() {
library.flagExporter.exportLinkDirs(deps.linkDirs...)
- library.flagExporter.exportDepFlags(deps.depFlags...)
library.flagExporter.exportLinkObjects(deps.linkObjects...)
}
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index f753e7f..115045a 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -79,6 +79,6 @@
return stem + String(procMacro.baseCompiler.Properties.Suffix)
}
-func (procMacro *procMacroDecorator) autoDep(ctx BaseModuleContext) autoDep {
+func (procMacro *procMacroDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
return rlibAutoDep
}
diff --git a/rust/rust.go b/rust/rust.go
index 2ef9daf..e1af776 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -280,10 +280,15 @@
SharedLibDeps android.Paths
StaticLibs android.Paths
ProcMacros RustLibraries
- linkDirs []string
- depFlags []string
- linkObjects []string
- //ReexportedDeps android.Paths
+
+ // depFlags and depLinkFlags are rustc and linker (clang) flags.
+ depFlags []string
+ depLinkFlags []string
+
+ // linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker.
+ // Both of these are exported and propagate to dependencies.
+ linkDirs []string
+ linkObjects []string
// Used by bindgen modules which call clang
depClangFlags []string
@@ -328,12 +333,10 @@
type exportedFlagsProducer interface {
exportLinkDirs(...string)
- exportDepFlags(...string)
exportLinkObjects(...string)
}
type flagExporter struct {
- depFlags []string
linkDirs []string
linkObjects []string
}
@@ -342,17 +345,12 @@
flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
}
-func (flagExporter *flagExporter) exportDepFlags(flags ...string) {
- flagExporter.depFlags = android.FirstUniqueStrings(append(flagExporter.depFlags, flags...))
-}
-
func (flagExporter *flagExporter) exportLinkObjects(flags ...string) {
flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...))
}
func (flagExporter *flagExporter) setProvider(ctx ModuleContext) {
ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
- Flags: flagExporter.depFlags,
LinkDirs: flagExporter.linkDirs,
LinkObjects: flagExporter.linkObjects,
})
@@ -785,7 +783,7 @@
)
type autoDeppable interface {
- autoDep(ctx BaseModuleContext) autoDep
+ autoDep(ctx android.BottomUpMutatorContext) autoDep
}
func (mod *Module) begin(ctx BaseModuleContext) {
@@ -898,8 +896,21 @@
exportDep := false
switch {
case cc.IsStaticDepTag(depTag):
- depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
+ // Link cc static libraries using "-lstatic" so rustc can reason about how to handle these
+ // (for example, bundling them into rlibs).
+ //
+ // rustc does not support linking libraries with the "-l" flag unless they are prefixed by "lib".
+ // If we need to link a library that isn't prefixed by "lib", we'll just link to it directly through
+ // linkObjects; such a library may need to be redeclared by static dependents.
+ if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
+ depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName)
+ }
+
+ // Add this to linkObjects to pass the library directly to the linker as well. This propagates
+ // to dependencies to avoid having to redeclare static libraries for dependents of the dylib variant.
depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
+ depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
+
exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
@@ -1213,6 +1224,16 @@
return false
}
+// If a library file has a "lib" prefix, extract the library name without the prefix.
+func libNameFromFilePath(filepath android.Path) (string, bool) {
+ libName := strings.TrimSuffix(filepath.Base(), filepath.Ext())
+ if strings.HasPrefix(libName, "lib") {
+ libName = libName[3:]
+ return libName, true
+ }
+ return "", false
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
diff --git a/rust/rust_test.go b/rust/rust_test.go
index abc9af9..a32c6a7 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -230,6 +230,7 @@
}
`)
module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
+ rustc := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc")
// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
if !android.InList("libdylib", module.Properties.AndroidMkDylibs) {
@@ -251,6 +252,11 @@
if !android.InList("libstatic", module.Properties.AndroidMkStaticLibs) {
t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)")
}
+
+ if !strings.Contains(rustc.Args["rustcFlags"], "-lstatic=static") {
+ t.Errorf("-lstatic flag not being passed to rustc for static library")
+ }
+
}
func TestSourceProviderDeps(t *testing.T) {
diff --git a/rust/test.go b/rust/test.go
index 92b4860..3fa5f95 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -141,7 +141,7 @@
return flags
}
-func (test *testDecorator) autoDep(ctx BaseModuleContext) autoDep {
+func (test *testDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
return rlibAutoDep
}
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 18749b5..66e493b 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -154,9 +154,6 @@
}
func (s *ShBinary) DepsMutator(ctx android.BottomUpMutatorContext) {
- if s.properties.Src == nil {
- ctx.PropertyErrorf("src", "missing prebuilt source file")
- }
}
func (s *ShBinary) OutputFile() android.OutputPath {
@@ -203,6 +200,10 @@
}
func (s *ShBinary) generateAndroidBuildActions(ctx android.ModuleContext) {
+ if s.properties.Src == nil {
+ ctx.PropertyErrorf("src", "missing prebuilt source file")
+ }
+
s.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(s.properties.Src))
filename := proptools.String(s.properties.Filename)
filenameFromSrc := proptools.Bool(s.properties.Filename_from_src)
@@ -275,7 +276,7 @@
ctx.AddFarVariationDependencies(ctx.Target().Variations(), shTestDataBinsTag, s.testProperties.Data_bins...)
ctx.AddFarVariationDependencies(append(ctx.Target().Variations(), sharedLibVariations...),
shTestDataLibsTag, s.testProperties.Data_libs...)
- if ctx.Target().Os.Class == android.Host && len(ctx.Config().Targets[android.Android]) > 0 {
+ if (ctx.Target().Os.Class == android.Host || ctx.BazelConversionMode()) && len(ctx.Config().Targets[android.Android]) > 0 {
deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations()
ctx.AddFarVariationDependencies(deviceVariations, shTestDataDeviceBinsTag, s.testProperties.Data_device_bins...)
ctx.AddFarVariationDependencies(append(deviceVariations, sharedLibVariations...),