Merge changes from topic "aidl_interface_bp2build"

* changes:
  add bp2build unit tests for aidl_interface
  AIDL source generation accounts for Bazel paths
  convert .aidl srcs for java_library
  add Partition method to LabelListAttribute
This commit is contained in:
Sam Delmerico
2022-08-26 20:07:58 +00:00
committed by Gerrit Code Review
17 changed files with 770 additions and 50 deletions

View File

@@ -157,6 +157,7 @@ var (
"frameworks/av/media/liberror": Bp2BuildDefaultTrueRecursively,
"frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively,
"frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue,
"frameworks/base/services/tests/servicestests/aidl": Bp2BuildDefaultTrue,
"frameworks/base/startop/apps/test": Bp2BuildDefaultTrue,
"frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively,
@@ -408,6 +409,7 @@ var (
"linker_config",
"java_import",
"java_import_host",
"aidl_interface_headers",
}
Bp2buildModuleDoNotConvertList = []string{

View File

@@ -16,6 +16,7 @@ package android
import (
"path/filepath"
"regexp"
"strings"
"android/soong/bazel"
@@ -37,6 +38,34 @@ func IsFilegroup(ctx bazel.OtherModuleContext, m blueprint.Module) bool {
return ctx.OtherModuleType(m) == "filegroup"
}
var (
// ignoring case, checks for proto or protos as an independent word in the name, whether at the
// beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match
filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)")
filegroupLikelyAidlPattern = regexp.MustCompile("(?i)(^|[^a-z])aidl([^a-z]|$)")
ProtoSrcLabelPartition = bazel.LabelPartition{
Extensions: []string{".proto"},
LabelMapper: isFilegroupWithPattern(filegroupLikelyProtoPattern),
}
AidlSrcLabelPartition = bazel.LabelPartition{
Extensions: []string{".aidl"},
LabelMapper: isFilegroupWithPattern(filegroupLikelyAidlPattern),
}
)
func isFilegroupWithPattern(pattern *regexp.Regexp) bazel.LabelMapper {
return func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
m, exists := ctx.ModuleFromName(label.OriginalModuleName)
labelStr := label.Label
if !exists || !IsFilegroup(ctx, m) {
return labelStr, false
}
likelyMatched := pattern.MatchString(label.OriginalModuleName)
return labelStr, likelyMatched
}
}
// https://docs.bazel.build/versions/master/be/general.html#filegroup
type bazelFilegroupAttributes struct {
Srcs bazel.LabelListAttribute
@@ -232,3 +261,16 @@ func (fg *fileGroup) GetAidlLibraryLabel(ctx BazelConversionPathContext) string
return fg.GetBazelLabel(ctx, fg)
}
}
// Given a name in srcs prop, check to see if the name references a filegroup
// and the filegroup is converted to aidl_library
func IsConvertedToAidlLibrary(ctx BazelConversionPathContext, name string) bool {
if module, ok := ctx.ModuleFromName(name); ok {
if IsFilegroup(ctx, module) {
if fg, ok := module.(Bp2buildAidlLibrary); ok {
return fg.ShouldConvertToAidlLibrary(ctx)
}
}
}
return false
}

View File

