diff options
| -rw-r--r-- | android/paths.go | 19 | ||||
| -rw-r--r-- | bp2build/Android.bp | 1 | ||||
| -rw-r--r-- | bp2build/build_conversion_test.go | 39 | ||||
| -rw-r--r-- | bp2build/sh_conversion_test.go | 134 | ||||
| -rw-r--r-- | cc/config/clang.go | 2 | ||||
| -rw-r--r-- | cc/config/global.go | 4 | ||||
| -rw-r--r-- | java/hiddenapi.go | 28 | ||||
| -rw-r--r-- | java/hiddenapi_singleton_test.go | 19 | ||||
| -rw-r--r-- | java/java.go | 6 | ||||
| -rwxr-xr-x | scripts/hiddenapi/merge_csv.py | 21 |
10 files changed, 224 insertions, 49 deletions
diff --git a/android/paths.go b/android/paths.go index c3fa61a09..58e1f746b 100644 --- a/android/paths.go +++ b/android/paths.go @@ -280,7 +280,8 @@ func (paths Paths) containsPath(path Path) bool { return false } -// PathsForSource returns Paths rooted from SrcDir +// PathsForSource returns Paths rooted from SrcDir, *not* rooted from the module's local source +// directory func PathsForSource(ctx PathContext, paths []string) Paths { ret := make(Paths, len(paths)) for i, path := range paths { @@ -289,9 +290,9 @@ func PathsForSource(ctx PathContext, paths []string) Paths { return ret } -// ExistentPathsForSources returns a list of Paths rooted from SrcDir that are -// found in the tree. If any are not found, they are omitted from the list, -// and dependencies are added so that we're re-run when they are added. +// ExistentPathsForSources returns a list of Paths rooted from SrcDir, *not* rooted from the +// module's local source directory, that are found in the tree. If any are not found, they are +// omitted from the list, and dependencies are added so that we're re-run when they are added. func ExistentPathsForSources(ctx PathContext, paths []string) Paths { ret := make(Paths, 0, len(paths)) for _, path := range paths { @@ -395,6 +396,9 @@ func BazelLabelForModuleSrcExcludes(ctx BazelConversionPathContext, paths, exclu // `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 { + if paths == nil { + return bazel.LabelList{} + } labels := bazel.LabelList{ Includes: []bazel.Label{}, } @@ -1024,9 +1028,10 @@ func PathForSource(ctx PathContext, pathComponents ...string) SourcePath { return path } -// ExistentPathForSource returns an OptionalPath with the SourcePath if the -// path exists, or an empty OptionalPath if it doesn't exist. Dependencies are added -// so that the ninja file will be regenerated if the state of the path changes. +// ExistentPathForSource returns an OptionalPath with the SourcePath, rooted from SrcDir, *not* +// rooted from the module's local source directory, if the path exists, or an empty OptionalPath if +// it doesn't exist. Dependencies are added so that the ninja file will be regenerated if the state +// of the path changes. func ExistentPathForSource(ctx PathContext, pathComponents ...string) OptionalPath { path, err := pathForSource(ctx, pathComponents...) if err != nil { diff --git a/bp2build/Android.bp b/bp2build/Android.bp index fdac88dfd..6570b163c 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -22,6 +22,7 @@ bootstrap_go_package { "build_conversion_test.go", "bzl_conversion_test.go", "conversion_test.go", + "sh_conversion_test.go", "testing.go", ], pluginFor: [ diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index df554a09a..422422b1f 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -17,7 +17,6 @@ package bp2build import ( "android/soong/android" "android/soong/genrule" - "android/soong/sh" "strings" "testing" ) @@ -358,12 +357,6 @@ load("//build/bazel/rules:java.bzl", "java_binary")`, ruleClass: "genrule", // Note: no bzlLoadLocation for native rules }, - BazelTarget{ - name: "sh_binary_target", - ruleClass: "sh_binary", - // Note: no bzlLoadLocation for native rules - // TODO(ruperts): Could open source the existing, experimental Starlark sh_ rules? - }, }, expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary") load("//build/bazel/rules:java.bzl", "java_binary")`, @@ -476,6 +469,21 @@ genrule { dir string }{ { + description: "filegroup with does not specify srcs", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + bp: `filegroup { + name: "fg_foo", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + `filegroup( + name = "fg_foo", +)`, + }, + }, + { description: "filegroup with no srcs", moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, @@ -860,23 +868,6 @@ genrule { )`, }, }, - { - description: "sh_binary test", - moduleTypeUnderTest: "sh_binary", - moduleTypeUnderTestFactory: sh.ShBinaryFactory, - moduleTypeUnderTestBp2BuildMutator: sh.ShBinaryBp2Build, - bp: `sh_binary { - name: "foo", - src: "foo.sh", - bazel_module: { bp2build_available: true }, -}`, - expectedBazelTargets: []string{`sh_binary( - name = "foo", - srcs = [ - "foo.sh", - ], -)`}, - }, } dir := "." diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go new file mode 100644 index 000000000..dcc75bd5c --- /dev/null +++ b/bp2build/sh_conversion_test.go @@ -0,0 +1,134 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bp2build + +import ( + "android/soong/android" + "android/soong/sh" + "strings" + "testing" +) + +func TestShBinaryLoadStatement(t *testing.T) { + testCases := []struct { + bazelTargets BazelTargets + expectedLoadStatements string + }{ + { + bazelTargets: BazelTargets{ + BazelTarget{ + name: "sh_binary_target", + ruleClass: "sh_binary", + // Note: no bzlLoadLocation for native rules + // TODO(ruperts): Could open source the existing, experimental Starlark sh_ rules? + }, + }, + expectedLoadStatements: ``, + }, + } + + for _, testCase := range testCases { + actual := testCase.bazelTargets.LoadStatements() + expected := testCase.expectedLoadStatements + if actual != expected { + t.Fatalf("Expected load statements to be %s, got %s", expected, actual) + } + } + +} + +func TestShBinaryBp2Build(t *testing.T) { + testCases := []struct { + description string + moduleTypeUnderTest string + moduleTypeUnderTestFactory android.ModuleFactory + moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext) + preArchMutators []android.RegisterMutatorFunc + depsMutators []android.RegisterMutatorFunc + bp string + expectedBazelTargets []string + filesystem map[string]string + dir string + }{ + { + description: "sh_binary test", + moduleTypeUnderTest: "sh_binary", + moduleTypeUnderTestFactory: sh.ShBinaryFactory, + moduleTypeUnderTestBp2BuildMutator: sh.ShBinaryBp2Build, + bp: `sh_binary { + name: "foo", + src: "foo.sh", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{`sh_binary( + name = "foo", + srcs = [ + "foo.sh", + ], +)`}, + }, + } + + dir := "." + for _, testCase := range testCases { + filesystem := make(map[string][]byte) + toParse := []string{ + "Android.bp", + } + for f, content := range testCase.filesystem { + if strings.HasSuffix(f, "Android.bp") { + toParse = append(toParse, f) + } + filesystem[f] = []byte(content) + } + config := android.TestConfig(buildDir, nil, testCase.bp, filesystem) + 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, toParse) + if Errored(t, testCase.description, errs) { + continue + } + _, errs = ctx.ResolveDependencies(config) + if Errored(t, testCase.description, errs) { + continue + } + + 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, + ) + } + } + } + } +} diff --git a/cc/config/clang.go b/cc/config/clang.go index 71c7626d9..76186be57 100644 --- a/cc/config/clang.go +++ b/cc/config/clang.go @@ -150,6 +150,8 @@ func init() { "-Wunguarded-availability", // This macro allows the bionic versioning.h to indirectly determine whether the // option -Wunguarded-availability is on or not. + "-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__", + // TODO: remove this once prebuilt SDKs are only using the above macro instead. "-D__ANDROID_UNGUARDED_AVAILABILITY__", }, " ")) diff --git a/cc/config/global.go b/cc/config/global.go index ee4112544..e60bb3d51 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -144,8 +144,8 @@ var ( // prebuilts/clang default settings. ClangDefaultBase = "prebuilts/clang/host" - ClangDefaultVersion = "clang-r407598b" - ClangDefaultShortVersion = "12.0.2" + ClangDefaultVersion = "clang-r412851" + ClangDefaultShortVersion = "12.0.3" // Directories with warnings from Android.bp files. WarningAllowedProjects = []string{ diff --git a/java/hiddenapi.go b/java/hiddenapi.go index 1651c1c6d..f8e41c458 100644 --- a/java/hiddenapi.go +++ b/java/hiddenapi.go @@ -221,13 +221,19 @@ func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJa return } + classesJars := android.Paths{classesJar} + ctx.VisitDirectDepsWithTag(hiddenApiAnnotationsTag, func(dep android.Module) { + javaInfo := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) + classesJars = append(classesJars, javaInfo.ImplementationJars...) + }) + stubFlagsCSV := hiddenAPISingletonPaths(ctx).stubFlags flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv") ctx.Build(pctx, android.BuildParams{ Rule: hiddenAPIGenerateCSVRule, Description: "hiddenapi flags", - Input: classesJar, + Inputs: classesJars, Output: flagsCSV, Implicit: stubFlagsCSV, Args: map[string]string{ @@ -241,7 +247,7 @@ func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJa ctx.Build(pctx, android.BuildParams{ Rule: hiddenAPIGenerateCSVRule, Description: "hiddenapi metadata", - Input: classesJar, + Inputs: classesJars, Output: metadataCSV, Implicit: stubFlagsCSV, Args: map[string]string{ @@ -255,8 +261,9 @@ func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJa rule := android.NewRuleBuilder(pctx, ctx) rule.Command(). BuiltTool("merge_csv"). - FlagWithInput("--zip_input=", classesJar). - FlagWithOutput("--output=", indexCSV) + Flag("--zip_input"). + FlagWithOutput("--output=", indexCSV). + Inputs(classesJars) rule.Build("merged-hiddenapi-index", "Merged Hidden API index") h.indexCSVPath = indexCSV @@ -335,3 +342,16 @@ func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, TransformZipAlign(ctx, output, tmpOutput) } } + +type hiddenApiAnnotationsDependencyTag struct { + blueprint.BaseDependencyTag +} + +// Tag used to mark dependencies on java_library instances that contains Java source files whose +// sole purpose is to provide additional hiddenapi annotations. +var hiddenApiAnnotationsTag hiddenApiAnnotationsDependencyTag + +// Mark this tag so dependencies that use it are excluded from APEX contents. +func (t hiddenApiAnnotationsDependencyTag) ExcludeFromApexContents() {} + +var _ android.ExcludeFromApexContentsTag = hiddenApiAnnotationsTag diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go index df825bb3a..4670d0311 100644 --- a/java/hiddenapi_singleton_test.go +++ b/java/hiddenapi_singleton_test.go @@ -82,6 +82,10 @@ func TestHiddenAPIIndexSingleton(t *testing.T) { name: "foo", srcs: ["a.java"], compile_dex: true, + + hiddenapi_additional_annotations: [ + "foo-hiddenapi-annotations", + ], } java_library { @@ -90,6 +94,12 @@ func TestHiddenAPIIndexSingleton(t *testing.T) { compile_dex: true, } + java_library { + name: "foo-hiddenapi-annotations", + srcs: ["a.java"], + compile_dex: true, + } + java_import { name: "foo", jars: ["a.jar"], @@ -112,6 +122,15 @@ func TestHiddenAPIIndexSingleton(t *testing.T) { .intermediates/foo/android_common/hiddenapi/index.csv `, indexRule) + + // Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that + // creates the index.csv file. + foo := ctx.ModuleForTests("foo", "android_common") + indexParams := foo.Output("hiddenapi/index.csv") + CheckHiddenAPIRuleInputs(t, ` +.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar +.intermediates/foo/android_common/javac/foo.jar +`, indexParams) } func TestHiddenAPISingletonWithPrebuilt(t *testing.T) { diff --git a/java/java.go b/java/java.go index c2cd45746..69ec2a442 100644 --- a/java/java.go +++ b/java/java.go @@ -298,6 +298,9 @@ type CompilerProperties struct { // If true, package the kotlin stdlib into the jar. Defaults to true. Static_kotlin_stdlib *bool `android:"arch_variant"` + + // A list of java_library instances that provide additional hiddenapi annotations for the library. + Hiddenapi_additional_annotations []string } type CompilerDeviceProperties struct { @@ -840,6 +843,9 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { libDeps := ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...) ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...) + // Add dependency on libraries that provide additional hidden api annotations. + ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...) + if ctx.DeviceConfig().VndkVersion() != "" && ctx.Config().EnforceInterPartitionJavaSdkLibrary() { // Require java_sdk_library at inter-partition java dependency to ensure stable // interface between partitions. If inter-partition java_library dependency is detected, diff --git a/scripts/hiddenapi/merge_csv.py b/scripts/hiddenapi/merge_csv.py index 6a5b0e134..5ad61b2f6 100755 --- a/scripts/hiddenapi/merge_csv.py +++ b/scripts/hiddenapi/merge_csv.py @@ -26,7 +26,8 @@ from zipfile import ZipFile args_parser = argparse.ArgumentParser(description='Merge given CSV files into a single one.') args_parser.add_argument('--header', help='Comma separated field names; ' 'if missing determines the header from input files.') -args_parser.add_argument('--zip_input', help='ZIP archive with all CSV files to merge.') +args_parser.add_argument('--zip_input', help='Treat files as ZIP archives containing CSV files to merge.', + action="store_true") args_parser.add_argument('--output', help='Output file for merged CSV.', default='-', type=argparse.FileType('w')) args_parser.add_argument('files', nargs=argparse.REMAINDER) @@ -36,20 +37,16 @@ args = args_parser.parse_args() def dict_reader(input): return csv.DictReader(input, delimiter=',', quotechar='|') - -if args.zip_input and len(args.files) > 0: - raise ValueError('Expecting either a single ZIP with CSV files' - ' or a list of CSV files as input; not both.') - csv_readers = [] -if len(args.files) > 0: +if not(args.zip_input): for file in args.files: csv_readers.append(dict_reader(open(file, 'r'))) -elif args.zip_input: - with ZipFile(args.zip_input) as zip: - for entry in zip.namelist(): - if entry.endswith('.uau'): - csv_readers.append(dict_reader(io.TextIOWrapper(zip.open(entry, 'r')))) +else: + for file in args.files: + with ZipFile(file) as zip: + for entry in zip.namelist(): + if entry.endswith('.uau'): + csv_readers.append(dict_reader(io.TextIOWrapper(zip.open(entry, 'r')))) headers = set() if args.header: |