Merge "Add MediaProvider dependencies to allowed_deps.txt"
diff --git a/Android.bp b/Android.bp
index 1012dba..9d5b07d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
subdirs = [
"androidmk",
"bpfix",
diff --git a/android/Android.bp b/android/Android.bp
index eabb137..00139d8 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-android",
pkgPath: "android/soong/android",
diff --git a/android/apex.go b/android/apex.go
index 6bb0751..4637942 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -757,7 +757,6 @@
"captiveportal-lib": 28,
"flatbuffer_headers": 30,
"framework-permission": 30,
- "framework-statsd": 30,
"gemmlowp_headers": 30,
"ike-internals": 30,
"kotlinx-coroutines-android": 28,
@@ -790,11 +789,6 @@
"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,
@@ -807,9 +801,6 @@
"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,
})
diff --git a/android/arch.go b/android/arch.go
index b277381..6fb70c9 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1442,7 +1442,7 @@
func getNdkAbisConfig() []archConfig {
return []archConfig{
{"arm", "armv7-a", "", []string{"armeabi-v7a"}},
- {"arm64", "armv8-a", "", []string{"arm64-v8a"}},
+ {"arm64", "armv8-a-branchprot", "", []string{"arm64-v8a"}},
{"x86", "", "", []string{"x86"}},
{"x86_64", "", "", []string{"x86_64"}},
}
@@ -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/arch_list.go b/android/arch_list.go
index 0c33b9d..d68a0d1 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -41,6 +41,7 @@
},
Arm64: {
"armv8_a",
+ "armv8_a_branchprot",
"armv8_2a",
"armv8-2a-dotprod",
"cortex-a53",
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 4a25119..a5c4bed 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -234,6 +234,13 @@
cmdFlags = append(cmdFlags, labels...)
cmdFlags = append(cmdFlags, "--package_path=%workspace%/"+context.intermediatesDir())
cmdFlags = append(cmdFlags, "--profile="+shared.BazelMetricsFilename(context, runName))
+ // Set default platforms to canonicalized values for mixed builds requests. If these are set
+ // in the bazelrc, they will have values that are non-canonicalized, and thus be invalid.
+ // The actual platform values here may be overridden by configuration transitions from the buildroot.
+ cmdFlags = append(cmdFlags,
+ fmt.Sprintf("--platforms=%s", canonicalizeLabel("//build/bazel/platforms:generic_x86_64")))
+ cmdFlags = append(cmdFlags,
+ fmt.Sprintf("--extra_toolchains=%s", canonicalizeLabel("//prebuilts/clang/host/linux-x86:all")))
cmdFlags = append(cmdFlags, extraFlags...)
bazelCmd := exec.Command(context.bazelPath, cmdFlags...)
@@ -460,7 +467,6 @@
return err
}
- fmt.Printf("Build statements %s", context.buildStatements)
// Clear requests.
context.requests = map[cqueryKey]bool{}
return nil
diff --git a/android/config.go b/android/config.go
index e0f3a91..c6885dd 100644
--- a/android/config.go
+++ b/android/config.go
@@ -24,6 +24,7 @@
"os"
"path/filepath"
"runtime"
+ "strconv"
"strings"
"sync"
@@ -127,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.
@@ -246,6 +247,7 @@
AAPTCharacteristics: stringPtr("nosdcard"),
AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
UncompressPrivAppDex: boolPtr(true),
+ ShippingApiLevel: stringPtr("30"),
},
buildDir: buildDir,
@@ -254,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{},
}
@@ -1413,6 +1415,26 @@
return c.config.productVariables.VendorSnapshotModules
}
+func (c *deviceConfig) DirectedRecoverySnapshot() bool {
+ return c.config.productVariables.DirectedRecoverySnapshot
+}
+
+func (c *deviceConfig) RecoverySnapshotModules() map[string]bool {
+ return c.config.productVariables.RecoverySnapshotModules
+}
+
+func (c *deviceConfig) ShippingApiLevel() ApiLevel {
+ if c.config.productVariables.ShippingApiLevel == nil {
+ return NoneApiLevel
+ }
+ apiLevel, _ := strconv.Atoi(*c.config.productVariables.ShippingApiLevel)
+ return uncheckedFinalApiLevel(apiLevel)
+}
+
+func (c *deviceConfig) BuildBrokenVendorPropertyNamespace() bool {
+ return c.config.productVariables.BuildBrokenVendorPropertyNamespace
+}
+
// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
// Such lists are used in the build system for things like bootclasspath jars or system server jars.
// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
diff --git a/android/filegroup.go b/android/filegroup.go
index 7a6cc4f..674a196 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -17,8 +17,6 @@
import (
"android/soong/bazel"
"strings"
-
- "github.com/google/blueprint/proptools"
)
func init() {
@@ -28,7 +26,6 @@
// https://docs.bazel.build/versions/master/be/general.html#filegroup
type bazelFilegroupAttributes struct {
- Name *string
Srcs bazel.LabelList
}
@@ -50,20 +47,19 @@
func (bfg *bazelFilegroup) GenerateAndroidBuildActions(ctx ModuleContext) {}
-// TODO: Create helper functions to avoid this boilerplate.
func FilegroupBp2Build(ctx TopDownMutatorContext) {
fg, ok := ctx.Module().(*fileGroup)
- if !ok {
+ if !ok || !fg.properties.Bazel_module.Bp2build_available {
return
}
- name := "__bp2build__" + fg.base().BaseModuleName()
- ctx.CreateModule(BazelFileGroupFactory, &bazelFilegroupAttributes{
- Name: proptools.StringPtr(name),
+ attrs := &bazelFilegroupAttributes{
Srcs: BazelLabelForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs),
- }, &bazel.BazelTargetModuleProperties{
- Rule_class: "filegroup",
- })
+ }
+
+ props := bazel.NewBazelTargetModuleProperties(fg.Name(), "filegroup", "")
+
+ ctx.CreateBazelTargetModule(BazelFileGroupFactory, props, attrs)
}
type fileGroupProperties struct {
diff --git a/android/module.go b/android/module.go
index 1409d44..bf74cad 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2374,6 +2374,16 @@
return b.bp.FinalModule().(Module)
}
+// IsMetaDependencyTag returns true for cross-cutting metadata dependencies.
+func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
+ if tag == licenseKindTag {
+ return true
+ } else if tag == licensesTag {
+ return true
+ }
+ return false
+}
+
// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
// a dependency tag.
var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:{}\E(, )?`)
diff --git a/android/mutator.go b/android/mutator.go
index 15be65f..c387193 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -15,7 +15,10 @@
package android
import (
+ "android/soong/bazel"
+ "fmt"
"reflect"
+ "strings"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -275,6 +278,12 @@
// CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
// the specified property structs to it as if the properties were set in a blueprint file.
CreateModule(ModuleFactory, ...interface{}) Module
+
+ // CreateBazelTargetModule creates a BazelTargetModule by calling the
+ // factory method, just like in CreateModule, but also requires
+ // BazelTargetModuleProperties containing additional metadata for the
+ // bp2build codegenerator.
+ CreateBazelTargetModule(ModuleFactory, bazel.BazelTargetModuleProperties, interface{}) BazelTargetModule
}
type topDownMutatorContext struct {
@@ -502,6 +511,21 @@
ctx.BottomUp("deps", depsMutator).Parallel()
}
+func (t *topDownMutatorContext) CreateBazelTargetModule(
+ factory ModuleFactory,
+ bazelProps bazel.BazelTargetModuleProperties,
+ attrs interface{}) BazelTargetModule {
+ if !strings.HasPrefix(*bazelProps.Name, bazel.BazelTargetModuleNamePrefix) {
+ panic(fmt.Errorf(
+ "bp2build error: the bazel target module name must start with '%s': %s",
+ bazel.BazelTargetModuleNamePrefix,
+ *bazelProps.Name,
+ ))
+ }
+
+ return t.CreateModule(factory, &bazelProps, attrs).(BazelTargetModule)
+}
+
func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
for _, p := range props {
err := proptools.AppendMatchingProperties(t.Module().base().customizableProperties,
diff --git a/android/paths.go b/android/paths.go
index 44221be..ada4da6 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -280,7 +280,8 @@
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 @@
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 @@
// `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{},
}
@@ -582,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)
}
@@ -1018,15 +1022,16 @@
}
} 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
}
-// 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 {
@@ -1949,3 +1954,28 @@
// The install path of the data file, relative to the install root.
RelativeInstallPath string
}
+
+// PathsIfNonNil returns a Paths containing only the non-nil input arguments.
+func PathsIfNonNil(paths ...Path) Paths {
+ if len(paths) == 0 {
+ // Fast path for empty argument list
+ return nil
+ } else if len(paths) == 1 {
+ // Fast path for a single argument
+ if paths[0] != nil {
+ return paths
+ } else {
+ return nil
+ }
+ }
+ ret := make(Paths, 0, len(paths))
+ for _, path := range paths {
+ if path != nil {
+ ret = append(ret, path)
+ }
+ }
+ if len(ret) == 0 {
+ return nil
+ }
+ return ret
+}
diff --git a/android/soongconfig/Android.bp b/android/soongconfig/Android.bp
index 6bb68eb..e7fa5a0 100644
--- a/android/soongconfig/Android.bp
+++ b/android/soongconfig/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-android-soongconfig",
pkgPath: "android/soong/android/soongconfig",
diff --git a/android/util.go b/android/util.go
index 0f940fa..506f8f7 100644
--- a/android/util.go
+++ b/android/util.go
@@ -137,6 +137,16 @@
return false
}
+// Returns true if any string in the given list has the given substring.
+func SubstringInList(list []string, substr string) bool {
+ for _, s := range list {
+ if strings.Contains(s, substr) {
+ return true
+ }
+ }
+ return false
+}
+
// Returns true if any string in the given list has the given prefix.
func PrefixInList(list []string, prefix string) bool {
for _, s := range list {
diff --git a/android/variable.go b/android/variable.go
index 9b3ed17..76666c5 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -121,10 +121,6 @@
Cppflags []string
}
- Use_lmkd_stats_log struct {
- Cflags []string
- }
-
Arc struct {
Cflags []string `android:"arch_variant"`
Exclude_srcs []string `android:"arch_variant"`
@@ -240,7 +236,6 @@
Treble_linker_namespaces *bool `json:",omitempty"`
Enforce_vintf_manifest *bool `json:",omitempty"`
Uml *bool `json:",omitempty"`
- Use_lmkd_stats_log *bool `json:",omitempty"`
Arc *bool `json:",omitempty"`
MinimizeJavaDebugInfo *bool `json:",omitempty"`
@@ -312,6 +307,9 @@
DirectedVendorSnapshot bool `json:",omitempty"`
VendorSnapshotModules map[string]bool `json:",omitempty"`
+ DirectedRecoverySnapshot bool `json:",omitempty"`
+ RecoverySnapshotModules map[string]bool `json:",omitempty"`
+
BoardVendorSepolicyDirs []string `json:",omitempty"`
BoardOdmSepolicyDirs []string `json:",omitempty"`
BoardReqdMaskPolicy []string `json:",omitempty"`
@@ -369,6 +367,10 @@
BoardMoveRecoveryResourcesToVendorBoot *bool `json:",omitempty"`
PrebuiltHiddenApiDir *string `json:",omitempty"`
+
+ ShippingApiLevel *string `json:",omitempty"`
+
+ BuildBrokenVendorPropertyNamespace bool `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/androidmk/Android.bp b/androidmk/Android.bp
index 70fc1f7..f04d01c 100644
--- a/androidmk/Android.bp
+++ b/androidmk/Android.bp
@@ -16,6 +16,10 @@
// androidmk Android.mk to Blueprints translator
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "androidmk",
srcs: [
diff --git a/apex/Android.bp b/apex/Android.bp
index b6fdcf4..8a2edeb 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-apex",
pkgPath: "android/soong/apex",
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index e0730d6..4e7039c 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -39,6 +39,7 @@
android.hardware.media.c2@1.1(minSdkVersion:29)
android.hardware.media.omx@1.0(minSdkVersion:29)
android.hardware.media@1.0(minSdkVersion:29)
+android.hardware.neuralnetworks-V1-ndk_platform(minSdkVersion:30)
android.hardware.neuralnetworks@1.0(minSdkVersion:30)
android.hardware.neuralnetworks@1.1(minSdkVersion:30)
android.hardware.neuralnetworks@1.2(minSdkVersion:30)
@@ -183,6 +184,7 @@
framework-permission-s-shared(minSdkVersion:30)
framework-sdkextensions(minSdkVersion:30)
framework-sdkextensions(minSdkVersion:current)
+framework-statsd(minSdkVersion:30)
framework-statsd(minSdkVersion:current)
framework-tethering(minSdkVersion:30)
framework-tethering(minSdkVersion:current)
@@ -429,11 +431,15 @@
libstagefright_mpeg2extractor(minSdkVersion:29)
libstagefright_mpeg2support_nocrypto(minSdkVersion:29)
libstats_jni(minSdkVersion:(no version))
+libstats_jni(minSdkVersion:30)
libstatslog_resolv(minSdkVersion:29)
libstatslog_statsd(minSdkVersion:(no version))
+libstatslog_statsd(minSdkVersion:30)
libstatspull(minSdkVersion:(no version))
+libstatspull(minSdkVersion:30)
libstatspush_compat(minSdkVersion:29)
libstatssocket(minSdkVersion:(no version))
+libstatssocket(minSdkVersion:30)
libstatssocket_headers(minSdkVersion:29)
libstd(minSdkVersion:29)
libsystem_headers(minSdkVersion:apex_inherit)
@@ -505,6 +511,7 @@
neuralnetworks_utils_hal_1_1(minSdkVersion:30)
neuralnetworks_utils_hal_1_2(minSdkVersion:30)
neuralnetworks_utils_hal_1_3(minSdkVersion:30)
+neuralnetworks_utils_hal_aidl(minSdkVersion:30)
neuralnetworks_utils_hal_common(minSdkVersion:30)
neuralnetworks_utils_hal_service(minSdkVersion:30)
no_op(minSdkVersion:current)
@@ -596,6 +603,7 @@
service-permission(minSdkVersion:30)
service-permission(minSdkVersion:current)
service-permission-shared(minSdkVersion:30)
+service-statsd(minSdkVersion:30)
service-statsd(minSdkVersion:current)
SettingsLibActionBarShadow(minSdkVersion:21)
SettingsLibAppPreference(minSdkVersion:21)
@@ -609,7 +617,9 @@
SettingsLibUtils(minSdkVersion:21)
stats_proto(minSdkVersion:29)
statsd(minSdkVersion:(no version))
+statsd(minSdkVersion:30)
statsd-aidl-ndk_platform(minSdkVersion:(no version))
+statsd-aidl-ndk_platform(minSdkVersion:30)
statsprotos(minSdkVersion:29)
tensorflow_headers(minSdkVersion:(no version))
Tethering(minSdkVersion:30)
diff --git a/apex/apex.go b/apex/apex.go
index cfeac72..e06a967 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -208,6 +208,9 @@
// List of native tests that are embedded inside this APEX.
Tests []string
+
+ // List of filesystem images that are embedded inside this APEX bundle.
+ Filesystems []string
}
type apexMultilibProperties struct {
@@ -580,6 +583,7 @@
ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag, nativeModules.Rust_dyn_libs...)
+ ctx.AddFarVariationDependencies(target.Variations(), fsTag, nativeModules.Filesystems...)
}
func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 9f8cd06..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",
@@ -4364,7 +4364,7 @@
checkDexJarBuildPath := func(t *testing.T, ctx *android.TestContext, name string) {
// Make sure the import has been given the correct path to the dex jar.
- p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.Dependency)
+ p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
dexJarBuildPath := p.DexJarBuildPath()
if expected, actual := ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar", android.NormalizePathForTesting(dexJarBuildPath); actual != expected {
t.Errorf("Incorrect DexJarBuildPath value '%s', expected '%s'", actual, expected)
@@ -4495,6 +4495,12 @@
}
}
+ checkHiddenAPIIndexInputs := func(t *testing.T, ctx *android.TestContext, expectedInputs string) {
+ hiddenAPIIndex := ctx.SingletonForTests("hiddenapi_index")
+ indexRule := hiddenAPIIndex.Rule("singleton-merged-hiddenapi-index")
+ java.CheckHiddenAPIRuleInputs(t, expectedInputs, indexRule)
+ }
+
t.Run("prebuilt only", func(t *testing.T) {
bp := `
prebuilt_apex {
@@ -4519,6 +4525,11 @@
ctx := testDexpreoptWithApexes(t, bp, "", transform)
checkBootDexJarPath(t, ctx, ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+
+ // Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
+ checkHiddenAPIIndexInputs(t, ctx, `
+.intermediates/libfoo/android_common_myapex/hiddenapi/index.csv
+`)
})
t.Run("prebuilt with source library preferred", func(t *testing.T) {
@@ -4588,6 +4599,11 @@
ctx := testDexpreoptWithApexes(t, bp, "", transform)
checkBootDexJarPath(t, ctx, ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+
+ // Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
+ checkHiddenAPIIndexInputs(t, ctx, `
+.intermediates/prebuilt_libfoo/android_common_myapex/hiddenapi/index.csv
+`)
})
t.Run("prebuilt with source apex preferred", func(t *testing.T) {
@@ -4631,7 +4647,12 @@
`
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkBootDexJarPath(t, ctx, ".intermediates/libfoo/android_common_apex10000/aligned/libfoo.jar")
+ checkBootDexJarPath(t, ctx, ".intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar")
+
+ // Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
+ checkHiddenAPIIndexInputs(t, ctx, `
+.intermediates/libfoo/android_common_apex10000/hiddenapi/index.csv
+`)
})
t.Run("prebuilt preferred with source apex disabled", func(t *testing.T) {
@@ -4678,6 +4699,11 @@
ctx := testDexpreoptWithApexes(t, bp, "", transform)
checkBootDexJarPath(t, ctx, ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+
+ // Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
+ checkHiddenAPIIndexInputs(t, ctx, `
+.intermediates/prebuilt_libfoo/android_common_prebuilt_myapex/hiddenapi/index.csv
+`)
})
}
@@ -6304,6 +6330,7 @@
android.RegisterPrebuiltMutators(ctx)
cc.RegisterRequiredBuildComponentsForTest(ctx)
java.RegisterRequiredBuildComponentsForTest(ctx)
+ java.RegisterHiddenApiSingletonComponents(ctx)
ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
ctx.PreDepsMutators(RegisterPreDepsMutators)
ctx.PostDepsMutators(RegisterPostDepsMutators)
@@ -6315,6 +6342,11 @@
transformDexpreoptConfig(dexpreoptConfig)
dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
+ // Make sure that any changes to these dexpreopt properties are mirrored in the corresponding
+ // product variables.
+ config.TestProductVariables.BootJars = dexpreoptConfig.BootJars
+ config.TestProductVariables.UpdatableBootJars = dexpreoptConfig.UpdatableBootJars
+
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
android.FailIfErrored(t, errs)
diff --git a/apex/builder.go b/apex/builder.go
index 16ca74c..2663a67 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -700,15 +700,20 @@
})
a.apisUsedByModuleFile = apisUsedbyOutputFile
+ var libNames []string
+ for _, f := range a.filesInfo {
+ if f.class == nativeSharedLib {
+ libNames = append(libNames, f.stem())
+ }
+ }
apisBackedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_backing.txt")
ndkLibraryList := android.PathForSource(ctx, "system/core/rootdir/etc/public.libraries.android.txt")
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
Tool(android.PathForSource(ctx, "build/soong/scripts/gen_ndk_backedby_apex.sh")).
- Text(imageDir.String()).
- Implicits(implicitInputs).
Output(apisBackedbyOutputFile).
- Input(ndkLibraryList)
+ Input(ndkLibraryList).
+ Flags(libNames)
rule.Build("ndk_backedby_list", "Generate API libraries backed by Apex")
a.apisBackedByModuleFile = apisBackedbyOutputFile
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 3149952..041afb3 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -260,12 +260,36 @@
}
}
+type exportedDependencyTag struct {
+ blueprint.BaseDependencyTag
+ name string
+}
+
+// Mark this tag so dependencies that use it are excluded from visibility enforcement.
+//
+// This does allow any prebuilt_apex to reference any module which does open up a small window for
+// restricted visibility modules to be referenced from the wrong prebuilt_apex. However, doing so
+// avoids opening up a much bigger window by widening the visibility of modules that need files
+// provided by the prebuilt_apex to include all the possible locations they may be defined, which
+// could include everything below vendor/.
+//
+// A prebuilt_apex that references a module via this tag will have to contain the appropriate files
+// corresponding to that module, otherwise it will fail when attempting to retrieve the files from
+// the .apex file. It will also have to be included in the module's apex_available property too.
+// That makes it highly unlikely that a prebuilt_apex would reference a restricted module
+// incorrectly.
+func (t exportedDependencyTag) ExcludeFromVisibilityEnforcement() {}
+
+var (
+ exportedJavaLibTag = exportedDependencyTag{name: "exported_java_lib"}
+)
+
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 {
dep := prebuiltApexExportedModuleName(ctx, lib)
- ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), javaLibTag, dep)
+ ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), exportedJavaLibTag, dep)
}
}
@@ -305,7 +329,7 @@
var dependencies []android.ApexModule
mctx.VisitDirectDeps(func(m android.Module) {
tag := mctx.OtherModuleDependencyTag(m)
- if tag == javaLibTag {
+ if tag == exportedJavaLibTag {
depName := mctx.OtherModuleName(m)
// It is an error if the other module is not a prebuilt.
diff --git a/bazel/Android.bp b/bazel/Android.bp
index d222d98..117fd46 100644
--- a/bazel/Android.bp
+++ b/bazel/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-bazel",
pkgPath: "android/soong/bazel",
diff --git a/bazel/properties.go b/bazel/properties.go
index 5b98d15..8055306 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -14,9 +14,17 @@
package bazel
+import (
+ "fmt"
+ "strings"
+)
+
type bazelModuleProperties struct {
// The label of the Bazel target replacing this Soong module.
Label string
+
+ // If true, bp2build will generate the converted Bazel target for this module.
+ Bp2build_available bool
}
// Properties contains common module properties for Bazel migration purposes.
@@ -29,6 +37,8 @@
// BazelTargetModuleProperties contain properties and metadata used for
// Blueprint to BUILD file conversion.
type BazelTargetModuleProperties struct {
+ Name *string
+
// The Bazel rule class for this target.
Rule_class string
@@ -36,6 +46,23 @@
Bzl_load_location string
}
+const BazelTargetModuleNamePrefix = "__bp2build__"
+
+func NewBazelTargetModuleProperties(name string, ruleClass string, bzlLoadLocation string) BazelTargetModuleProperties {
+ if strings.HasPrefix(name, BazelTargetModuleNamePrefix) {
+ panic(fmt.Errorf(
+ "The %s name prefix is added automatically, do not set it manually: %s",
+ BazelTargetModuleNamePrefix,
+ name))
+ }
+ name = BazelTargetModuleNamePrefix + name
+ return BazelTargetModuleProperties{
+ Name: &name,
+ Rule_class: ruleClass,
+ Bzl_load_location: bzlLoadLocation,
+ }
+}
+
// Label is used to represent a Bazel compatible Label. Also stores the original bp text to support
// string replacement.
type Label struct {
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 2bbe4b5..ddde1b7 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-bp2build",
pkgPath: "android/soong/bp2build",
@@ -11,12 +15,16 @@
deps: [
"soong-android",
"soong-bazel",
+ "soong-cc",
"soong-genrule",
+ "soong-sh",
],
testSrcs: [
"build_conversion_test.go",
"bzl_conversion_test.go",
+ "cc_conversion_test.go",
"conversion_test.go",
+ "sh_conversion_test.go",
"testing.go",
],
pluginFor: [
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 2c293ea..7ffcfa4 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -173,6 +173,12 @@
}
t = generateBazelTarget(ctx, m)
case QueryView:
+ // Blocklist certain module types from being generated.
+ if canonicalizeModuleType(ctx.ModuleType(m)) == "package" {
+ // package module name contain slashes, and thus cannot
+ // be mapped cleanly to a bazel label.
+ return
+ }
t = generateSoongModuleTarget(ctx, m)
default:
panic(fmt.Errorf("Unknown code-generation mode: %s", codegenMode))
@@ -213,6 +219,8 @@
// Delete it from being generated in the BUILD file.
delete(props.Attrs, "bzl_load_location")
+ delete(props.Attrs, "bp2build_available")
+
// Return the Bazel target with rule class and attributes, ready to be
// code-generated.
attributes := propsToAttributes(props.Attrs)
@@ -461,7 +469,7 @@
}
func targetNameForBp2Build(c bpToBuildContext, logicModule blueprint.Module) string {
- return strings.Replace(c.ModuleName(logicModule), "__bp2build__", "", 1)
+ return strings.Replace(c.ModuleName(logicModule), bazel.BazelTargetModuleNamePrefix, "", 1)
}
func targetNameWithVariant(c bpToBuildContext, logicModule blueprint.Module) string {
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 081b0e5..422422b 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -228,6 +228,7 @@
name: "foo",
string_list_prop: ["a", "b"],
string_prop: "a",
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTarget: `custom(
name = "foo",
@@ -382,6 +383,7 @@
{
bp: `custom {
name: "bar",
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTarget: `my_library(
name = "bar",
@@ -467,6 +469,21 @@
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,
@@ -474,6 +491,7 @@
bp: `filegroup {
name: "fg_foo",
srcs: [],
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
`filegroup(
@@ -491,6 +509,7 @@
bp: `filegroup {
name: "fg_foo",
srcs: ["a", "b"],
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`filegroup(
name = "fg_foo",
@@ -510,6 +529,7 @@
name: "fg_foo",
srcs: ["a", "b"],
exclude_srcs: ["a"],
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`filegroup(
name = "fg_foo",
@@ -527,6 +547,7 @@
bp: `filegroup {
name: "foo",
srcs: ["**/*.txt"],
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`filegroup(
name = "foo",
@@ -552,6 +573,7 @@
bp: `filegroup {
name: "foo",
srcs: ["a.txt"],
+ bazel_module: { bp2build_available: true },
}`,
dir: "other",
expectedBazelTargets: []string{`filegroup(
@@ -567,6 +589,7 @@
"other/Android.bp": `filegroup {
name: "fg_foo",
srcs: ["**/*.txt"],
+ bazel_module: { bp2build_available: true },
}`,
"other/a.txt": "",
"other/b.txt": "",
@@ -585,6 +608,7 @@
":foo",
"c",
],
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`filegroup(
name = "foobar",
@@ -612,6 +636,7 @@
out: ["foo_tool.out"],
srcs: ["foo_tool.in"],
cmd: "cp $(in) $(out)",
+ bazel_module: { bp2build_available: true },
}
genrule {
@@ -620,6 +645,7 @@
srcs: ["foo.in"],
tools: [":foo.tool"],
cmd: "$(location :foo.tool) --genDir=$(genDir) arg $(in) $(out)",
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{
`genrule(
@@ -658,7 +684,8 @@
out: ["foo_tool.out", "foo_tool2.out"],
srcs: ["foo_tool.in"],
cmd: "cp $(in) $(out)",
- }
+ bazel_module: { bp2build_available: true },
+}
genrule {
name: "foo",
@@ -666,6 +693,7 @@
srcs: ["foo.in"],
tools: [":foo.tools"],
cmd: "$(locations :foo.tools) -s $(out) $(in)",
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`genrule(
name = "foo",
@@ -705,6 +733,7 @@
srcs: ["foo.in"],
tool_files: [":foo.tool"],
cmd: "$(locations :foo.tool) -s $(out) $(in)",
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`genrule(
name = "foo",
@@ -734,6 +763,7 @@
srcs: [":other.tool"],
tool_files: [":foo.tool"],
cmd: "$(locations :foo.tool) -s $(out) $(location :other.tool)",
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`genrule(
name = "foo",
@@ -763,6 +793,7 @@
srcs: ["foo.in"],
tool_files: [":foo.tool", ":other.tool"],
cmd: "$(location) -s $(out) $(in)",
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`genrule(
name = "foo",
@@ -793,6 +824,7 @@
srcs: ["foo.in"],
tools: [":foo.tool", ":other.tool"],
cmd: "$(locations) -s $(out) $(in)",
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`genrule(
name = "foo",
@@ -822,6 +854,7 @@
out: ["foo.out"],
srcs: ["foo.in"],
cmd: "cp $(in) $(out)",
+ bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`genrule(
name = "foo",
@@ -927,6 +960,7 @@
out: ["out"],
srcs: ["in1"],
defaults: ["gen_defaults"],
+ bazel_module: { bp2build_available: true },
}
`,
expectedBazelTarget: `genrule(
@@ -961,6 +995,7 @@
srcs: ["in1"],
defaults: ["gen_defaults"],
cmd: "do-something $(in) $(out)",
+ bazel_module: { bp2build_available: true },
}
`,
expectedBazelTarget: `genrule(
@@ -999,6 +1034,7 @@
name: "gen",
out: ["out"],
defaults: ["gen_defaults1", "gen_defaults2"],
+ bazel_module: { bp2build_available: true },
}
`,
expectedBazelTarget: `genrule(
@@ -1045,6 +1081,7 @@
name: "gen",
out: ["out"],
defaults: ["gen_defaults1"],
+ bazel_module: { bp2build_available: true },
}
`,
expectedBazelTarget: `genrule(
@@ -1097,3 +1134,80 @@
}
}
}
+
+func TestAllowlistingBp2buildTargets(t *testing.T) {
+ testCases := []struct {
+ moduleTypeUnderTest string
+ moduleTypeUnderTestFactory android.ModuleFactory
+ moduleTypeUnderTestBp2BuildMutator bp2buildMutator
+ bp string
+ expectedCount int
+ description string
+ }{
+ {
+ description: "explicitly unavailable",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ bp: `filegroup {
+ name: "foo",
+ srcs: ["a", "b"],
+ bazel_module: { bp2build_available: false },
+}`,
+ expectedCount: 0,
+ },
+ {
+ description: "implicitly unavailable",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ bp: `filegroup {
+ name: "foo",
+ srcs: ["a", "b"],
+}`,
+ expectedCount: 0,
+ },
+ {
+ description: "explicitly available",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ bp: `filegroup {
+ name: "foo",
+ srcs: ["a", "b"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedCount: 1,
+ },
+ {
+ description: "generates more than 1 target if needed",
+ moduleTypeUnderTest: "custom",
+ moduleTypeUnderTestFactory: customModuleFactory,
+ moduleTypeUnderTestBp2BuildMutator: customBp2BuildMutatorFromStarlark,
+ bp: `custom {
+ name: "foo",
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedCount: 3,
+ },
+ }
+
+ dir := "."
+ for _, testCase := range testCases {
+ config := android.TestConfig(buildDir, nil, testCase.bp, nil)
+ ctx := android.NewTestContext(config)
+ ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
+ ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
+ ctx.RegisterForBazelConversion()
+
+ _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.ResolveDependencies(config)
+ android.FailIfErrored(t, errs)
+
+ bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
+ if actualCount := len(bazelTargets); actualCount != testCase.expectedCount {
+ t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount)
+ }
+ }
+}
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index f2a4058..30c1a5b 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -86,6 +86,10 @@
"soong_module_name": attr.string(mandatory = True),
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
+ # bazel_module start
+# "label": attr.string(),
+# "bp2build_available": attr.bool(),
+ # bazel_module end
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"int64_ptr_prop": attr.int(),
diff --git a/bp2build/cc_conversion_test.go b/bp2build/cc_conversion_test.go
new file mode 100644
index 0000000..3cd3762
--- /dev/null
+++ b/bp2build/cc_conversion_test.go
@@ -0,0 +1,221 @@
+// 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"
+ "strings"
+ "testing"
+)
+
+const (
+ // See cc/testing.go for more context
+ soongCcLibraryPreamble = `
+cc_defaults {
+ name: "linux_bionic_supported",
+}
+
+toolchain_library {
+ name: "libclang_rt.builtins-x86_64-android",
+ defaults: ["linux_bionic_supported"],
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ product_available: true,
+ recovery_available: true,
+ native_bridge_supported: true,
+ src: "",
+}
+
+toolchain_library {
+ name: "libatomic",
+ defaults: ["linux_bionic_supported"],
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ product_available: true,
+ recovery_available: true,
+ native_bridge_supported: true,
+ src: "",
+}`
+)
+
+func TestCcLibraryHeadersLoadStatement(t *testing.T) {
+ testCases := []struct {
+ bazelTargets BazelTargets
+ expectedLoadStatements string
+ }{
+ {
+ bazelTargets: BazelTargets{
+ BazelTarget{
+ name: "cc_library_headers_target",
+ ruleClass: "cc_library_headers",
+ // Note: no bzlLoadLocation for native 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 TestCcLibraryHeadersBp2Build(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: "cc_library_headers test",
+ moduleTypeUnderTest: "cc_library_headers",
+ moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
+ filesystem: map[string]string{
+ "lib-1/lib1a.h": "",
+ "lib-1/lib1b.h": "",
+ "lib-2/lib2a.h": "",
+ "lib-2/lib2b.h": "",
+ "dir-1/dir1a.h": "",
+ "dir-1/dir1b.h": "",
+ "dir-2/dir2a.h": "",
+ "dir-2/dir2b.h": "",
+ },
+ bp: soongCcLibraryPreamble + `
+cc_library_headers {
+ name: "lib-1",
+ export_include_dirs: ["lib-1"],
+ bazel_module: { bp2build_available: true },
+}
+
+cc_library_headers {
+ name: "lib-2",
+ export_include_dirs: ["lib-2"],
+ bazel_module: { bp2build_available: true },
+}
+
+cc_library_headers {
+ name: "foo_headers",
+ export_include_dirs: ["dir-1", "dir-2"],
+ header_libs: ["lib-1", "lib-2"],
+ export_header_lib_headers: ["lib-1", "lib-2"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{`cc_library_headers(
+ name = "foo_headers",
+ deps = [
+ ":lib-1",
+ ":lib-2",
+ ],
+ hdrs = [
+ "dir-1/dir1a.h",
+ "dir-1/dir1b.h",
+ "dir-2/dir2a.h",
+ "dir-2/dir2b.h",
+ ],
+ includes = [
+ "dir-1",
+ "dir-2",
+ ],
+)`, `cc_library_headers(
+ name = "lib-1",
+ hdrs = [
+ "lib-1/lib1a.h",
+ "lib-1/lib1b.h",
+ ],
+ includes = [
+ "lib-1",
+ ],
+)`, `cc_library_headers(
+ name = "lib-2",
+ hdrs = [
+ "lib-2/lib2a.h",
+ "lib-2/lib2b.h",
+ ],
+ includes = [
+ "lib-2",
+ ],
+)`},
+ },
+ }
+
+ 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)
+
+ cc.RegisterCCBuildComponents(ctx)
+ ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
+
+ 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/bp2build/conversion.go b/bp2build/conversion.go
index 62cd8d4..081e082 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -50,14 +50,19 @@
sort.Slice(targets, func(i, j int) bool { return targets[i].name < targets[j].name })
content := soongModuleLoad
if mode == Bp2Build {
- content = targets.LoadStatements()
+ content = `# This file was automatically generated by bp2build for the Bazel migration project.
+# Feel free to edit or test it, but do *not* check it into your version control system.`
+ content += "\n\n"
+ content += "package(default_visibility = [\"//visibility:public\"])"
+ content += "\n\n"
+ content += targets.LoadStatements()
}
if content != "" {
// If there are load statements, add a couple of newlines.
content += "\n\n"
}
content += targets.String()
- files = append(files, newFile(dir, "BUILD.bazel", content))
+ files = append(files, newFile(dir, "BUILD", content))
}
return files
}
diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go
new file mode 100644
index 0000000..dcc75bd
--- /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/bp2build/testing.go b/bp2build/testing.go
index 5e6481b..2e59999 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -3,8 +3,6 @@
import (
"android/soong/android"
"android/soong/bazel"
-
- "github.com/google/blueprint/proptools"
)
type nestedProps struct {
@@ -29,6 +27,8 @@
android.ModuleBase
props customProps
+
+ bazelProps bazel.Properties
}
// OutputFiles is needed because some instances of this module use dist with a
@@ -44,6 +44,7 @@
func customModuleFactoryBase() android.Module {
module := &customModule{}
module.AddProperties(&module.props)
+ module.AddProperties(&module.bazelProps)
return module
}
@@ -105,7 +106,6 @@
}
type customBazelModuleAttributes struct {
- Name *string
String_prop string
String_list_prop []string
}
@@ -127,14 +127,18 @@
func customBp2BuildMutator(ctx android.TopDownMutatorContext) {
if m, ok := ctx.Module().(*customModule); ok {
- name := "__bp2build__" + m.Name()
- ctx.CreateModule(customBazelModuleFactory, &customBazelModuleAttributes{
- Name: proptools.StringPtr(name),
+ if !m.bazelProps.Bazel_module.Bp2build_available {
+ return
+ }
+
+ attrs := &customBazelModuleAttributes{
String_prop: m.props.String_prop,
String_list_prop: m.props.String_list_prop,
- }, &bazel.BazelTargetModuleProperties{
- Rule_class: "custom",
- })
+ }
+
+ props := bazel.NewBazelTargetModuleProperties(m.Name(), "custom", "")
+
+ ctx.CreateBazelTargetModule(customBazelModuleFactory, props, attrs)
}
}
@@ -142,24 +146,32 @@
// module to target.
func customBp2BuildMutatorFromStarlark(ctx android.TopDownMutatorContext) {
if m, ok := ctx.Module().(*customModule); ok {
- baseName := "__bp2build__" + m.Name()
- ctx.CreateModule(customBazelModuleFactory, &customBazelModuleAttributes{
- Name: proptools.StringPtr(baseName),
- }, &bazel.BazelTargetModuleProperties{
- Rule_class: "my_library",
- Bzl_load_location: "//build/bazel/rules:rules.bzl",
- })
- ctx.CreateModule(customBazelModuleFactory, &customBazelModuleAttributes{
- Name: proptools.StringPtr(baseName + "_proto_library_deps"),
- }, &bazel.BazelTargetModuleProperties{
- Rule_class: "proto_library",
- Bzl_load_location: "//build/bazel/rules:proto.bzl",
- })
- ctx.CreateModule(customBazelModuleFactory, &customBazelModuleAttributes{
- Name: proptools.StringPtr(baseName + "_my_proto_library_deps"),
- }, &bazel.BazelTargetModuleProperties{
- Rule_class: "my_proto_library",
- Bzl_load_location: "//build/bazel/rules:proto.bzl",
- })
+ if !m.bazelProps.Bazel_module.Bp2build_available {
+ return
+ }
+
+ baseName := m.Name()
+ attrs := &customBazelModuleAttributes{}
+
+ myLibraryProps := bazel.NewBazelTargetModuleProperties(
+ baseName,
+ "my_library",
+ "//build/bazel/rules:rules.bzl",
+ )
+ ctx.CreateBazelTargetModule(customBazelModuleFactory, myLibraryProps, attrs)
+
+ protoLibraryProps := bazel.NewBazelTargetModuleProperties(
+ baseName+"_proto_library_deps",
+ "proto_library",
+ "//build/bazel/rules:proto.bzl",
+ )
+ ctx.CreateBazelTargetModule(customBazelModuleFactory, protoLibraryProps, attrs)
+
+ myProtoLibraryProps := bazel.NewBazelTargetModuleProperties(
+ baseName+"_my_proto_library_deps",
+ "my_proto_library",
+ "//build/bazel/rules:proto.bzl",
+ )
+ ctx.CreateBazelTargetModule(customBazelModuleFactory, myProtoLibraryProps, attrs)
}
}
diff --git a/bpf/Android.bp b/bpf/Android.bp
index 882cd8a..3ffa29f 100644
--- a/bpf/Android.bp
+++ b/bpf/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-bpf",
pkgPath: "android/soong/bpf",
diff --git a/bpfix/Android.bp b/bpfix/Android.bp
index b244e3a..345dbd0 100644
--- a/bpfix/Android.bp
+++ b/bpfix/Android.bp
@@ -16,6 +16,10 @@
// androidmk Android.mk to Blueprints translator
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "bpfix",
srcs: [
diff --git a/cc/Android.bp b/cc/Android.bp
index 6ec7e0e..bdbb3c0 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-cc",
pkgPath: "android/soong/cc",
diff --git a/cc/androidmk.go b/cc/androidmk.go
index ddb81d9..8652c10 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -26,9 +26,9 @@
var (
nativeBridgeSuffix = ".native_bridge"
productSuffix = ".product"
- vendorSuffix = ".vendor"
+ VendorSuffix = ".vendor"
ramdiskSuffix = ".ramdisk"
- vendorRamdiskSuffix = ".vendor_ramdisk"
+ VendorRamdiskSuffix = ".vendor_ramdisk"
recoverySuffix = ".recovery"
sdkSuffix = ".sdk"
)
diff --git a/cc/cc.go b/cc/cc.go
index df38499..7f59158 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1544,7 +1544,7 @@
nameSuffix = productSuffix
} else {
vndkVersion = ctx.DeviceConfig().VndkVersion()
- nameSuffix = vendorSuffix
+ nameSuffix = VendorSuffix
}
if vndkVersion == "current" {
vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
@@ -1591,11 +1591,11 @@
} else if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok {
// .vendor suffix is added for backward compatibility with VNDK snapshot whose names with
// such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp.
- c.Properties.SubName += vendorSuffix
+ c.Properties.SubName += VendorSuffix
} else if c.InRamdisk() && !c.OnlyInRamdisk() {
c.Properties.SubName += ramdiskSuffix
} else if c.InVendorRamdisk() && !c.OnlyInVendorRamdisk() {
- c.Properties.SubName += vendorRamdiskSuffix
+ c.Properties.SubName += VendorRamdiskSuffix
} else if c.InRecovery() && !c.OnlyInRecovery() {
c.Properties.SubName += recoverySuffix
} else if c.IsSdkVariant() && (c.Properties.SdkAndPlatformVariantVisibleToMake || c.SplitPerApiLevel()) {
@@ -2927,7 +2927,7 @@
} else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() {
return libName + ramdiskSuffix
} else if ccDep.InVendorRamdisk() && !ccDep.OnlyInVendorRamdisk() {
- return libName + vendorRamdiskSuffix
+ return libName + VendorRamdiskSuffix
} else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() {
return libName + recoverySuffix
} else if ccDep.Target().NativeBridge == android.NativeBridgeEnabled {
diff --git a/cc/config/Android.bp b/cc/config/Android.bp
index ce4bdfb..5ef247d 100644
--- a/cc/config/Android.bp
+++ b/cc/config/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-cc-config",
pkgPath: "android/soong/cc/config",
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index e6024aa..d083d2a 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -31,6 +31,10 @@
"armv8-a": []string{
"-march=armv8-a",
},
+ "armv8-a-branchprot": []string{
+ "-march=armv8-a",
+ "-mbranch-protection=standard",
+ },
"armv8-2a": []string{
"-march=armv8.2-a",
},
@@ -102,6 +106,7 @@
pctx.StaticVariable("Arm64ClangCppflags", strings.Join(ClangFilterUnknownCflags(arm64Cppflags), " "))
pctx.StaticVariable("Arm64ClangArmv8ACflags", strings.Join(arm64ArchVariantCflags["armv8-a"], " "))
+ pctx.StaticVariable("Arm64ClangArmv8ABranchProtCflags", strings.Join(arm64ArchVariantCflags["armv8-a-branchprot"], " "))
pctx.StaticVariable("Arm64ClangArmv82ACflags", strings.Join(arm64ArchVariantCflags["armv8-2a"], " "))
pctx.StaticVariable("Arm64ClangArmv82ADotprodCflags", strings.Join(arm64ArchVariantCflags["armv8-2a-dotprod"], " "))
@@ -124,6 +129,7 @@
var (
arm64ClangArchVariantCflagsVar = map[string]string{
"armv8-a": "${config.Arm64ClangArmv8ACflags}",
+ "armv8-a-branchprot": "${config.Arm64ClangArmv8ABranchProtCflags}",
"armv8-2a": "${config.Arm64ClangArmv82ACflags}",
"armv8-2a-dotprod": "${config.Arm64ClangArmv82ADotprodCflags}",
}
@@ -202,6 +208,7 @@
func arm64ToolchainFactory(arch android.Arch) Toolchain {
switch arch.ArchVariant {
case "armv8-a":
+ case "armv8-a-branchprot":
case "armv8-2a":
case "armv8-2a-dotprod":
// Nothing extra for armv8-a/armv8-2a
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 71c7626..76186be 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -150,6 +150,8 @@
"-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 ee41125..e60bb3d 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -144,8 +144,8 @@
// 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/cc/config/tidy.go b/cc/config/tidy.go
index 7cc9f43..7c20dd5 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -87,27 +87,11 @@
}, ",")
})
- // Give warnings to header files only in selected directories.
- // Do not give warnings to external or vendor header files, which contain too
- // many warnings.
+ // To reduce duplicate warnings from the same header files,
+ // header-filter will contain only the module directory and
+ // those specified by DEFAULT_TIDY_HEADER_DIRS.
pctx.VariableFunc("TidyDefaultHeaderDirs", func(ctx android.PackageVarContext) string {
- if override := ctx.Config().Getenv("DEFAULT_TIDY_HEADER_DIRS"); override != "" {
- return override
- }
- return strings.Join([]string{
- "art/",
- "bionic/",
- "bootable/",
- "build/",
- "cts/",
- "dalvik/",
- "developers/",
- "development/",
- "frameworks/",
- "libcore/",
- "libnativehelper/",
- "system/",
- }, "|")
+ return ctx.Config().Getenv("DEFAULT_TIDY_HEADER_DIRS")
})
// Use WTIH_TIDY_FLAGS to pass extra global default clang-tidy flags.
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index 45c18c2..425e349 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -41,6 +41,9 @@
"android.hardware.power-V1-ndk_platform",
"android.hardware.power-ndk_platform",
"android.hardware.rebootescrow-V1-ndk_platform",
+ "android.hardware.power.stats-V1-ndk_platform",
+ "android.hardware.power.stats-ndk_platform",
+ "android.hardware.power.stats-unstable-ndk_platform",
"android.hardware.rebootescrow-ndk_platform",
"android.hardware.security.keymint-V1-ndk_platform",
"android.hardware.security.keymint-ndk_platform",
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/libbuildversion/Android.bp b/cc/libbuildversion/Android.bp
index b63338d..4debb1c 100644
--- a/cc/libbuildversion/Android.bp
+++ b/cc/libbuildversion/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "libbuildversion",
host_supported: true,
diff --git a/cc/libbuildversion/tests/Android.bp b/cc/libbuildversion/tests/Android.bp
index b3b2061..0e97fed 100644
--- a/cc/libbuildversion/tests/Android.bp
+++ b/cc/libbuildversion/tests/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_defaults {
name: "build_version_test_defaults",
use_version_lib: true,
diff --git a/cc/library.go b/cc/library.go
index f185cb7..bdcb8ae 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -27,6 +27,7 @@
"github.com/google/blueprint/pathtools"
"android/soong/android"
+ "android/soong/bazel"
"android/soong/cc/config"
)
@@ -120,6 +121,9 @@
// 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
@@ -648,6 +652,11 @@
return objs
}
if library.buildStubs() {
+ symbolFile := String(library.Properties.Stubs.Symbol_file)
+ if symbolFile != "" && !strings.HasSuffix(symbolFile, ".map.txt") {
+ ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
+ return Objects{}
+ }
objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Stubs.Symbol_file), library.MutatedProperties.StubsVersion, "--apex")
library.versionScriptPath = android.OptionalPathForPath(versionScript)
return objs
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 8b3dbeb..448e144 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -14,13 +14,18 @@
package cc
-import "android/soong/android"
+import (
+ "android/soong/android"
+ "android/soong/bazel"
+)
func init() {
RegisterLibraryHeadersBuildComponents(android.InitRegistrationContext)
// Register sdk member types.
android.RegisterSdkMemberType(headersLibrarySdkMemberType)
+
+ android.RegisterBp2BuildMutator("cc_library_headers", CcLibraryHeadersBp2Build)
}
var headersLibrarySdkMemberType = &librarySdkMemberType{
@@ -55,3 +60,86 @@
library.HeaderOnly()
return module.Init()
}
+
+type bazelCcLibraryHeadersAttributes struct {
+ Hdrs bazel.LabelList
+ Includes bazel.LabelList
+ Deps bazel.LabelList
+}
+
+type bazelCcLibraryHeaders struct {
+ android.BazelTargetModuleBase
+ bazelCcLibraryHeadersAttributes
+}
+
+func BazelCcLibraryHeadersFactory() android.Module {
+ module := &bazelCcLibraryHeaders{}
+ module.AddProperties(&module.bazelCcLibraryHeadersAttributes)
+ android.InitBazelTargetModule(module)
+ return module
+}
+
+func CcLibraryHeadersBp2Build(ctx android.TopDownMutatorContext) {
+ module, ok := ctx.Module().(*Module)
+ if !ok {
+ // Not a cc module
+ return
+ }
+
+ lib, ok := module.linker.(*libraryDecorator)
+ if !ok {
+ // Not a cc_library module
+ return
+ }
+ if !lib.header() {
+ // Not a cc_library_headers module
+ 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
+ includeDirs = append(includeDirs, lib.flagExporter.Properties.Export_include_dirs...)
+ includeDirLabels := android.BazelLabelForModuleSrc(ctx, includeDirs)
+
+ var includeDirGlobs []string
+ for _, includeDir := range includeDirs {
+ includeDirGlobs = append(includeDirGlobs, includeDir+"/**/*.h")
+ }
+
+ headerLabels := android.BazelLabelForModuleSrc(ctx, includeDirGlobs)
+
+ // list of modules that should only provide headers for this module.
+ var headerLibs []string
+ for _, linkerProps := range lib.linkerProps() {
+ if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
+ headerLibs = baseLinkerProps.Export_header_lib_headers
+ break
+ }
+ }
+ headerLibLabels := android.BazelLabelForModuleDeps(ctx, headerLibs)
+
+ attrs := &bazelCcLibraryHeadersAttributes{
+ Includes: includeDirLabels,
+ Hdrs: headerLabels,
+ Deps: headerLibLabels,
+ }
+
+ props := bazel.NewBazelTargetModuleProperties(
+ module.Name(),
+ "cc_library_headers",
+ "//build/bazel/rules:cc_library_headers.bzl",
+ )
+
+ ctx.CreateBazelTargetModule(BazelCcLibraryHeadersFactory, props, attrs)
+}
+
+func (m *bazelCcLibraryHeaders) Name() string {
+ return m.BaseModuleName()
+}
+
+func (m *bazelCcLibraryHeaders) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/cc/ndk_api_coverage_parser/Android.bp b/cc/ndk_api_coverage_parser/Android.bp
index 8d9827c..b119e90 100644
--- a/cc/ndk_api_coverage_parser/Android.bp
+++ b/cc/ndk_api_coverage_parser/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
python_library_host {
name: "ndk_api_coverage_parser_lib",
pkg_path: "ndk_api_coverage_parser",
diff --git a/cc/ndkstubgen/Android.bp b/cc/ndkstubgen/Android.bp
index 85dfaee..782c124 100644
--- a/cc/ndkstubgen/Android.bp
+++ b/cc/ndkstubgen/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
python_binary_host {
name: "ndkstubgen",
pkg_path: "ndkstubgen",
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index ffaed8e..62daafd 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -144,7 +144,7 @@
}
func (vendorSnapshotImage) moduleNameSuffix() string {
- return vendorSuffix
+ return VendorSuffix
}
func (recoverySnapshotImage) init(ctx android.RegistrationContext) {
@@ -195,8 +195,12 @@
}
func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
- // directed recovery snapshot is not implemented yet
- return false
+ // If we're using full snapshot, not directed snapshot, capture every module
+ if !cfg.DirectedRecoverySnapshot() {
+ return false
+ }
+ // Else, checks if name is in RECOVERY_SNAPSHOT_MODULES.
+ return !cfg.RecoverySnapshotModules()[name]
}
func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
diff --git a/cc/symbolfile/Android.bp b/cc/symbolfile/Android.bp
index 5b43309..6722110 100644
--- a/cc/symbolfile/Android.bp
+++ b/cc/symbolfile/Android.bp
@@ -14,6 +14,10 @@
// limitations under the License.
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
python_library_host {
name: "symbolfile",
pkg_path: "symbolfile",
diff --git a/cc/testing.go b/cc/testing.go
index 3a5bd17..45e5312 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -43,6 +43,7 @@
name: "libatomic",
defaults: ["linux_bionic_supported"],
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_bridge_supported: true,
@@ -52,6 +53,7 @@
toolchain_library {
name: "libcompiler_rt-extras",
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
src: "",
@@ -60,6 +62,7 @@
toolchain_library {
name: "libclang_rt.builtins-arm-android",
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_bridge_supported: true,
@@ -69,6 +72,7 @@
toolchain_library {
name: "libclang_rt.builtins-aarch64-android",
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_bridge_supported: true,
@@ -93,6 +97,7 @@
toolchain_library {
name: "libclang_rt.builtins-i686-android",
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_bridge_supported: true,
@@ -103,6 +108,7 @@
name: "libclang_rt.builtins-x86_64-android",
defaults: ["linux_bionic_supported"],
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_bridge_supported: true,
@@ -113,6 +119,7 @@
name: "libunwind",
defaults: ["linux_bionic_supported"],
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_bridge_supported: true,
@@ -238,6 +245,7 @@
cc_library {
name: "libprofile-extras",
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_coverage: false,
@@ -248,6 +256,7 @@
cc_library {
name: "libprofile-clang-extras",
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_coverage: false,
@@ -319,6 +328,7 @@
system_shared_libs: [],
stl: "none",
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
host_supported: true,
@@ -356,6 +366,7 @@
stl: "none",
host_supported: false,
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
min_sdk_version: "29",
@@ -380,6 +391,7 @@
defaults: ["linux_bionic_supported"],
recovery_available: true,
vendor_available: true,
+ vendor_ramdisk_available: true,
product_available: true,
native_bridge_supported: true,
stl: "none",
diff --git a/cc/tidy.go b/cc/tidy.go
index 972ad7b..251c67b 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -20,6 +20,7 @@
"github.com/google/blueprint/proptools"
+ "android/soong/android"
"android/soong/cc/config"
)
@@ -75,9 +76,17 @@
}
esc := proptools.NinjaAndShellEscapeList
flags.TidyFlags = append(flags.TidyFlags, esc(tidy.Properties.Tidy_flags)...)
- // If TidyFlags is empty, add default header filter.
- if len(flags.TidyFlags) == 0 {
- headerFilter := "-header-filter=\"(" + ctx.ModuleDir() + "|${config.TidyDefaultHeaderDirs})\""
+ // If TidyFlags does not contain -header-filter, add default header filter.
+ // Find the substring because the flag could also appear as --header-filter=...
+ // and with or without single or double quotes.
+ if !android.SubstringInList(flags.TidyFlags, "-header-filter=") {
+ defaultDirs := ctx.Config().Getenv("DEFAULT_TIDY_HEADER_DIRS")
+ headerFilter := "-header-filter="
+ if defaultDirs == "" {
+ headerFilter += ctx.ModuleDir() + "/"
+ } else {
+ headerFilter += "\"(" + ctx.ModuleDir() + "/|" + defaultDirs + ")\""
+ }
flags.TidyFlags = append(flags.TidyFlags, headerFilter)
}
diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go
index 659b693..7e283fb 100644
--- a/cc/vendor_snapshot_test.go
+++ b/cc/vendor_snapshot_test.go
@@ -1051,3 +1051,85 @@
}
}
}
+
+func TestRecoverySnapshotDirected(t *testing.T) {
+ bp := `
+ cc_library_shared {
+ name: "librecovery",
+ recovery: true,
+ nocrt: true,
+ }
+
+ cc_library_shared {
+ name: "librecovery_available",
+ recovery_available: true,
+ nocrt: true,
+ }
+
+ genrule {
+ name: "libfoo_gen",
+ cmd: "",
+ out: ["libfoo.so"],
+ }
+
+ cc_prebuilt_library_shared {
+ name: "libfoo",
+ recovery: true,
+ prefer: true,
+ srcs: [":libfoo_gen"],
+ }
+
+ cc_library_shared {
+ name: "libfoo",
+ recovery: true,
+ nocrt: true,
+ }
+`
+ config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+ config.TestProductVariables.DirectedRecoverySnapshot = true
+ config.TestProductVariables.RecoverySnapshotModules = make(map[string]bool)
+ config.TestProductVariables.RecoverySnapshotModules["librecovery"] = true
+ config.TestProductVariables.RecoverySnapshotModules["libfoo"] = true
+ ctx := testCcWithConfig(t, config)
+
+ // Check recovery snapshot output.
+
+ snapshotDir := "recovery-snapshot"
+ snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+ snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
+
+ var includeJsonFiles []string
+
+ for _, arch := range [][]string{
+ []string{"arm64", "armv8-a"},
+ } {
+ archType := arch[0]
+ archVariant := arch[1]
+ archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
+
+ sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
+ sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
+
+ // Included modules
+ checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
+ // Check that snapshot captures "prefer: true" prebuilt
+ checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
+
+ // Excluded modules. Modules not included in the directed recovery snapshot
+ // are still include as fake modules.
+ checkSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery_available.so.json"))
+ }
+
+ // Verify that each json file for an included module has a rule.
+ for _, jsonFile := range includeJsonFiles {
+ if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
+ t.Errorf("include json file %q not found", jsonFile)
+ }
+ }
+}
diff --git a/cmd/dep_fixer/Android.bp b/cmd/dep_fixer/Android.bp
index 97364d5..818fd28 100644
--- a/cmd/dep_fixer/Android.bp
+++ b/cmd/dep_fixer/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "dep_fixer",
deps: ["soong-makedeps"],
diff --git a/cmd/diff_target_files/Android.bp b/cmd/diff_target_files/Android.bp
index bc6b068..ae8c329 100644
--- a/cmd/diff_target_files/Android.bp
+++ b/cmd/diff_target_files/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "diff_target_files",
srcs: [
diff --git a/cmd/extract_apks/Android.bp b/cmd/extract_apks/Android.bp
index f8fe864..8a4ed63 100644
--- a/cmd/extract_apks/Android.bp
+++ b/cmd/extract_apks/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "extract_apks",
srcs: ["main.go"],
diff --git a/cmd/extract_jar_packages/Android.bp b/cmd/extract_jar_packages/Android.bp
index 4ea8798..ab33504 100644
--- a/cmd/extract_jar_packages/Android.bp
+++ b/cmd/extract_jar_packages/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "extract_jar_packages",
deps: [
diff --git a/cmd/extract_linker/Android.bp b/cmd/extract_linker/Android.bp
index 690c4fa..d40d250 100644
--- a/cmd/extract_linker/Android.bp
+++ b/cmd/extract_linker/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "extract_linker",
srcs: ["main.go"],
diff --git a/cmd/fileslist/Android.bp b/cmd/fileslist/Android.bp
index cbf939a..3c6f675 100644
--- a/cmd/fileslist/Android.bp
+++ b/cmd/fileslist/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "fileslist",
srcs: [
diff --git a/cmd/host_bionic_inject/Android.bp b/cmd/host_bionic_inject/Android.bp
index 5994103..16bc179 100644
--- a/cmd/host_bionic_inject/Android.bp
+++ b/cmd/host_bionic_inject/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "host_bionic_inject",
deps: ["soong-symbol_inject"],
diff --git a/cmd/javac_wrapper/Android.bp b/cmd/javac_wrapper/Android.bp
index c00f4bd..e441567 100644
--- a/cmd/javac_wrapper/Android.bp
+++ b/cmd/javac_wrapper/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "soong_javac_wrapper",
srcs: [
diff --git a/cmd/merge_zips/Android.bp b/cmd/merge_zips/Android.bp
index 8c97b6d..930d040 100644
--- a/cmd/merge_zips/Android.bp
+++ b/cmd/merge_zips/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "merge_zips",
deps: [
diff --git a/cmd/multiproduct_kati/Android.bp b/cmd/multiproduct_kati/Android.bp
index d34f8c3..21d8e21 100644
--- a/cmd/multiproduct_kati/Android.bp
+++ b/cmd/multiproduct_kati/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "multiproduct_kati",
deps: [
diff --git a/cmd/path_interposer/Android.bp b/cmd/path_interposer/Android.bp
index 41a219f..875cd72 100644
--- a/cmd/path_interposer/Android.bp
+++ b/cmd/path_interposer/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "path_interposer",
deps: ["soong-ui-build-paths"],
diff --git a/cmd/pom2bp/Android.bp b/cmd/pom2bp/Android.bp
index 0b2b7b5..0dfed8b 100644
--- a/cmd/pom2bp/Android.bp
+++ b/cmd/pom2bp/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "pom2bp",
deps: [
diff --git a/cmd/pom2mk/Android.bp b/cmd/pom2mk/Android.bp
index 54422b1..cc9dacc 100644
--- a/cmd/pom2mk/Android.bp
+++ b/cmd/pom2mk/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "pom2mk",
deps: ["blueprint-proptools"],
diff --git a/cmd/sbox/Android.bp b/cmd/sbox/Android.bp
index f5e87c0..d88505f 100644
--- a/cmd/sbox/Android.bp
+++ b/cmd/sbox/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "sbox",
deps: [
diff --git a/cmd/soong_build/Android.bp b/cmd/soong_build/Android.bp
index 6714978..6a0a87b 100644
--- a/cmd/soong_build/Android.bp
+++ b/cmd/soong_build/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_binary {
name: "soong_build",
deps: [
diff --git a/cmd/soong_env/Android.bp b/cmd/soong_env/Android.bp
index 4db0da3..ad717d0 100644
--- a/cmd/soong_env/Android.bp
+++ b/cmd/soong_env/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_binary {
name: "soong_env",
deps: [
diff --git a/cmd/soong_ui/Android.bp b/cmd/soong_ui/Android.bp
index 4e57bef..4f5eea9 100644
--- a/cmd/soong_ui/Android.bp
+++ b/cmd/soong_ui/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "soong_ui",
deps: [
diff --git a/cmd/zip2zip/Android.bp b/cmd/zip2zip/Android.bp
index 2c4cd82..3ef7668 100644
--- a/cmd/zip2zip/Android.bp
+++ b/cmd/zip2zip/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "zip2zip",
deps: [
diff --git a/cmd/zipsync/Android.bp b/cmd/zipsync/Android.bp
index 49b5f3e..0dcdd5c 100644
--- a/cmd/zipsync/Android.bp
+++ b/cmd/zipsync/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "zipsync",
deps: [
diff --git a/cuj/Android.bp b/cuj/Android.bp
index 21d667f..a2da6e6 100644
--- a/cuj/Android.bp
+++ b/cuj/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "cuj_tests",
deps: [
diff --git a/dexpreopt/Android.bp b/dexpreopt/Android.bp
index 35f90df..679d066 100644
--- a/dexpreopt/Android.bp
+++ b/dexpreopt/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-dexpreopt",
pkgPath: "android/soong/dexpreopt",
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index ec62eb3..ad52b00 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -489,20 +489,16 @@
}
// Class loader contexts that come from Make via JSON dexpreopt.config. JSON CLC representation is
-// slightly different: it uses a map of library names to their CLC (instead of a list of structs
-// that including the name, as in the Soong CLC representation). The difference is insubstantial, it
-// is caused only by the language differerences between Go and JSON.
+// the same as Soong representation except that SDK versions and paths are represented with strings.
type jsonClassLoaderContext struct {
+ Name string
Host string
Device string
- Subcontexts map[string]*jsonClassLoaderContext
+ Subcontexts []*jsonClassLoaderContext
}
-// A map of <uses-library> name to its on-host and on-device build paths and CLC.
-type jsonClassLoaderContexts map[string]*jsonClassLoaderContext
-
// A map from SDK version (represented with a JSON string) to JSON CLCs.
-type jsonClassLoaderContextMap map[string]map[string]*jsonClassLoaderContext
+type jsonClassLoaderContextMap map[string][]*jsonClassLoaderContext
// Convert JSON CLC map to Soong represenation.
func fromJsonClassLoaderContext(ctx android.PathContext, jClcMap jsonClassLoaderContextMap) ClassLoaderContextMap {
@@ -522,11 +518,11 @@
}
// Recursive helper for fromJsonClassLoaderContext.
-func fromJsonClassLoaderContextRec(ctx android.PathContext, jClcs map[string]*jsonClassLoaderContext) []*ClassLoaderContext {
+func fromJsonClassLoaderContextRec(ctx android.PathContext, jClcs []*jsonClassLoaderContext) []*ClassLoaderContext {
clcs := make([]*ClassLoaderContext, 0, len(jClcs))
- for lib, clc := range jClcs {
+ for _, clc := range jClcs {
clcs = append(clcs, &ClassLoaderContext{
- Name: lib,
+ Name: clc.Name,
Host: constructPath(ctx, clc.Host),
Device: clc.Device,
Subcontexts: fromJsonClassLoaderContextRec(ctx, clc.Subcontexts),
@@ -546,14 +542,15 @@
}
// Recursive helper for toJsonClassLoaderContext.
-func toJsonClassLoaderContextRec(clcs []*ClassLoaderContext) map[string]*jsonClassLoaderContext {
- jClcs := make(map[string]*jsonClassLoaderContext, len(clcs))
+func toJsonClassLoaderContextRec(clcs []*ClassLoaderContext) []*jsonClassLoaderContext {
+ jClcs := make([]*jsonClassLoaderContext, len(clcs))
for _, clc := range clcs {
- jClcs[clc.Name] = &jsonClassLoaderContext{
+ jClcs = append(jClcs, &jsonClassLoaderContext{
+ Name: clc.Name,
Host: clc.Host.String(),
Device: clc.Device,
Subcontexts: toJsonClassLoaderContextRec(clc.Subcontexts),
- }
+ })
}
return jClcs
}
diff --git a/dexpreopt/dexpreopt_gen/Android.bp b/dexpreopt/dexpreopt_gen/Android.bp
index 3f0619c..2111451 100644
--- a/dexpreopt/dexpreopt_gen/Android.bp
+++ b/dexpreopt/dexpreopt_gen/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "dexpreopt_gen",
srcs: [
diff --git a/env/Android.bp b/env/Android.bp
index 90c6047..c6a97b1 100644
--- a/env/Android.bp
+++ b/env/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-env",
pkgPath: "android/soong/env",
diff --git a/etc/Android.bp b/etc/Android.bp
index cfd303e..cab7389 100644
--- a/etc/Android.bp
+++ b/etc/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-etc",
pkgPath: "android/soong/etc",
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 850c8f9..57563eb 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -28,6 +28,8 @@
// various `prebuilt_*` mutators.
import (
+ "fmt"
+
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -208,6 +210,17 @@
return p.outputFilePath
}
+var _ android.OutputFileProducer = (*PrebuiltEtc)(nil)
+
+func (p *PrebuiltEtc) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return android.Paths{p.outputFilePath}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
+}
+
func (p *PrebuiltEtc) SubDir() string {
if subDir := proptools.String(p.properties.Sub_dir); subDir != "" {
return subDir
diff --git a/filesystem/Android.bp b/filesystem/Android.bp
index 9994241..42a4c88 100644
--- a/filesystem/Android.bp
+++ b/filesystem/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-filesystem",
pkgPath: "android/soong/filesystem",
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 4bc1823..c90929a 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -38,6 +38,9 @@
}
type bootimgProperties struct {
+ // Set the name of the output. Defaults to <module_name>.img.
+ Stem *string
+
// Path to the linux kernel prebuilt file
Kernel_prebuilt *string `android:"arch_variant,path"`
@@ -96,7 +99,7 @@
}
func (b *bootimg) installFileName() string {
- return b.BaseModuleName() + ".img"
+ return proptools.StringDefault(b.properties.Stem, b.BaseModuleName()+".img")
}
func (b *bootimg) partitionName() string {
@@ -110,6 +113,7 @@
} else {
// TODO(jiyong): fix this
ctx.PropertyErrorf("vendor_boot", "only vendor_boot:true is supported")
+ return
}
if proptools.Bool(b.properties.Use_avb) {
@@ -123,7 +127,8 @@
}
func (b *bootimg) buildVendorBootImage(ctx android.ModuleContext) android.OutputPath {
- output := android.PathForModuleOut(ctx, "unsigned.img").OutputPath
+ output := android.PathForModuleOut(ctx, "unsigned", b.installFileName()).OutputPath
+
builder := android.NewRuleBuilder(pctx, ctx)
cmd := builder.Command().BuiltTool("mkbootimg")
@@ -182,21 +187,20 @@
}
func (b *bootimg) signImage(ctx android.ModuleContext, unsignedImage android.OutputPath) android.OutputPath {
- signedImage := android.PathForModuleOut(ctx, "signed.img").OutputPath
+ output := android.PathForModuleOut(ctx, b.installFileName()).OutputPath
key := android.PathForModuleSrc(ctx, proptools.String(b.properties.Avb_private_key))
builder := android.NewRuleBuilder(pctx, ctx)
- builder.Command().Text("cp").Input(unsignedImage).Output(signedImage)
+ builder.Command().Text("cp").Input(unsignedImage).Output(output)
builder.Command().
BuiltTool("avbtool").
Flag("add_hash_footer").
FlagWithArg("--partition_name ", b.partitionName()).
FlagWithInput("--key ", key).
- FlagWithOutput("--image ", signedImage)
+ FlagWithOutput("--image ", output)
builder.Build("sign_bootimg", fmt.Sprintf("Signing %s", b.BaseModuleName()))
-
- return signedImage
+ return output
}
var _ android.AndroidMkEntriesProvider = (*bootimg)(nil)
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 7658154..3bccde9 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -16,6 +16,8 @@
import (
"fmt"
+ "path/filepath"
+ "strings"
"android/soong/android"
@@ -37,6 +39,11 @@
installDir android.InstallPath
}
+type symlinkDefinition struct {
+ Target *string
+ Name *string
+}
+
type filesystemProperties struct {
// When set to true, sign the image with avbtool. Default is false.
Use_avb *bool
@@ -54,6 +61,16 @@
// file_contexts file to make image. Currently, only ext4 is supported.
File_contexts *string `android:"path"`
+
+ // Base directory relative to root, to which deps are installed, e.g. "system". Default is "."
+ // (root).
+ Base_dir *string
+
+ // Directories to be created under root. e.g. /dev, /proc, etc.
+ Dirs []string
+
+ // Symbolic links to be created under root with "ln -sf <target> <name>".
+ Symlinks []symlinkDefinition
}
// android_filesystem packages a set of modules and their transitive dependencies into a filesystem
@@ -124,16 +141,75 @@
ctx.InstallFile(f.installDir, f.installFileName(), f.output)
}
+// root zip will contain stuffs like dirs or symlinks.
+func (f *filesystem) buildRootZip(ctx android.ModuleContext) android.OutputPath {
+ rootDir := android.PathForModuleGen(ctx, "root").OutputPath
+ builder := android.NewRuleBuilder(pctx, ctx)
+ builder.Command().Text("rm -rf").Text(rootDir.String())
+ builder.Command().Text("mkdir -p").Text(rootDir.String())
+
+ // create dirs and symlinks
+ for _, dir := range f.properties.Dirs {
+ // OutputPath.Join verifies dir
+ builder.Command().Text("mkdir -p").Text(rootDir.Join(ctx, dir).String())
+ }
+
+ for _, symlink := range f.properties.Symlinks {
+ name := strings.TrimSpace(proptools.String(symlink.Name))
+ target := strings.TrimSpace(proptools.String(symlink.Target))
+
+ if name == "" {
+ ctx.PropertyErrorf("symlinks", "Name can't be empty")
+ continue
+ }
+
+ if target == "" {
+ ctx.PropertyErrorf("symlinks", "Target can't be empty")
+ continue
+ }
+
+ // OutputPath.Join verifies name. don't need to verify target.
+ dst := rootDir.Join(ctx, name)
+
+ builder.Command().Text("mkdir -p").Text(filepath.Dir(dst.String()))
+ builder.Command().Text("ln -sf").Text(proptools.ShellEscape(target)).Text(dst.String())
+ }
+
+ zipOut := android.PathForModuleGen(ctx, "root.zip").OutputPath
+
+ builder.Command().
+ BuiltTool("soong_zip").
+ FlagWithOutput("-o ", zipOut).
+ FlagWithArg("-C ", rootDir.String()).
+ Flag("-L 0"). // no compression because this will be unzipped soon
+ FlagWithArg("-D ", rootDir.String()).
+ Flag("-d") // include empty directories
+ builder.Command().Text("rm -rf").Text(rootDir.String())
+
+ builder.Build("zip_root", fmt.Sprintf("zipping root contents for %s", ctx.ModuleName()))
+ return zipOut
+}
+
func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) android.OutputPath {
- zipFile := android.PathForModuleOut(ctx, "temp.zip").OutputPath
- f.CopyDepsToZip(ctx, zipFile)
+ depsZipFile := android.PathForModuleOut(ctx, "deps.zip").OutputPath
+ f.CopyDepsToZip(ctx, depsZipFile)
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+ depsBase := proptools.StringDefault(f.properties.Base_dir, ".")
+ rebasedDepsZip := android.PathForModuleOut(ctx, "rebased_deps.zip").OutputPath
+ builder.Command().
+ BuiltTool("zip2zip").
+ FlagWithInput("-i ", depsZipFile).
+ FlagWithOutput("-o ", rebasedDepsZip).
+ Text("**/*:" + proptools.ShellEscape(depsBase)) // zip2zip verifies depsBase
rootDir := android.PathForModuleOut(ctx, "root").OutputPath
- builder := android.NewRuleBuilder(pctx, ctx)
+ rootZip := f.buildRootZip(ctx)
builder.Command().
BuiltTool("zipsync").
FlagWithArg("-d ", rootDir.String()). // zipsync wipes this. No need to clear.
- Input(zipFile)
+ Input(rootZip).
+ Input(rebasedDepsZip)
propFile, toolDeps := f.buildPropFile(ctx)
output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
@@ -187,7 +263,7 @@
}
addStr("fs_type", fsTypeStr(f.fsType(ctx)))
- addStr("mount_point", "system")
+ addStr("mount_point", "/")
addStr("use_dynamic_partition_size", "true")
addPath("ext_mkuserimg", ctx.Config().HostToolPath(ctx, "mkuserimg_mke2fs"))
// b/177813163 deps of the host tools have to be added. Remove this.
@@ -233,15 +309,25 @@
ctx.PropertyErrorf("file_contexts", "file_contexts is not supported for compressed cpio image.")
}
- zipFile := android.PathForModuleOut(ctx, "temp.zip").OutputPath
- f.CopyDepsToZip(ctx, zipFile)
+ depsZipFile := android.PathForModuleOut(ctx, "deps.zip").OutputPath
+ f.CopyDepsToZip(ctx, depsZipFile)
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+ depsBase := proptools.StringDefault(f.properties.Base_dir, ".")
+ rebasedDepsZip := android.PathForModuleOut(ctx, "rebased_deps.zip").OutputPath
+ builder.Command().
+ BuiltTool("zip2zip").
+ FlagWithInput("-i ", depsZipFile).
+ FlagWithOutput("-o ", rebasedDepsZip).
+ Text("**/*:" + proptools.ShellEscape(depsBase)) // zip2zip verifies depsBase
rootDir := android.PathForModuleOut(ctx, "root").OutputPath
- builder := android.NewRuleBuilder(pctx, ctx)
+ rootZip := f.buildRootZip(ctx)
builder.Command().
BuiltTool("zipsync").
FlagWithArg("-d ", rootDir.String()). // zipsync wipes this. No need to clear.
- Input(zipFile)
+ Input(rootZip).
+ Input(rebasedDepsZip)
output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
cmd := builder.Command().
diff --git a/finder/Android.bp b/finder/Android.bp
index a5d7fd4..a3df6ec 100644
--- a/finder/Android.bp
+++ b/finder/Android.bp
@@ -16,6 +16,10 @@
// fast, parallel, caching implementation of `find`
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
subdirs = [
"cmd",
]
diff --git a/finder/cmd/Android.bp b/finder/cmd/Android.bp
index e066c39..32843a0 100644
--- a/finder/cmd/Android.bp
+++ b/finder/cmd/Android.bp
@@ -16,6 +16,10 @@
// fast, parallel, caching implementation of `find`
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "finder",
srcs: [
diff --git a/finder/fs/Android.bp b/finder/fs/Android.bp
index 85929ae..14bdb30 100644
--- a/finder/fs/Android.bp
+++ b/finder/fs/Android.bp
@@ -16,6 +16,21 @@
// mock filesystem
//
+package {
+ default_applicable_licenses: [
+ "Android-Apache-2.0",
+ "build_soong_finder_fs_license",
+ ],
+}
+
+license {
+ name: "build_soong_finder_fs_license",
+ license_kinds: [
+ "SPDX-license-identifier-BSD",
+ ],
+ license_text: ["LICENSE"],
+}
+
bootstrap_go_package {
name: "soong-finder-fs",
pkgPath: "android/soong/finder/fs",
diff --git a/finder/fs/LICENSE b/finder/fs/LICENSE
new file mode 100644
index 0000000..e5c5baf
--- /dev/null
+++ b/finder/fs/LICENSE
@@ -0,0 +1,28 @@
+Copyright 2009, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of the Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/genrule/Android.bp b/genrule/Android.bp
index 0e27d4e..214940d 100644
--- a/genrule/Android.bp
+++ b/genrule/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-genrule",
pkgPath: "android/soong/genrule",
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 62aa7f8..9fa6c48 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -780,7 +780,6 @@
}
type bazelGenruleAttributes struct {
- Name *string
Srcs bazel.LabelList
Outs []string
Tools bazel.LabelList
@@ -801,10 +800,10 @@
func GenruleBp2Build(ctx android.TopDownMutatorContext) {
m, ok := ctx.Module().(*Module)
- if !ok {
+ if !ok || !m.properties.Bazel_module.Bp2build_available {
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)
@@ -847,16 +846,17 @@
}
}
- // Create the BazelTargetModule.
- ctx.CreateModule(BazelGenruleFactory, &bazelGenruleAttributes{
- Name: proptools.StringPtr(name),
+ attrs := &bazelGenruleAttributes{
Srcs: srcs,
Outs: outs,
Cmd: cmd,
Tools: tools,
- }, &bazel.BazelTargetModuleProperties{
- Rule_class: "genrule",
- })
+ }
+
+ props := bazel.NewBazelTargetModuleProperties(m.Name(), "genrule", "")
+
+ // Create the BazelTargetModule.
+ ctx.CreateBazelTargetModule(BazelGenruleFactory, props, attrs)
}
func (m *bazelGenrule) Name() string {
diff --git a/jar/Android.bp b/jar/Android.bp
index 2563474..46113d8 100644
--- a/jar/Android.bp
+++ b/jar/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-jar",
pkgPath: "android/soong/jar",
diff --git a/java/Android.bp b/java/Android.bp
index 364566a..9bfd009 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-java",
pkgPath: "android/soong/java",
diff --git a/java/aar.go b/java/aar.go
index e3ad252..ac7ae25 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -28,7 +28,6 @@
)
type AndroidLibraryDependency interface {
- Dependency
ExportPackage() android.Path
ExportedProguardFlagFiles() android.Paths
ExportedRRODirs() []rroDir
@@ -796,9 +795,13 @@
aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
-}
-var _ Dependency = (*AARImport)(nil)
+ ctx.SetProvider(JavaInfoProvider, JavaInfo{
+ HeaderJars: android.PathsIfNonNil(a.classpathFile),
+ ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
+ ImplementationJars: android.PathsIfNonNil(a.classpathFile),
+ })
+}
func (a *AARImport) HeaderJars() android.Paths {
return android.Paths{a.classpathFile}
diff --git a/java/androidmk.go b/java/androidmk.go
index 21f3012..6e7c437 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -646,6 +646,9 @@
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", a.dexpreopter.builtInstalled)
}
entries.AddStrings("LOCAL_INSTALLED_MODULE_STEM", a.installPath.Rel())
+ if Bool(a.properties.Export_package_resources) {
+ entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", a.outputFile)
+ }
},
},
}}
diff --git a/java/app_import.go b/java/app_import.go
index 6f21bfb..59eb10a 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -92,6 +92,10 @@
// Optional name for the installed app. If unspecified, it is derived from the module name.
Filename *string
+
+ // If set, create package-export.apk, which other packages can
+ // use to get PRODUCT-agnostic resource data like IDs and type definitions.
+ Export_package_resources *bool
}
func (a *AndroidAppImport) IsInstallable() bool {
@@ -142,13 +146,17 @@
}
}
+func (a *AndroidAppImport) isPrebuiltFrameworkRes() bool {
+ return a.Name() == "prebuilt_framework-res"
+}
+
func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
cert := android.SrcIsModule(String(a.properties.Certificate))
if cert != "" {
ctx.AddDependency(ctx.Module(), certificateTag, cert)
}
- a.usesLibrary.deps(ctx, true)
+ a.usesLibrary.deps(ctx, !a.isPrebuiltFrameworkRes())
}
func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
@@ -247,7 +255,12 @@
a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed.OutputPath)
var installDir android.InstallPath
- if Bool(a.properties.Privileged) {
+
+ if a.isPrebuiltFrameworkRes() {
+ // framework-res.apk is installed as system/framework/framework-res.apk
+ installDir = android.PathForModuleInstall(ctx, "framework")
+ a.preprocessed = true
+ } else if Bool(a.properties.Privileged) {
installDir = android.PathForModuleInstall(ctx, "priv-app", a.BaseModuleName())
} else if ctx.InstallInTestcases() {
installDir = android.PathForModuleInstall(ctx, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
@@ -275,7 +288,15 @@
// TODO: Handle EXTERNAL
// Sign or align the package if package has not been preprocessed
- if a.preprocessed {
+
+ if a.isPrebuiltFrameworkRes() {
+ a.outputFile = srcApk
+ certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
+ if len(certificates) != 1 {
+ ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
+ }
+ a.certificate = certificates[0]
+ } else if a.preprocessed {
a.outputFile = srcApk
a.certificate = PresignedCertificate
} else if !Bool(a.properties.Presigned) {
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 344d23b..d7f69eb 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -393,6 +393,69 @@
}
}
+func TestAndroidAppImport_frameworkRes(t *testing.T) {
+ ctx, config := testJava(t, `
+ android_app_import {
+ name: "framework-res",
+ certificate: "platform",
+ apk: "package-res.apk",
+ prefer: true,
+ export_package_resources: true,
+ // Disable dexpreopt and verify_uses_libraries check as the app
+ // contains no Java code to be dexpreopted.
+ enforce_uses_libs: false,
+ dex_preopt: {
+ enabled: false,
+ },
+ }
+ `)
+
+ mod := ctx.ModuleForTests("prebuilt_framework-res", "android_common").Module()
+ a := mod.(*AndroidAppImport)
+
+ if !a.preprocessed {
+ t.Errorf("prebuilt framework-res is not preprocessed")
+ }
+
+ expectedInstallPath := buildDir + "/target/product/test_device/system/framework/framework-res.apk"
+
+ if a.dexpreopter.installPath.String() != expectedInstallPath {
+ t.Errorf("prebuilt framework-res installed to incorrect location, actual: %s, expected: %s", a.dexpreopter.installPath, expectedInstallPath)
+
+ }
+
+ entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0]
+
+ expectedPath := "."
+ // From apk property above, in the root of the source tree.
+ expectedPrebuiltModuleFile := "package-res.apk"
+ // Verify that the apk is preprocessed: The export package is the same
+ // as the prebuilt.
+ expectedSoongResourceExportPackage := expectedPrebuiltModuleFile
+
+ actualPath := entries.EntryMap["LOCAL_PATH"]
+ actualPrebuiltModuleFile := entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"]
+ actualSoongResourceExportPackage := entries.EntryMap["LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE"]
+
+ if len(actualPath) != 1 {
+ t.Errorf("LOCAL_PATH incorrect len %d", len(actualPath))
+ } else if actualPath[0] != expectedPath {
+ t.Errorf("LOCAL_PATH mismatch, actual: %s, expected: %s", actualPath[0], expectedPath)
+ }
+
+ if len(actualPrebuiltModuleFile) != 1 {
+ t.Errorf("LOCAL_PREBUILT_MODULE_FILE incorrect len %d", len(actualPrebuiltModuleFile))
+ } else if actualPrebuiltModuleFile[0] != expectedPrebuiltModuleFile {
+ t.Errorf("LOCAL_PREBUILT_MODULE_FILE mismatch, actual: %s, expected: %s", actualPrebuiltModuleFile[0], expectedPrebuiltModuleFile)
+ }
+
+ if len(actualSoongResourceExportPackage) != 1 {
+ t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE incorrect len %d", len(actualSoongResourceExportPackage))
+ } else if actualSoongResourceExportPackage[0] != expectedSoongResourceExportPackage {
+ t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE mismatch, actual: %s, expected: %s", actualSoongResourceExportPackage[0], expectedSoongResourceExportPackage)
+ }
+}
+
func TestAndroidTestImport(t *testing.T) {
ctx, config := testJava(t, `
android_test_import {
diff --git a/java/boot_image.go b/java/boot_image.go
index 0a525b7..8a1e3c9 100644
--- a/java/boot_image.go
+++ b/java/boot_image.go
@@ -90,6 +90,10 @@
// The dex2oat tool is only needed for building and is not required in the apex.
return false
}
+ if android.IsMetaDependencyTag(tag) {
+ // Cross-cutting metadata dependencies are metadata.
+ return false
+ }
panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
}
diff --git a/java/builder.go b/java/builder.go
index 995160d..22a891a 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -193,12 +193,19 @@
jarjar = pctx.AndroidStaticRule("jarjar",
blueprint.RuleParams{
- Command: "${config.JavaCmd} ${config.JavaVmFlags}" +
+ Command: "" +
+ // Jarjar doesn't exit with an error when the rules file contains a syntax error,
+ // leading to stale or missing files later in the build. Remove the output file
+ // before running jarjar.
+ "rm -f ${out} && " +
+ "${config.JavaCmd} ${config.JavaVmFlags}" +
// b/146418363 Enable Android specific jarjar transformer to drop compat annotations
// for newly repackaged classes. Dropping @UnsupportedAppUsage on repackaged classes
// avoids adding new hiddenapis after jarjar'ing.
" -DremoveAndroidCompatAnnotations=true" +
- " -jar ${config.JarjarCmd} process $rulesFile $in $out",
+ " -jar ${config.JarjarCmd} process $rulesFile $in $out && " +
+ // Turn a missing output file into a ninja error
+ `[ -e ${out} ] || (echo "Missing output file"; exit 1)`,
CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
},
"rulesFile")
diff --git a/java/config/Android.bp b/java/config/Android.bp
index 1983521..194e2c6 100644
--- a/java/config/Android.bp
+++ b/java/config/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-java-config",
pkgPath: "android/soong/java/config",
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 4914d74..ee7d018 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -97,15 +97,15 @@
}
ctx.VisitDirectDepsWithTag(deviceHostConverterDepTag, func(m android.Module) {
- if dep, ok := m.(Dependency); ok {
- d.headerJars = append(d.headerJars, dep.HeaderJars()...)
- d.implementationJars = append(d.implementationJars, dep.ImplementationJars()...)
- d.implementationAndResourceJars = append(d.implementationAndResourceJars, dep.ImplementationAndResourcesJars()...)
- d.resourceJars = append(d.resourceJars, dep.ResourceJars()...)
+ if ctx.OtherModuleHasProvider(m, JavaInfoProvider) {
+ dep := ctx.OtherModuleProvider(m, JavaInfoProvider).(JavaInfo)
+ d.headerJars = append(d.headerJars, dep.HeaderJars...)
+ d.implementationJars = append(d.implementationJars, dep.ImplementationJars...)
+ d.implementationAndResourceJars = append(d.implementationAndResourceJars, dep.ImplementationAndResourcesJars...)
+ d.resourceJars = append(d.resourceJars, dep.ResourceJars...)
- srcJarArgs, srcJarDeps := dep.SrcJarArgs()
- d.srcJarArgs = append(d.srcJarArgs, srcJarArgs...)
- d.srcJarDeps = append(d.srcJarDeps, srcJarDeps...)
+ d.srcJarArgs = append(d.srcJarArgs, dep.SrcJarArgs...)
+ d.srcJarDeps = append(d.srcJarDeps, dep.SrcJarDeps...)
} else {
ctx.PropertyErrorf("libs", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
}
@@ -131,9 +131,16 @@
d.combinedHeaderJar = d.headerJars[0]
}
-}
+ ctx.SetProvider(JavaInfoProvider, JavaInfo{
+ HeaderJars: d.headerJars,
+ ImplementationAndResourcesJars: d.implementationAndResourceJars,
+ ImplementationJars: d.implementationJars,
+ ResourceJars: d.resourceJars,
+ SrcJarArgs: d.srcJarArgs,
+ SrcJarDeps: d.srcJarDeps,
+ })
-var _ Dependency = (*DeviceHostConverter)(nil)
+}
func (d *DeviceHostConverter) HeaderJars() android.Paths {
return d.headerJars
diff --git a/java/dex.go b/java/dex.go
index 24600c2..e52fdb5 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -204,8 +204,9 @@
// - prevent ProGuard stripping subclass in the support library that extends class added in the higher SDK version.
// See b/20667396
var proguardRaiseDeps classpath
- ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(dep android.Module) {
- proguardRaiseDeps = append(proguardRaiseDeps, dep.(Dependency).HeaderJars()...)
+ ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(m android.Module) {
+ dep := ctx.OtherModuleProvider(m, JavaInfoProvider).(JavaInfo)
+ proguardRaiseDeps = append(proguardRaiseDeps, dep.HeaderJars...)
})
r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars"))
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index c315124..282e936 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -82,10 +82,6 @@
deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
artModules := global.ArtApexJars
- // With EMMA_INSTRUMENT_FRAMEWORK=true the Core libraries depend on jacoco.
- if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- artModules = artModules.Append("com.android.art", "jacocoagent")
- }
frameworkModules := global.BootJars.RemoveList(artModules)
artSubdir := "apex/art_boot_images/javalib"
diff --git a/java/droiddoc.go b/java/droiddoc.go
index c74009e..8f1644c 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -470,8 +470,9 @@
switch tag {
case bootClasspathTag:
- if dep, ok := module.(Dependency); ok {
- deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
+ if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+ dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars...)
} else if sm, ok := module.(SystemModulesProvider); ok {
// A system modules dependency has been added to the bootclasspath
// so add its libs to the bootclasspath.
@@ -480,23 +481,23 @@
panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
}
case libTag:
- switch dep := module.(type) {
- case SdkLibraryDependency:
+ if dep, ok := module.(SdkLibraryDependency); ok {
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
- case Dependency:
- deps.classpath = append(deps.classpath, dep.HeaderJars()...)
- deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
- case android.SourceFileProducer:
+ } else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+ dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ deps.classpath = append(deps.classpath, dep.HeaderJars...)
+ deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
+ } else if dep, ok := module.(android.SourceFileProducer); ok {
checkProducesJars(ctx, dep)
deps.classpath = append(deps.classpath, dep.Srcs()...)
- default:
+ } else {
ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
case java9LibTag:
- switch dep := module.(type) {
- case Dependency:
- deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
- default:
+ if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+ dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
+ } else {
ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
case systemModulesTag:
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index eafbf5d..f8e41c4 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -28,10 +28,39 @@
}, "outFlag", "stubAPIFlags")
type hiddenAPI struct {
+ // The name of the module as it would be used in the boot jars configuration, e.g. without any
+ // prebuilt_ prefix (if it is a prebuilt), without any "-hiddenapi" suffix if it just provides
+ // annotations and without any ".impl" suffix if it is a java_sdk_library implementation library.
+ configurationName string
+
+ // True if the module containing this structure contributes to the hiddenapi information or has
+ // that information encoded within it.
+ active bool
+
+ // Identifies the active module variant which will be used as the source of hiddenapi information.
+ //
+ // A class may be compiled into a number of different module variants each of which will need the
+ // hiddenapi information encoded into it and so will be marked as active. However, only one of
+ // them must be used as a source of information by hiddenapi otherwise it will end up with
+ // duplicate entries. That module will have primary=true.
+ //
+ // Note, that modules <x>-hiddenapi that provide additional annotation information for module <x>
+ // that is on the bootclasspath are marked as primary=true as they are the primary source of that
+ // annotation information.
+ primary bool
+
+ // True if the module only contains additional annotations and so does not require hiddenapi
+ // information to be encoded in its dex file and should not be used to generate the
+ // hiddenAPISingletonPathsStruct.stubFlags file.
+ annotationsOnly bool
+
// The path to the dex jar that is in the boot class path. If this is nil then the associated
// module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional
// annotations for the <x> boot dex jar but which do not actually provide a boot dex jar
// themselves.
+ //
+ // This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on
+ // this file so using the encoded dex jar here would result in a cycle in the ninja rules.
bootDexJarPath android.Path
// The path to the CSV file that contains mappings from Java signature to various flags derived
@@ -89,59 +118,122 @@
var _ hiddenAPIIntf = (*hiddenAPI)(nil)
-func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, name string, primary bool, dexJar android.OutputPath,
- implementationJar android.Path, uncompressDex bool) android.OutputPath {
- if !ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+// Initialize the hiddenapi structure
+func (h *hiddenAPI) initHiddenAPI(ctx android.BaseModuleContext, name string) {
+ // If hiddenapi processing is disabled treat this as inactive.
+ if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+ return
+ }
- // Modules whose names are of the format <x>-hiddenapi provide hiddenapi information
- // for the boot jar module <x>. Otherwise, the module provides information for itself.
- // Either way extract the name of the boot jar module.
- bootJarName := strings.TrimSuffix(name, "-hiddenapi")
+ // Modules whose names are of the format <x>-hiddenapi provide hiddenapi information for the boot
+ // jar module <x>. Otherwise, the module provides information for itself. Either way extract the
+ // configurationName of the boot jar module.
+ configurationName := strings.TrimSuffix(name, "-hiddenapi")
+ h.configurationName = configurationName
- // If this module is on the boot jars list (or providing information for a module
- // on the list) then extract the hiddenapi information from it, and if necessary
- // encode that information in the generated dex file.
- //
- // It is important that hiddenapi information is only gathered for/from modules on
- // that are actually on the boot jars list because the runtime only enforces access
- // to the hidden API for the bootclassloader. If information is gathered for modules
- // not on the list then that will cause failures in the CtsHiddenApiBlacklist...
- // tests.
- if inList(bootJarName, ctx.Config().BootJars()) {
- // Create ninja rules to generate various CSV files needed by hiddenapi and store the paths
- // in the hiddenAPI structure.
- h.hiddenAPIGenerateCSV(ctx, implementationJar)
+ // It is important that hiddenapi information is only gathered for/from modules that are actually
+ // on the boot jars list because the runtime only enforces access to the hidden API for the
+ // bootclassloader. If information is gathered for modules not on the list then that will cause
+ // failures in the CtsHiddenApiBlocklist... tests.
+ h.active = inList(configurationName, ctx.Config().BootJars())
+ if !h.active {
+ // The rest of the properties will be ignored if active is false.
+ return
+ }
- // If this module is actually on the boot jars list and not providing
- // hiddenapi information for a module on the boot jars list then encode
- // the gathered information in the generated dex file.
- if name == bootJarName {
- hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", name+".jar").OutputPath
+ // If this module has a suffix of -hiddenapi then it only provides additional annotation
+ // information for a module on the boot jars list.
+ h.annotationsOnly = strings.HasSuffix(name, "-hiddenapi")
- // More than one library with the same classes can be encoded but only one can
- // be added to the global set of flags, otherwise it will result in duplicate
- // classes which is an error. Therefore, only add the dex jar of one of them
- // to the global set of flags.
- if primary {
- h.bootDexJarPath = dexJar
- }
- hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
- dexJar = hiddenAPIJar
- }
+ // Determine whether this module is the primary module or not.
+ primary := true
+
+ // A prebuilt module is only primary if it is preferred and conversely a source module is only
+ // primary if it has not been replaced by a prebuilt module.
+ module := ctx.Module()
+ if pi, ok := module.(android.PrebuiltInterface); ok {
+ if p := pi.Prebuilt(); p != nil {
+ primary = p.UsePrebuilt()
}
+ } else {
+ // The only module that will pass a different name to its module name to this method is the
+ // implementation library of a java_sdk_library. It has a configuration name of <x> the same
+ // as its parent java_sdk_library but a module name of <x>.impl. It is not the primary module,
+ // the java_sdk_library with the name of <x> is.
+ primary = name == ctx.ModuleName()
+
+ // A source module that has been replaced by a prebuilt can never be the primary module.
+ primary = primary && !module.IsReplacedByPrebuilt()
+ }
+ h.primary = primary
+}
+
+// hiddenAPIExtractAndEncode is called by any module that could contribute to the hiddenapi
+// processing.
+//
+// It ignores any module that has not had initHiddenApi() called on it and which is not in the boot
+// jar list.
+//
+// Otherwise, it generates ninja rules to do the following:
+// 1. Extract information needed for hiddenapi processing from the module and output it into CSV
+// files.
+// 2. Conditionally adds the supplied dex file to the list of files used to generate the
+// hiddenAPISingletonPathsStruct.stubsFlag file.
+// 3. Conditionally creates a copy of the supplied dex file into which it has encoded the hiddenapi
+// flags and returns this instead of the supplied dex jar, otherwise simply returns the supplied
+// dex jar.
+func (h *hiddenAPI) hiddenAPIExtractAndEncode(ctx android.ModuleContext, dexJar android.OutputPath,
+ implementationJar android.Path, uncompressDex bool) android.OutputPath {
+
+ if !h.active {
+ return dexJar
+ }
+
+ h.hiddenAPIExtractInformation(ctx, dexJar, implementationJar)
+
+ if !h.annotationsOnly {
+ hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", h.configurationName+".jar").OutputPath
+
+ // Create a copy of the dex jar which has been encoded with hiddenapi flags.
+ hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
+
+ // Use the encoded dex jar from here onwards.
+ dexJar = hiddenAPIJar
}
return dexJar
}
-func (h *hiddenAPI) hiddenAPIGenerateCSV(ctx android.ModuleContext, classesJar android.Path) {
+// hiddenAPIExtractInformation generates ninja rules to extract the information from the classes
+// jar, and outputs it to the appropriate module specific CSV file.
+//
+// It also makes the dex jar available for use when generating the
+// hiddenAPISingletonPathsStruct.stubFlags.
+func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJar, classesJar android.Path) {
+ if !h.active {
+ return
+ }
+
+ // More than one library with the same classes may need to be encoded but only one should be
+ // used as a source of information for hidden API processing otherwise it will result in
+ // duplicate entries in the files.
+ if !h.primary {
+ 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{
@@ -155,7 +247,7 @@
ctx.Build(pctx, android.BuildParams{
Rule: hiddenAPIGenerateCSVRule,
Description: "hiddenapi metadata",
- Input: classesJar,
+ Inputs: classesJars,
Output: metadataCSV,
Implicit: stubFlagsCSV,
Args: map[string]string{
@@ -169,10 +261,15 @@
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
+
+ // Save the unencoded dex jar so it can be used when generating the
+ // hiddenAPISingletonPathsStruct.stubFlags file.
+ h.bootDexJarPath = dexJar
}
var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", blueprint.RuleParams{
@@ -245,3 +342,16 @@
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.go b/java/hiddenapi_singleton.go
index 32d1e3f..6341a34 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -22,9 +22,13 @@
)
func init() {
- android.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory)
- android.RegisterSingletonType("hiddenapi_index", hiddenAPIIndexSingletonFactory)
- android.RegisterModuleType("hiddenapi_flags", hiddenAPIFlagsFactory)
+ RegisterHiddenApiSingletonComponents(android.InitRegistrationContext)
+}
+
+func RegisterHiddenApiSingletonComponents(ctx android.RegistrationContext) {
+ ctx.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory)
+ ctx.RegisterSingletonType("hiddenapi_index", hiddenAPIIndexSingletonFactory)
+ ctx.RegisterModuleType("hiddenapi_flags", hiddenAPIFlagsFactory)
}
type hiddenAPISingletonPathsStruct struct {
@@ -219,7 +223,7 @@
ctx.VisitAllModules(func(module android.Module) {
// Collect dex jar paths for the modules listed above.
- if j, ok := module.(Dependency); ok {
+ if j, ok := module.(UsesLibraryDependency); ok {
name := ctx.ModuleName(module)
for moduleList, pathList := range moduleListToPathList {
if i := android.IndexList(name, *moduleList); i != -1 {
@@ -368,7 +372,7 @@
stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
rule.Command().
- Tool(android.PathForSource(ctx, "frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py")).
+ BuiltTool("generate_hiddenapi_lists").
FlagWithInput("--csv ", stubFlags).
Inputs(flagsCSV).
FlagWithInput("--unsupported ",
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 27f363e..4670d03 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -15,11 +15,12 @@
package java
import (
- "android/soong/android"
"fmt"
"strings"
"testing"
+ "android/soong/android"
+
"github.com/google/blueprint/proptools"
)
@@ -32,7 +33,7 @@
func testContextWithHiddenAPI(config android.Config) *android.TestContext {
ctx := testContext(config)
- ctx.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory)
+ RegisterHiddenApiSingletonComponents(ctx)
return ctx
}
@@ -64,7 +65,7 @@
name: "foo",
srcs: ["a.java"],
compile_dex: true,
- }
+ }
`, []string{"platform:foo"}, nil)
hiddenAPI := ctx.SingletonForTests("hiddenapi")
@@ -75,6 +76,63 @@
}
}
+func TestHiddenAPIIndexSingleton(t *testing.T) {
+ ctx, _ := testHiddenAPIBootJars(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ compile_dex: true,
+
+ hiddenapi_additional_annotations: [
+ "foo-hiddenapi-annotations",
+ ],
+ }
+
+ java_library {
+ name: "foo-hiddenapi",
+ srcs: ["a.java"],
+ compile_dex: true,
+ }
+
+ java_library {
+ name: "foo-hiddenapi-annotations",
+ srcs: ["a.java"],
+ compile_dex: true,
+ }
+
+ java_import {
+ name: "foo",
+ jars: ["a.jar"],
+ compile_dex: true,
+ prefer: false,
+ }
+
+ java_sdk_library {
+ name: "bar",
+ srcs: ["a.java"],
+ compile_dex: true,
+ }
+ `, []string{"platform:foo", "platform:bar"}, nil)
+
+ hiddenAPIIndex := ctx.SingletonForTests("hiddenapi_index")
+ indexRule := hiddenAPIIndex.Rule("singleton-merged-hiddenapi-index")
+ CheckHiddenAPIRuleInputs(t, `
+.intermediates/bar/android_common/hiddenapi/index.csv
+.intermediates/foo-hiddenapi/android_common/hiddenapi/index.csv
+.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) {
ctx, _ := testHiddenAPIBootJars(t, `
java_import {
@@ -98,14 +156,14 @@
name: "foo",
srcs: ["a.java"],
compile_dex: true,
- }
+ }
java_import {
name: "foo",
jars: ["a.jar"],
compile_dex: true,
prefer: false,
- }
+ }
`, []string{"platform:foo"}, nil)
hiddenAPI := ctx.SingletonForTests("hiddenapi")
@@ -127,14 +185,14 @@
name: "foo",
srcs: ["a.java"],
compile_dex: true,
- }
+ }
java_import {
name: "foo",
jars: ["a.jar"],
compile_dex: true,
prefer: true,
- }
+ }
`, []string{"platform:foo"}, nil)
hiddenAPI := ctx.SingletonForTests("hiddenapi")
diff --git a/java/java.go b/java/java.go
index bed232b..dbfad02 100644
--- a/java/java.go
+++ b/java/java.go
@@ -298,6 +298,9 @@
// 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 {
@@ -533,6 +536,53 @@
var _ android.OutputFileProducer = (*Module)(nil)
+// JavaInfo contains information about a java module for use by modules that depend on it.
+type JavaInfo struct {
+ // HeaderJars is a list of jars that can be passed as the javac classpath in order to link
+ // against this module. If empty, ImplementationJars should be used instead.
+ HeaderJars android.Paths
+
+ // ImplementationAndResourceJars is a list of jars that contain the implementations of classes
+ // in the module as well as any resources included in the module.
+ ImplementationAndResourcesJars android.Paths
+
+ // ImplementationJars is a list of jars that contain the implementations of classes in the
+ //module.
+ ImplementationJars android.Paths
+
+ // ResourceJars is a list of jars that contain the resources included in the module.
+ ResourceJars android.Paths
+
+ // AidlIncludeDirs is a list of directories that should be passed to the aidl tool when
+ // depending on this module.
+ AidlIncludeDirs android.Paths
+
+ // SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this
+ // module.
+ SrcJarArgs []string
+
+ // SrcJarDeps is a list of paths to depend on when packaging the sources of this module.
+ SrcJarDeps android.Paths
+
+ // ExportedPlugins is a list of paths that should be used as annotation processors for any
+ // module that depends on this module.
+ ExportedPlugins android.Paths
+
+ // ExportedPluginClasses is a list of classes that should be run as annotation processors for
+ // any module that depends on this module.
+ ExportedPluginClasses []string
+
+ // ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs,
+ // requiring disbling turbine for any modules that depend on it.
+ ExportedPluginDisableTurbine bool
+
+ // JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
+ // instrumented by jacoco.
+ JacocoReportClassesFile android.Path
+}
+
+var JavaInfoProvider = blueprint.NewProvider(JavaInfo{})
+
// Methods that need to be implemented for a module that is added to apex java_libs property.
type ApexDependency interface {
HeaderJars() android.Paths
@@ -546,18 +596,6 @@
ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
}
-type Dependency interface {
- ApexDependency
- UsesLibraryDependency
- ImplementationJars() android.Paths
- ResourceJars() android.Paths
- AidlIncludeDirs() android.Paths
- ExportedPlugins() (android.Paths, []string, bool)
- SrcJarArgs() ([]string, android.Paths)
- BaseModuleName() string
- JacocoReportClassesFile() android.Path
-}
-
type xref interface {
XrefJavaFiles() android.Paths
}
@@ -805,6 +843,9 @@
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,
@@ -973,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
@@ -981,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)
@@ -1040,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)
}
}
@@ -1111,44 +1147,42 @@
return
}
- switch dep := module.(type) {
- case SdkLibraryDependency:
+ if dep, ok := module.(SdkLibraryDependency); ok {
switch tag {
case libTag:
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
case staticLibTag:
ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
}
- case Dependency:
+ } else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+ dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
switch tag {
case bootClasspathTag:
- deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
+ deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
case libTag, instrumentationForTag:
- deps.classpath = append(deps.classpath, dep.HeaderJars()...)
- deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
- pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins()
- addPlugins(&deps, pluginJars, pluginClasses...)
- deps.disableTurbine = deps.disableTurbine || disableTurbine
+ deps.classpath = append(deps.classpath, dep.HeaderJars...)
+ deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
+ addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
+ deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
case java9LibTag:
- deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
+ deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
case staticLibTag:
- deps.classpath = append(deps.classpath, dep.HeaderJars()...)
- deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
- deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
- deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
- deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
- pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins()
- addPlugins(&deps, pluginJars, pluginClasses...)
+ deps.classpath = append(deps.classpath, dep.HeaderJars...)
+ deps.staticJars = append(deps.staticJars, dep.ImplementationJars...)
+ deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars...)
+ deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars...)
+ deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
+ addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
// Turbine doesn't run annotation processors, so any module that uses an
// annotation processor that generates API is incompatible with the turbine
// optimization.
- deps.disableTurbine = deps.disableTurbine || disableTurbine
+ deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
case pluginTag:
- if plugin, ok := dep.(*Plugin); ok {
+ if plugin, ok := module.(*Plugin); ok {
if plugin.pluginProperties.Processor_class != nil {
- addPlugins(&deps, plugin.ImplementationAndResourcesJars(), *plugin.pluginProperties.Processor_class)
+ addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.pluginProperties.Processor_class)
} else {
- addPlugins(&deps, plugin.ImplementationAndResourcesJars())
+ addPlugins(&deps, dep.ImplementationAndResourcesJars)
}
// Turbine doesn't run annotation processors, so any module that uses an
// annotation processor that generates API is incompatible with the turbine
@@ -1158,14 +1192,14 @@
ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
}
case errorpronePluginTag:
- if plugin, ok := dep.(*Plugin); ok {
- deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, plugin.ImplementationAndResourcesJars()...)
+ if _, ok := module.(*Plugin); ok {
+ deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...)
} else {
ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
}
case exportedPluginTag:
- if plugin, ok := dep.(*Plugin); ok {
- j.exportedPluginJars = append(j.exportedPluginJars, plugin.ImplementationAndResourcesJars()...)
+ if plugin, ok := module.(*Plugin); ok {
+ j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...)
if plugin.pluginProperties.Processor_class != nil {
j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)
}
@@ -1177,12 +1211,11 @@
ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
}
case kotlinStdlibTag:
- deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars()...)
+ deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars...)
case kotlinAnnotationsTag:
- deps.kotlinAnnotations = dep.HeaderJars()
+ deps.kotlinAnnotations = dep.HeaderJars
}
-
- case android.SourceFileProducer:
+ } else if dep, ok := module.(android.SourceFileProducer); ok {
switch tag {
case libTag:
checkProducesJars(ctx, dep)
@@ -1193,7 +1226,7 @@
deps.staticJars = append(deps.staticJars, dep.Srcs()...)
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
}
- default:
+ } else {
switch tag {
case bootClasspathTag:
// If a system modules dependency has been added to the bootclasspath
@@ -1798,14 +1831,8 @@
return
}
- configurationName := j.ConfigurationName()
- primary := configurationName == ctx.ModuleName()
- // If the prebuilt is being used rather than the from source, skip this
- // module to prevent duplicated classes
- primary = primary && !j.IsReplacedByPrebuilt()
-
// Hidden API CSV generation and dex encoding
- dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, j.implementationJarFile,
+ dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, j.implementationJarFile,
proptools.Bool(j.dexProperties.Uncompress_dex))
// merge dex jar with resources if necessary
@@ -1866,6 +1893,20 @@
ctx.CheckbuildFile(outputFile)
+ ctx.SetProvider(JavaInfoProvider, JavaInfo{
+ HeaderJars: android.PathsIfNonNil(j.headerJarFile),
+ ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
+ ImplementationJars: android.PathsIfNonNil(j.implementationJarFile),
+ ResourceJars: android.PathsIfNonNil(j.resourceJar),
+ AidlIncludeDirs: j.exportAidlIncludeDirs,
+ SrcJarArgs: j.srcJarArgs,
+ SrcJarDeps: j.srcJarDeps,
+ ExportedPlugins: j.exportedPluginJars,
+ ExportedPluginClasses: j.exportedPluginClasses,
+ ExportedPluginDisableTurbine: j.exportedDisableTurbine,
+ JacocoReportClassesFile: j.jacocoReportClassesFile,
+ })
+
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
j.outputFile = outputFile.WithoutRel()
}
@@ -1973,8 +2014,6 @@
return instrumentedJar
}
-var _ Dependency = (*Module)(nil)
-
func (j *Module) HeaderJars() android.Paths {
if j.headerJarFile == nil {
return nil
@@ -2090,6 +2129,11 @@
return proptools.StringDefault(j.deviceProperties.Stem, j.Name())
}
+// ConfigurationName returns the name of the module as used in build configuration.
+//
+// This is usually the same as BaseModuleName() except for the <x>.impl libraries created by
+// java_sdk_library in which case this is the BaseModuleName() without the ".impl" suffix,
+// i.e. just <x>.
func (j *Module) ConfigurationName() string {
return proptools.StringDefault(j.deviceProperties.ConfigurationName, j.BaseModuleName())
}
@@ -2149,6 +2193,11 @@
}
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Initialize the hiddenapi structure. Pass in the configuration name rather than the module name
+ // so the hidden api will encode the <x>.impl java_ library created by java_sdk_library just as it
+ // would the <x> library if <x> was configured as a boot jar.
+ j.initHiddenAPI(ctx, j.ConfigurationName())
+
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if !apexInfo.IsForPlatform() {
j.hideApexVariantFromMake = true
@@ -2378,7 +2427,7 @@
// list of files or filegroup modules that provide data that should be installed alongside
// the test
- Data []string `android:"path,arch_variant"`
+ Data []string `android:"path"`
// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
@@ -2849,6 +2898,9 @@
}
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Initialize the hiddenapi structure.
+ j.initHiddenAPI(ctx, j.BaseModuleName())
+
if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() {
j.hideApexVariantFromMake = true
}
@@ -2873,15 +2925,15 @@
ctx.VisitDirectDeps(func(module android.Module) {
tag := ctx.OtherModuleDependencyTag(module)
- switch dep := module.(type) {
- case Dependency:
+ if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+ dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
switch tag {
case libTag, staticLibTag:
- flags.classpath = append(flags.classpath, dep.HeaderJars()...)
+ flags.classpath = append(flags.classpath, dep.HeaderJars...)
case bootClasspathTag:
- flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars()...)
+ flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...)
}
- case SdkLibraryDependency:
+ } else if dep, ok := module.(SdkLibraryDependency); ok {
switch tag {
case libTag:
flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
@@ -2917,8 +2969,10 @@
// Get the path of the dex implementation jar from the `deapexer` module.
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
- j.dexJarFile = di.PrebuiltExportPath(j.BaseModuleName(), ".dexjar")
- if j.dexJarFile == nil {
+ if dexOutputPath := di.PrebuiltExportPath(j.BaseModuleName(), ".dexjar"); dexOutputPath != nil {
+ j.dexJarFile = dexOutputPath
+ j.hiddenAPIExtractInformation(ctx, dexOutputPath, outputFile)
+ } else {
// This should never happen as a variant for a prebuilt_apex is only created if the
// prebuilt_apex has been configured to export the java library dex file.
ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name())
@@ -2948,16 +3002,20 @@
return
}
- configurationName := j.BaseModuleName()
- primary := j.Prebuilt().UsePrebuilt()
-
// Hidden API CSV generation and dex encoding
- dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, outputFile,
+ dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, outputFile,
proptools.Bool(j.dexProperties.Uncompress_dex))
j.dexJarFile = dexOutputFile
}
}
+
+ ctx.SetProvider(JavaInfoProvider, JavaInfo{
+ HeaderJars: android.PathsIfNonNil(j.combinedClasspathFile),
+ ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
+ ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile),
+ AidlIncludeDirs: j.exportAidlIncludeDirs,
+ })
}
func (j *Import) OutputFiles(tag string) (android.Paths, error) {
@@ -2971,8 +3029,6 @@
var _ android.OutputFileProducer = (*Import)(nil)
-var _ Dependency = (*Import)(nil)
-
func (j *Import) HeaderJars() android.Paths {
if j.combinedClasspathFile == nil {
return nil
@@ -3318,6 +3374,7 @@
&android.ApexProperties{},
&RuntimeResourceOverlayProperties{},
&LintProperties{},
+ &appTestHelperAppProperties{},
)
android.InitDefaultsModule(module)
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/jdeps.go b/java/jdeps.go
index 2b5ee74..0ab2e42 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -87,8 +87,9 @@
dpInfo.Classes = append(dpInfo.Classes, data.Class)
}
- if dep, ok := module.(Dependency); ok {
- dpInfo.Installed_paths = append(dpInfo.Installed_paths, dep.ImplementationJars().Strings()...)
+ if ctx.ModuleHasProvider(module, JavaInfoProvider) {
+ dep := ctx.ModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ dpInfo.Installed_paths = append(dpInfo.Installed_paths, dep.ImplementationJars.Strings()...)
}
dpInfo.Classes = android.FirstUniqueStrings(dpInfo.Classes)
dpInfo.Installed_paths = android.FirstUniqueStrings(dpInfo.Installed_paths)
diff --git a/java/lint.go b/java/lint.go
index cd2a904..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
}
}
@@ -276,8 +281,9 @@
extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag)
for _, extraLintCheckModule := range extraLintCheckModules {
- if dep, ok := extraLintCheckModule.(Dependency); ok {
- l.extraLintCheckJars = append(l.extraLintCheckJars, dep.ImplementationAndResourcesJars()...)
+ if ctx.OtherModuleHasProvider(extraLintCheckModule, JavaInfoProvider) {
+ dep := ctx.OtherModuleProvider(extraLintCheckModule, JavaInfoProvider).(JavaInfo)
+ l.extraLintCheckJars = append(l.extraLintCheckJars, dep.ImplementationAndResourcesJars...)
} else {
ctx.PropertyErrorf("lint.extra_check_modules",
"%s is not a java module", ctx.OtherModuleName(extraLintCheckModule))
@@ -343,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/java/robolectric.go b/java/robolectric.go
index c821e5b..98bb710 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -148,10 +148,10 @@
}
for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
- m := dep.(Dependency)
- r.libs = append(r.libs, m.BaseModuleName())
- if !android.InList(m.BaseModuleName(), config.FrameworkLibraries) {
- combinedJarJars = append(combinedJarJars, m.ImplementationAndResourcesJars()...)
+ m := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
+ r.libs = append(r.libs, ctx.OtherModuleName(dep))
+ if !android.InList(ctx.OtherModuleName(dep), config.FrameworkLibraries) {
+ combinedJarJars = append(combinedJarJars, m.ImplementationAndResourcesJars...)
}
}
@@ -245,10 +245,10 @@
srcJarDeps := append(android.Paths(nil), instrumentedApp.srcJarDeps...)
for _, m := range ctx.GetDirectDepsWithTag(roboCoverageLibsTag) {
- if dep, ok := m.(Dependency); ok {
- depSrcJarArgs, depSrcJarDeps := dep.SrcJarArgs()
- srcJarArgs = append(srcJarArgs, depSrcJarArgs...)
- srcJarDeps = append(srcJarDeps, depSrcJarDeps...)
+ if ctx.OtherModuleHasProvider(m, JavaInfoProvider) {
+ dep := ctx.OtherModuleProvider(m, JavaInfoProvider).(JavaInfo)
+ srcJarArgs = append(srcJarArgs, dep.SrcJarArgs...)
+ srcJarDeps = append(srcJarDeps, dep.SrcJarDeps...)
}
}
diff --git a/java/sdk.go b/java/sdk.go
index a68abfb..74d5a81 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -566,10 +566,11 @@
ctx.VisitAllModules(func(module android.Module) {
// Collect dex jar paths for the modules listed above.
- if j, ok := module.(Dependency); ok {
+ if ctx.ModuleHasProvider(module, JavaInfoProvider) {
+ j := ctx.ModuleProvider(module, JavaInfoProvider).(JavaInfo)
name := ctx.ModuleName(module)
if i := android.IndexList(name, stubsModules); i != -1 {
- stubsJars[i] = j.HeaderJars()
+ stubsJars[i] = j.HeaderJars
}
}
})
@@ -640,14 +641,26 @@
if ctx.Config().PlatformSdkCodename() == "REL" {
cmd.Text("echo REL >").Output(out)
- } else if !ctx.Config().AlwaysUsePrebuiltSdks() {
- in, err := ctx.GlobWithDeps("frameworks/base/api/*current.txt", nil)
- if err != nil {
- ctx.Errorf("error globbing API files: %s", err)
+ } else if ctx.Config().FrameworksBaseDirExists(ctx) && !ctx.Config().AlwaysUsePrebuiltSdks() {
+ cmd.Text("cat")
+ apiTxtFileModules := []string{
+ "frameworks-base-api-current.txt",
+ "frameworks-base-api-system-current.txt",
+ "frameworks-base-api-module-lib-current.txt",
}
-
- cmd.Text("cat").
- Inputs(android.PathsForSource(ctx, in)).
+ count := 0
+ ctx.VisitAllModules(func(module android.Module) {
+ name := ctx.ModuleName(module)
+ if android.InList(name, apiTxtFileModules) {
+ cmd.Inputs(android.OutputFilesForModule(ctx, module, ""))
+ count++
+ }
+ })
+ if count != len(apiTxtFileModules) {
+ ctx.Errorf("Could not find all the expected API modules %v, found %d\n", apiTxtFileModules, count)
+ return
+ }
+ cmd.Input(android.PathForSource(ctx, "frameworks/base/services/api/current.txt")).
Text("| md5sum | cut -d' ' -f1 >").
Output(out)
} else {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 638740f..aa96e0d 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -60,12 +60,12 @@
apiScope *apiScope
// Function for extracting appropriate path information from the dependency.
- depInfoExtractor func(paths *scopePaths, dep android.Module) error
+ depInfoExtractor func(paths *scopePaths, ctx android.ModuleContext, dep android.Module) error
}
// Extract tag specific information from the dependency.
func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.Module, paths *scopePaths) {
- err := tag.depInfoExtractor(paths, dep)
+ err := tag.depInfoExtractor(paths, ctx, dep)
if err != nil {
ctx.ModuleErrorf("has an invalid {scopeDependencyTag: %s} dependency on module %s: %s", tag.name, ctx.OtherModuleName(dep), err.Error())
}
@@ -539,13 +539,14 @@
stubsSrcJar android.OptionalPath
}
-func (paths *scopePaths) extractStubsLibraryInfoFromDependency(dep android.Module) error {
- if lib, ok := dep.(Dependency); ok {
- paths.stubsHeaderPath = lib.HeaderJars()
- paths.stubsImplPath = lib.ImplementationJars()
+func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
+ if ctx.OtherModuleHasProvider(dep, JavaInfoProvider) {
+ lib := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
+ paths.stubsHeaderPath = lib.HeaderJars
+ paths.stubsImplPath = lib.ImplementationJars
return nil
} else {
- return fmt.Errorf("expected module that implements Dependency, e.g. java_library")
+ return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
}
}
@@ -572,7 +573,7 @@
paths.removedApiFilePath = android.OptionalPathForPath(provider.RemovedApiFilePath())
}
-func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error {
+func (paths *scopePaths) extractApiInfoFromDep(ctx android.ModuleContext, dep android.Module) error {
return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
paths.extractApiInfoFromApiStubsProvider(provider)
})
@@ -582,13 +583,13 @@
paths.stubsSrcJar = android.OptionalPathForPath(provider.StubsSrcJar())
}
-func (paths *scopePaths) extractStubsSourceInfoFromDep(dep android.Module) error {
+func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext, dep android.Module) error {
return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) {
paths.extractStubsSourceInfoFromApiStubsProviders(provider)
})
}
-func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(dep android.Module) error {
+func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx android.ModuleContext, dep android.Module) error {
return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
paths.extractApiInfoFromApiStubsProvider(provider)
paths.extractStubsSourceInfoFromApiStubsProviders(provider)
@@ -951,7 +952,6 @@
commonToSdkLibraryAndImport
}
-var _ Dependency = (*SdkLibrary)(nil)
var _ SdkLibraryDependency = (*SdkLibrary)(nil)
func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
diff --git a/java/system_modules.go b/java/system_modules.go
index 5cc546d..95f71b8 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -160,8 +160,8 @@
var jars android.Paths
ctx.VisitDirectDepsWithTag(systemModulesLibsTag, func(module android.Module) {
- dep, _ := module.(Dependency)
- jars = append(jars, dep.HeaderJars()...)
+ dep, _ := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ jars = append(jars, dep.HeaderJars...)
})
system.headerJars = jars
diff --git a/java/testing.go b/java/testing.go
index 5fcf84c..781106f 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -18,6 +18,7 @@
"fmt"
"reflect"
"sort"
+ "strings"
"testing"
"android/soong/android"
@@ -237,3 +238,11 @@
t.Errorf("expected %#q, found %#q", expected, actual)
}
}
+
+func CheckHiddenAPIRuleInputs(t *testing.T, expected string, hiddenAPIRule android.TestingBuildParams) {
+ actual := strings.TrimSpace(strings.Join(android.NormalizePathsForTesting(hiddenAPIRule.Implicits), "\n"))
+ expected = strings.TrimSpace(expected)
+ if actual != expected {
+ t.Errorf("Expected hiddenapi rule inputs:\n%s\nactual inputs:\n%s", expected, actual)
+ }
+}
diff --git a/kernel/Android.bp b/kernel/Android.bp
index f8a48d9..91e7490 100644
--- a/kernel/Android.bp
+++ b/kernel/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-kernel",
pkgPath: "android/soong/kernel",
diff --git a/licenses/Android.bp b/licenses/Android.bp
index f4a76d7..c70d6bd 100644
--- a/licenses/Android.bp
+++ b/licenses/Android.bp
@@ -307,10 +307,7 @@
license_kind {
name: "SPDX-license-identifier-Beerware",
- conditions: [
- "by_exception_only",
- "not_allowed",
- ],
+ conditions: ["notice"],
url: "https://spdx.org/licenses/Beerware.html",
}
@@ -1137,10 +1134,7 @@
license_kind {
name: "SPDX-license-identifier-WTFPL",
- conditions: [
- "by_exception_only",
- "not_allowed",
- ],
+ conditions: ["notice"],
url: "https://spdx.org/licenses/WTFPL.html",
}
diff --git a/linkerconfig/Android.bp b/linkerconfig/Android.bp
index 8807a2e..9161f0e 100644
--- a/linkerconfig/Android.bp
+++ b/linkerconfig/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-linkerconfig",
pkgPath: "android/soong/linkerconfig",
diff --git a/linkerconfig/proto/Android.bp b/linkerconfig/proto/Android.bp
index 4d97128..3b1e4ab 100644
--- a/linkerconfig/proto/Android.bp
+++ b/linkerconfig/proto/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_static {
name: "lib_linker_config_proto_lite",
host_supported: true,
diff --git a/makedeps/Android.bp b/makedeps/Android.bp
index b77b08f..62bdfd5 100644
--- a/makedeps/Android.bp
+++ b/makedeps/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-makedeps",
pkgPath: "android/soong/makedeps",
diff --git a/partner/Android.bp b/partner/Android.bp
index f2ced8d..7fc873e 100644
--- a/partner/Android.bp
+++ b/partner/Android.bp
@@ -16,6 +16,10 @@
// Sample project for creating an extended androidmk
//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "partner_androidmk",
srcs: [
diff --git a/phony/Android.bp b/phony/Android.bp
index 2c423ef..db5efc9 100644
--- a/phony/Android.bp
+++ b/phony/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-phony",
pkgPath: "android/soong/phony",
diff --git a/python/Android.bp b/python/Android.bp
index ffd03fe..b633f1e 100644
--- a/python/Android.bp
+++ b/python/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-python",
pkgPath: "android/soong/python",
diff --git a/python/tests/Android.bp b/python/tests/Android.bp
index c8bf420..0e8eef6 100644
--- a/python/tests/Android.bp
+++ b/python/tests/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
python_test_host {
name: "par_test",
main: "par_test.py",
diff --git a/remoteexec/Android.bp b/remoteexec/Android.bp
index fc2c0e3..9f75df5 100644
--- a/remoteexec/Android.bp
+++ b/remoteexec/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-remoteexec",
pkgPath: "android/soong/remoteexec",
diff --git a/rust/Android.bp b/rust/Android.bp
index ad3040a..8b2aa30 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-rust",
pkgPath: "android/soong/rust",
diff --git a/rust/compiler.go b/rust/compiler.go
index 586063e..c26f208 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -232,6 +232,10 @@
flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpathPrefix+"../"+rpath)
}
+ if ctx.RustModule().UseVndk() {
+ flags.RustFlags = append(flags.RustFlags, "--cfg 'android_vndk'")
+ }
+
return flags
}
@@ -254,7 +258,7 @@
if !Bool(compiler.Properties.No_stdlibs) {
for _, stdlib := range config.Stdlibs {
// If we're building for the primary arch of the build host, use the compiler's stdlibs
- if ctx.Target().Os == android.BuildOs && ctx.TargetPrimary() {
+ if ctx.Target().Os == android.BuildOs {
stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
}
diff --git a/rust/config/Android.bp b/rust/config/Android.bp
index 1f0109f..5b121c3 100644
--- a/rust/config/Android.bp
+++ b/rust/config/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-rust-config",
pkgPath: "android/soong/rust/config",
diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go
index 5066428..186e571 100644
--- a/rust/config/arm64_device.go
+++ b/rust/config/arm64_device.go
@@ -26,9 +26,10 @@
Arm64LinkFlags = []string{}
Arm64ArchVariantRustFlags = map[string][]string{
- "armv8-a": []string{},
- "armv8-2a": []string{},
- "armv8-2a-dotprod": []string{},
+ "armv8-a": []string{},
+ "armv8-a-branchprot": []string{},
+ "armv8-2a": []string{},
+ "armv8-2a-dotprod": []string{},
}
)
diff --git a/rust/image.go b/rust/image.go
index ac8c1b3..628aca3 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -24,7 +24,7 @@
var _ android.ImageInterface = (*Module)(nil)
func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
+ return mod.Properties.VendorRamdiskVariantNeeded
}
func (mod *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
@@ -52,6 +52,10 @@
return false
}
+func (mod *Module) InVendorRamdisk() bool {
+ return mod.ModuleBase.InVendorRamdisk() || mod.ModuleBase.InstallInVendorRamdisk()
+}
+
func (mod *Module) OnlyInRamdisk() bool {
// TODO(b/165791368)
return false
@@ -86,7 +90,9 @@
func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
m := module.(*Module)
- if strings.HasPrefix(variant, cc.VendorVariationPrefix) {
+ if variant == android.VendorRamdiskVariation {
+ m.MakeAsPlatform()
+ } else if strings.HasPrefix(variant, cc.VendorVariationPrefix) {
m.Properties.ImageVariationPrefix = cc.VendorVariationPrefix
m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.VendorVariationPrefix)
@@ -117,6 +123,8 @@
}
coreVariantNeeded := true
+ vendorRamdiskVariantNeeded := false
+
var vendorVariants []string
if mod.HasVendorVariant() {
@@ -138,15 +146,23 @@
// We can't check shared() here because image mutator is called before the library mutator, so we need to
// check buildShared()
if lib.buildShared() {
- mctx.PropertyErrorf(prop, "can only be set for rust_ffi_static modules.")
+ mctx.PropertyErrorf(prop, "cannot be set for rust_ffi or rust_ffi_shared modules.")
} else {
vendorVariants = append(vendorVariants, platformVndkVersion)
}
}
}
+ if Bool(mod.Properties.Vendor_ramdisk_available) {
+ if lib, ok := mod.compiler.(libraryInterface); !ok || (ok && lib.buildShared()) {
+ mctx.PropertyErrorf("vendor_ramdisk_available", "cannot be set for rust_ffi or rust_ffi_shared modules.")
+ } else {
+ vendorRamdiskVariantNeeded = true
+ }
+ }
+
if vendorSpecific {
- if lib, ok := mod.compiler.(libraryInterface); !ok || (ok && !lib.static()) {
+ if lib, ok := mod.compiler.(libraryInterface); !ok || (ok && (lib.buildShared() || lib.buildDylib() || lib.buildRlib())) {
mctx.ModuleErrorf("Rust vendor specific modules are currently only supported for rust_ffi_static modules.")
} else {
coreVariantNeeded = false
@@ -155,6 +171,8 @@
}
mod.Properties.CoreVariantNeeded = coreVariantNeeded
+ mod.Properties.VendorRamdiskVariantNeeded = vendorRamdiskVariantNeeded
+
for _, variant := range android.FirstUniqueStrings(vendorVariants) {
mod.Properties.ExtraVariants = append(mod.Properties.ExtraVariants, cc.VendorVariationPrefix+variant)
}
diff --git a/rust/image_test.go b/rust/image_test.go
index fd71962..e40599c 100644
--- a/rust/image_test.go
+++ b/rust/image_test.go
@@ -15,15 +15,16 @@
package rust
import (
+ "strings"
"testing"
"android/soong/android"
"android/soong/cc"
)
-// Test that cc_binaries can link against rust_ffi_static libraries.
+// Test that cc modules can link against vendor_available rust_ffi_static libraries.
func TestVendorLinkage(t *testing.T) {
- ctx := testRust(t, `
+ ctx := testRustVndk(t, `
cc_binary {
name: "fizz_vendor",
static_libs: ["libfoo_vendor"],
@@ -37,16 +38,58 @@
}
`)
- vendorBinary := ctx.ModuleForTests("fizz_vendor", "android_arm64_armv8-a").Module().(*cc.Module)
+ vendorBinary := ctx.ModuleForTests("fizz_vendor", "android_vendor.VER_arm64_armv8-a").Module().(*cc.Module)
if !android.InList("libfoo_vendor", vendorBinary.Properties.AndroidMkStaticLibs) {
t.Errorf("vendorBinary should have a dependency on libfoo_vendor")
}
}
+// Test that variants which use the vndk emit the appropriate cfg flag.
+func TestImageVndkCfgFlag(t *testing.T) {
+ ctx := testRustVndk(t, `
+ rust_ffi_static {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ vendor_available: true,
+ }
+ `)
+
+ vendor := ctx.ModuleForTests("libfoo", "android_vendor.VER_arm64_armv8-a_static").Rule("rustc")
+
+ if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") {
+ t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
+ }
+}
+
+// Test that cc modules can link against vendor_ramdisk_available rust_ffi_static libraries.
+func TestVendorRamdiskLinkage(t *testing.T) {
+ ctx := testRustVndk(t, `
+ cc_library_static {
+ name: "libcc_vendor_ramdisk",
+ static_libs: ["libfoo_vendor_ramdisk"],
+ system_shared_libs: [],
+ vendor_ramdisk_available: true,
+ }
+ rust_ffi_static {
+ name: "libfoo_vendor_ramdisk",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ vendor_ramdisk_available: true,
+ }
+ `)
+
+ vendorRamdiskLibrary := ctx.ModuleForTests("libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_static").Module().(*cc.Module)
+
+ if !android.InList("libfoo_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) {
+ t.Errorf("libcc_vendor_ramdisk should have a dependency on libfoo_vendor_ramdisk")
+ }
+}
+
// Test that shared libraries cannot be made vendor available until proper support is added.
func TestForbiddenVendorLinkage(t *testing.T) {
- testRustError(t, "can only be set for rust_ffi_static modules", `
+ testRustError(t, "cannot be set for rust_ffi or rust_ffi_shared modules.", `
rust_ffi_shared {
name: "libfoo_vendor",
crate_name: "foo",
@@ -54,6 +97,14 @@
vendor_available: true,
}
`)
+ testRustError(t, "cannot be set for rust_ffi or rust_ffi_shared modules.", `
+ rust_ffi_shared {
+ name: "libfoo_vendor",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ vendor_ramdisk_available: true,
+ }
+ `)
testRustError(t, "Rust vendor specific modules are currently only supported for rust_ffi_static modules.", `
rust_ffi {
name: "libfoo_vendor",
@@ -70,4 +121,13 @@
vendor: true,
}
`)
+ testRustError(t, "Rust vendor specific modules are currently only supported for rust_ffi_static modules.", `
+ rust_binary {
+ name: "foo_vendor",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ vendor: true,
+ }
+ `)
+
}
diff --git a/rust/rust.go b/rust/rust.go
index 0b733cc..dc23abb 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -74,8 +74,16 @@
SubName string `blueprint:"mutated"`
// Set by imageMutator
- CoreVariantNeeded bool `blueprint:"mutated"`
- ExtraVariants []string `blueprint:"mutated"`
+ CoreVariantNeeded bool `blueprint:"mutated"`
+ VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
+ ExtraVariants []string `blueprint:"mutated"`
+
+ // Make this module available when building for vendor ramdisk.
+ // On device without a dedicated recovery partition, the module is only
+ // available after switching root into
+ // /first_stage_ramdisk. To expose the module before switching root, install
+ // the recovery variant instead (TODO(b/165791368) recovery not yet supported)
+ Vendor_ramdisk_available *bool
// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
Min_sdk_version *string
@@ -658,7 +666,9 @@
// Differentiate static libraries that are vendor available
if mod.UseVndk() {
- mod.Properties.SubName += ".vendor"
+ mod.Properties.SubName += cc.VendorSuffix
+ } else if mod.InVendorRamdisk() && !mod.OnlyInVendorRamdisk() {
+ mod.Properties.SubName += cc.VendorRamdiskSuffix
}
if !toolchain.Supported() {
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 88d9643..a0ed534 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -64,6 +64,14 @@
return tctx.parse(t)
}
+func testRustVndk(t *testing.T, bp string) *android.TestContext {
+ tctx := newTestRustCtx(t, bp)
+ tctx.useMockedFs()
+ tctx.generateConfig()
+ tctx.setVndk(t)
+ return tctx.parse(t)
+}
+
// testRustCov returns a TestContext in which a basic environment has been
// setup. This environment explicitly enables coverage.
func testRustCov(t *testing.T, bp string) *android.TestContext {
@@ -140,6 +148,15 @@
tctx.config.TestProductVariables.NativeCoveragePaths = []string{"*"}
}
+func (tctx *testRustCtx) setVndk(t *testing.T) {
+ if tctx.config == nil {
+ t.Fatalf("tctx.config not been generated yet. Please call generateConfig first.")
+ }
+ tctx.config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+ tctx.config.TestProductVariables.ProductVndkVersion = StringPtr("current")
+ tctx.config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+}
+
// parse validates the configuration and parses the Blueprint file. It returns
// a TestContext which can be used to retrieve the generated modules via
// ModuleForTests.
diff --git a/rust/test.go b/rust/test.go
index 3fa5f95..6caa7b1 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -15,6 +15,8 @@
package rust
import (
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
"android/soong/tradefed"
)
@@ -127,6 +129,9 @@
ctx.PropertyErrorf("no_named_install_directory", "Module install directory may only be disabled if relative_install_path is set")
}
+ if ctx.Host() && test.Properties.Test_options.Unit_test == nil {
+ test.Properties.Test_options.Unit_test = proptools.BoolPtr(true)
+ }
test.binaryDecorator.install(ctx)
}
diff --git a/rust/testing.go b/rust/testing.go
index bb511b6..1afe27e 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -46,6 +46,30 @@
sysroot: true,
}
rust_prebuilt_library {
+ name: "libstd_i686-unknown-linux-gnu",
+ crate_name: "std",
+ rlib: {
+ srcs: ["libstd.rlib"],
+ },
+ dylib: {
+ srcs: ["libstd.so"],
+ },
+ host_supported: true,
+ sysroot: true,
+ }
+ rust_prebuilt_library {
+ name: "libtest_i686-unknown-linux-gnu",
+ crate_name: "test",
+ rlib: {
+ srcs: ["libtest.rlib"],
+ },
+ dylib: {
+ srcs: ["libtest.so"],
+ },
+ host_supported: true,
+ sysroot: true,
+ }
+ rust_prebuilt_library {
name: "libstd_x86_64-apple-darwin",
crate_name: "std",
rlib: {
@@ -101,6 +125,7 @@
no_stdlibs: true,
host_supported: true,
vendor_available: true,
+ vendor_ramdisk_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
@@ -113,6 +138,7 @@
no_stdlibs: true,
host_supported: true,
vendor_available: true,
+ vendor_ramdisk_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
diff --git a/scripts/Android.bp b/scripts/Android.bp
index dd03f28..b9163cc 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
python_binary_host {
name: "check_boot_jars",
main: "check_boot_jars/check_boot_jars.py",
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index b8485ea..ac67438 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -26,6 +26,8 @@
platform-mainline-test-exports
runtime-module-host-exports
runtime-module-sdk
+ stats-log-api-gen-exports
+ statsd-module-sdk
tzdata-module-test-exports
)
diff --git a/scripts/gen_ndk_backedby_apex.sh b/scripts/gen_ndk_backedby_apex.sh
index e0da602..4abaaba 100755
--- a/scripts/gen_ndk_backedby_apex.sh
+++ b/scripts/gen_ndk_backedby_apex.sh
@@ -23,33 +23,50 @@
echo "**************************** Usage Instructions ****************************"
echo "This script is used to generate the Mainline modules backed-by NDK symbols."
echo ""
- echo "To run this script use: ./ndk_backedby_module.sh \$BINARY_IMAGE_DIRECTORY \$OUTPUT_FILE_PATH \$NDK_LIB_NAME_LIST"
- echo "For example: If all the module image files that you would like to run is under directory '/myModule' and output write to /backedby.txt then the command would be:"
- echo "./ndk_usedby_module.sh /myModule /backedby.txt /ndkLibList.txt"
+ echo "To run this script use: ./gen_ndk_backed_by_apex.sh \$OUTPUT_FILE_PATH \$NDK_LIB_NAME_LIST \$MODULE_LIB1 \$MODULE_LIB2..."
+ echo "For example: If output write to /backedby.txt then the command would be:"
+ echo "./gen_ndk_backed_by_apex.sh /backedby.txt /ndkLibList.txt lib1.so lib2.so"
echo "If the module1 is backing lib1 then the backedby.txt would contains: "
echo "lib1"
}
+contains() {
+ val="$1"
+ shift
+ for x in "$@"; do
+ if [ "$x" = "$val" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
+
+
genBackedByList() {
- dir="$1"
- [[ ! -e "$2" ]] && echo "" >> "$2"
+ out="$1"
+ shift
+ ndk_list="$1"
+ shift
+ rm -f "$out"
+ touch "$out"
while IFS= read -r line
do
soFileName=$(echo "$line" | sed 's/\(.*so\).*/\1/')
if [[ ! -z "$soFileName" && "$soFileName" != *"#"* ]]
then
- find "$dir" -type f -name "$soFileName" -exec echo "$soFileName" >> "$2" \;
+ if contains "$soFileName" "$@"; then
+ echo "$soFileName" >> "$out"
+ fi
fi
- done < "$3"
+ done < "$ndk_list"
}
if [[ "$1" == "help" ]]
then
printHelp
-elif [[ "$#" -ne 3 ]]
+elif [[ "$#" -lt 2 ]]
then
- echo "Wrong argument length. Expecting 3 argument representing image file directory, output path, path to ndk library list."
+ echo "Wrong argument length. Expecting at least 2 argument representing output path, path to ndk library list, followed by a list of libraries in the Mainline module."
else
- [[ -e "$2" ]] && rm "$2"
- genBackedByList "$1" "$2" "$3"
+ genBackedByList "$@"
fi
diff --git a/scripts/hiddenapi/Android.bp b/scripts/hiddenapi/Android.bp
new file mode 100644
index 0000000..af7e7fe
--- /dev/null
+++ b/scripts/hiddenapi/Android.bp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+python_binary_host {
+ name: "merge_csv",
+ main: "merge_csv.py",
+ srcs: ["merge_csv.py"],
+ version: {
+ py2: {
+ enabled: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: true,
+ },
+ },
+}
+
+python_binary_host {
+ name: "generate_hiddenapi_lists",
+ main: "generate_hiddenapi_lists.py",
+ srcs: ["generate_hiddenapi_lists.py"],
+ version: {
+ py2: {
+ enabled: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: true,
+ },
+ },
+}
diff --git a/scripts/hiddenapi/generate_hiddenapi_lists.py b/scripts/hiddenapi/generate_hiddenapi_lists.py
new file mode 100755
index 0000000..6816475
--- /dev/null
+++ b/scripts/hiddenapi/generate_hiddenapi_lists.py
@@ -0,0 +1,383 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# 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.
+"""Generate API lists for non-SDK API enforcement."""
+import argparse
+from collections import defaultdict, namedtuple
+import functools
+import os
+import re
+import sys
+
+# Names of flags recognized by the `hiddenapi` tool.
+FLAG_SDK = 'sdk'
+FLAG_UNSUPPORTED = 'unsupported'
+FLAG_BLOCKED = 'blocked'
+FLAG_MAX_TARGET_O = 'max-target-o'
+FLAG_MAX_TARGET_P = 'max-target-p'
+FLAG_MAX_TARGET_Q = 'max-target-q'
+FLAG_MAX_TARGET_R = 'max-target-r'
+FLAG_CORE_PLATFORM_API = 'core-platform-api'
+FLAG_PUBLIC_API = 'public-api'
+FLAG_SYSTEM_API = 'system-api'
+FLAG_TEST_API = 'test-api'
+
+# List of all known flags.
+FLAGS_API_LIST = [
+ FLAG_SDK,
+ FLAG_UNSUPPORTED,
+ FLAG_BLOCKED,
+ FLAG_MAX_TARGET_O,
+ FLAG_MAX_TARGET_P,
+ FLAG_MAX_TARGET_Q,
+ FLAG_MAX_TARGET_R,
+]
+ALL_FLAGS = FLAGS_API_LIST + [
+ FLAG_CORE_PLATFORM_API,
+ FLAG_PUBLIC_API,
+ FLAG_SYSTEM_API,
+ FLAG_TEST_API,
+]
+
+FLAGS_API_LIST_SET = set(FLAGS_API_LIST)
+ALL_FLAGS_SET = set(ALL_FLAGS)
+
+# Option specified after one of FLAGS_API_LIST to indicate that
+# only known and otherwise unassigned entries should be assign the
+# given flag.
+# For example, the max-target-P list is checked in as it was in P,
+# but signatures have changes since then. The flag instructs this
+# script to skip any entries which do not exist any more.
+FLAG_IGNORE_CONFLICTS = "ignore-conflicts"
+
+# Option specified after one of FLAGS_API_LIST to express that all
+# apis within a given set of packages should be assign the given flag.
+FLAG_PACKAGES = "packages"
+
+# Option specified after one of FLAGS_API_LIST to indicate an extra
+# tag that should be added to the matching APIs.
+FLAG_TAG = "tag"
+
+# Regex patterns of fields/methods used in serialization. These are
+# considered public API despite being hidden.
+SERIALIZATION_PATTERNS = [
+ r'readObject\(Ljava/io/ObjectInputStream;\)V',
+ r'readObjectNoData\(\)V',
+ r'readResolve\(\)Ljava/lang/Object;',
+ r'serialVersionUID:J',
+ r'serialPersistentFields:\[Ljava/io/ObjectStreamField;',
+ r'writeObject\(Ljava/io/ObjectOutputStream;\)V',
+ r'writeReplace\(\)Ljava/lang/Object;',
+]
+
+# Single regex used to match serialization API. It combines all the
+# SERIALIZATION_PATTERNS into a single regular expression.
+SERIALIZATION_REGEX = re.compile(r'.*->(' + '|'.join(SERIALIZATION_PATTERNS) + r')$')
+
+# Predicates to be used with filter_apis.
+HAS_NO_API_LIST_ASSIGNED = lambda api, flags: not FLAGS_API_LIST_SET.intersection(flags)
+IS_SERIALIZATION = lambda api, flags: SERIALIZATION_REGEX.match(api)
+
+
+class StoreOrderedOptions(argparse.Action):
+ """An argparse action that stores a number of option arguments in the order that
+ they were specified.
+ """
+ def __call__(self, parser, args, values, option_string = None):
+ items = getattr(args, self.dest, None)
+ if items is None:
+ items = []
+ items.append([option_string.lstrip('-'), values])
+ setattr(args, self.dest, items)
+
+def get_args():
+ """Parses command line arguments.
+
+ Returns:
+ Namespace: dictionary of parsed arguments
+ """
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--output', required=True)
+ parser.add_argument('--csv', nargs='*', default=[], metavar='CSV_FILE',
+ help='CSV files to be merged into output')
+
+ for flag in ALL_FLAGS:
+ parser.add_argument('--' + flag, dest='ordered_flags', metavar='TXT_FILE',
+ action=StoreOrderedOptions, help='lists of entries with flag "' + flag + '"')
+ parser.add_argument('--' + FLAG_IGNORE_CONFLICTS, dest='ordered_flags', nargs=0,
+ action=StoreOrderedOptions, help='Indicates that only known and otherwise unassigned '
+ 'entries should be assign the given flag. Must follow a list of entries and applies '
+ 'to the preceding such list.')
+ parser.add_argument('--' + FLAG_PACKAGES, dest='ordered_flags', nargs=0,
+ action=StoreOrderedOptions, help='Indicates that the previous list of entries '
+ 'is a list of packages. All members in those packages will be given the flag. '
+ 'Must follow a list of entries and applies to the preceding such list.')
+ parser.add_argument('--' + FLAG_TAG, dest='ordered_flags', nargs=1,
+ action=StoreOrderedOptions, help='Adds an extra tag to the previous list of entries. '
+ 'Must follow a list of entries and applies to the preceding such list.')
+
+ return parser.parse_args()
+
+
+def read_lines(filename):
+ """Reads entire file and return it as a list of lines.
+
+ Lines which begin with a hash are ignored.
+
+ Args:
+ filename (string): Path to the file to read from.
+
+ Returns:
+ Lines of the file as a list of string.
+ """
+ with open(filename, 'r') as f:
+ lines = f.readlines();
+ lines = filter(lambda line: not line.startswith('#'), lines)
+ lines = map(lambda line: line.strip(), lines)
+ return set(lines)
+
+
+def write_lines(filename, lines):
+ """Writes list of lines into a file, overwriting the file if it exists.
+
+ Args:
+ filename (string): Path to the file to be writing into.
+ lines (list): List of strings to write into the file.
+ """
+ lines = map(lambda line: line + '\n', lines)
+ with open(filename, 'w') as f:
+ f.writelines(lines)
+
+
+def extract_package(signature):
+ """Extracts the package from a signature.
+
+ Args:
+ signature (string): JNI signature of a method or field.
+
+ Returns:
+ The package name of the class containing the field/method.
+ """
+ full_class_name = signature.split(";->")[0]
+ # Example: Landroid/hardware/radio/V1_2/IRadio$Proxy
+ if (full_class_name[0] != "L"):
+ raise ValueError("Expected to start with 'L': %s" % full_class_name)
+ full_class_name = full_class_name[1:]
+ # If full_class_name doesn't contain '/', then package_name will be ''.
+ package_name = full_class_name.rpartition("/")[0]
+ return package_name.replace('/', '.')
+
+
+class FlagsDict:
+ def __init__(self):
+ self._dict_keyset = set()
+ self._dict = defaultdict(set)
+
+ def _check_entries_set(self, keys_subset, source):
+ assert isinstance(keys_subset, set)
+ assert keys_subset.issubset(self._dict_keyset), (
+ "Error: {} specifies signatures not present in code:\n"
+ "{}"
+ "Please visit go/hiddenapi for more information.").format(
+ source, "".join(map(lambda x: " " + str(x) + "\n", keys_subset - self._dict_keyset)))
+
+ def _check_flags_set(self, flags_subset, source):
+ assert isinstance(flags_subset, set)
+ assert flags_subset.issubset(ALL_FLAGS_SET), (
+ "Error processing: {}\n"
+ "The following flags were not recognized: \n"
+ "{}\n"
+ "Please visit go/hiddenapi for more information.").format(
+ source, "\n".join(flags_subset - ALL_FLAGS_SET))
+
+ def filter_apis(self, filter_fn):
+ """Returns APIs which match a given predicate.
+
+ This is a helper function which allows to filter on both signatures (keys) and
+ flags (values). The built-in filter() invokes the lambda only with dict's keys.
+
+ Args:
+ filter_fn : Function which takes two arguments (signature/flags) and returns a boolean.
+
+ Returns:
+ A set of APIs which match the predicate.
+ """
+ return set(filter(lambda x: filter_fn(x, self._dict[x]), self._dict_keyset))
+
+ def get_valid_subset_of_unassigned_apis(self, api_subset):
+ """Sanitizes a key set input to only include keys which exist in the dictionary
+ and have not been assigned any API list flags.
+
+ Args:
+ entries_subset (set/list): Key set to be sanitized.
+
+ Returns:
+ Sanitized key set.
+ """
+ assert isinstance(api_subset, set)
+ return api_subset.intersection(self.filter_apis(HAS_NO_API_LIST_ASSIGNED))
+
+ def generate_csv(self):
+ """Constructs CSV entries from a dictionary.
+
+ Old versions of flags are used to generate the file.
+
+ Returns:
+ List of lines comprising a CSV file. See "parse_and_merge_csv" for format description.
+ """
+ lines = []
+ for api in self._dict:
+ flags = sorted(self._dict[api])
+ lines.append(",".join([api] + flags))
+ return sorted(lines)
+
+ def parse_and_merge_csv(self, csv_lines, source = "<unknown>"):
+ """Parses CSV entries and merges them into a given dictionary.
+
+ The expected CSV format is:
+ <api signature>,<flag1>,<flag2>,...,<flagN>
+
+ Args:
+ csv_lines (list of strings): Lines read from a CSV file.
+ source (string): Origin of `csv_lines`. Will be printed in error messages.
+
+ Throws:
+ AssertionError if parsed flags are invalid.
+ """
+ # Split CSV lines into arrays of values.
+ csv_values = [ line.split(',') for line in csv_lines ]
+
+ # Update the full set of API signatures.
+ self._dict_keyset.update([ csv[0] for csv in csv_values ])
+
+ # Check that all flags are known.
+ csv_flags = set()
+ for csv in csv_values:
+ csv_flags.update(csv[1:])
+ self._check_flags_set(csv_flags, source)
+
+ # Iterate over all CSV lines, find entry in dict and append flags to it.
+ for csv in csv_values:
+ flags = csv[1:]
+ if (FLAG_PUBLIC_API in flags) or (FLAG_SYSTEM_API in flags):
+ flags.append(FLAG_SDK)
+ self._dict[csv[0]].update(flags)
+
+ def assign_flag(self, flag, apis, source="<unknown>", tag = None):
+ """Assigns a flag to given subset of entries.
+
+ Args:
+ flag (string): One of ALL_FLAGS.
+ apis (set): Subset of APIs to receive the flag.
+ source (string): Origin of `entries_subset`. Will be printed in error messages.
+
+ Throws:
+ AssertionError if parsed API signatures of flags are invalid.
+ """
+ # Check that all APIs exist in the dict.
+ self._check_entries_set(apis, source)
+
+ # Check that the flag is known.
+ self._check_flags_set(set([ flag ]), source)
+
+ # Iterate over the API subset, find each entry in dict and assign the flag to it.
+ for api in apis:
+ self._dict[api].add(flag)
+ if tag:
+ self._dict[api].add(tag)
+
+
+FlagFile = namedtuple('FlagFile', ('flag', 'file', 'ignore_conflicts', 'packages', 'tag'))
+
+def parse_ordered_flags(ordered_flags):
+ r = []
+ currentflag, file, ignore_conflicts, packages, tag = None, None, False, False, None
+ for flag_value in ordered_flags:
+ flag, value = flag_value[0], flag_value[1]
+ if flag in ALL_FLAGS_SET:
+ if currentflag:
+ r.append(FlagFile(currentflag, file, ignore_conflicts, packages, tag))
+ ignore_conflicts, packages, tag = False, False, None
+ currentflag = flag
+ file = value
+ else:
+ if currentflag is None:
+ raise argparse.ArgumentError('--%s is only allowed after one of %s' % (
+ flag, ' '.join(['--%s' % f for f in ALL_FLAGS_SET])))
+ if flag == FLAG_IGNORE_CONFLICTS:
+ ignore_conflicts = True
+ elif flag == FLAG_PACKAGES:
+ packages = True
+ elif flag == FLAG_TAG:
+ tag = value[0]
+
+
+ if currentflag:
+ r.append(FlagFile(currentflag, file, ignore_conflicts, packages, tag))
+ return r
+
+
+def main(argv):
+ # Parse arguments.
+ args = vars(get_args())
+ flagfiles = parse_ordered_flags(args['ordered_flags'])
+
+ # Initialize API->flags dictionary.
+ flags = FlagsDict()
+
+ # Merge input CSV files into the dictionary.
+ # Do this first because CSV files produced by parsing API stubs will
+ # contain the full set of APIs. Subsequent additions from text files
+ # will be able to detect invalid entries, and/or filter all as-yet
+ # unassigned entries.
+ for filename in args["csv"]:
+ flags.parse_and_merge_csv(read_lines(filename), filename)
+
+ # Combine inputs which do not require any particular order.
+ # (1) Assign serialization API to SDK.
+ flags.assign_flag(FLAG_SDK, flags.filter_apis(IS_SERIALIZATION))
+
+ # (2) Merge text files with a known flag into the dictionary.
+ for info in flagfiles:
+ if (not info.ignore_conflicts) and (not info.packages):
+ flags.assign_flag(info.flag, read_lines(info.file), info.file, info.tag)
+
+ # Merge text files where conflicts should be ignored.
+ # This will only assign the given flag if:
+ # (a) the entry exists, and
+ # (b) it has not been assigned any other flag.
+ # Because of (b), this must run after all strict assignments have been performed.
+ for info in flagfiles:
+ if info.ignore_conflicts:
+ valid_entries = flags.get_valid_subset_of_unassigned_apis(read_lines(info.file))
+ flags.assign_flag(info.flag, valid_entries, filename, info.tag)
+
+ # All members in the specified packages will be assigned the appropriate flag.
+ for info in flagfiles:
+ if info.packages:
+ packages_needing_list = set(read_lines(info.file))
+ should_add_signature_to_list = lambda sig,lists: extract_package(
+ sig) in packages_needing_list and not lists
+ valid_entries = flags.filter_apis(should_add_signature_to_list)
+ flags.assign_flag(info.flag, valid_entries, info.file, info.tag)
+
+ # Mark all remaining entries as blocked.
+ flags.assign_flag(FLAG_BLOCKED, flags.filter_apis(HAS_NO_API_LIST_ASSIGNED))
+
+ # Write output.
+ write_lines(args["output"], flags.generate_csv())
+
+if __name__ == "__main__":
+ main(sys.argv)
diff --git a/scripts/hiddenapi/generate_hiddenapi_lists_test.py b/scripts/hiddenapi/generate_hiddenapi_lists_test.py
new file mode 100755
index 0000000..ff3d708
--- /dev/null
+++ b/scripts/hiddenapi/generate_hiddenapi_lists_test.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# 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.
+"""Unit tests for Hidden API list generation."""
+import unittest
+from generate_hiddenapi_lists import *
+
+class TestHiddenapiListGeneration(unittest.TestCase):
+
+ def test_filter_apis(self):
+ # Initialize flags so that A and B are put on the allow list and
+ # C, D, E are left unassigned. Try filtering for the unassigned ones.
+ flags = FlagsDict()
+ flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B,' + FLAG_SDK,
+ 'C', 'D', 'E'])
+ filter_set = flags.filter_apis(lambda api, flags: not flags)
+ self.assertTrue(isinstance(filter_set, set))
+ self.assertEqual(filter_set, set([ 'C', 'D', 'E' ]))
+
+ def test_get_valid_subset_of_unassigned_keys(self):
+ # Create flags where only A is unassigned.
+ flags = FlagsDict()
+ flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B', 'C'])
+ flags.assign_flag(FLAG_UNSUPPORTED, set(['C']))
+ self.assertEqual(flags.generate_csv(),
+ [ 'A,' + FLAG_SDK, 'B', 'C,' + FLAG_UNSUPPORTED ])
+
+ # Check three things:
+ # (1) B is selected as valid unassigned
+ # (2) A is not selected because it is assigned to the allow list
+ # (3) D is not selected because it is not a valid key
+ self.assertEqual(
+ flags.get_valid_subset_of_unassigned_apis(set(['A', 'B', 'D'])), set([ 'B' ]))
+
+ def test_parse_and_merge_csv(self):
+ flags = FlagsDict()
+
+ # Test empty CSV entry.
+ self.assertEqual(flags.generate_csv(), [])
+
+ # Test new additions.
+ flags.parse_and_merge_csv([
+ 'A,' + FLAG_UNSUPPORTED,
+ 'B,' + FLAG_BLOCKED + ',' + FLAG_MAX_TARGET_O,
+ 'C,' + FLAG_SDK + ',' + FLAG_SYSTEM_API,
+ 'D,' + FLAG_UNSUPPORTED + ',' + FLAG_TEST_API,
+ 'E,' + FLAG_BLOCKED + ',' + FLAG_TEST_API,
+ ])
+ self.assertEqual(flags.generate_csv(), [
+ 'A,' + FLAG_UNSUPPORTED,
+ 'B,' + FLAG_BLOCKED + "," + FLAG_MAX_TARGET_O,
+ 'C,' + FLAG_SDK + ',' + FLAG_SYSTEM_API,
+ 'D,' + FLAG_TEST_API + ',' + FLAG_UNSUPPORTED,
+ 'E,' + FLAG_BLOCKED + ',' + FLAG_TEST_API,
+ ])
+
+ # Test unknown flag.
+ with self.assertRaises(AssertionError):
+ flags.parse_and_merge_csv([ 'Z,foo' ])
+
+ def test_assign_flag(self):
+ flags = FlagsDict()
+ flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B'])
+
+ # Test new additions.
+ flags.assign_flag(FLAG_UNSUPPORTED, set([ 'A', 'B' ]))
+ self.assertEqual(flags.generate_csv(),
+ [ 'A,' + FLAG_SDK + "," + FLAG_UNSUPPORTED, 'B,' + FLAG_UNSUPPORTED ])
+
+ # Test invalid API signature.
+ with self.assertRaises(AssertionError):
+ flags.assign_flag(FLAG_SDK, set([ 'C' ]))
+
+ # Test invalid flag.
+ with self.assertRaises(AssertionError):
+ flags.assign_flag('foo', set([ 'A' ]))
+
+ def test_extract_package(self):
+ signature = 'Lcom/foo/bar/Baz;->method1()Lcom/bar/Baz;'
+ expected_package = 'com.foo.bar'
+ self.assertEqual(extract_package(signature), expected_package)
+
+ signature = 'Lcom/foo1/bar/MyClass;->method2()V'
+ expected_package = 'com.foo1.bar'
+ self.assertEqual(extract_package(signature), expected_package)
+
+ signature = 'Lcom/foo_bar/baz/MyClass;->method3()V'
+ expected_package = 'com.foo_bar.baz'
+ self.assertEqual(extract_package(signature), expected_package)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/scripts/hiddenapi/merge_csv.py b/scripts/hiddenapi/merge_csv.py
new file mode 100755
index 0000000..5ad61b2
--- /dev/null
+++ b/scripts/hiddenapi/merge_csv.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# 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.
+"""
+Merge multiple CSV files, possibly with different columns.
+"""
+
+import argparse
+import csv
+import io
+
+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='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)
+args = args_parser.parse_args()
+
+
+def dict_reader(input):
+ return csv.DictReader(input, delimiter=',', quotechar='|')
+
+csv_readers = []
+if not(args.zip_input):
+ for file in args.files:
+ csv_readers.append(dict_reader(open(file, '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:
+ fieldnames = args.header.split(',')
+else:
+ # Build union of all columns from source files:
+ for reader in csv_readers:
+ headers = headers.union(reader.fieldnames)
+ fieldnames = sorted(headers)
+
+# Concatenate all files to output:
+writer = csv.DictWriter(args.output, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL,
+ dialect='unix', fieldnames=fieldnames)
+writer.writeheader()
+for reader in csv_readers:
+ for row in reader:
+ writer.writerow(row)
diff --git a/sdk/Android.bp b/sdk/Android.bp
index cb93351..8a3119c 100644
--- a/sdk/Android.bp
+++ b/sdk/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-sdk",
pkgPath: "android/soong/sdk",
diff --git a/sh/Android.bp b/sh/Android.bp
index e5ffeef..f9198dc 100644
--- a/sh/Android.bp
+++ b/sh/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-sh",
pkgPath: "android/soong/sh",
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 66e493b..54dfc24 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -24,6 +24,7 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/bazel"
"android/soong/cc"
"android/soong/tradefed"
)
@@ -43,6 +44,8 @@
android.RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
android.RegisterModuleType("sh_test", ShTestFactory)
android.RegisterModuleType("sh_test_host", ShTestHostFactory)
+
+ android.RegisterBp2BuildMutator("sh_binary", ShBinaryBp2Build)
}
type shBinaryProperties struct {
@@ -81,6 +84,9 @@
// Make this module available when building for recovery.
Recovery_available *bool
+
+ // Properties for Bazel migration purposes.
+ bazel.Properties
}
type TestProperties struct {
@@ -461,4 +467,62 @@
return module
}
+type bazelShBinaryAttributes struct {
+ Srcs bazel.LabelList
+ // Bazel also supports the attributes below, but (so far) these are not required for Bionic
+ // deps
+ // data
+ // args
+ // compatible_with
+ // deprecation
+ // distribs
+ // env
+ // exec_compatible_with
+ // exec_properties
+ // features
+ // licenses
+ // output_licenses
+ // restricted_to
+ // tags
+ // target_compatible_with
+ // testonly
+ // toolchains
+ // visibility
+}
+
+type bazelShBinary struct {
+ android.BazelTargetModuleBase
+ bazelShBinaryAttributes
+}
+
+func BazelShBinaryFactory() android.Module {
+ module := &bazelShBinary{}
+ module.AddProperties(&module.bazelShBinaryAttributes)
+ android.InitBazelTargetModule(module)
+ return module
+}
+
+func ShBinaryBp2Build(ctx android.TopDownMutatorContext) {
+ m, ok := ctx.Module().(*ShBinary)
+ if !ok || !m.properties.Bazel_module.Bp2build_available {
+ return
+ }
+
+ srcs := android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src})
+
+ attrs := &bazelShBinaryAttributes{
+ Srcs: srcs,
+ }
+
+ props := bazel.NewBazelTargetModuleProperties(m.Name(), "sh_binary", "")
+
+ ctx.CreateBazelTargetModule(BazelShBinaryFactory, props, attrs)
+}
+
+func (m *bazelShBinary) Name() string {
+ return m.BaseModuleName()
+}
+
+func (m *bazelShBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
+
var Bool = proptools.Bool
diff --git a/shared/Android.bp b/shared/Android.bp
index 2a4f56f..5aa9d54 100644
--- a/shared/Android.bp
+++ b/shared/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-shared",
pkgPath: "android/soong/shared",
diff --git a/symbol_inject/Android.bp b/symbol_inject/Android.bp
index 8308043..7180248 100644
--- a/symbol_inject/Android.bp
+++ b/symbol_inject/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-symbol_inject",
pkgPath: "android/soong/symbol_inject",
diff --git a/symbol_inject/cmd/Android.bp b/symbol_inject/cmd/Android.bp
index ee2f259..ac23f00 100644
--- a/symbol_inject/cmd/Android.bp
+++ b/symbol_inject/cmd/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "symbol_inject",
deps: ["soong-symbol_inject"],
diff --git a/sysprop/Android.bp b/sysprop/Android.bp
index 48094f1..540a8da 100644
--- a/sysprop/Android.bp
+++ b/sysprop/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-sysprop",
pkgPath: "android/soong/sysprop",
diff --git a/third_party/zip/Android.bp b/third_party/zip/Android.bp
index ec89c0c..f279d12 100644
--- a/third_party/zip/Android.bp
+++ b/third_party/zip/Android.bp
@@ -12,6 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: [
+ "Android-Apache-2.0",
+ "build_soong_third_party_zip_license",
+ ],
+}
+
+license {
+ name: "build_soong_third_party_zip_license",
+ license_kinds: [
+ "SPDX-license-identifier-BSD",
+ ],
+ license_text: ["LICENSE"],
+}
+
bootstrap_go_package {
name: "android-archive-zip",
pkgPath: "android/soong/third_party/zip",
diff --git a/third_party/zip/LICENSE b/third_party/zip/LICENSE
new file mode 100644
index 0000000..e5c5baf
--- /dev/null
+++ b/third_party/zip/LICENSE
@@ -0,0 +1,28 @@
+Copyright 2009, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of the Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tradefed/Android.bp b/tradefed/Android.bp
index 4e4e6a7..f0336a3 100644
--- a/tradefed/Android.bp
+++ b/tradefed/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-tradefed",
pkgPath: "android/soong/tradefed",
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index c314b7b..32b6eda 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-ui-build-paths",
pkgPath: "android/soong/ui/build/paths",
diff --git a/ui/logger/Android.bp b/ui/logger/Android.bp
index 8091ef9..269a5a0 100644
--- a/ui/logger/Android.bp
+++ b/ui/logger/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-ui-logger",
pkgPath: "android/soong/ui/logger",
diff --git a/ui/metrics/Android.bp b/ui/metrics/Android.bp
index 95c8f5c..c428ec4 100644
--- a/ui/metrics/Android.bp
+++ b/ui/metrics/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-ui-metrics",
pkgPath: "android/soong/ui/metrics",
diff --git a/ui/metrics/proc/Android.bp b/ui/metrics/proc/Android.bp
index 32d8217..4501fed 100644
--- a/ui/metrics/proc/Android.bp
+++ b/ui/metrics/proc/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-ui-metrics-proc",
pkgPath: "android/soong/ui/metrics/proc",
diff --git a/ui/status/Android.bp b/ui/status/Android.bp
index 19e5a2a..ac31390 100644
--- a/ui/status/Android.bp
+++ b/ui/status/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-ui-status",
pkgPath: "android/soong/ui/status",
diff --git a/ui/terminal/Android.bp b/ui/terminal/Android.bp
index aa6e35d..fdf300f 100644
--- a/ui/terminal/Android.bp
+++ b/ui/terminal/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-ui-terminal",
pkgPath: "android/soong/ui/terminal",
diff --git a/ui/tracer/Android.bp b/ui/tracer/Android.bp
index af588f1..d8942fd 100644
--- a/ui/tracer/Android.bp
+++ b/ui/tracer/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-ui-tracer",
pkgPath: "android/soong/ui/tracer",
diff --git a/xml/Android.bp b/xml/Android.bp
index cd25cff..a5e5f4c 100644
--- a/xml/Android.bp
+++ b/xml/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-xml",
pkgPath: "android/soong/xml",
diff --git a/zip/Android.bp b/zip/Android.bp
index 5081e91..b28adbd 100644
--- a/zip/Android.bp
+++ b/zip/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
subdirs = ["cmd"]
bootstrap_go_package {
diff --git a/zip/cmd/Android.bp b/zip/cmd/Android.bp
index 6029a69..43bf232 100644
--- a/zip/cmd/Android.bp
+++ b/zip/cmd/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
blueprint_go_binary {
name: "soong_zip",
deps: [