@@ -642,6 +642,20 @@ type TestResult struct {
NinjaDeps []string
}
type TestPathContext struct {
*TestResult
}
var _ PathContext = &TestPathContext{}
func (t *TestPathContext) Config() Config {
return t.TestResult.Config
}
func (t *TestPathContext) AddNinjaFileDeps(deps ...string) {
panic("unimplemented")
}
func createFixture(t *testing.T, buildDir string, preparers []*simpleFixturePreparer) Fixture {
config := TestConfig(buildDir, nil, "", nil)
ctx := NewTestContext(config)

View File

@@ -1978,6 +1978,18 @@ func PathForTesting(paths ...string) Path {
return testPath{basePath{path: p, rel: p}}
}
func PathForTestingWithRel(path, rel string) Path {
p, err := validateSafePath(path, rel)
if err != nil {
panic(err)
}
r, err := validatePath(rel)
if err != nil {
panic(err)
}
return testPath{basePath{path: p, rel: r}}
}
// PathsForTesting returns a Path constructed from each element in strs. It should only be used from within tests.
func PathsForTesting(strs ...string) Paths {
p := make(Paths, len(strs))

View File

@@ -16,7 +16,6 @@ package android
import (
"android/soong/bazel"
"regexp"
"strings"
"github.com/google/blueprint"
@@ -27,14 +26,6 @@ const (
canonicalPathFromRootDefault = true
)
var (
// ignoring case, checks for proto or protos as an independent word in the name, whether at the
// beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match
filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)")
ProtoSrcLabelPartition = bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup}
)
// TODO(ccross): protos are often used to communicate between multiple modules. If the only
// way to convert a proto to source is to reference it as a source file, and external modules cannot
// reference source files in other modules, then every module that owns a proto file will need to
@@ -213,13 +204,3 @@ func Bp2buildProtoProperties(ctx Bp2buildMutatorContext, m *ModuleBase, srcs baz
return info, true
}
func isProtoFilegroup(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
m, exists := ctx.ModuleFromName(label.OriginalModuleName)
labelStr := label.Label
if !exists || !IsFilegroup(ctx, m) {
return labelStr, false
}
likelyProtos := filegroupLikelyProtoPattern.MatchString(label.OriginalModuleName)
return labelStr, likelyProtos
}

View File

@@ -119,7 +119,7 @@ func (ll *LabelList) uniqueParentDirectories() []string {
return dirs
}
// Add inserts the label Label at the end of the LabelList.
// Add inserts the label Label at the end of the LabelList.Includes.
func (ll *LabelList) Add(label *Label) {
if label == nil {
return
@@ -127,6 +127,14 @@ func (ll *LabelList) Add(label *Label) {
ll.Includes = append(ll.Includes, *label)
}
// AddExclude inserts the label Label at the end of the LabelList.Excludes.
func (ll *LabelList) AddExclude(label *Label) {
if label == nil {
return
}
ll.Excludes = append(ll.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 {
@@ -137,6 +145,30 @@ func (ll *LabelList) Append(other LabelList) {
}
}
// Partition splits a LabelList into two LabelLists depending on the return value
// of the predicate.
// This function preserves the Includes and Excludes, but it does not provide
// that information to the partition function.
func (ll *LabelList) Partition(predicate func(label Label) bool) (LabelList, LabelList) {
predicated := LabelList{}
unpredicated := LabelList{}
for _, include := range ll.Includes {
if predicate(include) {
predicated.Add(&include)
} else {
unpredicated.Add(&include)
}
}
for _, exclude := range ll.Excludes {
if predicate(exclude) {
predicated.AddExclude(&exclude)
} else {
unpredicated.AddExclude(&exclude)
}
}
return predicated, unpredicated
}
// UniqueSortedBazelLabels takes a []Label and deduplicates the labels, and returns
// the slice in a sorted order.
func UniqueSortedBazelLabels(originalLabels []Label) []Label {
@@ -822,6 +854,29 @@ func (lla *LabelListAttribute) ResolveExcludes() {
}
}
// Partition splits a LabelListAttribute into two LabelListAttributes depending
// on the return value of the predicate.
// This function preserves the Includes and Excludes, but it does not provide
// that information to the partition function.
func (lla LabelListAttribute) Partition(predicate func(label Label) bool) (LabelListAttribute, LabelListAttribute) {
predicated := LabelListAttribute{}
unpredicated := LabelListAttribute{}
valuePartitionTrue, valuePartitionFalse := lla.Value.Partition(predicate)
predicated.SetValue(valuePartitionTrue)
unpredicated.SetValue(valuePartitionFalse)
for axis, selectValueLabelLists := range lla.ConfigurableValues {
for config, labelList := range selectValueLabelLists {
configPredicated, configUnpredicated := labelList.Partition(predicate)
predicated.SetSelectValue(axis, config, configPredicated)
unpredicated.SetSelectValue(axis, config, configUnpredicated)
}
}
return predicated, unpredicated
}
// OtherModuleContext is a limited context that has methods with information about other modules.
type OtherModuleContext interface {
ModuleFromName(name string) (blueprint.Module, bool)

View File

@@ -310,6 +310,134 @@ func TestResolveExcludes(t *testing.T) {
}
}
func TestLabelListAttributePartition(t *testing.T) {
testCases := []struct {
name string
input LabelListAttribute
predicated LabelListAttribute
unpredicated LabelListAttribute
predicate func(label Label) bool
}{
{
name: "move all to predicated partition",
input: MakeLabelListAttribute(makeLabelList(
[]string{"keep1", "throw1", "keep2", "throw2"},
[]string{"keep1", "throw1", "keep2", "throw2"},
)),
predicated: MakeLabelListAttribute(makeLabelList(
[]string{"keep1", "throw1", "keep2", "throw2"},
[]string{"keep1", "throw1", "keep2", "throw2"},
)),
unpredicated: LabelListAttribute{},
predicate: func(label Label) bool {
return true
},
},
{
name: "move all to unpredicated partition",
input: MakeLabelListAttribute(makeLabelList(
[]string{"keep1", "throw1", "keep2", "throw2"},
[]string{"keep1", "throw1", "keep2", "throw2"},
)),
predicated: LabelListAttribute{},
unpredicated: MakeLabelListAttribute(makeLabelList(
[]string{"keep1", "throw1", "keep2", "throw2"},
[]string{"keep1", "throw1", "keep2", "throw2"},
)),
predicate: func(label Label) bool {
return false
},
},
{
name: "partition includes and excludes",
input: MakeLabelListAttribute(makeLabelList(
[]string{"keep1", "throw1", "keep2", "throw2"},
[]string{"keep1", "throw1", "keep2", "throw2"},
)),
predicated: MakeLabelListAttribute(makeLabelList(
[]string{"keep1", "keep2"},
[]string{"keep1", "keep2"},
)),
unpredicated: MakeLabelListAttribute(makeLabelList(
[]string{"throw1", "throw2"},
[]string{"throw1", "throw2"},
)),
predicate: func(label Label) bool {
return strings.HasPrefix(label.Label, "keep")
},
},
{
name: "partition excludes only",
input: MakeLabelListAttribute(makeLabelList(
[]string{},
[]string{"keep1", "throw1", "keep2", "throw2"},
)),
predicated: MakeLabelListAttribute(makeLabelList(
[]string{},
[]string{"keep1", "keep2"},
)),
unpredicated: MakeLabelListAttribute(makeLabelList(
[]string{},
[]string{"throw1", "throw2"},
)),
predicate: func(label Label) bool {
return strings.HasPrefix(label.Label, "keep")
},
},
{
name: "partition includes only",
input: MakeLabelListAttribute(makeLabelList(
[]string{"keep1", "throw1", "keep2", "throw2"},
[]string{},
)),
predicated: MakeLabelListAttribute(makeLabelList(
[]string{"keep1", "keep2"},
[]string{},
)),
unpredicated: MakeLabelListAttribute(makeLabelList(
[]string{"throw1", "throw2"},
[]string{},
)),
predicate: func(label Label) bool {
return strings.HasPrefix(label.Label, "keep")
},
},
{
name: "empty partition",
input: MakeLabelListAttribute(makeLabelList([]string{}, []string{})),
predicated: LabelListAttribute{},
unpredicated: LabelListAttribute{},
predicate: func(label Label) bool {
return true
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
predicated, unpredicated := tc.input.Partition(tc.predicate)
if !predicated.Value.Equals(tc.predicated.Value) {
t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
}
for axis, configs := range predicated.ConfigurableValues {
tcConfigs, ok := tc.predicated.ConfigurableValues[axis]
if !ok || !reflect.DeepEqual(configs, tcConfigs) {
t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
}
}
if !unpredicated.Value.Equals(tc.unpredicated.Value) {
t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
}
for axis, configs := range unpredicated.ConfigurableValues {
tcConfigs, ok := tc.unpredicated.ConfigurableValues[axis]
if !ok || !reflect.DeepEqual(configs, tcConfigs) {
t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
}
}
})
}
}
// labelAddSuffixForTypeMapper returns a LabelMapper that adds suffix to label name for modules of
// typ
func labelAddSuffixForTypeMapper(suffix, typ string) LabelMapper {

View File

@@ -18,6 +18,7 @@ bootstrap_go_package {
"testing.go",
],
deps: [
"aidl-soong-rules",
"soong-android",
"soong-android-allowlists",
"soong-android-soongconfig",
@@ -36,6 +37,7 @@ bootstrap_go_package {
],
testSrcs: [
"aar_conversion_test.go",
"aidl_interface_conversion_test.go",
"android_app_certificate_conversion_test.go",
"android_app_conversion_test.go",
"apex_conversion_test.go",

View File

@@ -0,0 +1,249 @@
package bp2build
import (
"android/soong/aidl"
"android/soong/android"
"testing"
)
func runAidlInterfaceTestCase(t *testing.T, tc Bp2buildTestCase) {
t.Helper()
RunBp2BuildTestCase(
t,
func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("aidl_interface", aidl.AidlInterfaceFactory)
ctx.RegisterModuleType("aidl_interface_headers", aidl.AidlInterfaceHeadersFactory)
},
tc,
)
}
func TestAidlInterfaceHeaders(t *testing.T) {
runAidlInterfaceTestCase(t, Bp2buildTestCase{
Description: `aidl_interface_headers`,
Blueprint: `
aidl_interface_headers {
name: "aidl-interface-headers",
include_dir: "src",
srcs: [
"src/A.aidl",
],
}
`,
ExpectedBazelTargets: []string{
MakeBazelTargetNoRestrictions("aidl_library", "aidl-interface-headers", AttrNameToString{
"strip_import_prefix": `"src"`,
"hdrs": `["src/A.aidl"]`,
}),
},
})
}
func TestAidlInterface(t *testing.T) {
runAidlInterfaceTestCase(t, Bp2buildTestCase{
Description: `aidl_interface with single "latest" aidl_interface import`,
Blueprint: `
aidl_interface_headers {
name: "aidl-interface-headers",
}
aidl_interface {
name: "aidl-interface-import",
versions: [
"1",
"2",
],
}
aidl_interface {
name: "aidl-interface1",
flags: ["--flag1"],
imports: [
"aidl-interface-import-V1",
],
headers: [
"aidl-interface-headers",
],
versions: [
"1",
"2",
"3",
],
}`,
ExpectedBazelTargets: []string{
MakeBazelTargetNoRestrictions("aidl_library", "aidl-interface-headers", AttrNameToString{}),
MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface-import", AttrNameToString{
"backends": `[
"cpp",
"java",
"ndk",
]`,
"versions": `[
"1",
"2",
]`,
}),
MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
"backends": `[
"cpp",
"java",
"ndk",
]`,
"deps": `[
":aidl-interface-import-V1",
":aidl-interface-headers",
]`,
"flags": `["--flag1"]`,
"versions": `[
"1",
"2",
"3",
]`,
}),
},
})
}
func TestAidlInterfaceWithNoProperties(t *testing.T) {
runAidlInterfaceTestCase(t, Bp2buildTestCase{
Description: `aidl_interface no properties set`,
Blueprint: `
aidl_interface {
name: "aidl-interface1",
}
`,
ExpectedBazelTargets: []string{
MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
"backends": `[
"cpp",
"java",
"ndk",
]`,
}),
},
})
}
func TestAidlInterfaceWithDisabledBackends(t *testing.T) {
runAidlInterfaceTestCase(t, Bp2buildTestCase{
Description: `aidl_interface with some backends disabled`,
Blueprint: `
aidl_interface {
name: "aidl-interface1",
backend: {
ndk: {
enabled: false,
},
cpp: {
enabled: false,
},
},
}
`,
ExpectedBazelTargets: []string{
MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
"backends": `["java"]`,
}),
},
})
}
func TestAidlInterfaceWithLatestImport(t *testing.T) {
runAidlInterfaceTestCase(t, Bp2buildTestCase{
Description: `aidl_interface with single "latest" aidl_interface import`,
Blueprint: `
aidl_interface {
name: "aidl-interface-import",
versions: [
"1",
"2",
],
}
aidl_interface {
name: "aidl-interface1",
imports: [
"aidl-interface-import",
],
versions: [
"1",
"2",
"3",
],
}`,
ExpectedBazelTargets: []string{
MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface-import", AttrNameToString{
"backends": `[
"cpp",
"java",
"ndk",
]`,
"versions": `[
"1",
"2",
]`,
}),
MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
"backends": `[
"cpp",
"java",
"ndk",
]`,
"deps": `[":aidl-interface-import-latest"]`,
"versions": `[
"1",
"2",
"3",
]`,
}),
},
})
}
func TestAidlInterfaceWithVersionedImport(t *testing.T) {
runAidlInterfaceTestCase(t, Bp2buildTestCase{
Description: `aidl_interface with single versioned aidl_interface import`,
Blueprint: `
aidl_interface {
name: "aidl-interface-import",
versions: [
"1",
"2",
],
}
aidl_interface {
name: "aidl-interface1",
imports: [
"aidl-interface-import-V2",
],
versions: [
"1",
"2",
"3",
],
}`,
ExpectedBazelTargets: []string{
MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface-import", AttrNameToString{
"backends": `[
"cpp",
"java",
"ndk",
]`,
"versions": `[
"1",
"2",
]`,
}),
MakeBazelTargetNoRestrictions("aidl_interface", "aidl-interface1", AttrNameToString{
"backends": `[
"cpp",
"java",
"ndk",
]`,
"deps": `[":aidl-interface-import-V2"]`,
"versions": `[
"1",
"2",
"3",
]`,
}),
},
})
}

