Merge "Add bloaty package"
diff --git a/android/arch.go b/android/arch.go
index 2decea8..6fb70c9 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1609,13 +1609,15 @@
} else {
buildTargets = firstTarget(targets, "lib64", "lib32")
}
+ case "first_prefer32":
+ buildTargets = firstTarget(targets, "lib32", "lib64")
case "prefer32":
buildTargets = filterMultilibTargets(targets, "lib32")
if len(buildTargets) == 0 {
buildTargets = filterMultilibTargets(targets, "lib64")
}
default:
- return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", or "prefer32" found %q`,
+ return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", "prefer32" or "first_prefer32" found %q`,
multilib)
}
diff --git a/android/config.go b/android/config.go
index 9162eaa..c6885dd 100644
--- a/android/config.go
+++ b/android/config.go
@@ -128,7 +128,7 @@
// If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error
// in tests when a path doesn't exist.
- testAllowNonExistentPaths bool
+ TestAllowNonExistentPaths bool
// The list of files that when changed, must invalidate soong_build to
// regenerate build.ninja.
@@ -256,7 +256,7 @@
// Set testAllowNonExistentPaths so that test contexts don't need to specify every path
// passed to PathForSource or PathForModuleSrc.
- testAllowNonExistentPaths: true,
+ TestAllowNonExistentPaths: true,
BazelContext: noopBazelContext{},
}
diff --git a/android/paths.go b/android/paths.go
index 58e1f74..ada4da6 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -586,7 +586,7 @@
p := pathForModuleSrc(ctx, sPath)
if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil {
ReportPathErrorf(ctx, "%s: %s", p, err.Error())
- } else if !exists && !ctx.Config().testAllowNonExistentPaths {
+ } else if !exists && !ctx.Config().TestAllowNonExistentPaths {
ReportPathErrorf(ctx, "module source path %q does not exist", p)
}
@@ -1022,7 +1022,7 @@
}
} else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil {
ReportPathErrorf(ctx, "%s: %s", path, err.Error())
- } else if !exists && !ctx.Config().testAllowNonExistentPaths {
+ } else if !exists && !ctx.Config().TestAllowNonExistentPaths {
ReportPathErrorf(ctx, "source path %q does not exist", path)
}
return path
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index add0e1e..4e7039c 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -176,6 +176,8 @@
ExtServices-core(minSdkVersion:current)
flatbuffer_headers(minSdkVersion:(no version))
fmtlib(minSdkVersion:29)
+fmtlib_ndk(minSdkVersion:29)
+framework-mediaprovider(minSdkVersion:30)
framework-permission(minSdkVersion:30)
framework-permission(minSdkVersion:current)
framework-permission-s(minSdkVersion:30)
@@ -240,6 +242,7 @@
libbacktrace_sys.rust_sysroot(minSdkVersion:29)
libbase(minSdkVersion:29)
libbase_headers(minSdkVersion:29)
+libbase_ndk(minSdkVersion:29)
libbinder_headers(minSdkVersion:29)
libbinder_headers_platform_shared(minSdkVersion:29)
libbinderthreadstateutils(minSdkVersion:29)
@@ -315,6 +318,8 @@
libfmq(minSdkVersion:29)
libfmq-base(minSdkVersion:29)
libFraunhoferAAC(minSdkVersion:29)
+libfuse(minSdkVersion:30)
+libfuse_jni(minSdkVersion:30)
libgav1(minSdkVersion:29)
libgcc(minSdkVersion:(no version))
libgcc_stripped(minSdkVersion:(no version))
@@ -468,6 +473,7 @@
libzstd(minSdkVersion:(no version))
media_ndk_headers(minSdkVersion:29)
media_plugin_headers(minSdkVersion:29)
+MediaProvider(minSdkVersion:30)
mediaswcodec(minSdkVersion:29)
metrics-constants-protos(minSdkVersion:29)
modules-utils-build(minSdkVersion:29)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 181946b..bbc4b93 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2039,7 +2039,7 @@
},
{
name: "Updatable apex with non-stable transitive dep",
- expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against non-public Android API.",
+ expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against private API.",
bp: `
apex {
name: "myapex",
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index ddde1b7..521bb06 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -22,7 +22,8 @@
testSrcs: [
"build_conversion_test.go",
"bzl_conversion_test.go",
- "cc_conversion_test.go",
+ "cc_library_headers_conversion_test.go",
+ "cc_object_conversion_test.go",
"conversion_test.go",
"sh_conversion_test.go",
"testing.go",
diff --git a/bp2build/cc_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
similarity index 100%
rename from bp2build/cc_conversion_test.go
rename to bp2build/cc_library_headers_conversion_test.go
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
new file mode 100644
index 0000000..e4ffe16
--- /dev/null
+++ b/bp2build/cc_object_conversion_test.go
@@ -0,0 +1,186 @@
+// 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/cc"
+ "fmt"
+ "strings"
+ "testing"
+)
+
+func TestCcObjectBp2Build(t *testing.T) {
+ testCases := []struct {
+ description string
+ moduleTypeUnderTest string
+ moduleTypeUnderTestFactory android.ModuleFactory
+ moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
+ blueprint string
+ expectedBazelTargets []string
+ filesystem map[string]string
+ }{
+ {
+ description: "simple cc_object generates cc_object with include header dep",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ filesystem: map[string]string{
+ "a/b/foo.h": "",
+ "a/b/bar.h": "",
+ "a/b/c.c": "",
+ },
+ blueprint: `cc_object {
+ name: "foo",
+ local_include_dirs: ["include"],
+ cflags: [
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ ],
+ srcs: [
+ "a/b/*.h",
+ "a/b/c.c"
+ ],
+
+ bazel_module: { bp2build_available: true },
+}
+`,
+ expectedBazelTargets: []string{`cc_object(
+ name = "foo",
+ copts = [
+ "-fno-addrsig",
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ ],
+ local_include_dirs = [
+ "include",
+ ],
+ srcs = [
+ "a/b/bar.h",
+ "a/b/foo.h",
+ "a/b/c.c",
+ ],
+)`,
+ },
+ },
+ {
+ description: "simple cc_object with defaults",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
+ name: "foo",
+ local_include_dirs: ["include"],
+ srcs: [
+ "a/b/*.h",
+ "a/b/c.c"
+ ],
+
+ defaults: ["foo_defaults"],
+ bazel_module: { bp2build_available: true },
+}
+
+cc_defaults {
+ name: "foo_defaults",
+ defaults: ["foo_bar_defaults"],
+ // TODO(b/178130668): handle configurable attributes that depend on the platform
+ arch: {
+ x86: {
+ cflags: ["-fPIC"],
+ },
+ x86_64: {
+ cflags: ["-fPIC"],
+ },
+ },
+}
+
+cc_defaults {
+ name: "foo_bar_defaults",
+ cflags: [
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ ],
+}
+`,
+ expectedBazelTargets: []string{`cc_object(
+ name = "foo",
+ copts = [
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ "-fno-addrsig",
+ ],
+ local_include_dirs = [
+ "include",
+ ],
+ srcs = [
+ "a/b/c.c",
+ ],
+)`,
+ },
+ },
+ }
+
+ 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.blueprint, filesystem)
+ ctx := android.NewTestContext(config)
+ // Always register cc_defaults module factory
+ ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
+
+ ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
+ 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
+ }
+
+ bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
+ if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
+ fmt.Println(bazelTargets)
+ 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/cc.go b/cc/cc.go
index 7f59158..6c1469f 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -28,6 +28,7 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/bazel"
"android/soong/cc/config"
"android/soong/genrule"
)
@@ -364,6 +365,8 @@
// can depend on libraries that are not exported by the APEXes and use private symbols
// from the exported libraries.
Test_for []string
+
+ bazel.Properties
}
type VendorProperties struct {
diff --git a/cc/fuzz.go b/cc/fuzz.go
index d7da5ab..9fe5b17 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -20,6 +20,8 @@
"sort"
"strings"
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
"android/soong/cc/config"
)
@@ -172,7 +174,7 @@
// This function takes a module and determines if it is a unique shared library
// that should be installed in the fuzz target output directories. This function
// returns true, unless:
-// - The module is not a shared library, or
+// - The module is not an installable shared library, or
// - The module is a header, stub, or vendor-linked library, or
// - The module is a prebuilt and its source is available, or
// - The module is a versioned member of an SDK snapshot.
@@ -209,6 +211,11 @@
if _, isLLndkStubLibrary := ccLibrary.linker.(*stubDecorator); isLLndkStubLibrary {
return false
}
+ // Discard installable:false libraries because they are expected to be absent
+ // in runtime.
+ if !proptools.BoolDefault(ccLibrary.Properties.Installable, true) {
+ return false
+ }
}
// If the same library is present both as source and a prebuilt we must pick
diff --git a/cc/library.go b/cc/library.go
index bdcb8ae..65533bc 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -27,7 +27,6 @@
"github.com/google/blueprint/pathtools"
"android/soong/android"
- "android/soong/bazel"
"android/soong/cc/config"
)
@@ -121,9 +120,6 @@
// If this is an LLNDK library, properties to describe the LLNDK stubs. Will be copied from
// the module pointed to by llndk_stubs if it is set.
Llndk llndkLibraryProperties
-
- // Properties for Bazel migration purposes.
- bazel.Properties
}
// StaticProperties is a properties stanza to affect only attributes of the "static" variants of a
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 448e144..e5a5557 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -86,6 +86,10 @@
return
}
+ if !module.Properties.Bazel_module.Bp2build_available {
+ return
+ }
+
lib, ok := module.linker.(*libraryDecorator)
if !ok {
// Not a cc_library module
@@ -96,10 +100,6 @@
return
}
- if !lib.Properties.Bazel_module.Bp2build_available {
- return
- }
-
// list of directories that will be added to the include path (using -I) for this
// module and any module that links against this module.
includeDirs := lib.flagExporter.Properties.Export_system_include_dirs
diff --git a/cc/object.go b/cc/object.go
index 3ce7676..d92e110 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -18,6 +18,7 @@
"fmt"
"android/soong/android"
+ "android/soong/bazel"
)
//
@@ -27,6 +28,8 @@
func init() {
android.RegisterModuleType("cc_object", ObjectFactory)
android.RegisterSdkMemberType(ccObjectSdkMemberType)
+
+ android.RegisterBp2BuildMutator("cc_object", ObjectBp2Build)
}
var ccObjectSdkMemberType = &librarySdkMemberType{
@@ -82,9 +85,80 @@
module.compiler.appendCflags([]string{"-fno-addrsig"})
module.sdkMemberTypes = []android.SdkMemberType{ccObjectSdkMemberType}
+
return module.Init()
}
+// For bp2build conversion.
+type bazelObjectAttributes struct {
+ Srcs bazel.LabelList
+ Copts []string
+ Local_include_dirs []string
+}
+
+type bazelObject struct {
+ android.BazelTargetModuleBase
+ bazelObjectAttributes
+}
+
+func (m *bazelObject) Name() string {
+ return m.BaseModuleName()
+}
+
+func (m *bazelObject) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
+
+func BazelObjectFactory() android.Module {
+ module := &bazelObject{}
+ module.AddProperties(&module.bazelObjectAttributes)
+ android.InitBazelTargetModule(module)
+ return module
+}
+
+// ObjectBp2Build is the bp2build converter from cc_object modules to the
+// Bazel equivalent target, plus any necessary include deps for the cc_object.
+func ObjectBp2Build(ctx android.TopDownMutatorContext) {
+ m, ok := ctx.Module().(*Module)
+ if !ok || !m.Properties.Bazel_module.Bp2build_available {
+ return
+ }
+
+ // a Module can be something other than a cc_object.
+ if ctx.ModuleType() != "cc_object" {
+ return
+ }
+
+ if m.compiler == nil {
+ // a cc_object must have access to the compiler decorator for its props.
+ ctx.ModuleErrorf("compiler must not be nil for a cc_object module")
+ }
+
+ var copts []string
+ var srcs []string
+ var localIncludeDirs []string
+ for _, props := range m.compiler.compilerProps() {
+ if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
+ copts = baseCompilerProps.Cflags
+ srcs = baseCompilerProps.Srcs
+ localIncludeDirs = baseCompilerProps.Local_include_dirs
+ break
+ }
+ }
+
+ attrs := &bazelObjectAttributes{
+ Srcs: android.BazelLabelForModuleSrc(ctx, srcs),
+ Copts: copts,
+ Local_include_dirs: localIncludeDirs,
+ }
+
+ props := bazel.NewBazelTargetModuleProperties(
+ m.Name(),
+ "cc_object",
+ "//build/bazel/rules:cc_object.bzl",
+ )
+
+ ctx.CreateBazelTargetModule(BazelObjectFactory, props, attrs)
+}
+
func (object *objectLinker) appendLdflags(flags []string) {
panic(fmt.Errorf("appendLdflags on objectLinker not supported"))
}
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 57563eb..e15324b 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -282,11 +282,14 @@
Input: p.sourceFilePath,
})
- if p.Installable() {
- installPath := ctx.InstallFile(p.installDirPath, p.outputFilePath.Base(), p.outputFilePath)
- for _, sl := range p.properties.Symlinks {
- ctx.InstallSymlink(p.installDirPath, sl, installPath)
- }
+ if !p.Installable() {
+ p.SkipInstall()
+ }
+
+ // Call InstallFile even when uninstallable to make the module included in the package
+ installPath := ctx.InstallFile(p.installDirPath, p.outputFilePath.Base(), p.outputFilePath)
+ for _, sl := range p.properties.Symlinks {
+ ctx.InstallSymlink(p.installDirPath, sl, installPath)
}
}
diff --git a/java/java.go b/java/java.go
index 69ec2a4..dbfad02 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1014,6 +1014,7 @@
const (
// TODO(jiyong) rename these for better readability. Make the allowed
// and disallowed link types explicit
+ // order is important here. See rank()
javaCore linkType = iota
javaSdk
javaSystem
@@ -1022,6 +1023,31 @@
javaPlatform
)
+func (lt linkType) String() string {
+ switch lt {
+ case javaCore:
+ return "core Java API"
+ case javaSdk:
+ return "Android API"
+ case javaSystem:
+ return "system API"
+ case javaModule:
+ return "module API"
+ case javaSystemServer:
+ return "system server API"
+ case javaPlatform:
+ return "private API"
+ default:
+ panic(fmt.Errorf("unrecognized linktype: %v", lt))
+ }
+}
+
+// rank determins the total order among linkTypes. A link type of rank A can link to another link
+// type of rank B only when B <= A
+func (lt linkType) rank() int {
+ return int(lt)
+}
+
type linkTypeContext interface {
android.Module
getLinkType(name string) (ret linkType, stubs bool)
@@ -1081,44 +1107,13 @@
return
}
otherLinkType, _ := to.getLinkType(ctx.OtherModuleName(to))
- commonMessage := " In order to fix this, consider adjusting sdk_version: OR platform_apis: " +
- "property of the source or target module so that target module is built with the same " +
- "or smaller API set when compared to the source."
- switch myLinkType {
- case javaCore:
- if otherLinkType != javaCore {
- ctx.ModuleErrorf("compiles against core Java API, but dependency %q is compiling against non-core Java APIs."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaSdk:
- if otherLinkType != javaCore && otherLinkType != javaSdk {
- ctx.ModuleErrorf("compiles against Android API, but dependency %q is compiling against non-public Android API."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaSystem:
- if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer {
- ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaModule:
- if otherLinkType == javaPlatform || otherLinkType == javaSystemServer {
- ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaSystemServer:
- if otherLinkType == javaPlatform {
- ctx.ModuleErrorf("compiles against system server API, but dependency %q is compiling against private API."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaPlatform:
- // no restriction on link-type
- break
+ if myLinkType.rank() < otherLinkType.rank() {
+ ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
+ "In order to fix this, consider adjusting sdk_version: OR platform_apis: "+
+ "property of the source or target module so that target module is built "+
+ "with the same or smaller API set when compared to the source.",
+ myLinkType, ctx.OtherModuleName(to), otherLinkType)
}
}
diff --git a/java/java_test.go b/java/java_test.go
index e7776c3..0ef4db6 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -127,7 +127,6 @@
}
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
-
return ctx, config
}
@@ -1179,6 +1178,110 @@
}
}
+func TestJavaLint(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ "b.java",
+ "c.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ }
+ `, map[string][]byte{
+ "lint-baseline.xml": nil,
+ })
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+ rule := foo.Rule("lint")
+
+ if !strings.Contains(rule.RuleParams.Command, "--baseline lint-baseline.xml") {
+ t.Error("did not pass --baseline flag")
+ }
+}
+
+func TestJavaLintWithoutBaseline(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ "b.java",
+ "c.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ }
+ `, map[string][]byte{})
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+ rule := foo.Rule("lint")
+
+ if strings.Contains(rule.RuleParams.Command, "--baseline") {
+ t.Error("passed --baseline flag for non existent file")
+ }
+}
+
+func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
+ config := testConfig(
+ nil,
+ `
+ java_library {
+ name: "foo",
+ srcs: [
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ lint: {
+ baseline_filename: "mybaseline.xml",
+ },
+ }
+ `, map[string][]byte{
+ "build/soong/java/lint_defaults.txt": nil,
+ "prebuilts/cmdline-tools/tools/bin/lint": nil,
+ "prebuilts/cmdline-tools/tools/lib/lint-classpath.jar": nil,
+ "framework/aidl": nil,
+ "a.java": nil,
+ "AndroidManifest.xml": nil,
+ "build/make/target/product/security": nil,
+ })
+ config.TestAllowNonExistentPaths = false
+ testJavaErrorWithConfig(t,
+ "source path \"mybaseline.xml\" does not exist",
+ config,
+ )
+}
+
+func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ "b.java",
+ "c.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ lint: {
+ error_checks: ["SomeCheck"],
+ baseline_filename: "mybaseline.xml",
+ },
+ }
+ `, map[string][]byte{
+ "mybaseline.xml": nil,
+ })
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+ rule := foo.Rule("lint")
+
+ if !strings.Contains(rule.RuleParams.Command, "--baseline mybaseline.xml") {
+ t.Error("did not use the correct file for baseline")
+ }
+}
+
func TestGeneratedSources(t *testing.T) {
ctx, _ := testJavaWithFS(t, `
java_library {
diff --git a/java/lint.go b/java/lint.go
index c9e0cdd..8272595 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -19,6 +19,8 @@
"sort"
"strings"
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
)
@@ -46,6 +48,9 @@
// Modules that provide extra lint checks
Extra_check_modules []string
+
+ // Name of the file that lint uses as the baseline. Defaults to "lint-baseline.xml".
+ Baseline_filename *string
}
}
@@ -344,6 +349,19 @@
cmd.FlagWithArg("--check ", checkOnly)
}
+ if lintFilename := proptools.StringDefault(l.properties.Lint.Baseline_filename, "lint-baseline.xml"); lintFilename != "" {
+ var lintBaseline android.OptionalPath
+ if String(l.properties.Lint.Baseline_filename) != "" {
+ // if manually specified, we require the file to exist
+ lintBaseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, lintFilename))
+ } else {
+ lintBaseline = android.ExistentPathForSource(ctx, ctx.ModuleDir(), lintFilename)
+ }
+ if lintBaseline.Valid() {
+ cmd.FlagWithInput("--baseline ", lintBaseline.Path())
+ }
+ }
+
cmd.Text("|| (").Text("cat").Input(text).Text("; exit 7)").Text(")")
rule.Command().Text("rm -rf").Flag(cacheDir.String()).Flag(homeDir.String())
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 1e90149..c91b321 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -106,14 +106,18 @@
mctx.CreateModule(ImportFactory, &props)
}
-func createFilegroup(mctx android.LoadHookContext, name string, path string) {
- filegroupProps := struct {
+func createApiModule(mctx android.LoadHookContext, name string, path string) {
+ genruleProps := struct {
Name *string
Srcs []string
+ Out []string
+ Cmd *string
}{}
- filegroupProps.Name = proptools.StringPtr(name)
- filegroupProps.Srcs = []string{path}
- mctx.CreateModule(android.FileGroupFactory, &filegroupProps)
+ genruleProps.Name = proptools.StringPtr(name)
+ genruleProps.Srcs = []string{path}
+ genruleProps.Out = []string{name}
+ genruleProps.Cmd = proptools.StringPtr("cp $(in) $(out)")
+ mctx.CreateModule(genrule.GenRuleFactory, &genruleProps)
}
func createEmptyFile(mctx android.LoadHookContext, name string) {
@@ -205,16 +209,16 @@
path string
}
- // Create filegroups for all (<module>, <scope, <version>) triplets,
- // and a "latest" filegroup variant for each (<module>, <scope>) pair
- moduleName := func(module, scope, version string) string {
+ // Create modules for all (<module>, <scope, <version>) triplets,
+ // and a "latest" module variant for each (<module>, <scope>) pair
+ apiModuleName := func(module, scope, version string) string {
return module + ".api." + scope + "." + version
}
m := make(map[string]latestApiInfo)
for _, f := range files {
localPath := strings.TrimPrefix(f, mydir)
module, apiver, scope := parseApiFilePath(mctx, localPath)
- createFilegroup(mctx, moduleName(module, scope, apiver), localPath)
+ createApiModule(mctx, apiModuleName(module, scope, apiver), localPath)
version, err := strconv.Atoi(apiver)
if err != nil {
@@ -239,8 +243,8 @@
// Sort the keys in order to make build.ninja stable
for _, k := range android.SortedStringKeys(m) {
info := m[k]
- name := moduleName(info.module, info.scope, "latest")
- createFilegroup(mctx, name, info.path)
+ name := apiModuleName(info.module, info.scope, "latest")
+ createApiModule(mctx, name, info.path)
}
// Create incompatibilities tracking files for all modules, if we have a "next" api.
@@ -258,14 +262,14 @@
referencedModule = "android"
}
- createFilegroup(mctx, moduleName(referencedModule+"-incompatibilities", scope, "latest"), localPath)
+ createApiModule(mctx, apiModuleName(referencedModule+"-incompatibilities", scope, "latest"), localPath)
incompatibilities[referencedModule+"."+scope] = true
}
// Create empty incompatibilities files for remaining modules
for _, k := range android.SortedStringKeys(m) {
if _, ok := incompatibilities[k]; !ok {
- createEmptyFile(mctx, moduleName(m[k].module+"-incompatibilities", m[k].scope, "latest"))
+ createEmptyFile(mctx, apiModuleName(m[k].module+"-incompatibilities", m[k].scope, "latest"))
}
}
}
@@ -279,10 +283,10 @@
}
}
-// prebuilt_apis is a meta-module that generates filegroup modules for all
-// API txt files found under the directory where the Android.bp is located.
+// prebuilt_apis is a meta-module that generates modules for all API txt files
+// found under the directory where the Android.bp is located.
// Specifically, an API file located at ./<ver>/<scope>/api/<module>.txt
-// generates a filegroup module named <module>-api.<scope>.<ver>.
+// generates a module named <module>-api.<scope>.<ver>.
//
// It also creates <module>-api.<scope>.latest for the latest <ver>.
//
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index ac67438..b93c883 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -8,6 +8,7 @@
com.android.art.testing
com.android.conscrypt
com.android.i18n
+ com.android.os.statsd
com.android.runtime
com.android.tzdata
)