Merge "Fix minor issues in updatability lint CLs."
diff --git a/android/arch.go b/android/arch.go
index 9f93752..d7b12bc 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -412,6 +412,54 @@
}
}
+func registerBp2buildArchPathDepsMutator(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("bp2build-arch-pathdeps", bp2buildArchPathDepsMutator).Parallel()
+}
+
+// add dependencies for architecture specific properties tagged with `android:"path"`
+func bp2buildArchPathDepsMutator(ctx BottomUpMutatorContext) {
+ var module Module
+ module = ctx.Module()
+
+ m := module.base()
+ if !m.ArchSpecific() {
+ return
+ }
+
+ // addPathDepsForProps does not descend into sub structs, so we need to descend into the
+ // arch-specific properties ourselves
+ properties := []interface{}{}
+ for _, archProperties := range m.archProperties {
+ for _, archProps := range archProperties {
+ archPropValues := reflect.ValueOf(archProps).Elem()
+ // there are three "arch" variations, descend into each
+ for _, variant := range []string{"Arch", "Multilib", "Target"} {
+ // The properties are an interface, get the value (a pointer) that it points to
+ archProps := archPropValues.FieldByName(variant).Elem()
+ if archProps.IsNil() {
+ continue
+ }
+ // And then a pointer to a struct
+ archProps = archProps.Elem()
+ for i := 0; i < archProps.NumField(); i += 1 {
+ f := archProps.Field(i)
+ // If the value of the field is a struct (as opposed to a pointer to a struct) then step
+ // into the BlueprintEmbed field.
+ if f.Kind() == reflect.Struct {
+ f = f.FieldByName("BlueprintEmbed")
+ }
+ if f.IsZero() {
+ continue
+ }
+ props := f.Interface().(interface{})
+ properties = append(properties, props)
+ }
+ }
+ }
+ }
+ addPathDepsForProps(ctx, properties)
+}
+
// osMutator splits an arch-specific module into a variant for each OS that is enabled for the
// module. It uses the HostOrDevice value passed to InitAndroidArchModule and the
// device_supported and host_supported properties to determine which OsTypes are enabled for this
@@ -617,7 +665,7 @@
}
// only the primary arch in the ramdisk / vendor_ramdisk / recovery partition
- if os == Android && (module.InstallInRecovery() || module.InstallInRamdisk() || module.InstallInVendorRamdisk() || module.InstallInDebugRamdisk()) {
+ if os == Android && (module.InstallInRecovery() || module.InstallInRamdisk() || module.InstallInVendorRamdisk()) {
osTargets = []Target{osTargets[0]}
}
@@ -899,13 +947,17 @@
if string(field.Tag) != `android:"`+strings.Join(values, ",")+`"` {
panic(fmt.Errorf("unexpected tag format %q", field.Tag))
}
+ // don't delete path tag as it is needed for bp2build
// these tags don't need to be present in the runtime generated struct type.
- values = RemoveListFromList(values, []string{"arch_variant", "variant_prepend", "path"})
- if len(values) > 0 {
+ values = RemoveListFromList(values, []string{"arch_variant", "variant_prepend"})
+ if len(values) > 0 && values[0] != "path" {
panic(fmt.Errorf("unknown tags %q in field %q", values, prefix+field.Name))
+ } else if len(values) == 1 {
+ field.Tag = reflect.StructTag(`android:"` + strings.Join(values, ",") + `"`)
+ } else {
+ field.Tag = ``
}
- field.Tag = ""
return true, field
}
return false, field
diff --git a/android/arch_test.go b/android/arch_test.go
index 633ddaa..3aa4779 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -66,9 +66,9 @@
}{},
out: &struct {
A *string
- B *string
- C *string
- D *string
+ B *string `android:"path"`
+ C *string `android:"path"`
+ D *string `android:"path"`
}{},
filtered: true,
},
diff --git a/android/bazel.go b/android/bazel.go
index 6800c91..ba5ae31 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -185,7 +185,7 @@
"libc_bionic_ndk", // ruperts@, cc_library_static, depends on //bionic/libc/system_properties
"libc_bionic_systrace", // ruperts@, cc_library_static, 'private/bionic_systrace.h' file not found
"libc_pthread", // ruperts@, cc_library_static, 'private/bionic_defs.h' file not found
- "libc_syscalls", // ruperts@, cc_library_static, mutator panic cannot get direct dep syscalls-arm64.S of libc_syscalls
+ "libc_syscalls", // eakammer@, cc_library_static, 'private/bionic_asm.h' file not found
"libc_ndk", // ruperts@, cc_library_static, depends on //bionic/libm:libm
"libc_nopthread", // ruperts@, cc_library_static, depends on //external/arm-optimized-routines
"libc_common", // ruperts@, cc_library_static, depends on //bionic/libc:libc_nopthread
@@ -212,8 +212,8 @@
"libc_malloc_debug", // jingwen@, cc_library, fatal error: 'assert.h' file not found
"libc_malloc_hooks", // jingwen@, cc_library, fatal error: 'errno.h' file not found
"libdl", // jingwen@, cc_library, ld.lld: error: no input files
- "libm", // jingwen@, cc_library, fatal error: 'freebsd-compat.h' file not found
- "libseccomp_policy", // jingwen@, cc_library, fatal error: 'seccomp_policy.h' file not found
+ "libm", // lberki@, cc_library, compiler error: "Unexpected token in argument list"
+ "libseccomp_policy", // lberki@, cc_library, 'linux/filter.h' not found, caused by missing -isystem bionic/libc/kernel/uapi, dunno where it comes from in Soong
"libstdc++", // jingwen@, cc_library, depends on //external/gwp_asan
}
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 9727cc7..63e2c50 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -351,3 +351,13 @@
OutputPath: outputPath.withRel(validatedExecRootPath),
}
}
+
+// PathsForBazelOut returns a list of paths representing the paths under an output directory
+// dedicated to Bazel-owned outputs.
+func PathsForBazelOut(ctx PathContext, paths []string) Paths {
+ outs := make(Paths, 0, len(paths))
+ for _, p := range paths {
+ outs = append(outs, PathForBazelOut(ctx, p))
+ }
+ return outs
+}
diff --git a/android/image.go b/android/image.go
index bdb9be0..1a1a423 100644
--- a/android/image.go
+++ b/android/image.go
@@ -30,11 +30,6 @@
// vendor ramdisk partition).
VendorRamdiskVariantNeeded(ctx BaseModuleContext) bool
- // DebugRamdiskVariantNeeded should return true if the module needs a debug ramdisk variant (installed on the
- // debug ramdisk partition: $(PRODUCT_OUT)/debug_ramdisk/first_stage_ramdisk if BOARD_USES_RECOVERY_AS_ROOT is
- // true, $(PRODUCT_OUT)/debug_ramdisk otherise).
- DebugRamdiskVariantNeeded(ctx BaseModuleContext) bool
-
// RecoveryVariantNeeded should return true if the module needs a recovery variant (installed on the
// recovery partition).
RecoveryVariantNeeded(ctx BaseModuleContext) bool
@@ -65,9 +60,6 @@
// VendorRamdiskVariation means a module to be installed to vendor ramdisk image.
VendorRamdiskVariation string = "vendor_ramdisk"
-
- // DebugRamdiskVariation means a module to be installed to debug ramdisk image.
- DebugRamdiskVariation string = "debug_ramdisk"
)
// imageMutator creates variants for modules that implement the ImageInterface that
@@ -91,9 +83,6 @@
if m.VendorRamdiskVariantNeeded(ctx) {
variations = append(variations, VendorRamdiskVariation)
}
- if m.DebugRamdiskVariantNeeded(ctx) {
- variations = append(variations, DebugRamdiskVariation)
- }
if m.RecoveryVariantNeeded(ctx) {
variations = append(variations, RecoveryVariation)
}
diff --git a/android/module.go b/android/module.go
index 942e071..9f923e2 100644
--- a/android/module.go
+++ b/android/module.go
@@ -393,7 +393,6 @@
InstallInSanitizerDir() bool
InstallInRamdisk() bool
InstallInVendorRamdisk() bool
- InstallInDebugRamdisk() bool
InstallInRecovery() bool
InstallInRoot() bool
InstallBypassMake() bool
@@ -451,7 +450,6 @@
InstallInSanitizerDir() bool
InstallInRamdisk() bool
InstallInVendorRamdisk() bool
- InstallInDebugRamdisk() bool
InstallInRecovery() bool
InstallInRoot() bool
InstallBypassMake() bool
@@ -755,9 +753,6 @@
// Whether this module is installed to vendor ramdisk
Vendor_ramdisk *bool
- // Whether this module is installed to debug ramdisk
- Debug_ramdisk *bool
-
// Whether this module is built for non-native architectures (also known as native bridge binary)
Native_bridge_supported *bool `android:"arch_variant"`
@@ -1545,10 +1540,6 @@
return Bool(m.commonProperties.Vendor_ramdisk)
}
-func (m *ModuleBase) InstallInDebugRamdisk() bool {
- return Bool(m.commonProperties.Debug_ramdisk)
-}
-
func (m *ModuleBase) InstallInRecovery() bool {
return Bool(m.commonProperties.Recovery)
}
@@ -1602,10 +1593,6 @@
return m.base().commonProperties.ImageVariation == VendorRamdiskVariation
}
-func (m *ModuleBase) InDebugRamdisk() bool {
- return m.base().commonProperties.ImageVariation == DebugRamdiskVariation
-}
-
func (m *ModuleBase) InRecovery() bool {
return m.base().commonProperties.ImageVariation == RecoveryVariation
}
@@ -2561,10 +2548,6 @@
return m.module.InstallInVendorRamdisk()
}
-func (m *moduleContext) InstallInDebugRamdisk() bool {
- return m.module.InstallInDebugRamdisk()
-}
-
func (m *moduleContext) InstallInRecovery() bool {
return m.module.InstallInRecovery()
}
diff --git a/android/mutator.go b/android/mutator.go
index e25e2e8..365bf29 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -55,6 +55,7 @@
bp2buildDepsMutators = append([]RegisterMutatorFunc{
registerDepsMutatorBp2Build,
registerPathDepsMutator,
+ registerBp2buildArchPathDepsMutator,
}, depsMutators...)
for _, f := range bp2buildDepsMutators {
diff --git a/android/path_properties.go b/android/path_properties.go
index 2c8d27c..4446773 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -34,7 +34,10 @@
// ":module" module reference syntax in a property that is tagged with `android:"path"`.
func pathDepsMutator(ctx BottomUpMutatorContext) {
props := ctx.Module().base().generalProperties
+ addPathDepsForProps(ctx, props)
+}
+func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) {
// Iterate through each property struct of the module extracting the contents of all properties
// tagged with `android:"path"`.
var pathProperties []string
diff --git a/android/paths.go b/android/paths.go
index 026cb87..93c5684 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -106,7 +106,6 @@
InstallInSanitizerDir() bool
InstallInRamdisk() bool
InstallInVendorRamdisk() bool
- InstallInDebugRamdisk() bool
InstallInRecovery() bool
InstallInRoot() bool
InstallBypassMake() bool
@@ -1690,16 +1689,6 @@
if !ctx.InstallInRoot() {
partition += "/system"
}
- } else if ctx.InstallInDebugRamdisk() {
- // The module is only available after switching root into
- // /first_stage_ramdisk. To expose the module before switching root
- // on a device without a dedicated recovery partition, install the
- // recovery variant.
- if ctx.DeviceConfig().BoardUsesRecoveryAsBoot() {
- partition = "debug_ramdisk/first_stage_ramdisk"
- } else {
- partition = "debug_ramdisk"
- }
} else if ctx.InstallInRecovery() {
if ctx.InstallInRoot() {
partition = "recovery/root"
@@ -1870,7 +1859,6 @@
inSanitizerDir bool
inRamdisk bool
inVendorRamdisk bool
- inDebugRamdisk bool
inRecovery bool
inRoot bool
forceOS *OsType
@@ -1903,10 +1891,6 @@
return m.inVendorRamdisk
}
-func (m testModuleInstallPathContext) InstallInDebugRamdisk() bool {
- return m.inDebugRamdisk
-}
-
func (m testModuleInstallPathContext) InstallInRecovery() bool {
return m.inRecovery
}
diff --git a/android/paths_test.go b/android/paths_test.go
index cb9138b..6ec75b4 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -395,19 +395,6 @@
partitionDir: "target/product/test_device/vendor_ramdisk",
},
{
- name: "debug_ramdisk binary",
- ctx: &testModuleInstallPathContext{
- baseModuleContext: baseModuleContext{
- os: deviceTarget.Os,
- target: deviceTarget,
- },
- inDebugRamdisk: true,
- },
- in: []string{"my_test"},
- out: "target/product/test_device/debug_ramdisk/my_test",
- partitionDir: "target/product/test_device/debug_ramdisk",
- },
- {
name: "system native test binary",
ctx: &testModuleInstallPathContext{
baseModuleContext: baseModuleContext{
@@ -746,19 +733,6 @@
out: "target/product/test_device/vendor_ramdisk/first_stage_ramdisk/my_test",
partitionDir: "target/product/test_device/vendor_ramdisk/first_stage_ramdisk",
},
- {
- name: "debug_ramdisk binary",
- ctx: &testModuleInstallPathContext{
- baseModuleContext: baseModuleContext{
- os: deviceTarget.Os,
- target: deviceTarget,
- },
- inDebugRamdisk: true,
- },
- in: []string{"my_test"},
- out: "target/product/test_device/debug_ramdisk/first_stage_ramdisk/my_test",
- partitionDir: "target/product/test_device/debug_ramdisk/first_stage_ramdisk",
- },
}
for _, tc := range testCases {
diff --git a/apex/deapexer.go b/apex/deapexer.go
index 1db13f9..9bc5720 100644
--- a/apex/deapexer.go
+++ b/apex/deapexer.go
@@ -44,9 +44,13 @@
// module.`
type DeapexerProperties struct {
// List of java libraries that are embedded inside this prebuilt APEX bundle and for which this
- // APEX bundle will provide dex implementation jars for use by dexpreopt and boot jars package
- // check.
+ // APEX bundle will create an APEX variant and provide dex implementation jars for use by
+ // dexpreopt and boot jars package check.
Exported_java_libs []string
+
+ // List of bootclasspath fragments inside this prebuiltd APEX bundle and for which this APEX
+ // bundle will create an APEX variant.
+ Exported_bootclasspath_fragments []string
}
type SelectedApexProperties struct {
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index a9d24a7..7830f95 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -97,10 +97,17 @@
func (p *prebuiltCommon) deapexerDeps(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.deapexerProperties.Exported_java_libs {
- dep := prebuiltApexExportedModuleName(ctx, lib)
+ for _, exported := range p.deapexerProperties.Exported_java_libs {
+ dep := prebuiltApexExportedModuleName(ctx, exported)
ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), exportedJavaLibTag, dep)
}
+
+ // Add dependencies onto the bootclasspath fragment modules that are exported from this prebuilt
+ // apex.
+ for _, exported := range p.deapexerProperties.Exported_bootclasspath_fragments {
+ dep := prebuiltApexExportedModuleName(ctx, exported)
+ ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), exportedBootclasspathFragmentTag, dep)
+ }
}
// apexInfoMutator marks any modules for which this apex exports a file as requiring an apex
@@ -137,18 +144,19 @@
var dependencies []android.ApexModule
mctx.VisitDirectDeps(func(m android.Module) {
tag := mctx.OtherModuleDependencyTag(m)
- if tag == exportedJavaLibTag {
+ if exportedTag, ok := tag.(exportedDependencyTag); ok {
+ propertyName := exportedTag.name
depName := mctx.OtherModuleName(m)
// It is an error if the other module is not a prebuilt.
if _, ok := m.(android.PrebuiltInterface); !ok {
- mctx.PropertyErrorf("exported_java_libs", "%q is not a prebuilt module", depName)
+ mctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName)
return
}
// It is an error if the other module is not an ApexModule.
if _, ok := m.(android.ApexModule); !ok {
- mctx.PropertyErrorf("exported_java_libs", "%q is not usable within an apex", depName)
+ mctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName)
return
}
@@ -451,7 +459,8 @@
func (t exportedDependencyTag) ExcludeFromVisibilityEnforcement() {}
var (
- exportedJavaLibTag = exportedDependencyTag{name: "exported_java_lib"}
+ exportedJavaLibTag = exportedDependencyTag{name: "exported_java_libs"}
+ exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
)
func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 8049108..c30abeb 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -14,6 +14,8 @@
OutputFiles []string
CcObjectFiles []string
CcStaticLibraryFiles []string
+ Includes []string
+ SystemIncludes []string
}
type getOutputFilesRequestType struct{}
@@ -63,6 +65,9 @@
return `
outputFiles = [f.path for f in target.files.to_list()]
+includes = providers(target)["CcInfo"].compilation_context.includes.to_list()
+system_includes = providers(target)["CcInfo"].compilation_context.system_includes.to_list()
+
ccObjectFiles = []
staticLibraries = []
linker_inputs = providers(target)["CcInfo"].linking_context.linker_inputs.to_list()
@@ -78,6 +83,8 @@
outputFiles,
staticLibraries,
ccObjectFiles,
+ includes,
+ system_includes,
]
return "|".join([", ".join(r) for r in returns])`
@@ -91,7 +98,7 @@
var ccObjects []string
splitString := strings.Split(rawString, "|")
- if expectedLen := 3; len(splitString) != expectedLen {
+ if expectedLen := 5; len(splitString) != expectedLen {
return CcInfo{}, fmt.Errorf("Expected %d items, got %q", expectedLen, splitString)
}
outputFilesString := splitString[0]
@@ -100,10 +107,14 @@
outputFiles = splitOrEmpty(outputFilesString, ", ")
ccStaticLibraries := splitOrEmpty(ccStaticLibrariesString, ", ")
ccObjects = splitOrEmpty(ccObjectsString, ", ")
+ includes := splitOrEmpty(splitString[3], ", ")
+ systemIncludes := splitOrEmpty(splitString[4], ", ")
return CcInfo{
OutputFiles: outputFiles,
CcObjectFiles: ccObjects,
CcStaticLibraryFiles: ccStaticLibraries,
+ Includes: includes,
+ SystemIncludes: systemIncludes,
}, nil
}
diff --git a/bazel/cquery/request_type_test.go b/bazel/cquery/request_type_test.go
index 48edb90..6369999 100644
--- a/bazel/cquery/request_type_test.go
+++ b/bazel/cquery/request_type_test.go
@@ -3,6 +3,7 @@
import (
"fmt"
"reflect"
+ "strings"
"testing"
)
@@ -45,42 +46,48 @@
}{
{
description: "no result",
- input: "||",
+ input: "||||",
expectedOutput: CcInfo{
OutputFiles: []string{},
CcObjectFiles: []string{},
CcStaticLibraryFiles: []string{},
+ Includes: []string{},
+ SystemIncludes: []string{},
},
},
{
description: "only output",
- input: "test||",
+ input: "test||||",
expectedOutput: CcInfo{
OutputFiles: []string{"test"},
CcObjectFiles: []string{},
CcStaticLibraryFiles: []string{},
+ Includes: []string{},
+ SystemIncludes: []string{},
},
},
{
description: "all items set",
- input: "out1, out2|static_lib1, static_lib2|object1, object2",
+ input: "out1, out2|static_lib1, static_lib2|object1, object2|., dir/subdir|system/dir, system/other/dir",
expectedOutput: CcInfo{
OutputFiles: []string{"out1", "out2"},
CcObjectFiles: []string{"object1", "object2"},
CcStaticLibraryFiles: []string{"static_lib1", "static_lib2"},
+ Includes: []string{".", "dir/subdir"},
+ SystemIncludes: []string{"system/dir", "system/other/dir"},
},
},
{
description: "too few result splits",
input: "|",
expectedOutput: CcInfo{},
- expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 3, []string{"", ""}),
+ expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 5, []string{"", ""}),
},
{
description: "too many result splits",
- input: "|||",
+ input: strings.Repeat("|", 8),
expectedOutput: CcInfo{},
- expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 3, []string{"", "", "", ""}),
+ expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 5, make([]string, 9)),
},
}
for _, tc := range testCases {
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 1ede442..21d7062 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -204,8 +204,9 @@
func TestGenerateBazelTargetModules(t *testing.T) {
testCases := []struct {
- bp string
- expectedBazelTarget string
+ name string
+ bp string
+ expectedBazelTargets []string
}{
{
bp: `custom {
@@ -214,7 +215,7 @@
string_prop: "a",
bazel_module: { bp2build_available: true },
}`,
- expectedBazelTarget: `custom(
+ expectedBazelTargets: []string{`custom(
name = "foo",
string_list_prop = [
"a",
@@ -222,6 +223,7 @@
],
string_prop = "a",
)`,
+ },
},
{
bp: `custom {
@@ -230,7 +232,7 @@
string_prop: "a\t\n\r",
bazel_module: { bp2build_available: true },
}`,
- expectedBazelTarget: `custom(
+ expectedBazelTargets: []string{`custom(
name = "control_characters",
string_list_prop = [
"\t",
@@ -238,6 +240,77 @@
],
string_prop = "a\t\n\r",
)`,
+ },
+ },
+ {
+ bp: `custom {
+ name: "has_dep",
+ arch_paths: [":dep"],
+ bazel_module: { bp2build_available: true },
+}
+
+custom {
+ name: "dep",
+ arch_paths: ["abc"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{`custom(
+ name = "dep",
+ arch_paths = ["abc"],
+)`,
+ `custom(
+ name = "has_dep",
+ arch_paths = [":dep"],
+)`,
+ },
+ },
+ {
+ bp: `custom {
+ name: "arch_paths",
+ arch: {
+ x86: {
+ arch_paths: ["abc"],
+ },
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{`custom(
+ name = "arch_paths",
+ arch_paths = select({
+ "//build/bazel/platforms/arch:x86": ["abc"],
+ "//conditions:default": [],
+ }),
+)`,
+ },
+ },
+ {
+ bp: `custom {
+ name: "has_dep",
+ arch: {
+ x86: {
+ arch_paths: [":dep"],
+ },
+ },
+ bazel_module: { bp2build_available: true },
+}
+
+custom {
+ name: "dep",
+ arch_paths: ["abc"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{`custom(
+ name = "dep",
+ arch_paths = ["abc"],
+)`,
+ `custom(
+ name = "has_dep",
+ arch_paths = select({
+ "//build/bazel/platforms/arch:x86": [":dep"],
+ "//conditions:default": [],
+ }),
+)`,
+ },
},
}
@@ -262,16 +335,18 @@
codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
- if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
+ if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount)
} else {
- actualBazelTarget := bazelTargets[0]
- if actualBazelTarget.content != testCase.expectedBazelTarget {
- t.Errorf(
- "Expected generated Bazel target to be '%s', got '%s'",
- testCase.expectedBazelTarget,
- actualBazelTarget.content,
- )
+ for i, expectedBazelTarget := range testCase.expectedBazelTargets {
+ actualBazelTarget := bazelTargets[i]
+ if actualBazelTarget.content != expectedBazelTarget {
+ t.Errorf(
+ "Expected generated Bazel target to be '%s', got '%s'",
+ expectedBazelTarget,
+ actualBazelTarget.content,
+ )
+ }
}
}
}
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 30c1a5b..32b12e4 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -86,6 +86,7 @@
"soong_module_name": attr.string(mandatory = True),
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
+ "arch_paths": attr.string_list(),
# bazel_module start
# "label": attr.string(),
# "bp2build_available": attr.bool(),
@@ -114,6 +115,7 @@
"soong_module_name": attr.string(mandatory = True),
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
+ "arch_paths": attr.string_list(),
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"int64_ptr_prop": attr.int(),
@@ -138,6 +140,7 @@
"soong_module_name": attr.string(mandatory = True),
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
+ "arch_paths": attr.string_list(),
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"int64_ptr_prop": attr.int(),
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 114b668..d67ab3d 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -49,7 +49,7 @@
func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
files := make([]BazelFile, 0, len(buildToTargets))
for _, dir := range android.SortedStringKeys(buildToTargets) {
- if !android.ShouldWriteBuildFileForDir(dir) {
+ if mode == Bp2Build && !android.ShouldWriteBuildFileForDir(dir) {
fmt.Printf("[bp2build] Not writing generated BUILD file for dir: '%s'\n", dir)
continue
}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index c4661ea..452f6ed 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -28,6 +28,8 @@
Nested_props nestedProps
Nested_props_ptr *nestedProps
+
+ Arch_paths []string `android:"path,arch_variant"`
}
type customModule struct {
@@ -56,7 +58,7 @@
func customModuleFactory() android.Module {
m := customModuleFactoryBase()
- android.InitAndroidModule(m)
+ android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth)
return m
}
@@ -114,6 +116,7 @@
type customBazelModuleAttributes struct {
String_prop string
String_list_prop []string
+ Arch_paths bazel.LabelListAttribute
}
type customBazelModule struct {
@@ -137,9 +140,18 @@
return
}
+ paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.props.Arch_paths))
+
+ for arch, props := range m.GetArchProperties(&customProps{}) {
+ if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
+ paths.SetValueForArch(arch.Name, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths))
+ }
+ }
+
attrs := &customBazelModuleAttributes{
String_prop: m.props.String_prop,
String_list_prop: m.props.String_list_prop,
+ Arch_paths: paths,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 536efa4..8f3a652 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -191,17 +191,31 @@
}
func (library *libraryDecorator) androidMkWriteExportedFlags(entries *android.AndroidMkEntries) {
- exportedFlags := library.flagExporter.flags
- for _, dir := range library.flagExporter.dirs {
+ var exportedFlags []string
+ var includeDirs android.Paths
+ var systemIncludeDirs android.Paths
+ var exportedDeps android.Paths
+
+ if library.flagExporterInfo != nil {
+ exportedFlags = library.flagExporterInfo.Flags
+ includeDirs = library.flagExporterInfo.IncludeDirs
+ systemIncludeDirs = library.flagExporterInfo.SystemIncludeDirs
+ exportedDeps = library.flagExporterInfo.Deps
+ } else {
+ exportedFlags = library.flagExporter.flags
+ includeDirs = library.flagExporter.dirs
+ systemIncludeDirs = library.flagExporter.systemDirs
+ exportedDeps = library.flagExporter.deps
+ }
+ for _, dir := range includeDirs {
exportedFlags = append(exportedFlags, "-I"+dir.String())
}
- for _, dir := range library.flagExporter.systemDirs {
+ for _, dir := range systemIncludeDirs {
exportedFlags = append(exportedFlags, "-isystem "+dir.String())
}
if len(exportedFlags) > 0 {
entries.AddStrings("LOCAL_EXPORT_CFLAGS", exportedFlags...)
}
- exportedDeps := library.flagExporter.deps
if len(exportedDeps) > 0 {
entries.AddStrings("LOCAL_EXPORT_C_INCLUDE_DEPS", exportedDeps.Strings()...)
}
diff --git a/cc/cc.go b/cc/cc.go
index 9eebbae..98df545 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1145,12 +1145,7 @@
func (c *Module) isImplementationForLLNDKPublic() bool {
library, _ := c.library.(*libraryDecorator)
return library != nil && library.hasLLNDKStubs() &&
- (!Bool(library.Properties.Llndk.Private) ||
- // TODO(b/170784825): until the LLNDK properties are moved into the cc_library,
- // the non-Vendor variants of the cc_library don't know if the corresponding
- // llndk_library set private: true. Since libft2 is the only private LLNDK
- // library, hardcode it during the transition.
- c.BaseModuleName() != "libft2")
+ !Bool(library.Properties.Llndk.Private)
}
// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
diff --git a/cc/cc_test.go b/cc/cc_test.go
index db696ef..c56643b 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2824,6 +2824,100 @@
checkEquals(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
}
+func TestEmbeddedLlndkLibrary(t *testing.T) {
+ result := prepareForCcTest.RunTestWithBp(t, `
+ cc_library {
+ name: "libllndk",
+ stubs: { versions: ["1", "2"] },
+ llndk: {
+ symbol_file: "libllndk.map.txt",
+ },
+ export_include_dirs: ["include"],
+ }
+
+ cc_prebuilt_library_shared {
+ name: "libllndkprebuilt",
+ stubs: { versions: ["1", "2"] },
+ llndk: {
+ symbol_file: "libllndkprebuilt.map.txt",
+ },
+ }
+
+ cc_library {
+ name: "libllndk_with_external_headers",
+ stubs: { versions: ["1", "2"] },
+ llndk: {
+ symbol_file: "libllndk.map.txt",
+ export_llndk_headers: ["libexternal_llndk_headers"],
+ },
+ header_libs: ["libexternal_headers"],
+ export_header_lib_headers: ["libexternal_headers"],
+ }
+ cc_library_headers {
+ name: "libexternal_headers",
+ export_include_dirs: ["include"],
+ vendor_available: true,
+ }
+ cc_library_headers {
+ name: "libexternal_llndk_headers",
+ export_include_dirs: ["include_llndk"],
+ llndk: {
+ symbol_file: "libllndk.map.txt",
+ },
+ vendor_available: true,
+ }
+
+ cc_library {
+ name: "libllndk_with_override_headers",
+ stubs: { versions: ["1", "2"] },
+ llndk: {
+ symbol_file: "libllndk.map.txt",
+ override_export_include_dirs: ["include_llndk"],
+ },
+ export_include_dirs: ["include"],
+ }
+ `)
+ actual := result.ModuleVariantsForTests("libllndk")
+ for i := 0; i < len(actual); i++ {
+ if !strings.HasPrefix(actual[i], "android_vendor.29_") {
+ actual = append(actual[:i], actual[i+1:]...)
+ i--
+ }
+ }
+ expected := []string{
+ "android_vendor.29_arm64_armv8-a_shared_1",
+ "android_vendor.29_arm64_armv8-a_shared_2",
+ "android_vendor.29_arm64_armv8-a_shared_current",
+ "android_vendor.29_arm64_armv8-a_shared",
+ "android_vendor.29_arm_armv7-a-neon_shared_1",
+ "android_vendor.29_arm_armv7-a-neon_shared_2",
+ "android_vendor.29_arm_armv7-a-neon_shared_current",
+ "android_vendor.29_arm_armv7-a-neon_shared",
+ }
+ android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
+
+ params := result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared").Description("generate stub")
+ android.AssertSame(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
+
+ params = result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared_1").Description("generate stub")
+ android.AssertSame(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
+
+ checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
+ t.Helper()
+ m := result.ModuleForTests(module, variant).Module()
+ f := result.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
+ android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
+ expectedDirs, f.IncludeDirs)
+ }
+
+ checkExportedIncludeDirs("libllndk", "android_arm64_armv8-a_shared", "include")
+ checkExportedIncludeDirs("libllndk", "android_vendor.29_arm64_armv8-a_shared", "include")
+ checkExportedIncludeDirs("libllndk_with_external_headers", "android_arm64_armv8-a_shared", "include")
+ checkExportedIncludeDirs("libllndk_with_external_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
+ checkExportedIncludeDirs("libllndk_with_override_headers", "android_arm64_armv8-a_shared", "include")
+ checkExportedIncludeDirs("libllndk_with_override_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
+}
+
func TestLlndkHeaders(t *testing.T) {
ctx := testCc(t, `
llndk_headers {
diff --git a/cc/genrule.go b/cc/genrule.go
index 82d7205..ca4fda7 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -75,10 +75,6 @@
return Bool(g.Vendor_ramdisk_available)
}
-func (g *GenruleExtraProperties) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
func (g *GenruleExtraProperties) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
// If the build is using a snapshot, the recovery variant under AOSP directories
// is not needed.
diff --git a/cc/image.go b/cc/image.go
index bf662c6..c1e5dfe 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -601,10 +601,6 @@
return c.Properties.VendorRamdiskVariantNeeded
}
-func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
return c.Properties.RecoveryVariantNeeded
}
diff --git a/cc/library.go b/cc/library.go
index 9a2b02e..af92b24 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -403,8 +403,8 @@
func (f *flagExporter) setProvider(ctx android.ModuleContext) {
ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
- IncludeDirs: f.dirs,
- SystemIncludeDirs: f.systemDirs,
+ IncludeDirs: android.FirstUniquePaths(f.dirs),
+ SystemIncludeDirs: android.FirstUniquePaths(f.systemDirs),
Flags: f.flags,
Deps: f.deps,
GeneratedHeaders: f.headers,
@@ -426,7 +426,8 @@
tocFile android.OptionalPath
flagExporter
- stripper Stripper
+ flagExporterInfo *FlagExporterInfo
+ stripper Stripper
// For whole_static_libs
objects Objects
@@ -959,9 +960,8 @@
if ctx.IsLlndk() {
// LLNDK libraries ignore most of the properties on the cc_library and use the
// LLNDK-specific properties instead.
- deps.HeaderLibs = append(deps.HeaderLibs, library.Properties.Llndk.Export_llndk_headers...)
- deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders,
- library.Properties.Llndk.Export_llndk_headers...)
+ deps.HeaderLibs = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...)
+ deps.ReexportHeaderLibHeaders = append([]string(nil), library.Properties.Llndk.Export_llndk_headers...)
return deps
}
@@ -1406,6 +1406,12 @@
library.reexportDeps(timestampFiles...)
}
+ // override the module's export_include_dirs with llndk.override_export_include_dirs
+ // if it is set.
+ if override := library.Properties.Llndk.Override_export_include_dirs; override != nil {
+ library.flagExporter.Properties.Export_include_dirs = override
+ }
+
if Bool(library.Properties.Llndk.Export_headers_as_system) {
library.flagExporter.Properties.Export_system_include_dirs = append(
library.flagExporter.Properties.Export_system_include_dirs,
@@ -1667,6 +1673,13 @@
// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
func (library *libraryDecorator) hasLLNDKStubs() bool {
+ return library.hasVestigialLLNDKLibrary() || String(library.Properties.Llndk.Symbol_file) != ""
+}
+
+// hasVestigialLLNDKLibrary returns true if this cc_library module has a corresponding llndk_library
+// module containing properties describing the LLNDK variant.
+// TODO(b/170784825): remove this once there are no more llndk_library modules.
+func (library *libraryDecorator) hasVestigialLLNDKLibrary() bool {
return String(library.Properties.Llndk_stubs) != ""
}
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 078242f..f2cb52b 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -43,6 +43,52 @@
ctx.RegisterModuleType("cc_prebuilt_library_headers", prebuiltLibraryHeaderFactory)
}
+type libraryHeaderBazelHander struct {
+ bazelHandler
+
+ module *Module
+ library *libraryDecorator
+}
+
+func (h *libraryHeaderBazelHander) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
+ bazelCtx := ctx.Config().BazelContext
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ if err != nil {
+ ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
+ return false
+ }
+ if !ok {
+ return false
+ }
+
+ outputPaths := ccInfo.OutputFiles
+ if len(outputPaths) != 1 {
+ ctx.ModuleErrorf("expected exactly one output file for %q, but got %q", label, outputPaths)
+ return false
+ }
+
+ outputPath := android.PathForBazelOut(ctx, outputPaths[0])
+ h.module.outputFile = android.OptionalPathForPath(outputPath)
+
+ // HeaderLibraryInfo is an empty struct to indicate to dependencies that this is a header library
+ ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{})
+
+ flagExporterInfo := flagExporterInfoFromCcInfo(ctx, ccInfo)
+ // Store flag info to be passed along to androimk
+ // TODO(b/184387147): Androidmk should be done in Bazel, not Soong.
+ h.library.flagExporterInfo = &flagExporterInfo
+ // flag exporters consolidates properties like includes, flags, dependencies that should be
+ // exported from this module to other modules
+ ctx.SetProvider(FlagExporterInfoProvider, flagExporterInfo)
+
+ // Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise
+ // validation will fail. For now, set this to an empty list.
+ // TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation.
+ h.library.collectedSnapshotHeaders = android.Paths{}
+
+ return true
+}
+
// cc_library_headers contains a set of c/c++ headers which are imported by
// other soong cc modules using the header_libs property. For best practices,
// use export_include_dirs property or LOCAL_EXPORT_C_INCLUDE_DIRS for
@@ -51,6 +97,7 @@
module, library := NewLibrary(android.HostAndDeviceSupported)
library.HeaderOnly()
module.sdkMemberTypes = []android.SdkMemberType{headersLibrarySdkMemberType}
+ module.bazelHandler = &libraryHeaderBazelHander{module: module, library: library}
return module.Init()
}
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index d5f2adf..9010a1a 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -162,9 +162,16 @@
return &nativeLibInfoProperties{memberType: mt}
}
+func isBazelOutDirectory(p android.Path) bool {
+ _, bazel := p.(android.BazelOutPath)
+ return bazel
+}
+
func isGeneratedHeaderDirectory(p android.Path) bool {
_, gen := p.(android.WritablePath)
- return gen
+ // TODO(b/183213331): Here we assume that bazel-based headers are not generated; we need
+ // to support generated headers in mixed builds.
+ return gen && !isBazelOutDirectory(p)
}
type includeDirsProperty struct {
diff --git a/cc/linkable.go b/cc/linkable.go
index 0fb9c09..2fa12f6 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -2,6 +2,7 @@
import (
"android/soong/android"
+ "android/soong/bazel/cquery"
"github.com/google/blueprint"
)
@@ -274,3 +275,15 @@
}
var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{})
+
+// flagExporterInfoFromCcInfo populates FlagExporterInfo provider with information from Bazel.
+func flagExporterInfoFromCcInfo(ctx android.ModuleContext, ccInfo cquery.CcInfo) FlagExporterInfo {
+
+ includes := android.PathsForBazelOut(ctx, ccInfo.Includes)
+ systemIncludes := android.PathsForBazelOut(ctx, ccInfo.SystemIncludes)
+
+ return FlagExporterInfo{
+ IncludeDirs: includes,
+ SystemIncludeDirs: systemIncludes,
+ }
+}
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index a46b31c..d05dbce 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -56,7 +56,12 @@
Unversioned *bool
// list of llndk headers to re-export include directories from.
- Export_llndk_headers []string `android:"arch_variant"`
+ Export_llndk_headers []string
+
+ // list of directories relative to the Blueprints file that willbe added to the include path
+ // (using -I) for any module that links against the LLNDK variant of this module, replacing
+ // any that were listed outside the llndk clause.
+ Override_export_include_dirs []string
// whether this module can be directly depended upon by libs that are installed
// to /vendor and /product.
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index 885a0ce..c12ad79 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -308,10 +308,6 @@
return false
}
-func (s *snapshot) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
func (s *snapshot) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
diff --git a/cc/vndk.go b/cc/vndk.go
index 41f9fd3..e224e66 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -233,7 +233,7 @@
type moduleListerFunc func(ctx android.SingletonContext) (moduleNames, fileNames []string)
var (
- llndkLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsLLNDK && !isVestigialLLNDKModule(m) })
+ llndkLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsLLNDK && !isVestigialLLNDKModule(m) && !m.Header() })
llndkLibrariesWithoutHWASAN = vndkModuleListRemover(llndkLibraries, "libclang_rt.hwasan-")
vndkSPLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKSP })
vndkCoreLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKCore })
@@ -423,15 +423,24 @@
lib, isLib := m.linker.(*libraryDecorator)
prebuiltLib, isPrebuiltLib := m.linker.(*prebuiltLibraryLinker)
- if m.UseVndk() && isLib && lib.hasLLNDKStubs() {
+ if m.UseVndk() && isLib && lib.hasVestigialLLNDKLibrary() {
llndk := mctx.AddVariationDependencies(nil, llndkStubDepTag, String(lib.Properties.Llndk_stubs))
mergeLLNDKToLib(llndk[0].(*Module), &lib.Properties.Llndk, &lib.flagExporter)
}
- if m.UseVndk() && isPrebuiltLib && prebuiltLib.hasLLNDKStubs() {
+ if m.UseVndk() && isPrebuiltLib && prebuiltLib.hasVestigialLLNDKLibrary() {
llndk := mctx.AddVariationDependencies(nil, llndkStubDepTag, String(prebuiltLib.Properties.Llndk_stubs))
mergeLLNDKToLib(llndk[0].(*Module), &prebuiltLib.Properties.Llndk, &prebuiltLib.flagExporter)
}
+ if m.UseVndk() && isLib && lib.hasLLNDKStubs() && !lib.hasVestigialLLNDKLibrary() {
+ m.VendorProperties.IsLLNDK = true
+ m.VendorProperties.IsVNDKPrivate = Bool(lib.Properties.Llndk.Private)
+ }
+ if m.UseVndk() && isPrebuiltLib && prebuiltLib.hasLLNDKStubs() && !prebuiltLib.hasVestigialLLNDKLibrary() {
+ m.VendorProperties.IsLLNDK = true
+ m.VendorProperties.IsVNDKPrivate = Bool(prebuiltLib.Properties.Llndk.Private)
+ }
+
if (isLib && lib.buildShared()) || (isPrebuiltLib && prebuiltLib.buildShared()) {
if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
processVndkLibrary(mctx, m)
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index ad52b00..f76a205 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -544,13 +544,13 @@
// Recursive helper for toJsonClassLoaderContext.
func toJsonClassLoaderContextRec(clcs []*ClassLoaderContext) []*jsonClassLoaderContext {
jClcs := make([]*jsonClassLoaderContext, len(clcs))
- for _, clc := range clcs {
- jClcs = append(jClcs, &jsonClassLoaderContext{
+ for i, clc := range clcs {
+ jClcs[i] = &jsonClassLoaderContext{
Name: clc.Name,
Host: clc.Host.String(),
Device: clc.Device,
Subcontexts: toJsonClassLoaderContextRec(clc.Subcontexts),
- })
+ }
}
return jClcs
}
diff --git a/dexpreopt/class_loader_context_test.go b/dexpreopt/class_loader_context_test.go
index 86f7871..610a4c9 100644
--- a/dexpreopt/class_loader_context_test.go
+++ b/dexpreopt/class_loader_context_test.go
@@ -155,6 +155,29 @@
})
}
+func TestCLCJson(t *testing.T) {
+ ctx := testContext()
+ m := make(ClassLoaderContextMap)
+ m.AddContext(ctx, 28, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m.AddContext(ctx, 29, "b", buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+ m.AddContext(ctx, 30, "c", buildPath(ctx, "c"), installPath(ctx, "c"), nil)
+ m.AddContext(ctx, AnySdkVersion, "d", buildPath(ctx, "d"), installPath(ctx, "d"), nil)
+ jsonCLC := toJsonClassLoaderContext(m)
+ restored := fromJsonClassLoaderContext(ctx, jsonCLC)
+ android.AssertIntEquals(t, "The size of the maps should be the same.", len(m), len(restored))
+ for k := range m {
+ a, _ := m[k]
+ b, ok := restored[k]
+ android.AssertBoolEquals(t, "The both maps should have the same keys.", ok, true)
+ android.AssertIntEquals(t, "The size of the elements should be the same.", len(a), len(b))
+ for i, elemA := range a {
+ before := fmt.Sprintf("%v", *elemA)
+ after := fmt.Sprintf("%v", *b[i])
+ android.AssertStringEquals(t, "The content should be the same.", before, after)
+ }
+ }
+}
+
// Test that unknown library paths cause a validation error.
func testCLCUnknownPath(t *testing.T, whichPath string) {
ctx := testContext()
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 26ff5ba..151f032 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -130,7 +130,7 @@
ClassLoaderContexts ClassLoaderContextMap
Archs []android.ArchType
- DexPreoptImages []android.Path
+ DexPreoptImages android.Paths
DexPreoptImagesDeps []android.OutputPaths
DexPreoptImageLocations []string
@@ -259,29 +259,35 @@
config.Once(testGlobalConfigOnceKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} })
}
+// This struct is required to convert ModuleConfig from/to JSON.
+// The types of fields in ModuleConfig are not convertible,
+// so moduleJSONConfig has those fields as a convertible type.
+type moduleJSONConfig struct {
+ *ModuleConfig
+
+ BuildPath string
+ DexPath string
+ ManifestPath string
+
+ ProfileClassListing string
+ ProfileBootListing string
+
+ EnforceUsesLibrariesStatusFile string
+ ClassLoaderContexts jsonClassLoaderContextMap
+
+ DexPreoptImages []string
+ DexPreoptImagesDeps [][]string
+
+ PreoptBootClassPathDexFiles []string
+}
+
// ParseModuleConfig parses a per-module dexpreopt.config file into a
// ModuleConfig struct. It is not used in Soong, which receives a ModuleConfig
// struct directly from java/dexpreopt.go. It is used in dexpreopt_gen called
// from Make to read the module dexpreopt.config written in the Make config
// stage.
func ParseModuleConfig(ctx android.PathContext, data []byte) (*ModuleConfig, error) {
- type ModuleJSONConfig struct {
- *ModuleConfig
-
- // Copies of entries in ModuleConfig that are not constructable without extra parameters. They will be
- // used to construct the real value manually below.
- BuildPath string
- DexPath string
- ManifestPath string
- ProfileClassListing string
- EnforceUsesLibrariesStatusFile string
- ClassLoaderContexts jsonClassLoaderContextMap
- DexPreoptImages []string
- DexPreoptImageLocations []string
- PreoptBootClassPathDexFiles []string
- }
-
- config := ModuleJSONConfig{}
+ config := moduleJSONConfig{}
err := json.Unmarshal(data, &config)
if err != nil {
@@ -296,7 +302,6 @@
config.ModuleConfig.EnforceUsesLibrariesStatusFile = constructPath(ctx, config.EnforceUsesLibrariesStatusFile)
config.ModuleConfig.ClassLoaderContexts = fromJsonClassLoaderContext(ctx, config.ClassLoaderContexts)
config.ModuleConfig.DexPreoptImages = constructPaths(ctx, config.DexPreoptImages)
- config.ModuleConfig.DexPreoptImageLocations = config.DexPreoptImageLocations
config.ModuleConfig.PreoptBootClassPathDexFiles = constructPaths(ctx, config.PreoptBootClassPathDexFiles)
// This needs to exist, but dependencies are already handled in Make, so we don't need to pass them through JSON.
@@ -305,34 +310,38 @@
return config.ModuleConfig, nil
}
-// WriteSlimModuleConfigForMake serializes a subset of ModuleConfig into a per-module
-// dexpreopt.config JSON file. It is a way to pass dexpreopt information about Soong modules to
-// Make, which is needed when a Make module has a <uses-library> dependency on a Soong module.
-func WriteSlimModuleConfigForMake(ctx android.ModuleContext, config *ModuleConfig, path android.WritablePath) {
+func pathsListToStringLists(pathsList []android.OutputPaths) [][]string {
+ ret := make([][]string, 0, len(pathsList))
+ for _, paths := range pathsList {
+ ret = append(ret, paths.Strings())
+ }
+ return ret
+}
+
+func moduleConfigToJSON(config *ModuleConfig) ([]byte, error) {
+ return json.MarshalIndent(&moduleJSONConfig{
+ BuildPath: config.BuildPath.String(),
+ DexPath: config.DexPath.String(),
+ ManifestPath: config.ManifestPath.String(),
+ ProfileClassListing: config.ProfileClassListing.String(),
+ ProfileBootListing: config.ProfileBootListing.String(),
+ EnforceUsesLibrariesStatusFile: config.EnforceUsesLibrariesStatusFile.String(),
+ ClassLoaderContexts: toJsonClassLoaderContext(config.ClassLoaderContexts),
+ DexPreoptImages: config.DexPreoptImages.Strings(),
+ DexPreoptImagesDeps: pathsListToStringLists(config.DexPreoptImagesDeps),
+ PreoptBootClassPathDexFiles: config.PreoptBootClassPathDexFiles.Strings(),
+ ModuleConfig: config,
+ }, "", " ")
+}
+
+// WriteModuleConfig serializes a ModuleConfig into a per-module dexpreopt.config JSON file.
+// These config files are used for post-processing.
+func WriteModuleConfig(ctx android.ModuleContext, config *ModuleConfig, path android.WritablePath) {
if path == nil {
return
}
- // JSON representation of the slim module dexpreopt.config.
- type slimModuleJSONConfig struct {
- Name string
- DexLocation string
- BuildPath string
- EnforceUsesLibraries bool
- ProvidesUsesLibrary string
- ClassLoaderContexts jsonClassLoaderContextMap
- }
-
- jsonConfig := &slimModuleJSONConfig{
- Name: config.Name,
- DexLocation: config.DexLocation,
- BuildPath: config.BuildPath.String(),
- EnforceUsesLibraries: config.EnforceUsesLibraries,
- ProvidesUsesLibrary: config.ProvidesUsesLibrary,
- ClassLoaderContexts: toJsonClassLoaderContext(config.ClassLoaderContexts),
- }
-
- data, err := json.MarshalIndent(jsonConfig, "", " ")
+ data, err := moduleConfigToJSON(config)
if err != nil {
ctx.ModuleErrorf("failed to JSON marshal module dexpreopt.config: %v", err)
return
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 12df36b..cd7551c 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -166,3 +166,20 @@
t.Errorf("\nwant installs:\n %v\ngot:\n %v", wantInstalls, rule.Installs())
}
}
+
+func TestDexPreoptConfigToJson(t *testing.T) {
+ config := android.TestConfig("out", nil, "", nil)
+ ctx := android.BuilderContextForTesting(config)
+ module := testSystemModuleConfig(ctx, "test")
+ data, err := moduleConfigToJSON(module)
+ if err != nil {
+ t.Errorf("Failed to convert module config data to JSON, %v", err)
+ }
+ parsed, err := ParseModuleConfig(ctx, data)
+ if err != nil {
+ t.Errorf("Failed to parse JSON, %v", err)
+ }
+ before := fmt.Sprintf("%v", module)
+ after := fmt.Sprintf("%v", parsed)
+ android.AssertStringEquals(t, "The result must be the same as the original after marshalling and unmarshalling it.", before, after)
+}
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 3204e70..6e502b7 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -84,13 +84,6 @@
// the recovery variant instead.
Vendor_ramdisk_available *bool
- // Make this module available when building for debug 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.
- Debug_ramdisk_available *bool
-
// Make this module available when building for recovery.
Recovery_available *bool
@@ -166,18 +159,6 @@
return p.inVendorRamdisk()
}
-func (p *PrebuiltEtc) inDebugRamdisk() bool {
- return p.ModuleBase.InDebugRamdisk() || p.ModuleBase.InstallInDebugRamdisk()
-}
-
-func (p *PrebuiltEtc) onlyInDebugRamdisk() bool {
- return p.ModuleBase.InstallInDebugRamdisk()
-}
-
-func (p *PrebuiltEtc) InstallInDebugRamdisk() bool {
- return p.inDebugRamdisk()
-}
-
func (p *PrebuiltEtc) inRecovery() bool {
return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery()
}
@@ -196,7 +177,7 @@
func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
return !p.ModuleBase.InstallInRecovery() && !p.ModuleBase.InstallInRamdisk() &&
- !p.ModuleBase.InstallInVendorRamdisk() && !p.ModuleBase.InstallInDebugRamdisk()
+ !p.ModuleBase.InstallInVendorRamdisk()
}
func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
@@ -207,10 +188,6 @@
return proptools.Bool(p.properties.Vendor_ramdisk_available) || p.ModuleBase.InstallInVendorRamdisk()
}
-func (p *PrebuiltEtc) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return proptools.Bool(p.properties.Debug_ramdisk_available) || p.ModuleBase.InstallInDebugRamdisk()
-}
-
func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery()
}
@@ -336,9 +313,6 @@
if p.inVendorRamdisk() && !p.onlyInVendorRamdisk() {
nameSuffix = ".vendor_ramdisk"
}
- if p.inDebugRamdisk() && !p.onlyInDebugRamdisk() {
- nameSuffix = ".debug_ramdisk"
- }
if p.inRecovery() && !p.onlyInRecovery() {
nameSuffix = ".recovery"
}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 77dae75..b426b20 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -626,7 +626,6 @@
func (x noopImageInterface) CoreVariantNeeded(android.BaseModuleContext) bool { return false }
func (x noopImageInterface) RamdiskVariantNeeded(android.BaseModuleContext) bool { return false }
func (x noopImageInterface) VendorRamdiskVariantNeeded(android.BaseModuleContext) bool { return false }
-func (x noopImageInterface) DebugRamdiskVariantNeeded(android.BaseModuleContext) bool { return false }
func (x noopImageInterface) RecoveryVariantNeeded(android.BaseModuleContext) bool { return false }
func (x noopImageInterface) ExtraImageVariations(ctx android.BaseModuleContext) []string { return nil }
func (x noopImageInterface) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
diff --git a/java/Android.bp b/java/Android.bp
index 8e3e10d..e367a00 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -31,6 +31,7 @@
"base.go",
"boot_image.go",
"boot_jars.go",
+ "bootclasspath.go",
"builder.go",
"classpath_fragment.go",
"device_host_converter.go",
diff --git a/java/androidmk.go b/java/androidmk.go
index 4e594a2..0154544 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -398,6 +398,9 @@
if len(app.dexpreopter.builtInstalled) > 0 {
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", app.dexpreopter.builtInstalled)
}
+ if app.dexpreopter.configPath != nil {
+ entries.SetPath("LOCAL_SOONG_DEXPREOPT_CONFIG", app.dexpreopter.configPath)
+ }
for _, extra := range app.extraOutputFiles {
install := app.onDeviceDir + "/" + extra.Base()
entries.AddStrings("LOCAL_SOONG_BUILT_INSTALLED", extra.String()+":"+install)
diff --git a/java/boot_image.go b/java/boot_image.go
index d0862a9..6f50c27 100644
--- a/java/boot_image.go
+++ b/java/boot_image.go
@@ -124,8 +124,22 @@
if m.properties.Image_name != nil && len(contents) != 0 {
ctx.ModuleErrorf(`both of the "image_name" and "contents" properties have been supplied, please supply exactly one`)
}
+
imageName := proptools.String(m.properties.Image_name)
if imageName == "art" {
+ // TODO(b/177892522): Prebuilts (versioned or not) should not use the image_name property.
+ if m.MemberName() != "" {
+ // The module is a versioned prebuilt so ignore it. This is done for a couple of reasons:
+ // 1. There is no way to use this at the moment so ignoring it is safe.
+ // 2. Attempting to initialize the contents property from the configuration will end up having
+ // the versioned prebuilt depending on the unversioned prebuilt. That will cause problems
+ // as the unversioned prebuilt could end up with an APEX variant created for the source
+ // APEX which will prevent it from having an APEX variant for the prebuilt APEX which in
+ // turn will prevent it from accessing the dex implementation jar from that which will
+ // break hidden API processing, amongst others.
+ return
+ }
+
// Get the configuration for the art apex jars. Do not use getImageConfig(ctx) here as this is
// too early in the Soong processing for that to work.
global := dexpreopt.GetGlobalConfig(ctx)
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
new file mode 100644
index 0000000..b140a30
--- /dev/null
+++ b/java/bootclasspath.go
@@ -0,0 +1,145 @@
+// 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 java
+
+import (
+ "fmt"
+
+ "android/soong/android"
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+// Contains code that is common to both platform_bootclasspath and bootclasspath_fragment.
+
+// addDependencyOntoApexVariants adds dependencies onto the appropriate apex specific variants of
+// the module as specified in the ApexVariantReference list.
+func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tag blueprint.DependencyTag) {
+ for i, ref := range refs {
+ apex := proptools.StringDefault(ref.Apex, "platform")
+
+ if ref.Module == nil {
+ ctx.PropertyErrorf(propertyName, "missing module name at position %d", i)
+ continue
+ }
+ name := proptools.String(ref.Module)
+
+ addDependencyOntoApexModulePair(ctx, apex, name, tag)
+ }
+}
+
+// addDependencyOntoApexModulePair adds a dependency onto the specified APEX specific variant or the
+// specified module.
+//
+// If apex="platform" then this adds a dependency onto the platform variant of the module. This adds
+// dependencies onto the prebuilt and source modules with the specified name, depending on which
+// ones are available. Visiting must use isActiveModule to select the preferred module when both
+// source and prebuilt modules are available.
+func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) {
+ var variations []blueprint.Variation
+ if apex != "platform" {
+ // Pick the correct apex variant.
+ variations = []blueprint.Variation{
+ {Mutator: "apex", Variation: apex},
+ }
+ }
+
+ addedDep := false
+ if ctx.OtherModuleDependencyVariantExists(variations, name) {
+ ctx.AddFarVariationDependencies(variations, tag, name)
+ addedDep = true
+ }
+
+ // Add a dependency on the prebuilt module if it exists.
+ prebuiltName := android.PrebuiltNameFromSource(name)
+ if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) {
+ ctx.AddVariationDependencies(variations, tag, prebuiltName)
+ addedDep = true
+ }
+
+ // If no appropriate variant existing for this, so no dependency could be added, then it is an
+ // error, unless missing dependencies are allowed. The simplest way to handle that is to add a
+ // dependency that will not be satisfied and the default behavior will handle it.
+ if !addedDep {
+ // Add dependency on the unprefixed (i.e. source or renamed prebuilt) module which we know does
+ // not exist. The resulting error message will contain useful information about the available
+ // variants.
+ reportMissingVariationDependency(ctx, variations, name)
+
+ // Add dependency on the missing prefixed prebuilt variant too if a module with that name exists
+ // so that information about its available variants will be reported too.
+ if ctx.OtherModuleExists(prebuiltName) {
+ reportMissingVariationDependency(ctx, variations, prebuiltName)
+ }
+ }
+}
+
+// reportMissingVariationDependency intentionally adds a dependency on a missing variation in order
+// to generate an appropriate error message with information about the available variations.
+func reportMissingVariationDependency(ctx android.BottomUpMutatorContext, variations []blueprint.Variation, name string) {
+ modules := ctx.AddFarVariationDependencies(variations, nil, name)
+ if len(modules) != 1 {
+ panic(fmt.Errorf("Internal Error: expected one module, found %d", len(modules)))
+ return
+ }
+ if modules[0] != nil {
+ panic(fmt.Errorf("Internal Error: expected module to be missing but was found: %q", modules[0]))
+ return
+ }
+}
+
+// ApexVariantReference specifies a particular apex variant of a module.
+type ApexVariantReference struct {
+ // The name of the module apex variant, i.e. the apex containing the module variant.
+ //
+ // If this is not specified then it defaults to "platform" which will cause a dependency to be
+ // added to the module's platform variant.
+ Apex *string
+
+ // The name of the module.
+ Module *string
+}
+
+// BootclasspathFragmentsDepsProperties contains properties related to dependencies onto fragments.
+type BootclasspathFragmentsDepsProperties struct {
+ // The names of the bootclasspath_fragment modules that form part of this module.
+ Fragments []ApexVariantReference
+}
+
+// addDependenciesOntoFragments adds dependencies to the fragments specified in this properties
+// structure.
+func (p *BootclasspathFragmentsDepsProperties) addDependenciesOntoFragments(ctx android.BottomUpMutatorContext) {
+ addDependencyOntoApexVariants(ctx, "fragments", p.Fragments, bootclasspathFragmentDepTag)
+}
+
+// bootclasspathDependencyTag defines dependencies from/to bootclasspath_fragment,
+// prebuilt_bootclasspath_fragment and platform_bootclasspath onto either source or prebuilt
+// modules.
+type bootclasspathDependencyTag struct {
+ blueprint.BaseDependencyTag
+
+ name string
+}
+
+func (t bootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() {
+}
+
+// Dependencies that use the bootclasspathDependencyTag instances are only added after all the
+// visibility checking has been done so this has no functional effect. However, it does make it
+// clear that visibility is not being enforced on these tags.
+var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathDependencyTag{}
+
+// The tag used for dependencies onto bootclasspath_fragments.
+var bootclasspathFragmentDepTag = bootclasspathDependencyTag{name: "fragment"}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 3571590..d00d74b 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -41,9 +41,12 @@
builtInstalled string
- // A path to a dexpreopt.config file generated by Soong for libraries that may be used as a
- // <uses-library> by Make modules. The path is passed to Make via LOCAL_SOONG_DEXPREOPT_CONFIG
- // variable. If the path is nil, no config is generated (which is the case for apps and tests).
+ // The config is used for two purposes:
+ // - Passing dexpreopt information about libraries from Soong to Make. This is needed when
+ // a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py).
+ // Note that dexpreopt.config might be needed even if dexpreopt is disabled for the library itself.
+ // - Dexpreopt post-processing (using dexpreopt artifacts from a prebuilt system image to incrementally
+ // dexpreopt another partition).
configPath android.WritablePath
}
@@ -138,27 +141,13 @@
}
}
- if !d.isApp && !d.isTest {
- // Slim dexpreopt config is serialized to dexpreopt.config files and used by
- // dex_preopt_config_merger.py to get information about <uses-library> dependencies.
- // Note that it might be needed even if dexpreopt is disabled for this module.
- slimDexpreoptConfig := &dexpreopt.ModuleConfig{
- Name: ctx.ModuleName(),
- DexLocation: dexLocation,
- EnforceUsesLibraries: d.enforceUsesLibs,
- ProvidesUsesLibrary: providesUsesLib,
- ClassLoaderContexts: d.classLoaderContexts,
- // The rest of the fields are not needed.
- }
- d.configPath = android.PathForModuleOut(ctx, "dexpreopt", "dexpreopt.config")
- dexpreopt.WriteSlimModuleConfigForMake(ctx, slimDexpreoptConfig, d.configPath)
- }
-
- if d.dexpreoptDisabled(ctx) {
+ // If it is neither app nor test, make config files regardless of its dexpreopt setting.
+ // The config files are required for apps defined in make which depend on the lib.
+ // TODO(b/158843648): The config for apps should be generated as well regardless of setting.
+ if (d.isApp || d.isTest) && d.dexpreoptDisabled(ctx) {
return
}
- globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
isSystemServerJar := inList(ctx.ModuleName(), global.SystemServerJars)
@@ -251,6 +240,15 @@
PresignedPrebuilt: d.isPresignedPrebuilt,
}
+ d.configPath = android.PathForModuleOut(ctx, "dexpreopt", "dexpreopt.config")
+ dexpreopt.WriteModuleConfig(ctx, dexpreoptConfig, d.configPath)
+
+ if d.dexpreoptDisabled(ctx) {
+ return
+ }
+
+ globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
+
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, globalSoong, global, dexpreoptConfig)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 656f5ef..0ab6502 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -236,9 +236,5 @@
}
func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
- ctx.Strict("PRODUCT_BOOTCLASSPATH", strings.Join(defaultBootclasspath(ctx), ":"))
- ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).getAnyAndroidVariant().dexLocationsDeps, ":"))
- ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", strings.Join(systemServerClasspath(ctx), ":"))
-
ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules.CopyOfApexJarPairs(), ":"))
}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 568f5e4..38ce985 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -19,8 +19,6 @@
"android/soong/android"
"android/soong/dexpreopt"
- "github.com/google/blueprint"
- "github.com/google/blueprint/proptools"
)
func init() {
@@ -35,27 +33,8 @@
})
}
-type platformBootclasspathDependencyTag struct {
- blueprint.BaseDependencyTag
-
- name string
-}
-
-// Avoid having to make platform bootclasspath content visible to the platform bootclasspath.
-//
-// This is a temporary workaround to make it easier to migrate to platform bootclasspath with proper
-// dependencies.
-// TODO(b/177892522): Remove this and add needed visibility.
-func (t platformBootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() {
-}
-
// The tag used for the dependency between the platform bootclasspath and any configured boot jars.
-var platformBootclasspathModuleDepTag = platformBootclasspathDependencyTag{name: "module"}
-
-// The tag used for the dependency between the platform bootclasspath and bootclasspath_fragments.
-var platformBootclasspathFragmentDepTag = platformBootclasspathDependencyTag{name: "fragment"}
-
-var _ android.ExcludeFromVisibilityEnforcementTag = platformBootclasspathDependencyTag{}
+var platformBootclasspathModuleDepTag = bootclasspathDependencyTag{name: "module"}
type platformBootclasspathModule struct {
android.ModuleBase
@@ -83,22 +62,8 @@
hiddenAPIMetadataCSV android.OutputPath
}
-// ApexVariantReference specifies a particular apex variant of a module.
-type ApexVariantReference struct {
- // The name of the module apex variant, i.e. the apex containing the module variant.
- //
- // If this is not specified then it defaults to "platform" which will cause a dependency to be
- // added to the module's platform variant.
- Apex *string
-
- // The name of the module.
- Module *string
-}
-
type platformBootclasspathProperties struct {
- // The names of the bootclasspath_fragment modules that form part of this
- // platform_bootclasspath.
- Fragments []ApexVariantReference
+ BootclasspathFragmentsDepsProperties
Hidden_api HiddenAPIFlagFileProperties
}
@@ -178,74 +143,7 @@
addDependenciesOntoBootImageModules(ctx, updatableModules)
// Add dependencies on all the fragments.
- addDependencyOntoApexVariants(ctx, "fragments", p.properties.Fragments, platformBootclasspathFragmentDepTag)
- }
-}
-
-func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tag blueprint.DependencyTag) {
- for i, ref := range refs {
- apex := proptools.StringDefault(ref.Apex, "platform")
-
- if ref.Module == nil {
- ctx.PropertyErrorf(propertyName, "missing module name at position %d", i)
- continue
- }
- name := proptools.String(ref.Module)
-
- addDependencyOntoApexModulePair(ctx, apex, name, tag)
- }
-}
-
-func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) {
- var variations []blueprint.Variation
- if apex != "platform" {
- // Pick the correct apex variant.
- variations = []blueprint.Variation{
- {Mutator: "apex", Variation: apex},
- }
- }
-
- addedDep := false
- if ctx.OtherModuleDependencyVariantExists(variations, name) {
- ctx.AddFarVariationDependencies(variations, tag, name)
- addedDep = true
- }
-
- // Add a dependency on the prebuilt module if it exists.
- prebuiltName := android.PrebuiltNameFromSource(name)
- if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) {
- ctx.AddVariationDependencies(variations, tag, prebuiltName)
- addedDep = true
- }
-
- // If no appropriate variant existing for this, so no dependency could be added, then it is an
- // error, unless missing dependencies are allowed. The simplest way to handle that is to add a
- // dependency that will not be satisfied and the default behavior will handle it.
- if !addedDep {
- // Add dependency on the unprefixed (i.e. source or renamed prebuilt) module which we know does
- // not exist. The resulting error message will contain useful information about the available
- // variants.
- reportMissingVariationDependency(ctx, variations, name)
-
- // Add dependency on the missing prefixed prebuilt variant too if a module with that name exists
- // so that information about its available variants will be reported too.
- if ctx.OtherModuleExists(prebuiltName) {
- reportMissingVariationDependency(ctx, variations, prebuiltName)
- }
- }
-}
-
-// reportMissingVariationDependency intentionally adds a dependency on a missing variation in order
-// to generate an appropriate error message with information about the available variations.
-func reportMissingVariationDependency(ctx android.BottomUpMutatorContext, variations []blueprint.Variation, name string) {
- modules := ctx.AddFarVariationDependencies(variations, nil, name)
- if len(modules) != 1 {
- panic(fmt.Errorf("Internal Error: expected one module, found %d", len(modules)))
- return
- }
- if modules[0] != nil {
- panic(fmt.Errorf("Internal Error: expected module to be missing but was found: %q", modules[0]))
- return
+ p.properties.BootclasspathFragmentsDepsProperties.addDependenciesOntoFragments(ctx)
}
}
@@ -265,7 +163,7 @@
tag := ctx.OtherModuleDependencyTag(module)
if tag == platformBootclasspathModuleDepTag {
b.configuredModules = append(b.configuredModules, module)
- } else if tag == platformBootclasspathFragmentDepTag {
+ } else if tag == bootclasspathFragmentDepTag {
b.fragments = append(b.fragments, module)
}
})
diff --git a/rust/image.go b/rust/image.go
index 900842e..7eb49d9 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -97,10 +97,6 @@
return mod.InRamdisk()
}
-func (mod *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
func (mod *Module) RecoveryVariantNeeded(android.BaseModuleContext) bool {
return mod.InRecovery()
}
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 0ce4351..ef4d7cd 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -24,6 +24,7 @@
func TestSnapshotWithBootclasspathFragment_ImageName(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
+ java.PrepareForTestWithJavaDefaultModules,
prepareForSdkTestWithApex,
// Some additional files needed for the art apex.
@@ -32,6 +33,20 @@
"com.android.art.pem": nil,
"system/sepolicy/apex/com.android.art-file_contexts": nil,
}),
+
+ // platform_bootclasspath that depends on the fragment.
+ android.FixtureAddTextFile("frameworks/base/boot/Android.bp", `
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "mybootclasspathfragment",
+ },
+ ],
+ }
+ `),
+
java.FixtureConfigureBootJars("com.android.art:mybootlib"),
android.FixtureWithRootAndroidBp(`
sdk {
@@ -72,6 +87,23 @@
`),
).RunTest(t)
+ // A preparer to add a prebuilt apex to the test fixture.
+ prepareWithPrebuiltApex := android.GroupFixturePreparers(
+ android.FixtureAddTextFile("prebuilts/apex/Android.bp", `
+ prebuilt_apex {
+ name: "com.android.art",
+ src: "art.apex",
+ exported_java_libs: [
+ "mybootlib",
+ ],
+ exported_bootclasspath_fragments: [
+ "mybootclasspathfragment",
+ ],
+ }
+ `),
+ android.FixtureAddFile("prebuilts/apex/art.apex", nil),
+ )
+
CheckSnapshot(t, result, "mysdk", "",
checkUnversionedAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
@@ -121,19 +153,9 @@
checkAllCopyRules(`
.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar
`),
- snapshotTestPreparer(checkSnapshotPreferredWithSource, android.GroupFixturePreparers(
- android.FixtureAddTextFile("prebuilts/apex/Android.bp", `
- prebuilt_apex {
- name: "com.android.art",
- src: "art.apex",
- exported_java_libs: [
- "mybootlib",
- ],
- }
- `),
- android.FixtureAddFile("prebuilts/apex/art.apex", nil),
- ),
- ),
+ snapshotTestPreparer(checkSnapshotWithoutSource, prepareWithPrebuiltApex),
+ snapshotTestPreparer(checkSnapshotWithSourcePreferred, prepareWithPrebuiltApex),
+ snapshotTestPreparer(checkSnapshotPreferredWithSource, prepareWithPrebuiltApex),
)
}
diff --git a/sdk/testing.go b/sdk/testing.go
index bf59aed..f4e85c0 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -254,6 +254,7 @@
snapshotPreparer := android.GroupFixturePreparers(sourcePreparers, fs.AddToFixture())
var runSnapshotTestWithCheckers = func(t *testing.T, testConfig snapshotTest, extraPreparer android.FixturePreparer) {
+ t.Helper()
customization := snapshotBuildInfo.snapshotTestCustomization(testConfig)
customizedPreparers := android.GroupFixturePreparers(customization.preparers...)
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 42d5680..6623381 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -210,10 +210,6 @@
return proptools.Bool(s.properties.Vendor_ramdisk_available) || s.ModuleBase.InstallInVendorRamdisk()
}
-func (s *ShBinary) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
func (s *ShBinary) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
return proptools.Bool(s.properties.Recovery_available) || s.ModuleBase.InstallInRecovery()
}