View File

@@ -372,3 +372,132 @@ func TestJavaLibraryResourcesFailsWithMultipleDirs(t *testing.T) {
ExpectedBazelTargets: []string{},
})
}
func TestJavaLibraryAidl(t *testing.T) {
runJavaLibraryTestCase(t, Bp2buildTestCase{
Description: "Java library - aidl creates separate dependency",
ModuleTypeUnderTest: "java_library",
ModuleTypeUnderTestFactory: java.LibraryFactory,
Blueprint: `java_library {
name: "example_lib",
srcs: [
"a.java",
"b.java",
"a.aidl",
"b.aidl",
],
bazel_module: { bp2build_available: true },
}`,
ExpectedBazelTargets: []string{
makeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{
"srcs": `[
"a.aidl",
"b.aidl",
]`,
}),
makeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
"deps": `[":example_lib_aidl_library"]`,
}),
makeBazelTarget("java_library", "example_lib", AttrNameToString{
"deps": `[":example_lib_java_aidl_library"]`,
"exports": `[":example_lib_java_aidl_library"]`,
"srcs": `[
"a.java",
"b.java",
]`,
}),
}})
}
func TestJavaLibraryAidlSrcsNoFileGroup(t *testing.T) {
runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{
Description: "Java library - aidl filegroup is parsed",
ModuleTypeUnderTest: "java_library",
ModuleTypeUnderTestFactory: java.LibraryFactory,
Blueprint: `
java_library {
name: "example_lib",
srcs: [
"a.java",
"b.aidl",
],
bazel_module: { bp2build_available: true },
}`,
ExpectedBazelTargets: []string{
makeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{
"srcs": `["b.aidl"]`,
}),
makeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
"deps": `[":example_lib_aidl_library"]`,
}),
makeBazelTarget("java_library", "example_lib", AttrNameToString{
"deps": `[":example_lib_java_aidl_library"]`,
"exports": `[":example_lib_java_aidl_library"]`,
"srcs": `["a.java"]`,
}),
},
}, func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
})
}
func TestJavaLibraryAidlFilegroup(t *testing.T) {
runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{
Description: "Java library - aidl filegroup is parsed",
ModuleTypeUnderTest: "java_library",
ModuleTypeUnderTestFactory: java.LibraryFactory,
Blueprint: `
filegroup {
name: "random_other_files",
srcs: [
"a.java",
"b.java",
],
}
filegroup {
name: "aidl_files",
srcs: [
"a.aidl",
"b.aidl",
],
}
java_library {
name: "example_lib",
srcs: [
"a.java",
"b.java",
":aidl_files",
":random_other_files",
],
bazel_module: { bp2build_available: true },
}`,
ExpectedBazelTargets: []string{
MakeBazelTargetNoRestrictions("aidl_library", "aidl_files", AttrNameToString{
"srcs": `[
"a.aidl",
"b.aidl",
]`,
}),
makeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
"deps": `[":aidl_files"]`,
}),
makeBazelTarget("java_library", "example_lib", AttrNameToString{
"deps": `[":example_lib_java_aidl_library"]`,
"exports": `[":example_lib_java_aidl_library"]`,
"srcs": `[
"a.java",
"b.java",
":random_other_files",
]`,
}),
MakeBazelTargetNoRestrictions("filegroup", "random_other_files", AttrNameToString{
"srcs": `[
"a.java",
"b.java",
]`,
}),
},
}, func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
})
}

10
go.mod
View File

@@ -1,13 +1,17 @@
module android/soong
require google.golang.org/protobuf v0.0.0
require github.com/google/blueprint v0.0.0
require (
google.golang.org/protobuf v0.0.0
github.com/google/blueprint v0.0.0
android/soong/aidl v0.0.0
)
replace google.golang.org/protobuf v0.0.0 => ../../external/golang-protobuf
replace github.com/google/blueprint v0.0.0 => ../blueprint
replace android/soong/aidl v0.0.0 => ../../system/tools/aidl/build
// Indirect deps from golang-protobuf
exclude github.com/golang/protobuf v1.5.0

View File

@@ -820,7 +820,7 @@ func (j *Module) individualAidlFlags(ctx android.ModuleContext, aidlFile android
}
func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
aidlIncludeDirs android.Paths) (string, android.Paths) {
aidlIncludeDirs android.Paths, aidlSrcs android.Paths) (string, android.Paths) {
aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs)
aidlIncludes = append(aidlIncludes,
@@ -830,6 +830,7 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt
var flags []string
var deps android.Paths
var includeDirs android.Paths
flags = append(flags, j.deviceProperties.Aidl.Flags...)
@@ -837,21 +838,24 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt
flags = append(flags, "-p"+aidlPreprocess.String())
deps = append(deps, aidlPreprocess.Path())
} else if len(aidlIncludeDirs) > 0 {
flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
includeDirs = append(includeDirs, aidlIncludeDirs...)
}
if len(j.exportAidlIncludeDirs) > 0 {
flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
includeDirs = append(includeDirs, j.exportAidlIncludeDirs...)
}
if len(aidlIncludes) > 0 {
flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
includeDirs = append(includeDirs, aidlIncludes...)
}
flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
includeDirs = append(includeDirs, android.PathForModuleSrc(ctx))
if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
flags = append(flags, "-I"+src.String())
includeDirs = append(includeDirs, src.Path())
}
flags = append(flags, android.JoinWithPrefix(includeDirs.Strings(), "-I"))
// add flags for dirs containing AIDL srcs that haven't been specified yet
flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs))
if Bool(j.deviceProperties.Aidl.Generate_traces) {
flags = append(flags, "-t")
@@ -935,9 +939,6 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
// systemModules
flags.systemModules = deps.systemModules
// aidl flags.
flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
return flags
}
@@ -1046,6 +1047,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files")
}
aidlSrcs := srcFiles.FilterByExt(".aidl")
flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs, aidlSrcs)
nonGeneratedSrcJars := srcFiles.FilterByExt(".srcjar")
srcFiles = j.genSources(ctx, srcFiles, flags)

View File

@@ -314,7 +314,7 @@ func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
outSrcFiles := make(android.Paths, 0, len(srcFiles))
var aidlSrcs android.Paths
aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
aidlIncludeFlags := genAidlIncludeFlags(ctx, srcFiles, android.Paths{})
for _, srcFile := range srcFiles {
switch srcFile.Ext() {

View File

@@ -15,6 +15,7 @@
package java
import (
"path/filepath"
"strconv"
"strings"
@@ -116,12 +117,31 @@ func genLogtags(ctx android.ModuleContext, logtagsFile android.Path) android.Pat
return javaFile
}
func genAidlIncludeFlags(srcFiles android.Paths) string {
// genAidlIncludeFlags returns additional include flags based on the relative path
// of each .aidl file passed in srcFiles. excludeDirs is a list of paths relative to
// the Android checkout root that should not be included in the returned flags.
func genAidlIncludeFlags(ctx android.PathContext, srcFiles android.Paths, excludeDirs android.Paths) string {
var baseDirs []string
excludeDirsStrings := excludeDirs.Strings()
for _, srcFile := range srcFiles {
if srcFile.Ext() == ".aidl" {
baseDir := strings.TrimSuffix(srcFile.String(), srcFile.Rel())
if baseDir != "" && !android.InList(baseDir, baseDirs) {
baseDir = filepath.Clean(baseDir)
baseDirSeen := android.InList(baseDir, baseDirs) || android.InList(baseDir, excludeDirsStrings)
// For go/bp2build mixed builds, a file may be listed under a
// directory in the Bazel output tree that is symlinked to a
// directory under the android source tree. We should only
// include one copy of this directory so that the AIDL tool
// doesn't find multiple definitions of the same AIDL class.
// This code comes into effect when filegroups are used in mixed builds.
bazelPathPrefix := android.PathForBazelOut(ctx, "").String()
bazelBaseDir, err := filepath.Rel(bazelPathPrefix, baseDir)
bazelBaseDirSeen := err == nil &&
android.InList(bazelBaseDir, baseDirs) ||
android.InList(bazelBaseDir, excludeDirsStrings)
if baseDir != "" && !baseDirSeen && !bazelBaseDirSeen {
baseDirs = append(baseDirs, baseDir)
}
}
@@ -136,8 +156,6 @@ func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths,
var protoSrcs android.Paths
var aidlSrcs android.Paths
aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
for _, srcFile := range srcFiles {
switch srcFile.Ext() {
case ".aidl":
@@ -168,7 +186,7 @@ func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths,
individualFlags[aidlSrc.String()] = flags
}
}
srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, individualFlags, flags.aidlDeps)
srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags, individualFlags, flags.aidlDeps)
outSrcFiles = append(outSrcFiles, srcJarFiles...)
}

View File

@@ -2259,16 +2259,27 @@ type javaDependencyLabels struct {
StaticDeps bazel.LabelListAttribute
}
// convertLibraryAttrsBp2Build converts a few shared attributes from java_* modules
// and also separates dependencies into dynamic dependencies and static dependencies.
// Each corresponding Bazel target type, can have a different method for handling
// dynamic vs. static dependencies, and so these are returned to the calling function.
type eventLogTagsAttributes struct {
Srcs bazel.LabelListAttribute
}
type aidlLibraryAttributes struct {
Srcs bazel.LabelListAttribute
}
type javaAidlLibraryAttributes struct {
Deps bazel.LabelListAttribute
}
// convertLibraryAttrsBp2Build converts a few shared attributes from java_* modules
// and also separates dependencies into dynamic dependencies and static dependencies.
// Each corresponding Bazel target type, can have a different method for handling
// dynamic vs. static dependencies, and so these are returned to the calling function.
func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *javaDependencyLabels) {
var srcs bazel.LabelListAttribute
var deps bazel.LabelList
var staticDeps bazel.LabelList
archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{})
for axis, configToProps := range archVariantProps {
for config, _props := range configToProps {
@@ -2282,18 +2293,18 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
javaSrcPartition := "java"
protoSrcPartition := "proto"
logtagSrcPartition := "logtag"
aidlSrcPartition := "aidl"
srcPartitions := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{
javaSrcPartition: bazel.LabelPartition{Extensions: []string{".java"}, Keep_remainder: true},
logtagSrcPartition: bazel.LabelPartition{Extensions: []string{".logtags", ".logtag"}},
protoSrcPartition: android.ProtoSrcLabelPartition,
aidlSrcPartition: android.AidlSrcLabelPartition,
})
javaSrcs := srcPartitions[javaSrcPartition]
var logtagsSrcs bazel.LabelList
if !srcPartitions[logtagSrcPartition].IsEmpty() {
logtagsLibName := m.Name() + "_logtags"
logtagsSrcs = bazel.MakeLabelList([]bazel.Label{{Label: ":" + logtagsLibName}})
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{
Rule_class: "event_log_tags",
@@ -2304,8 +2315,45 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
Srcs: srcPartitions[logtagSrcPartition],
},
)
logtagsSrcs := bazel.MakeLabelList([]bazel.Label{{Label: ":" + logtagsLibName}})
javaSrcs.Append(bazel.MakeLabelListAttribute(logtagsSrcs))
}
if !srcPartitions[aidlSrcPartition].IsEmpty() {
aidlLibs, aidlSrcs := srcPartitions[aidlSrcPartition].Partition(func(src bazel.Label) bool {
return android.IsConvertedToAidlLibrary(ctx, src.OriginalModuleName)
})
if !aidlSrcs.IsEmpty() {
aidlLibName := m.Name() + "_aidl_library"
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{
Rule_class: "aidl_library",
Bzl_load_location: "//build/bazel/rules/aidl:library.bzl",
},
android.CommonAttributes{Name: aidlLibName},
&aidlLibraryAttributes{
Srcs: aidlSrcs,
},
)
aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}})
}
javaAidlLibName := m.Name() + "_java_aidl_library"
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{
Rule_class: "java_aidl_library",
Bzl_load_location: "//build/bazel/rules/java:aidl_library.bzl",
},
android.CommonAttributes{Name: javaAidlLibName},
&javaAidlLibraryAttributes{
Deps: aidlLibs,
},
)
staticDeps.Add(&bazel.Label{Label: ":" + javaAidlLibName})
}
javaSrcs.Append(bazel.MakeLabelListAttribute(logtagsSrcs))
var javacopts []string
if m.properties.Javacflags != nil {
@@ -2331,14 +2379,10 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
Javacopts: bazel.MakeStringListAttribute(javacopts),
}
depLabels := &javaDependencyLabels{}
var deps bazel.LabelList
if m.properties.Libs != nil {
deps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Libs))))
}
var staticDeps bazel.LabelList
if m.properties.Static_libs != nil {
staticDeps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Static_libs))))
}
@@ -2352,6 +2396,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext)
// and so this should be a static dependency.
staticDeps.Add(protoDepLabel)
depLabels := &javaDependencyLabels{}
depLabels.Deps = bazel.MakeLabelListAttribute(deps)
depLabels.StaticDeps = bazel.MakeLabelListAttribute(staticDeps)
@@ -2376,7 +2421,7 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) {
// TODO(b/220869005) remove forced dependency on current public android.jar
deps.Add(bazel.MakeLabelAttribute("//prebuilts/sdk:public_current_android_sdk_java_import"))
}
} else if !depLabels.Deps.IsEmpty() {
} else if !deps.IsEmpty() {
ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
}

View File

@@ -1747,3 +1747,37 @@ func TestImportMixedBuild(t *testing.T) {
android.AssertDeepEquals(t, "Implementation/Resources JARs are produced", expectedOutputFiles, android.NormalizePathsForTesting(javaInfo.ImplementationAndResourcesJars))
android.AssertDeepEquals(t, "Implementation JARs are produced", expectedOutputFiles, android.NormalizePathsForTesting(javaInfo.ImplementationJars))
}
func TestGenAidlIncludeFlagsForMixedBuilds(t *testing.T) {
bazelOutputBaseDir := filepath.Join("out", "bazel")
result := android.GroupFixturePreparers(
PrepareForIntegrationTestWithJava,
android.FixtureModifyConfig(func(config android.Config) {
config.BazelContext = android.MockBazelContext{
OutputBaseDir: bazelOutputBaseDir,
}
}),
).RunTest(t)
ctx := &android.TestPathContext{TestResult: result}
srcDirectory := filepath.Join("frameworks", "base")
srcDirectoryAlreadyIncluded := filepath.Join("frameworks", "base", "core", "java")
bazelSrcDirectory := android.PathForBazelOut(ctx, srcDirectory)
bazelSrcDirectoryAlreadyIncluded := android.PathForBazelOut(ctx, srcDirectoryAlreadyIncluded)
srcs := android.Paths{
android.PathForTestingWithRel(bazelSrcDirectory.String(), "bazelAidl.aidl"),
android.PathForTestingWithRel(bazelSrcDirectory.String(), "bazelAidl2.aidl"),
android.PathForTestingWithRel(bazelSrcDirectoryAlreadyIncluded.String(), "bazelAidlExclude.aidl"),
android.PathForTestingWithRel(bazelSrcDirectoryAlreadyIncluded.String(), "bazelAidl2Exclude.aidl"),
}
dirsAlreadyIncluded := android.Paths{
android.PathForTesting(srcDirectoryAlreadyIncluded),
}
expectedFlags := " -Iout/bazel/execroot/__main__/frameworks/base"
flags := genAidlIncludeFlags(ctx, srcs, dirsAlreadyIncluded)
if flags != expectedFlags {
t.Errorf("expected flags to be %q; was %q", expectedFlags, flags)
}
}

View File

@@ -93,6 +93,7 @@ function create_mock_soong {
symlink_directory external/go-cmp
symlink_directory external/golang-protobuf
symlink_directory external/starlark-go
symlink_directory system/tools/aidl
touch "$MOCK_TOP/Android.bp"
}