Merge "Change java_test_host to support cov variant." into main
diff --git a/aconfig/java_aconfig_library.go b/aconfig/java_aconfig_library.go
index 48cfb76..79573c7 100644
--- a/aconfig/java_aconfig_library.go
+++ b/aconfig/java_aconfig_library.go
@@ -58,6 +58,8 @@
// Add aconfig-annotations-lib as a dependency for the optimization / code stripping annotations
module.AddSharedLibrary("aconfig-annotations-lib")
+ // TODO(b/303773055): Remove the annotation after access issue is resolved.
+ module.AddSharedLibrary("unsupportedappusage")
}
func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuildActions(module *java.GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path {
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index bcb98f7..5354611 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -324,31 +324,37 @@
"libnativehelper": Bp2BuildDefaultTrueRecursively,
- "packages/apps/DevCamera": Bp2BuildDefaultTrue,
- "packages/apps/HTMLViewer": Bp2BuildDefaultTrue,
- "packages/apps/Protips": Bp2BuildDefaultTrue,
- "packages/apps/SafetyRegulatoryInfo": Bp2BuildDefaultTrue,
- "packages/apps/WallpaperPicker": Bp2BuildDefaultTrue,
- "packages/modules/NeuralNetworks/driver/cache": Bp2BuildDefaultTrueRecursively,
- "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb": Bp2BuildDefaultTrue,
- "packages/modules/adb/apex": Bp2BuildDefaultTrue,
- "packages/modules/adb/fastdeploy": Bp2BuildDefaultTrue,
- "packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/pairing_auth": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/pairing_connection": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively,
- "packages/modules/Connectivity/staticlibs/native": Bp2BuildDefaultTrueRecursively,
- "packages/modules/Connectivity/staticlibs/netd/libnetdutils": Bp2BuildDefaultTrueRecursively,
- "packages/modules/Gki/libkver": Bp2BuildDefaultTrue,
- "packages/modules/NetworkStack/common/captiveportal": Bp2BuildDefaultTrue,
- "packages/modules/NeuralNetworks/apex": Bp2BuildDefaultTrue,
- "packages/modules/NeuralNetworks/apex/testing": Bp2BuildDefaultTrue,
- "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultFalse, // TODO(b/242834374)
- "packages/screensavers/Basic": Bp2BuildDefaultTrue,
- "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321)
+ "packages/apps/DevCamera": Bp2BuildDefaultTrue,
+ "packages/apps/HTMLViewer": Bp2BuildDefaultTrue,
+ "packages/apps/Protips": Bp2BuildDefaultTrue,
+ "packages/apps/SafetyRegulatoryInfo": Bp2BuildDefaultTrue,
+ "packages/apps/WallpaperPicker": Bp2BuildDefaultTrue,
+ "packages/modules/NeuralNetworks/driver/cache": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb": Bp2BuildDefaultTrue,
+ "packages/modules/adb/apex": Bp2BuildDefaultTrue,
+ "packages/modules/adb/fastdeploy": Bp2BuildDefaultTrue,
+ "packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/pairing_auth": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/pairing_connection": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/Connectivity/bpf_progs": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/Connectivity/service-t": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/Connectivity/service/native": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/Connectivity/staticlibs/native": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/Connectivity/staticlibs/netd": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/Connectivity/tests/unit/jni": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/Gki/libkver": Bp2BuildDefaultTrue,
+ "packages/modules/NetworkStack/common/captiveportal": Bp2BuildDefaultTrue,
+ "packages/modules/NeuralNetworks/apex": Bp2BuildDefaultTrue,
+ "packages/modules/NeuralNetworks/apex/testing": Bp2BuildDefaultTrue,
+ "packages/modules/SdkExtensions/gen_sdk": Bp2BuildDefaultTrue,
+ "packages/modules/common/proto": Bp2BuildDefaultTrue,
+ "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultFalse, // TODO(b/242834374)
+ "packages/screensavers/Basic": Bp2BuildDefaultTrue,
+ "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321)
"platform_testing/libraries/annotations": Bp2BuildDefaultTrueRecursively,
"platform_testing/libraries/flag-helpers/libflagtest": Bp2BuildDefaultTrueRecursively,
@@ -578,6 +584,7 @@
"tagsoup",
// framework-minus-apex
+ "AndroidFrameworkLintChecker",
"ImmutabilityAnnotationProcessor",
"debian.mime.types.minimized",
"framework-javastream-protos",
@@ -634,7 +641,6 @@
"libneuralnetworks",
"libneuralnetworks_static",
"libgraphicsenv",
- "libhardware",
"libhardware_headers",
"libnativeloader-headers",
"libnativewindow_headers",
@@ -673,6 +679,7 @@
// prebuilts
"prebuilt_stats-log-api-gen",
+ "prebuilt_aapt2",
// fastboot
"fastboot",
@@ -854,6 +861,7 @@
"kotlinx_coroutines",
"kotlinx_coroutines-device",
"kotlinx_coroutines-host",
+ "kotlinx_coroutines_android",
// for building com.android.neuralnetworks
"libimapper_stablec",
@@ -994,6 +1002,10 @@
"tradefed-result-interfaces",
"tradefed-device-build-interfaces",
"tradefed-invocation-interfaces",
+ "tradefed-lib-core",
+
+ "libandroid_net_connectivity_com_android_net_module_util_jni",
+ "libservice-connectivity",
}
Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -1047,6 +1059,8 @@
"libfsverity_rs",
"libtombstoned_client_rust",
+ "libhardware", //Depends on unconverted libapexsupport
+
// TODO(b/263326760): Failed already.
"minijail_compiler_unittest",
"minijail_parser_unittest",
@@ -1076,7 +1090,7 @@
"versioner", // TODO(b/228313961): depends on prebuilt shared library libclang-cpp_host as a shared library, which does not supply expected providers for a shared library
// requires host tools for apexer
- "apexer_test", "apexer_test_host_tools", "host_apex_verifier",
+ "apexer_test", "apexer_test_host_tools", "host_apex_verifier", "host-apex-verifier",
// java bugs
"libbase_ndk", // TODO(b/186826477): fails to link libctscamera2_jni for device (required for CtsCameraTestCases)
diff --git a/android/apex.go b/android/apex.go
index d84499b..c6d9940 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -482,7 +482,9 @@
}
return InList(what, apex_available) ||
(what != AvailableToPlatform && InList(AvailableToAnyApex, apex_available)) ||
- (strings.HasPrefix(what, "com.android.gki.") && InList(AvailableToGkiApex, apex_available))
+ (strings.HasPrefix(what, "com.android.gki.") && InList(AvailableToGkiApex, apex_available)) ||
+ (what == "com.google.mainline.primary.libs") || // TODO b/248601389
+ (what == "com.google.mainline.go.primary.libs") // TODO b/248601389
}
// Implements ApexModule
diff --git a/android/bazel.go b/android/bazel.go
index b4e7ae5..202fc48 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -544,7 +544,18 @@
}
moduleName := moduleNameWithPossibleOverride(ctx, module, p.moduleName)
+ // use "prebuilt_" + original module name as the java_import(_host) module name,
+ // to avoid the failure that a normal module and a prebuilt module with
+ // the same name are both allowlisted. This cannot be applied to all the *_import
+ // module types. For example, android_library_import has to use original module
+ // name here otherwise the *-nodeps targets cannot be handled correctly.
+ // TODO(b/304385140): remove this special casing
+ if p.moduleType == "java_import" || p.moduleType == "java_import_host" {
+ moduleName = module.Name()
+ }
+
allowlist := ctx.Config().Bp2buildPackageConfig
+
moduleNameAllowed := allowlist.moduleAlwaysConvert[moduleName]
moduleTypeAllowed := allowlist.moduleTypeAlwaysConvert[p.moduleType]
allowlistConvert := moduleNameAllowed || moduleTypeAllowed
@@ -623,9 +634,6 @@
func registerBp2buildConversionMutator(ctx RegisterMutatorsContext) {
ctx.BottomUp("bp2build_conversion", bp2buildConversionMutator).Parallel()
-}
-
-func registerBp2buildDepsMutator(ctx RegisterMutatorsContext) {
ctx.BottomUp("bp2build_deps", bp2buildDepsMutator).Parallel()
}
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 5db668e..d272ec2 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -452,12 +452,34 @@
Label: ":" + dep + "__BP2BUILD__MISSING__DEP",
}
}
- if markAsDep {
+ // Returns true if a dependency from the current module to the target module
+ // should be skipped; doing so is a hack to circumvent certain problematic
+ // scenarios that will be addressed in the future.
+ shouldSkipDep := func(dep string) bool {
// Don't count dependencies of "libc". This is a hack to circumvent the
// fact that, in a variantless build graph, "libc" has a dependency on itself.
- if ctx.ModuleName() != "libc" {
- ctx.AddDependency(ctx.Module(), Bp2buildDepTag, dep)
+ if ctx.ModuleName() == "libc" {
+ return true
}
+
+ // TODO: b/303307672: Dependencies on this module happen to "work" because
+ // there is a source file with the same name as this module in the
+ // same directory. We should remove this hack and enforce the underlying
+ // module of this name is the actual one used.
+ if dep == "mke2fs.conf" {
+ return true
+ }
+
+ // TODO: b/303310285: Remove this special-casing once all dependencies of
+ // crtbegin_dynamic are convertible
+ if ctx.ModuleName() == "crtbegin_dynamic" {
+ return true
+ }
+
+ return false
+ }
+ if markAsDep && !shouldSkipDep(dep) {
+ ctx.AddDependency(ctx.Module(), Bp2buildDepTag, dep)
}
if !convertedToBazel(ctx, m) {
ctx.AddUnconvertedBp2buildDep(dep)
diff --git a/android/config.go b/android/config.go
index 524ff2f..2930c86 100644
--- a/android/config.go
+++ b/android/config.go
@@ -167,7 +167,8 @@
}
// DisableHiddenApiChecks returns true if hiddenapi checks have been disabled.
-// For 'eng' target variant hiddenapi checks are disabled by default for performance optimisation,
+// For 'eng' target variant hiddenapi checks are disabled by default for performance optimisation
+// Hiddenapi checks are also disabled when RELEASE_DEFAULT_MODULE_BUILD_FROM_SOURCE is set to false
// but can be enabled by setting environment variable ENABLE_HIDDENAPI_FLAGS=true.
// For other target variants hiddenapi check are enabled by default but can be disabled by
// setting environment variable UNSAFE_DISABLE_HIDDENAPI_FLAGS=true.
@@ -176,7 +177,8 @@
func (c Config) DisableHiddenApiChecks() bool {
return !c.IsEnvTrue("ENABLE_HIDDENAPI_FLAGS") &&
(c.IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") ||
- Bool(c.productVariables.Eng))
+ Bool(c.productVariables.Eng) ||
+ !c.ReleaseDefaultModuleBuildFromSource())
}
// MaxPageSizeSupported returns the max page size supported by the device. This
@@ -221,6 +223,13 @@
return c.config.productVariables.ReleaseAconfigFlagDefaultPermission
}
+// The flag indicating behavior for the tree wrt building modules or using prebuilts
+// derived from RELEASE_DEFAULT_MODULE_BUILD_FROM_SOURCE
+func (c Config) ReleaseDefaultModuleBuildFromSource() bool {
+ return c.config.productVariables.ReleaseDefaultModuleBuildFromSource == nil ||
+ Bool(c.config.productVariables.ReleaseDefaultModuleBuildFromSource)
+}
+
// A DeviceConfig object represents the configuration for a particular device
// being built. For now there will only be one of these, but in the future there
// may be multiple devices being built.
@@ -297,9 +306,6 @@
// in tests when a path doesn't exist.
TestAllowNonExistentPaths bool
- // If true, register the "bp2build_deps" mutator in the mutator pipeline.
- Bp2buildDepsMutator bool
-
// The list of files that when changed, must invalidate soong_build to
// regenerate build.ninja.
ninjaFileDepsSet sync.Map
@@ -678,7 +684,6 @@
"framework-media": {},
"framework-mediaprovider": {},
"framework-ondevicepersonalization": {},
- "framework-pdf": {},
"framework-permission": {},
"framework-permission-s": {},
"framework-scheduling": {},
@@ -1003,12 +1008,18 @@
func (c *config) PreviewApiLevels() []ApiLevel {
var levels []ApiLevel
- for i, codename := range c.PlatformVersionActiveCodenames() {
+ i := 0
+ for _, codename := range c.PlatformVersionActiveCodenames() {
+ if codename == "REL" {
+ continue
+ }
+
levels = append(levels, ApiLevel{
value: codename,
number: i,
isPreview: true,
})
+ i++
}
return levels
}
@@ -1443,7 +1454,7 @@
}
func (c *deviceConfig) VndkUseCoreVariant() bool {
- return Bool(c.config.productVariables.VndkUseCoreVariant)
+ return Bool(c.config.productVariables.VndkUseCoreVariant) && Bool(c.config.productVariables.KeepVndk)
}
func (c *deviceConfig) SystemSdkVersions() []string {
diff --git a/android/module.go b/android/module.go
index 74b8cb8..ce6c78d 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1272,6 +1272,22 @@
m.base().commonProperties.CreateCommonOSVariant = true
}
+func (attrs *CommonAttributes) getRequiredWithoutCycles(ctx *bottomUpMutatorContext, props *commonProperties) []string {
+ // Treat `required` as if it's empty if data should be skipped for this target,
+ // as `required` is only used for the `data` attribute at this time, and we want
+ // to avoid lookups of labels that won't actually be dependencies of this target.
+ // TODO: b/202299295 - Refactor this to use `required` dependencies, once they
+ // are handled other than passing to `data`.
+ if proptools.Bool(attrs.SkipData) {
+ return []string{}
+ }
+ // The required property can contain the module itself. This causes a cycle
+ // when generated as the 'data' label list attribute in Bazel. Remove it if
+ // it exists. See b/247985196.
+ _, requiredWithoutCycles := RemoveFromList(ctx.ModuleName(), props.Required)
+ return FirstUniqueStrings(requiredWithoutCycles)
+}
+
func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *bottomUpMutatorContext,
enabledPropertyOverrides bazel.BoolAttribute) constraintAttributes {
@@ -1340,18 +1356,13 @@
attrs.Applicable_licenses = bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, mod.commonProperties.Licenses))
- // The required property can contain the module itself. This causes a cycle
- // when generated as the 'data' label list attribute in Bazel. Remove it if
- // it exists. See b/247985196.
- _, requiredWithoutCycles := RemoveFromList(ctx.ModuleName(), mod.commonProperties.Required)
- requiredWithoutCycles = FirstUniqueStrings(requiredWithoutCycles)
+ requiredWithoutCycles := attrs.getRequiredWithoutCycles(ctx, &mod.commonProperties)
required := depsToLabelList(requiredWithoutCycles)
archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{})
for axis, configToProps := range archVariantProps {
for config, _props := range configToProps {
if archProps, ok := _props.(*commonProperties); ok {
- _, requiredWithoutCycles := RemoveFromList(ctx.ModuleName(), archProps.Required)
- requiredWithoutCycles = FirstUniqueStrings(requiredWithoutCycles)
+ requiredWithoutCycles := attrs.getRequiredWithoutCycles(ctx, archProps)
required.SetSelectValue(axis, config, depsToLabelList(requiredWithoutCycles).Value)
if !neitherHostNorDevice {
if archProps.Enabled != nil {
@@ -1408,9 +1419,8 @@
platformEnabledAttribute.Add(&l)
}
- if !proptools.Bool(attrs.SkipData) {
- attrs.Data.Append(required)
- }
+ attrs.Data.Append(required)
+
// SkipData is not an attribute of any Bazel target
// Set this to nil so that it does not appear in the generated build file
attrs.SkipData = nil
diff --git a/android/mutator.go b/android/mutator.go
index 3d59655..067d6c3 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -35,9 +35,6 @@
// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators []RegisterMutatorFunc) {
bp2buildMutators := append(preArchMutators, registerBp2buildConversionMutator)
- if ctx.config.Bp2buildDepsMutator {
- bp2buildMutators = append(bp2buildMutators, registerBp2buildDepsMutator)
- }
registerMutatorsForBazelConversion(ctx, bp2buildMutators)
}
diff --git a/android/updatable_modules.go b/android/updatable_modules.go
index 71c76c5..6d0eeb7 100644
--- a/android/updatable_modules.go
+++ b/android/updatable_modules.go
@@ -14,9 +14,9 @@
package android
-// This file contains branch specific constants for building updatable modules.
-// They are stored in a separate file to minimise the potential of merge
-// conflicts between branches when the code from the package is changed.
+// This file contains branch specific constants. They are stored in a separate
+// file to minimise the potential of merge conflicts between branches when
+// the code from the package is changed.
// The default manifest version for all the modules on this branch.
// This version code will be used only if there is no version field in the
@@ -33,4 +33,4 @@
// * AOSP - xx9990000
// * x-mainline-prod - xx9990000
// * master - 990090000
-const DefaultUpdatableModuleVersion = "339990000"
+const DefaultUpdatableModuleVersion = "340090000"
diff --git a/android/variable.go b/android/variable.go
index 8882e80..006a77f 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -479,6 +479,8 @@
ReleaseAconfigFlagDefaultPermission string `json:",omitempty"`
+ ReleaseDefaultModuleBuildFromSource *bool `json:",omitempty"`
+
KeepVndk *bool `json:",omitempty"`
CheckVendorSeappViolations *bool `json:",omitempty"`
diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go
index 57c38db..475c2d6 100644
--- a/bp2build/aar_conversion_test.go
+++ b/bp2build/aar_conversion_test.go
@@ -102,6 +102,7 @@
sdk_version: "current",
}
`,
+ StubbedBuildDefinitions: []string{"lib_dep"},
ExpectedBazelTargets: []string{
MakeBazelTarget(
"android_library",
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index dc56a17..0a4d749 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -349,19 +349,6 @@
},
},
{
- Description: "non-existent dep",
- Blueprint: `custom {
- name: "has_dep",
- arch_paths: [":dep"],
- bazel_module: { bp2build_available: true },
-}`,
- ExpectedBazelTargets: []string{
- MakeBazelTarget("custom", "has_dep", AttrNameToString{
- "arch_paths": `[":dep__BP2BUILD__MISSING__DEP"]`,
- }),
- },
- },
- {
Description: "arch-variant srcs",
Blueprint: `custom {
name: "arch_paths",
@@ -1071,50 +1058,6 @@
}),
},
},
- {
- Description: "depends_on_other_unconverted_module_error",
- ModuleTypeUnderTest: "filegroup",
- ModuleTypeUnderTestFactory: android.FileGroupFactory,
- UnconvertedDepsMode: errorModulesUnconvertedDeps,
- Blueprint: `filegroup {
- name: "foobar",
- srcs: [
- ":foo",
- "c",
- ],
- bazel_module: { bp2build_available: true },
-}`,
- ExpectedErr: fmt.Errorf(`filegroup .:foobar depends on unconverted modules: foo`),
- Filesystem: map[string]string{
- "other/Android.bp": `filegroup {
- name: "foo",
- srcs: ["a", "b"],
-}`,
- },
- },
- {
- Description: "depends_on_other_missing_module_error",
- ModuleTypeUnderTest: "filegroup",
- ModuleTypeUnderTestFactory: android.FileGroupFactory,
- UnconvertedDepsMode: errorModulesUnconvertedDeps,
- Blueprint: `filegroup {
- name: "foobar",
- srcs: [
- "c",
- "//other:foo",
- "//other:goo",
- ],
- bazel_module: { bp2build_available: true },
-}`,
- ExpectedErr: fmt.Errorf(`filegroup .:foobar depends on missing modules: //other:goo`),
- Filesystem: map[string]string{"other/Android.bp": `filegroup {
- name: "foo",
- srcs: ["a"],
- bazel_module: { bp2build_available: true },
-}
-`,
- },
- },
}
for _, testCase := range testCases {
@@ -2132,7 +2075,6 @@
Blueprint: bp,
ExpectedBazelTargets: expectedBazelTargets,
Description: "Skipping conversion of a target with missing transitive dep",
- DepsMutator: true,
})
}
@@ -2170,7 +2112,6 @@
Blueprint: bp,
ExpectedBazelTargets: expectedBazelTargets,
Description: "Skipping conversion of a target with missing direct dep",
- DepsMutator: true,
})
}
@@ -2193,7 +2134,6 @@
Blueprint: bp,
ExpectedBazelTargets: []string{},
Description: "Skipping conversion of a target with unconverted direct dep",
- DepsMutator: true,
})
}
@@ -2232,7 +2172,6 @@
Blueprint: bp,
ExpectedBazelTargets: expectedBazelTargets,
Description: "Skipping conversion of a target with unconverted transitive dep",
- DepsMutator: true,
})
}
@@ -2272,7 +2211,6 @@
Blueprint: bp,
ExpectedBazelTargets: expectedBazelTargets,
Description: "Convert target with already-existing build dep",
- DepsMutator: true,
})
}
@@ -2314,6 +2252,5 @@
Blueprint: bp,
ExpectedBazelTargets: expectedBazelTargets,
Description: "Convert target with dep on libc",
- DepsMutator: true,
})
}
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index bc88f86..d198596 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -559,8 +559,8 @@
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
Dir: "foo/bar",
- StubbedBuildDefinitions: []string{"//foo/bar:prebuilt_whole_static_lib_for_shared", "//foo/bar:prebuilt_whole_static_lib_for_static",
- "//foo/bar:prebuilt_whole_static_lib_for_both"},
+ StubbedBuildDefinitions: []string{"//foo/bar:whole_static_lib_for_shared", "//foo/bar:whole_static_lib_for_static",
+ "//foo/bar:whole_static_lib_for_both"},
Filesystem: map[string]string{
"foo/bar/Android.bp": `
cc_library {
@@ -3355,6 +3355,7 @@
Description: "cc_library with target.apex",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"bar", "baz", "buh"},
Blueprint: `
cc_library {
name: "foo",
@@ -3366,27 +3367,29 @@
exclude_static_libs: ["buh"],
}
}
-}`,
+}` + simpleModule("cc_library_static", "baz") +
+ simpleModule("cc_library_static", "buh") +
+ simpleModule("cc_library_static", "bar"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
- "implementation_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
+ "implementation_deps": `[":baz"] + select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":buh__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":buh"],
})`,
- "implementation_dynamic_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
+ "implementation_dynamic_deps": `[":baz"] + select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":bar__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":bar"],
})`,
"local_includes": `["."]`,
}),
MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
- "implementation_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
+ "implementation_deps": `[":baz"] + select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":buh__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":buh"],
})`,
- "implementation_dynamic_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
+ "implementation_dynamic_deps": `[":baz"] + select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":bar__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":bar"],
})`,
"local_includes": `["."]`,
}),
@@ -3412,20 +3415,23 @@
exclude_static_libs: ["abc"],
}
}
-}`,
+}` + simpleModule("cc_library_static", "bar") +
+ simpleModule("cc_library_static", "baz") +
+ simpleModule("cc_library_static", "abc"),
+ StubbedBuildDefinitions: []string{"bar", "baz", "abc"},
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
"implementation_dynamic_deps": `select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":bar__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":bar"],
})`,
"dynamic_deps": `select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":baz__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":baz"],
})`,
"deps": `select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":abc__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":abc"],
})`,
"local_includes": `["."]`,
}),
@@ -5172,6 +5178,7 @@
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_stub_suite", "libfoo.ndk_stub_libs", AttrNameToString{
"api_surface": `"publicapi"`,
+ "included_in_ndk": `True`,
"soname": `"libfoo.so"`,
"source_library_label": `"//:libfoo"`,
"symbol_file": `"libfoo.map.txt"`,
@@ -5198,7 +5205,7 @@
name: "libfoo_headers",
from: "from",
to: "to",
- srcs: ["from/foo.h", "from/foo_other.h"]
+ srcs: ["foo.h", "foo_other.h"]
}
`,
ExpectedBazelTargets: []string{
@@ -5206,8 +5213,8 @@
"strip_import_prefix": `"from"`,
"import_prefix": `"to"`,
"hdrs": `[
- "from/foo.h",
- "from/foo_other.h",
+ "foo.h",
+ "foo_other.h",
]`,
}),
},
@@ -5245,3 +5252,115 @@
}
runCcLibraryTestCase(t, tc)
}
+
+// Regression test for b/303307456.
+// TODO: b/202299295 - Remove this test when cc rules have proper support
+// for the `required` property
+func TestCcModules_requiredProperty(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc modules do not use the required property",
+ Filesystem: map[string]string{
+ "foo.c": "",
+ "bar.c": "",
+ },
+ Blueprint: soongCcLibraryPreamble + `
+cc_library {
+ name: "foo_both",
+ srcs: ["foo.c"],
+ include_build_directory: false,
+ required: ["bar"],
+}
+cc_library_shared {
+ name: "foo_shared",
+ srcs: ["foo.c"],
+ include_build_directory: false,
+ required: ["bar"],
+}
+cc_library_static {
+ name: "foo_static",
+ srcs: ["foo.c"],
+ include_build_directory: false,
+ required: ["bar"],
+}
+cc_library_static {
+ name: "bar",
+ srcs: ["bar.c"],
+ include_build_directory: false,
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_both_bp2build_cc_library_static", AttrNameToString{
+ "srcs_c": `["foo.c"]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo_both", AttrNameToString{
+ "srcs_c": `["foo.c"]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+ "srcs_c": `["foo.c"]`,
+ }),
+ MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+ "srcs_c": `["foo.c"]`,
+ }),
+ MakeBazelTarget("cc_library_static", "bar", AttrNameToString{
+ "srcs_c": `["bar.c"]`,
+ }),
+ },
+ })
+}
+
+func TestPropertiesIfStubLibraryIsInNdk(t *testing.T) {
+ tc := Bp2buildTestCase{
+ Description: "If an equivalent ndk_library exists, set included_in_ndk=true for module-libapi stubs",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+// libfoo is an ndk library and contributes to module-libapi
+cc_library {
+ name: "libfoo",
+ stubs: {symbol_file: "libfoo.map.txt"},
+}
+ndk_library {
+ name: "libfoo",
+ first_version: "29",
+ symbol_file: "libfoo.map.txt",
+}
+// libbar is not an ndk library, but contributes to module-libapi
+cc_library {
+ name: "libbar",
+ stubs: {symbol_file: "libbar.map.txt"},
+}
+`,
+ StubbedBuildDefinitions: []string{"libfoo.ndk"},
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "libfoo_bp2build_cc_library_static", AttrNameToString{
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "libfoo", AttrNameToString{
+ "local_includes": `["."]`,
+ "stubs_symbol_file": `"libfoo.map.txt"`,
+ }),
+ MakeBazelTarget("cc_stub_suite", "libfoo_stub_libs", AttrNameToString{
+ "api_surface": `"module-libapi"`,
+ "soname": `"libfoo.so"`,
+ "source_library_label": `"//:libfoo"`,
+ "symbol_file": `"libfoo.map.txt"`,
+ "versions": `["current"]`,
+ "included_in_ndk": `True`,
+ }),
+ MakeBazelTarget("cc_library_static", "libbar_bp2build_cc_library_static", AttrNameToString{
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "libbar", AttrNameToString{
+ "local_includes": `["."]`,
+ "stubs_symbol_file": `"libbar.map.txt"`,
+ }),
+ MakeBazelTarget("cc_stub_suite", "libbar_stub_libs", AttrNameToString{
+ "api_surface": `"module-libapi"`,
+ "soname": `"libbar.so"`,
+ "source_library_label": `"//:libbar"`,
+ "symbol_file": `"libbar.map.txt"`,
+ "versions": `["current"]`,
+ }),
+ },
+ }
+ runCcLibraryTestCase(t, tc)
+}
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index e54f051..5168fe9 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -70,10 +70,6 @@
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers test",
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": "",
@@ -86,7 +82,6 @@
cc_library_headers {
name: "foo_headers",
export_include_dirs: ["dir-1", "dir-2"],
- header_libs: ["lib-1", "lib-2"],
arch: {
arm64: {
@@ -322,7 +317,7 @@
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers exported_static_lib_headers is reexported",
Filesystem: map[string]string{},
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "foo_no_reexport"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
@@ -330,7 +325,8 @@
static_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
-` + simpleModule("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export") +
+ simpleModule("cc_library_headers", "foo_no_reexport"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
@@ -343,7 +339,7 @@
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers exported_shared_lib_headers is reexported",
Filesystem: map[string]string{},
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "foo_no_reexport"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
@@ -351,7 +347,8 @@
shared_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
-` + simpleModule("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export") +
+ simpleModule("cc_library_headers", "foo_no_reexport"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
@@ -364,7 +361,7 @@
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers exported_header_lib_headers is reexported",
Filesystem: map[string]string{},
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "foo_no_reexport"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
@@ -372,7 +369,8 @@
header_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
-` + simpleModule("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export") +
+ simpleModule("cc_library_headers", "foo_no_reexport"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
@@ -426,7 +424,7 @@
func TestPrebuiltCcLibraryHeadersPreferredRdepUpdated(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers prebuilt preferred is used as rdep",
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "//foo/bar:foo_headers"},
Filesystem: map[string]string{
"foo/bar/Android.bp": simpleModule("cc_library_headers", "foo_headers"),
},
@@ -458,7 +456,7 @@
func TestPrebuiltCcLibraryHeadersRdepUpdated(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers not preferred is not used for rdep",
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "//foo/bar:foo_headers"},
Filesystem: map[string]string{
"foo/bar/Android.bp": simpleModule("cc_library_headers", "foo_headers"),
},
diff --git a/bp2build/cc_test_conversion_test.go b/bp2build/cc_test_conversion_test.go
index 392a962..679a364 100644
--- a/bp2build/cc_test_conversion_test.go
+++ b/bp2build/cc_test_conversion_test.go
@@ -631,23 +631,3 @@
},
})
}
-
-func TestCcTest_UnitTestFalse(t *testing.T) {
- runCcTestTestCase(t, ccTestBp2buildTestCase{
- description: "cc test with test_options.tags converted to tags",
- blueprint: `
-cc_test {
- name: "mytest",
- host_supported: true,
- srcs: ["test.cpp"],
- test_options: { unit_test: false },
-}
-` + simpleModule("cc_library_static", "libgtest_main") +
- simpleModule("cc_library_static", "libgtest"),
- stubbedBuildDefinitions: []string{
- "libgtest_main",
- "libgtest",
- },
- targets: []testBazelTarget{},
- })
-}
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index c697235..b2792e6 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -15,7 +15,6 @@
rust_config "android/soong/rust/config"
"android/soong/starlark_fmt"
- "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -34,19 +33,9 @@
files = append(files, newFile("android", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
files = append(files, newFile("android", "constants.bzl", android.BazelCcToolchainVars(cfg)))
- // Visit all modules to determine the list of ndk libraries
- // This list will be used to add additional flags for cc stub generation
- ndkLibsStringFormatted := []string{}
- ctx.Context().VisitAllModules(func(m blueprint.Module) {
- if ctx.Context().ModuleType(m) == "ndk_library" {
- ndkLibsStringFormatted = append(ndkLibsStringFormatted, fmt.Sprintf(`"%s"`, m.Name())) // name will be `"libc.ndk"`
- }
- })
-
files = append(files, newFile("cc_toolchain", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
files = append(files, newFile("cc_toolchain", "config_constants.bzl", cc_config.BazelCcToolchainVars(cfg)))
files = append(files, newFile("cc_toolchain", "sanitizer_constants.bzl", cc.BazelCcSanitizerToolchainVars(cfg)))
- files = append(files, newFile("cc_toolchain", "ndk_libs.bzl", fmt.Sprintf("ndk_libs = [%v]", strings.Join(ndkLibsStringFormatted, ", "))))
files = append(files, newFile("java_toolchain", GeneratedBuildFileName, "")) // Creates a //java_toolchain package.
files = append(files, newFile("java_toolchain", "constants.bzl", java_config.BazelJavaToolchainVars(cfg)))
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index 6b10077..51675ce 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -107,10 +107,6 @@
},
{
dir: "cc_toolchain",
- basename: "ndk_libs.bzl",
- },
- {
- dir: "cc_toolchain",
basename: "sanitizer_constants.bzl",
},
{
diff --git a/bp2build/gensrcs_conversion_test.go b/bp2build/gensrcs_conversion_test.go
index e808340..e9fc61d 100644
--- a/bp2build/gensrcs_conversion_test.go
+++ b/bp2build/gensrcs_conversion_test.go
@@ -15,16 +15,22 @@
package bp2build
import (
+ "testing"
+
"android/soong/android"
"android/soong/genrule"
- "testing"
)
+func registerModulesForGensrcsTests(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+}
+
func TestGensrcs(t *testing.T) {
testcases := []struct {
- name string
- bp string
- expectedBazelAttrs AttrNameToString
+ name string
+ bp string
+ expectedBazelAttrs AttrNameToString
+ stubbedBuildDefinitions []string
}{
{
name: "gensrcs with common usage of properties",
@@ -37,18 +43,22 @@
data: ["foo/file.txt", ":external_files"],
output_extension: "out",
bazel_module: { bp2build_available: true },
+ }
+ filegroup {
+ name: "external_files",
}`,
+ stubbedBuildDefinitions: []string{"external_files"},
expectedBazelAttrs: AttrNameToString{
"srcs": `[
"test/input.txt",
- ":external_files__BP2BUILD__MISSING__DEP",
+ ":external_files",
]`,
"tools": `["program.py"]`,
"output_extension": `"out"`,
- "cmd": `"$(location program.py) $(SRC) $(OUT) $(location foo/file.txt) $(location :external_files__BP2BUILD__MISSING__DEP)"`,
+ "cmd": `"$(location program.py) $(SRC) $(OUT) $(location foo/file.txt) $(location :external_files)"`,
"data": `[
"foo/file.txt",
- ":external_files__BP2BUILD__MISSING__DEP",
+ ":external_files",
]`,
},
},
@@ -73,12 +83,13 @@
MakeBazelTargetNoRestrictions("gensrcs", "foo", test.expectedBazelAttrs),
}
t.Run(test.name, func(t *testing.T) {
- RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
+ RunBp2BuildTestCase(t, registerModulesForGensrcsTests,
Bp2buildTestCase{
ModuleTypeUnderTest: "gensrcs",
ModuleTypeUnderTestFactory: genrule.GenSrcsFactory,
Blueprint: test.bp,
ExpectedBazelTargets: expectedBazelTargets,
+ StubbedBuildDefinitions: test.stubbedBuildDefinitions,
})
})
}
diff --git a/bp2build/java_import_conversion_test.go b/bp2build/java_import_conversion_test.go
index 5661620..d9910af 100644
--- a/bp2build/java_import_conversion_test.go
+++ b/bp2build/java_import_conversion_test.go
@@ -21,6 +21,13 @@
"testing"
)
+func runJavaImportTestCaseWithRegistrationCtxFunc(t *testing.T, tc Bp2buildTestCase, registrationCtxFunc func(ctx android.RegistrationContext)) {
+ t.Helper()
+ (&tc).ModuleTypeUnderTest = "java_import"
+ (&tc).ModuleTypeUnderTestFactory = java.ImportFactory
+ RunBp2BuildTestCase(t, registrationCtxFunc, tc)
+}
+
func runJavaImportTestCase(t *testing.T, tc Bp2buildTestCase) {
t.Helper()
RunBp2BuildTestCase(t, registerJavaImportModuleTypes, tc)
@@ -120,3 +127,31 @@
}),
}})
}
+
+func TestJavaImportSameNameAsJavaLibrary(t *testing.T) {
+ runJavaImportTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{
+ Description: "java_import has the same name as other package java_library's",
+ Filesystem: map[string]string{
+ "foo/bar/Android.bp": simpleModule("java_library", "test_lib"),
+ "test.jar": "",
+ },
+ Blueprint: `java_import {
+ name: "test_lib",
+ jars: ["test.jar"],
+ bazel_module: { bp2build_available: true },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_import", "test_lib", AttrNameToString{
+ "jars": `["test.jar"]`,
+ }),
+ MakeBazelTarget("java_library", "test_lib-neverlink", AttrNameToString{
+ "exports": `[":test_lib"]`,
+ "neverlink": `True`,
+ "sdk_version": `"none"`,
+ }),
+ },
+ }, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("java_library", java.LibraryFactory)
+ })
+}
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index 38571d4..ad0ec65 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -635,7 +635,7 @@
Description: "java_library with non adjacent aidl filegroup",
ModuleTypeUnderTest: "java_library",
ModuleTypeUnderTestFactory: java.LibraryFactory,
- StubbedBuildDefinitions: []string{"A_aidl"},
+ StubbedBuildDefinitions: []string{"//path/to/A:A_aidl"},
Filesystem: map[string]string{
"path/to/A/Android.bp": `
filegroup {
@@ -1041,3 +1041,28 @@
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
})
}
+
+func TestJavaLibrarySameNameAsPrebuilt(t *testing.T) {
+ runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{
+ Description: "java_library and prebuilt module have the same name",
+ Filesystem: map[string]string{
+ "foo/bar/Android.bp": simpleModule("java_import", "test_lib"),
+ },
+ Blueprint: `java_library {
+ name: "test_lib",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ bazel_module: { bp2build_available: true },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_library", "test_lib", AttrNameToString{
+ "srcs": `["a.java"]`,
+ "sdk_version": `"current"`,
+ }),
+ MakeNeverlinkDuplicateTarget("java_library", "test_lib"),
+ },
+ }, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("java_import", java.ImportFactory)
+ })
+}
diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go
index 4e96efe..cd89978 100644
--- a/bp2build/java_proto_conversion_test.go
+++ b/bp2build/java_proto_conversion_test.go
@@ -193,3 +193,46 @@
},
})
}
+
+func TestJavaProtoPlugin(t *testing.T) {
+ runJavaProtoTestCase(t, Bp2buildTestCase{
+ Description: "java_library proto plugin",
+ StubbedBuildDefinitions: []string{"protoc-gen-test-plugin"},
+ Blueprint: `java_library_static {
+ name: "java-protos",
+ srcs: ["a.proto"],
+ proto: {
+ plugin: "test-plugin",
+ },
+ sdk_version: "current",
+}
+
+java_library_static {
+ name: "protoc-gen-test-plugin",
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{
+ "srcs": `["a.proto"]`,
+ }),
+ MakeBazelTarget(
+ "java_lite_proto_library",
+ "java-protos_java_proto_lite",
+ AttrNameToString{
+ "deps": `[":java-protos_proto"]`,
+ "plugin": `":protoc-gen-test-plugin"`,
+ "sdk_version": `"current"`,
+ }),
+ MakeBazelTarget("java_library", "java-protos", AttrNameToString{
+ "exports": `[":java-protos_java_proto_lite"]`,
+ "sdk_version": `"current"`,
+ }),
+ MakeNeverlinkDuplicateTargetWithAttrs(
+ "java_library",
+ "java-protos",
+ AttrNameToString{
+ "sdk_version": `"current"`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/sh_test_conversion_test.go b/bp2build/sh_test_conversion_test.go
index e99d566..48fd077 100644
--- a/bp2build/sh_test_conversion_test.go
+++ b/bp2build/sh_test_conversion_test.go
@@ -22,11 +22,18 @@
)
func TestShTestSimple(t *testing.T) {
- RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{
- Description: "sh_test test",
- ModuleTypeUnderTest: "sh_test",
+ RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ }, Bp2buildTestCase{
+ Description: "sh_test test",
+ ModuleTypeUnderTest: "sh_test",
+ StubbedBuildDefinitions: []string{"android.hardware.bluetooth@1.1-service.sim",
+ "android.hardware.bluetooth@1.1-impl-sim", "libc++", "libcrypto"},
ModuleTypeUnderTestFactory: sh.ShTestFactory,
- Blueprint: `sh_test{
+ Blueprint: simpleModule("filegroup", "android.hardware.bluetooth@1.1-service.sim") +
+ simpleModule("filegroup", "android.hardware.bluetooth@1.1-impl-sim") +
+ simpleModule("filegroup", "libc++") +
+ simpleModule("filegroup", "libcrypto") + `sh_test{
name: "sts-rootcanal-sidebins",
src: "empty.sh",
test_suites: [
@@ -47,28 +54,37 @@
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("sh_test", "sts-rootcanal-sidebins", AttrNameToString{
- "srcs": `["empty.sh"]`,
+ "srcs": `["empty.sh"]`,
+ "runs_on": `["device"]`,
"data": `[
"android.hardware.bluetooth@1.1-service.sim.rc",
- "android.hardware.bluetooth@1.1-service.sim",
- "android.hardware.bluetooth@1.1-impl-sim",
- "libc++",
- "libcrypto",
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ":libc++",
+ ":libcrypto",
]`,
- "test_config": `"art-gtests-target-install-apex.xml"`,
- "test_config_template": `":art-run-test-target-template"`,
- "auto_gen_config": "False",
- "tags": `["no-remote"]`,
+ "data_bins": `[
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ]`,
+ "tags": `["no-remote"]`,
})},
})
}
func TestShTestHostSimple(t *testing.T) {
- RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{
- Description: "sh_test_host test",
- ModuleTypeUnderTest: "sh_test_host",
+ RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ }, Bp2buildTestCase{
+ Description: "sh_test_host test",
+ ModuleTypeUnderTest: "sh_test_host",
+ StubbedBuildDefinitions: []string{"android.hardware.bluetooth@1.1-service.sim",
+ "android.hardware.bluetooth@1.1-impl-sim", "libc++", "libcrypto"},
ModuleTypeUnderTestFactory: sh.ShTestHostFactory,
- Blueprint: `sh_test_host{
+ Blueprint: simpleModule("filegroup", "android.hardware.bluetooth@1.1-service.sim") +
+ simpleModule("filegroup", "android.hardware.bluetooth@1.1-impl-sim") +
+ simpleModule("filegroup", "libc++") +
+ simpleModule("filegroup", "libcrypto") + `sh_test_host{
name: "sts-rootcanal-sidebins",
src: "empty.sh",
test_suites: [
@@ -89,18 +105,20 @@
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("sh_test", "sts-rootcanal-sidebins", AttrNameToString{
- "srcs": `["empty.sh"]`,
+ "srcs": `["empty.sh"]`,
+ "runs_on": `["host_without_device"]`,
"data": `[
"android.hardware.bluetooth@1.1-service.sim.rc",
- "android.hardware.bluetooth@1.1-service.sim",
- "android.hardware.bluetooth@1.1-impl-sim",
- "libc++",
- "libcrypto",
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ":libc++",
+ ":libcrypto",
]`,
- "tags": `["no-remote"]`,
- "test_config": `"art-gtests-target-install-apex.xml"`,
- "test_config_template": `":art-run-test-target-template"`,
- "auto_gen_config": "False",
+ "data_bins": `[
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ]`,
+ "tags": `["no-remote"]`,
"target_compatible_with": `select({
"//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
"//conditions:default": [],
@@ -109,12 +127,131 @@
})
}
-func TestShTestSimpleUnset(t *testing.T) {
- RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{
- Description: "sh_test test",
- ModuleTypeUnderTest: "sh_test",
+func TestShTestAutogen(t *testing.T) {
+ RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ }, Bp2buildTestCase{
+ Description: "sh_test test",
+ ModuleTypeUnderTest: "sh_test",
+ StubbedBuildDefinitions: []string{"android.hardware.bluetooth@1.1-service.sim",
+ "android.hardware.bluetooth@1.1-impl-sim", "libc++", "libcrypto", "art-run-test-target-template"},
ModuleTypeUnderTestFactory: sh.ShTestFactory,
- Blueprint: `sh_test{
+ Blueprint: simpleModule("filegroup", "android.hardware.bluetooth@1.1-service.sim") +
+ simpleModule("filegroup", "android.hardware.bluetooth@1.1-impl-sim") +
+ simpleModule("filegroup", "libc++") +
+ simpleModule("filegroup", "libcrypto") +
+ simpleModule("filegroup", "art-run-test-target-template") + `sh_test{
+ name: "sts-rootcanal-sidebins",
+ src: "empty.sh",
+ test_suites: [
+ "sts",
+ "sts-lite",
+ ],
+ data_bins: [
+ "android.hardware.bluetooth@1.1-service.sim",
+ "android.hardware.bluetooth@1.1-impl-sim"
+ ],
+ data: ["android.hardware.bluetooth@1.1-service.sim.rc"],
+ data_libs: ["libc++","libcrypto"],
+ test_config: "art-gtests-target-install-apex.xml",
+ test_config_template: ":art-run-test-target-template",
+ auto_gen_config: true,
+ test_options:{tags: ["no-remote"],
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("sh_test", "sts-rootcanal-sidebins", AttrNameToString{
+ "srcs": `["empty.sh"]`,
+ "runs_on": `["device"]`,
+ "auto_generate_test_config": "True",
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ "template_test_config": `":art-run-test-target-template"`,
+ "data": `[
+ "android.hardware.bluetooth@1.1-service.sim.rc",
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ":libc++",
+ ":libcrypto",
+ ]`,
+ "data_bins": `[
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ]`,
+ "tags": `["no-remote"]`,
+ })},
+ })
+}
+
+func TestShTestHostAutogen(t *testing.T) {
+ RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ }, Bp2buildTestCase{
+ Description: "sh_test_host test",
+ ModuleTypeUnderTest: "sh_test_host",
+ StubbedBuildDefinitions: []string{"android.hardware.bluetooth@1.1-service.sim",
+ "android.hardware.bluetooth@1.1-impl-sim", "libc++", "libcrypto", "art-run-test-target-template"},
+ ModuleTypeUnderTestFactory: sh.ShTestHostFactory,
+ Blueprint: simpleModule("filegroup", "android.hardware.bluetooth@1.1-service.sim") +
+ simpleModule("filegroup", "android.hardware.bluetooth@1.1-impl-sim") +
+ simpleModule("filegroup", "libc++") +
+ simpleModule("filegroup", "libcrypto") +
+ simpleModule("filegroup", "art-run-test-target-template") + `sh_test_host{
+ name: "sts-rootcanal-sidebins",
+ src: "empty.sh",
+ test_suites: [
+ "sts",
+ "sts-lite",
+ ],
+ data_bins: [
+ "android.hardware.bluetooth@1.1-service.sim",
+ "android.hardware.bluetooth@1.1-impl-sim"
+ ],
+ data: ["android.hardware.bluetooth@1.1-service.sim.rc"],
+ data_libs: ["libc++","libcrypto"],
+ test_config: "art-gtests-target-install-apex.xml",
+ test_config_template: ":art-run-test-target-template",
+ auto_gen_config: true,
+ test_options:{tags: ["no-remote"],
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("sh_test", "sts-rootcanal-sidebins", AttrNameToString{
+ "srcs": `["empty.sh"]`,
+ "runs_on": `["host_without_device"]`,
+ "auto_generate_test_config": "True",
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ "template_test_config": `":art-run-test-target-template"`,
+ "data": `[
+ "android.hardware.bluetooth@1.1-service.sim.rc",
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ":libc++",
+ ":libcrypto",
+ ]`,
+ "data_bins": `[
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ]`,
+ "tags": `["no-remote"]`,
+ })},
+ })
+}
+func TestShTestSimpleUnset(t *testing.T) {
+ RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ }, Bp2buildTestCase{
+ Description: "sh_test test",
+ ModuleTypeUnderTest: "sh_test",
+ StubbedBuildDefinitions: []string{"android.hardware.bluetooth@1.1-service.sim",
+ "android.hardware.bluetooth@1.1-impl-sim", "libc++", "libcrypto"},
+ ModuleTypeUnderTestFactory: sh.ShTestFactory,
+ Blueprint: simpleModule("filegroup", "android.hardware.bluetooth@1.1-service.sim") +
+ simpleModule("filegroup", "android.hardware.bluetooth@1.1-impl-sim") +
+ simpleModule("filegroup", "libc++") +
+ simpleModule("filegroup", "libcrypto") + `sh_test{
name: "sts-rootcanal-sidebins",
src: "empty.sh",
test_suites: [
@@ -132,13 +269,18 @@
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("sh_test", "sts-rootcanal-sidebins", AttrNameToString{
- "srcs": `["empty.sh"]`,
+ "srcs": `["empty.sh"]`,
+ "runs_on": `["device"]`,
"data": `[
"android.hardware.bluetooth@1.1-service.sim.rc",
- "android.hardware.bluetooth@1.1-service.sim",
- "android.hardware.bluetooth@1.1-impl-sim",
- "libc++",
- "libcrypto",
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ":libc++",
+ ":libcrypto",
+ ]`,
+ "data_bins": `[
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
]`,
"tags": `["no-remote"]`,
})},
@@ -146,11 +288,18 @@
}
func TestShTestHostSimpleUnset(t *testing.T) {
- RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{
+ RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ }, Bp2buildTestCase{
Description: "sh_test_host test",
ModuleTypeUnderTest: "sh_test_host",
ModuleTypeUnderTestFactory: sh.ShTestHostFactory,
- Blueprint: `sh_test_host{
+ StubbedBuildDefinitions: []string{"android.hardware.bluetooth@1.1-service.sim",
+ "android.hardware.bluetooth@1.1-impl-sim", "libc++", "libcrypto"},
+ Blueprint: simpleModule("filegroup", "android.hardware.bluetooth@1.1-service.sim") +
+ simpleModule("filegroup", "android.hardware.bluetooth@1.1-impl-sim") +
+ simpleModule("filegroup", "libc++") +
+ simpleModule("filegroup", "libcrypto") + `sh_test_host{
name: "sts-rootcanal-sidebins",
src: "empty.sh",
test_suites: [
@@ -168,13 +317,18 @@
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("sh_test", "sts-rootcanal-sidebins", AttrNameToString{
- "srcs": `["empty.sh"]`,
+ "srcs": `["empty.sh"]`,
+ "runs_on": `["host_without_device"]`,
"data": `[
"android.hardware.bluetooth@1.1-service.sim.rc",
- "android.hardware.bluetooth@1.1-service.sim",
- "android.hardware.bluetooth@1.1-impl-sim",
- "libc++",
- "libcrypto",
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
+ ":libc++",
+ ":libcrypto",
+ ]`,
+ "data_bins": `[
+ ":android.hardware.bluetooth@1.1-service.sim",
+ ":android.hardware.bluetooth@1.1-impl-sim",
]`,
"tags": `["no-remote"]`,
"target_compatible_with": `select({
diff --git a/bp2build/symlink_forest.go b/bp2build/symlink_forest.go
index 966b94a..15a6df0 100644
--- a/bp2build/symlink_forest.go
+++ b/bp2build/symlink_forest.go
@@ -22,7 +22,6 @@
"regexp"
"sort"
"strconv"
- "strings"
"sync"
"sync/atomic"
@@ -32,19 +31,12 @@
)
// A tree structure that describes what to do at each directory in the created
-// symlink tree. Currently it is used to enumerate which files/directories
+// symlink tree. Currently, it is used to enumerate which files/directories
// should be excluded from symlinking. Each instance of "node" represents a file
// or a directory. If excluded is true, then that file/directory should be
// excluded from symlinking. Otherwise, the node is not excluded, but one of its
// descendants is (otherwise the node in question would not exist)
-// This is a version int written to a file called symlink_forest_version at the root of the
-// symlink forest. If the version here does not match the version in the file, then we'll
-// clean the whole symlink forest and recreate it. This number can be bumped whenever there's
-// an incompatible change to the forest layout or a bug in incrementality that needs to be fixed
-// on machines that may still have the bug present in their forest.
-const symlinkForestVersion = 2
-
type instructionsNode struct {
name string
excluded bool // If false, this is just an intermediate node
@@ -193,7 +185,7 @@
srcPath := shared.JoinPath(topdir, src)
dstPath := shared.JoinPath(topdir, dst)
- // Check if a symlink already exists.
+ // Check whether a symlink already exists.
if dstInfo, err := os.Lstat(dstPath); err != nil {
if !os.IsNotExist(err) {
fmt.Fprintf(os.Stderr, "Failed to lstat '%s': %s", dst, err)
@@ -240,44 +232,49 @@
return false
}
-// maybeCleanSymlinkForest will remove the whole symlink forest directory if the version recorded
-// in the symlink_forest_version file is not equal to symlinkForestVersion.
-func maybeCleanSymlinkForest(topdir, forest string, verbose bool) error {
- versionFilePath := shared.JoinPath(topdir, forest, "symlink_forest_version")
- versionFileContents, err := os.ReadFile(versionFilePath)
- if err != nil && !os.IsNotExist(err) {
- return err
+// Returns the mtime of the soong_build binary to determine whether we should
+// force symlink_forest to re-execute
+func getSoongBuildMTime() (int64, error) {
+ binaryPath, err := os.Executable()
+ if err != nil {
+ return 0, err
}
- versionFileString := strings.TrimSpace(string(versionFileContents))
- symlinkForestVersionString := strconv.Itoa(symlinkForestVersion)
- if err != nil || versionFileString != symlinkForestVersionString {
- if verbose {
- fmt.Fprintf(os.Stderr, "Old symlink_forest_version was %q, current is %q. Cleaning symlink forest before recreating...\n", versionFileString, symlinkForestVersionString)
- }
- err = os.RemoveAll(shared.JoinPath(topdir, forest))
- if err != nil {
- return err
- }
+
+ info, err := os.Stat(binaryPath)
+ if err != nil {
+ return 0, err
}
- return nil
+
+ return info.ModTime().UnixMilli(), nil
}
-// maybeWriteVersionFile will write the symlink_forest_version file containing symlinkForestVersion
-// if it doesn't exist already. If it exists we know it must contain symlinkForestVersion because
-// we checked for that already in maybeCleanSymlinkForest
-func maybeWriteVersionFile(topdir, forest string) error {
- versionFilePath := shared.JoinPath(topdir, forest, "symlink_forest_version")
- _, err := os.Stat(versionFilePath)
+// cleanSymlinkForest will remove the whole symlink forest directory
+func cleanSymlinkForest(topdir, forest string) error {
+ return os.RemoveAll(shared.JoinPath(topdir, forest))
+}
+
+// This returns whether symlink forest should clean and replant symlinks.
+// It compares the mtime of this executable with the mtime of the last-run
+// soong_build binary. If they differ, then we should clean and replant.
+func shouldCleanSymlinkForest(topdir string, forest string, soongBuildMTime int64) (bool, error) {
+ mtimeFilePath := shared.JoinPath(topdir, forest, "soong_build_mtime")
+ mtimeFileContents, err := os.ReadFile(mtimeFilePath)
if err != nil {
- if !os.IsNotExist(err) {
- return err
- }
- err = os.WriteFile(versionFilePath, []byte(strconv.Itoa(symlinkForestVersion)+"\n"), 0666)
- if err != nil {
- return err
+ if os.IsNotExist(err) {
+ // This is likely the first time this has run with this functionality - clean away!
+ return true, nil
+ } else {
+ return false, err
}
}
- return nil
+ return strconv.FormatInt(soongBuildMTime, 10) != string(mtimeFileContents), nil
+}
+
+func writeSoongBuildMTimeFile(topdir, forest string, mtime int64) error {
+ mtimeFilePath := shared.JoinPath(topdir, forest, "soong_build_mtime")
+ contents := []byte(strconv.FormatInt(mtime, 10))
+
+ return os.WriteFile(mtimeFilePath, contents, 0666)
}
// Recursively plants a symlink forest at forestDir. The symlink tree will
@@ -473,12 +470,26 @@
symlinkCount: atomic.Uint64{},
}
- err := maybeCleanSymlinkForest(topdir, forest, verbose)
+ // Check whether soong_build has been modified since the last run
+ soongBuildMTime, err := getSoongBuildMTime()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
+ shouldClean, err := shouldCleanSymlinkForest(topdir, forest, soongBuildMTime)
+
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ } else if shouldClean {
+ err = cleanSymlinkForest(topdir, forest)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ }
+
instructions := instructionsFromExcludePathList(exclude)
go func() {
context.wg.Add(1)
@@ -491,11 +502,10 @@
deps = append(deps, dep)
}
- err = maybeWriteVersionFile(topdir, forest)
+ err = writeSoongBuildMTimeFile(topdir, forest, soongBuildMTime)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
-
return deps, context.mkdirCount.Load(), context.symlinkCount.Load()
}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 6907487..763cccc 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -124,12 +124,6 @@
// be merged with the generated BUILD file. This allows custom BUILD targets
// to be used in tests, or use BUILD files to draw package boundaries.
KeepBuildFileForDirs []string
-
- // If true, the bp2build_deps mutator is used for this test. This is an
- // experimental mutator that will disable modules which have transitive
- // dependencies with no bazel definition.
- // TODO: b/285631638 - Enable this feature by default.
- DepsMutator bool
}
func RunBp2BuildTestCaseExtraContext(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), modifyContext func(ctx *android.TestContext), tc Bp2buildTestCase) {
@@ -140,11 +134,6 @@
if modifyContext != nil {
preparers = append(preparers, android.FixtureModifyContext(modifyContext))
}
- if tc.DepsMutator {
- preparers = append(preparers, android.FixtureModifyConfig(func(cfg android.Config) {
- cfg.Bp2buildDepsMutator = true
- }))
- }
preparers = append(preparers, SetBp2BuildTestRunner)
bp2buildSetup := android.GroupFixturePreparers(
preparers...,
diff --git a/cc/afdo.go b/cc/afdo.go
index 23d196d..5c587c0 100644
--- a/cc/afdo.go
+++ b/cc/afdo.go
@@ -84,6 +84,7 @@
// 3. Make the profile searchable by the build system. So it's used the next time the binary
// is built.
flags.Local.CFlags = append([]string{"-funique-internal-linkage-names"}, flags.Local.CFlags...)
+ flags.Local.CFlags = append([]string{"-mllvm", "-enable-fs-discriminator=true"}, flags.Local.CFlags...)
}
if path := afdo.Properties.FdoProfilePath; path != nil {
// The flags are prepended to allow overriding.
diff --git a/cc/cc_test.go b/cc/cc_test.go
index f7eb8d2..794c5ee 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -677,6 +677,7 @@
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("29")
config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
+ config.TestProductVariables.KeepVndk = BoolPtr(true)
setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"})
diff --git a/cc/library.go b/cc/library.go
index 90d91ca..2161512 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -468,12 +468,16 @@
android.CommonAttributes{
Name: m.Name() + "_bp2build_cc_library_static",
Tags: tagsForStaticVariant,
+ // TODO: b/303307456 - Remove this when data is properly supported in cc rules.
+ SkipData: proptools.BoolPtr(true),
},
staticTargetAttrs, staticAttrs.Enabled)
ctx.CreateBazelTargetModuleWithRestrictions(sharedProps,
android.CommonAttributes{
Name: m.Name(),
Tags: tagsForSharedVariant,
+ // TODO: b/303307456 - Remove this when data is properly supported in cc rules.
+ SkipData: proptools.BoolPtr(true),
},
sharedTargetAttrs, sharedAttrs.Enabled)
@@ -496,8 +500,15 @@
Deps: baseAttributes.deps,
Api_surface: proptools.StringPtr("module-libapi"),
}
- ctx.CreateBazelTargetModule(stubSuitesProps,
- android.CommonAttributes{Name: m.Name() + "_stub_libs"},
+ if _, isNdk := ctx.ModuleFromName(m.Name() + ".ndk"); isNdk {
+ stubSuitesAttrs.Included_in_ndk = proptools.BoolPtr(true)
+ }
+
+ ctx.CreateBazelTargetModule(stubSuitesProps, android.CommonAttributes{
+ Name: m.Name() + "_stub_libs",
+ // TODO: b/303307456 - Remove this when data is properly supported in cc rules.
+ SkipData: proptools.BoolPtr(true),
+ },
stubSuitesAttrs)
// Add alias for the stub shared_library in @api_surfaces repository
@@ -2935,7 +2946,12 @@
tags := android.ApexAvailableTagsWithoutTestApexes(ctx, module)
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name(), Tags: tags}, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{
+ Name: module.Name(),
+ Tags: tags,
+ // TODO: b/303307456 - Remove this when data is properly supported in cc rules.
+ SkipData: proptools.BoolPtr(true),
+ }, attrs)
}
type includesAttributes struct {
@@ -3011,6 +3027,13 @@
Soname *string
Deps bazel.LabelListAttribute
Api_surface *string
+
+ // Unless the library is in the NDK, module-libapi stubs should *not* include the public symbols
+ // Soong uses a global variable to determine if the library is in the NDK
+ // Since Bazel does not have global analysis, create an explicit property
+ // This property is only relevant if `api_surface = module-libapi`
+ // https://cs.android.com/android/_/android/platform/build/soong/+/main:cc/library.go;l=1214-1219;drc=7123cc5370a38983ee6325b5f5f6df19f4e4f10b;bpv=1;bpt=0
+ Included_in_ndk *bool
}
type bazelCcHeaderAbiCheckerAttributes struct {
diff --git a/cc/lto.go b/cc/lto.go
index df9ca0a..d48be14 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -35,11 +35,11 @@
// optimized at link time and may not be compatible with features that require
// LTO, such as CFI.
//
-// This file adds support to soong to automatically propogate LTO options to a
+// This file adds support to soong to automatically propagate LTO options to a
// new variant of all static dependencies for each module with LTO enabled.
type LTOProperties struct {
- // Lto must violate capitialization style for acronyms so that it can be
+ // Lto must violate capitalization style for acronyms so that it can be
// referred to in blueprint files as "lto"
Lto struct {
Never *bool `android:"arch_variant"`
@@ -67,10 +67,12 @@
}
func (lto *lto) begin(ctx BaseModuleContext) {
- // First, determine the module indepedent default LTO mode.
- ltoDefault := GlobalThinLTO(ctx)
+ // First, determine the module independent default LTO mode.
+ ltoDefault := true
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
ltoDefault = false
+ } else if lto.Never() {
+ ltoDefault = false
} else if ctx.Host() {
// Performance and binary size are less important for host binaries.
ltoDefault = false
@@ -161,10 +163,6 @@
return lto != nil && proptools.Bool(lto.Properties.Lto.Never)
}
-func GlobalThinLTO(ctx android.BaseModuleContext) bool {
- return !ctx.Config().IsEnvFalse("GLOBAL_THINLTO")
-}
-
// Propagate lto requirements down from binaries
func ltoDepsMutator(mctx android.TopDownMutatorContext) {
if m, ok := mctx.Module().(*Module); ok {
@@ -203,8 +201,6 @@
// Create lto variants for modules that need them
func ltoMutator(mctx android.BottomUpMutatorContext) {
- globalThinLTO := GlobalThinLTO(mctx)
-
if m, ok := mctx.Module().(*Module); ok && m.lto != nil {
// Create variations for LTO types required as static
// dependencies
@@ -216,10 +212,10 @@
variationNames = append(variationNames, "lto-none")
}
- if globalThinLTO && !m.lto.Properties.LtoEnabled {
+ if !m.lto.Properties.LtoEnabled {
mctx.SetDependencyVariation("lto-none")
}
- if !globalThinLTO && m.lto.Properties.LtoEnabled {
+ if m.lto.Properties.LtoEnabled {
mctx.SetDependencyVariation("lto-thin")
}
diff --git a/cc/lto_test.go b/cc/lto_test.go
index e0afd4a..7b7fe8c 100644
--- a/cc/lto_test.go
+++ b/cc/lto_test.go
@@ -23,11 +23,19 @@
"github.com/google/blueprint"
)
-var NoGlobalThinLTOPreparer = android.GroupFixturePreparers(
+var LTOPreparer = android.GroupFixturePreparers(
prepareForCcTest,
- android.FixtureModifyEnv(func(env map[string]string) {
- env["GLOBAL_THINLTO"] = "false"
- }))
+)
+
+func hasDep(result *android.TestResult, m android.Module, wantDep android.Module) bool {
+ var found bool
+ result.VisitDirectDeps(m, func(dep blueprint.Module) {
+ if dep == wantDep {
+ found = true
+ }
+ })
+ return found
+}
func TestThinLtoDeps(t *testing.T) {
t.Parallel()
@@ -37,9 +45,6 @@
srcs: ["src.c"],
static_libs: ["foo", "lib_never_lto"],
shared_libs: ["bar"],
- lto: {
- thin: true,
- }
}
cc_library_static {
name: "foo",
@@ -63,50 +68,40 @@
}
`
- result := NoGlobalThinLTOPreparer.RunTestWithBp(t, bp)
+ result := LTOPreparer.RunTestWithBp(t, bp)
libLto := result.ModuleForTests("lto_enabled", "android_arm64_armv8-a_shared").Module()
- hasDep := func(m android.Module, wantDep android.Module) bool {
- var found bool
- result.VisitDirectDeps(m, func(dep blueprint.Module) {
- if dep == wantDep {
- found = true
- }
- })
- return found
+ libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static").Module()
+ if !hasDep(result, libLto, libFoo) {
+ t.Errorf("'lto_enabled' missing dependency on the default variant of 'foo'")
}
- libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static_lto-thin").Module()
- if !hasDep(libLto, libFoo) {
- t.Errorf("'lto_enabled' missing dependency on thin lto variant of 'foo'")
+ libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static").Module()
+ if !hasDep(result, libFoo, libBaz) {
+ t.Errorf("'foo' missing dependency on the default variant of transitive dep 'baz'")
}
- libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin").Module()
- if !hasDep(libFoo, libBaz) {
- t.Errorf("'foo' missing dependency on thin lto variant of transitive dep 'baz'")
- }
-
- libNeverLto := result.ModuleForTests("lib_never_lto", "android_arm64_armv8-a_static_lto-thin").Module()
- if !hasDep(libLto, libNeverLto) {
- t.Errorf("'lto_enabled' missing dependency on NO-thin lto variant of 'lib_never_lto'")
+ libNeverLto := result.ModuleForTests("lib_never_lto", "android_arm64_armv8-a_static").Module()
+ if !hasDep(result, libLto, libNeverLto) {
+ t.Errorf("'lto_enabled' missing dependency on the default variant of 'lib_never_lto'")
}
libBar := result.ModuleForTests("bar", "android_arm64_armv8-a_shared").Module()
- if !hasDep(libLto, libBar) {
- t.Errorf("'lto_enabled' missing dependency on non-thin lto variant of 'bar'")
+ if !hasDep(result, libLto, libBar) {
+ t.Errorf("'lto_enabled' missing dependency on the default variant of 'bar'")
}
barVariants := result.ModuleVariantsForTests("bar")
for _, v := range barVariants {
- if strings.Contains(v, "lto-thin") {
- t.Errorf("Expected variants for 'bar' to not contain 'lto-thin', but found %q", v)
+ if strings.Contains(v, "lto-none") {
+ t.Errorf("Expected variants for 'bar' to not contain 'lto-none', but found %q", v)
}
}
quxVariants := result.ModuleVariantsForTests("qux")
for _, v := range quxVariants {
- if strings.Contains(v, "lto-thin") {
- t.Errorf("Expected variants for 'qux' to not contain 'lto-thin', but found %q", v)
+ if strings.Contains(v, "lto-none") {
+ t.Errorf("Expected variants for 'qux' to not contain 'lto-none', but found %q", v)
}
}
}
@@ -141,28 +136,18 @@
}
`
- result := NoGlobalThinLTOPreparer.RunTestWithBp(t, bp)
+ result := LTOPreparer.RunTestWithBp(t, bp)
libRoot := result.ModuleForTests("root", "android_arm64_armv8-a_shared").Module()
libRootLtoNever := result.ModuleForTests("root_no_lto", "android_arm64_armv8-a_shared").Module()
- hasDep := func(m android.Module, wantDep android.Module) bool {
- var found bool
- result.VisitDirectDeps(m, func(dep blueprint.Module) {
- if dep == wantDep {
- found = true
- }
- })
- return found
- }
-
libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static")
- if !hasDep(libRoot, libFoo.Module()) {
- t.Errorf("'root' missing dependency on thin lto variant of 'foo'")
+ if !hasDep(result, libRoot, libFoo.Module()) {
+ t.Errorf("'root' missing dependency on the default variant of 'foo'")
}
- if !hasDep(libRootLtoNever, libFoo.Module()) {
- t.Errorf("'root_no_lto' missing dependency on thin lto variant of 'foo'")
+ if !hasDep(result, libRootLtoNever, libFoo.Module()) {
+ t.Errorf("'root_no_lto' missing dependency on the default variant of 'foo'")
}
libFooCFlags := libFoo.Rule("cc").Args["cFlags"]
@@ -170,9 +155,9 @@
t.Errorf("'foo' expected to have flags %q, but got %q", w, libFooCFlags)
}
- libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin")
- if !hasDep(libFoo.Module(), libBaz.Module()) {
- t.Errorf("'foo' missing dependency on thin lto variant of transitive dep 'baz'")
+ libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static")
+ if !hasDep(result, libFoo.Module(), libBaz.Module()) {
+ t.Errorf("'foo' missing dependency on the default variant of transitive dep 'baz'")
}
libBazCFlags := libFoo.Rule("cc").Args["cFlags"]
@@ -199,7 +184,7 @@
},
},
}`
- result := NoGlobalThinLTOPreparer.RunTestWithBp(t, bp)
+ result := LTOPreparer.RunTestWithBp(t, bp)
libFooWithLto := result.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
libFooWithoutLto := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
@@ -227,7 +212,7 @@
},
}`
- result := NoGlobalThinLTOPreparer.RunTestWithBp(t, bp)
+ result := LTOPreparer.RunTestWithBp(t, bp)
libFoo := result.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
libBar := result.ModuleForTests("runtime_libbar", "android_arm_armv7-a-neon_shared").Rule("ld")
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 2064b1b..df775de 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -61,7 +61,7 @@
// because we don't want to spam the build output with "nothing
// changed" messages, so redirect output message to $out, and if
// changes were detected print the output and fail.
- Command: "$stgdiff $args --stg $in -o $out || (cat $out && false; echo 'Run $$ANDROID_BUILD_TOP/development/tools/ndk/update_ndk_abi.sh to update the ABI dumps.')",
+ Command: "$stgdiff $args --stg $in -o $out || (cat $out && echo 'Run $$ANDROID_BUILD_TOP/development/tools/ndk/update_ndk_abi.sh to update the ABI dumps.' && false)",
CommandDeps: []string{"$stgdiff"},
}, "args")
@@ -594,9 +594,10 @@
symbolFileLabel := android.BazelLabelForModuleSrcSingle(ctx, proptools.String(ndk.properties.Symbol_file))
attrs := &bazelCcStubSuiteAttributes{
// TODO - b/300504837 Add ndk headers
- Symbol_file: proptools.StringPtr(symbolFileLabel.Label),
- Soname: proptools.StringPtr(sourceLibraryName + ".so"),
- Api_surface: proptools.StringPtr(android.PublicApi.String()),
+ Symbol_file: proptools.StringPtr(symbolFileLabel.Label),
+ Soname: proptools.StringPtr(sourceLibraryName + ".so"),
+ Api_surface: proptools.StringPtr(android.PublicApi.String()),
+ Included_in_ndk: proptools.BoolPtr(true),
}
if sourceLibrary, exists := ctx.ModuleFromName(sourceLibraryName); exists {
// the source library might not exist in minimal/unbuildable branches like kernel-build-tools.
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 6329e97..6624d4b 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -86,7 +86,7 @@
memtagStackCommonFlags = []string{"-march=armv8-a+memtag", "-mllvm", "-dom-tree-reachability-max-bbs-to-explore=128"}
hostOnlySanitizeFlags = []string{"-fno-sanitize-recover=all"}
- deviceOnlySanitizeFlags = []string{"-fsanitize-trap=all", "-ftrap-function=abort"}
+ deviceOnlySanitizeFlags = []string{"-fsanitize-trap=all"}
noSanitizeLinkRuntimeFlag = "-fno-sanitize-link-runtime"
)
diff --git a/cc/test.go b/cc/test.go
index f128187..5b778dc 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -25,7 +25,6 @@
"android/soong/bazel"
"android/soong/bazel/cquery"
"android/soong/tradefed"
- "android/soong/ui/metrics/bp2build_metrics_proto"
)
// TestLinkerProperties properties to be registered via the linker
@@ -719,13 +718,6 @@
combinedData.Append(android.BazelLabelForModuleDeps(ctx, p.Data_libs))
data.SetSelectValue(axis, config, combinedData)
tags.SetSelectValue(axis, config, p.Test_options.Tags)
-
- // TODO: b/300117121 - handle bp2build conversion of non-unit tests
- // default to true to only handle non-nil falses
- if !BoolDefault(p.Test_options.Unit_test, true) {
- ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "Host unit_test = false")
- return
- }
}
}
}
diff --git a/docs/clion.md b/docs/clion.md
index d6ae19a..110891b 100644
--- a/docs/clion.md
+++ b/docs/clion.md
@@ -3,6 +3,10 @@
Soong can generate CLion projects. This is intended for source code editing
only. Build should still be done via make/m/mm(a)/mmm(a).
+Note: alternatively, you can use
+[aidegen to generate a Clion or VSCode project](https://android.googlesource.com/platform/tools/asuite/+/refs/heads/master/aidegen/README.md)
+with a single command, using the `-i c` flag.
+
CMakeLists.txt project file generation is enabled via environment variable:
```bash
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index afa52cc..9647a18 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -17,6 +17,7 @@
var (
DepfileAllowList = []string{
"depfile_allowed_for_test",
+ "tflite_support_metadata_schema",
"tflite_support_spm_config",
"tflite_support_spm_encoder_config",
"gen_uwb_core_proto",
@@ -135,10 +136,132 @@
"ltp_config_arm_64_lowmem_hwasan",
"ltp_config_x86",
"libbssl_sys_src_nostd",
+ "libcore-non-cts-tests-txt",
+ "ControlEnvProxyServerProto_cc",
+ "ControlEnvProxyServerProto_h",
+ "camera-its",
+ "android-cts-verifier",
+ "CtsApkVerityTestDebugFiles",
+ "vm-tests-tf-lib",
+ "egl_extensions_functions_hdr",
+ "egl_functions_hdr",
+ "gles1_core_functions_hdr",
+ "gles1_extensions_functions_hdr",
+ "gles2_core_functions_hdr",
+ "gles2_extensions_functions_hdr",
+ "gles31_only_functions_hdr",
+ "gles3_only_functions_hdr",
+ "angle_commit_id",
+ "deqp_spvtools_update_build_version",
+ "emp_ematch.yacc.c",
+ "emp_ematch.yacc.h",
+ "libchrome-crypto-include",
+ "libchrome-include",
+ "libmojo_jni_headers",
+ "libxml2_schema_fuzz_corpus",
+ "libxml2_xml_fuzz_corpus",
+ "libc_musl_sysroot_bits",
+ "awkgram.tab.h",
+ "openwrt_rootfs_combined_aarch64",
+ "openwrt_rootfs_combined_x86_64",
+ "openwrt_rootfs_customization_aarch64",
+ "openwrt_rootfs_customization_x86_64",
+ "pandora-python-gen-src",
+ "pdl_cxx_canonical_be_src_gen",
+ "pdl_cxx_canonical_be_test_gen",
+ "pdl_cxx_canonical_le_src_gen",
+ "pdl_cxx_canonical_le_test_gen",
+ "pdl_python_generator_be_test_gen",
+ "pdl_python_generator_le_test_gen",
+ "pdl_rust_noalloc_le_test_backend_srcs",
+ "pdl_rust_noalloc_le_test_gen_harness",
+ "swiftshader_spvtools_update_build_version",
+ "uwb_core_artifacts",
+ "futility_cmds",
+ "MultiDexLegacyTestApp_genrule",
+ "com.android.overlaytest.overlaid.pem",
+ "com.android.overlaytest.overlaid.pubkey",
+ "com.android.overlaytest.overlay.pem",
+ "com.android.overlaytest.overlay.pubkey",
+ "wm_shell_protolog_src",
+ "services.core.protologsrc",
+ "PackageManagerServiceServerTests_apks_as_resources",
+ "wmtests.protologsrc",
+ "com.android.apex.apkrollback.test.pem",
+ "com.android.apex.apkrollback.test.pubkey",
+ "UpdatableSystemFontTest_NotoColorEmojiV0.sig",
+ "UpdatableSystemFontTest_NotoColorEmojiV0.ttf",
+ "UpdatableSystemFontTest_NotoColorEmojiVPlus1.sig",
+ "UpdatableSystemFontTest_NotoColorEmojiVPlus1.ttf",
+ "UpdatableSystemFontTest_NotoColorEmojiVPlus2.sig",
+ "UpdatableSystemFontTest_NotoColorEmojiVPlus2.ttf",
+ "temp_layoutlib",
+ "android-support-multidex-instrumentation-version",
+ "android-support-multidex-version",
+ "core-tests-smali-dex",
+ "gd_hci_packets_python3_gen",
+ "gd_smp_packets_python3_gen",
+ "bluetooth_core_rust_packets",
+ "HeadlessBuildTimestamp",
+ "hci_packets_python3_gen",
+ "link_layer_packets_python3_gen",
+ "llcp_packets_python3_gen",
+ "rootcanal_bredr_bb_packets_cxx_gen",
+ "rootcanal_hci_packets_cxx_gen",
+ "rootcanal_link_layer_packets_cxx_gen",
+ "authfs_test_apk_assets",
+ "measure_io_as_jar",
+ "statsd-config-protos",
+ "statsd-config-protos",
+ "sample-profile-text-protos",
+ "sample-profile-text-protos",
+ "lib-test-profile-text-protos",
+ "lib-test-profile-text-protos",
+ "common-profile-text-protos",
+ "common-profile-text-protos",
+ "vndk_abi_dump_zip",
+ "r8retrace-dexdump-sample-app",
+ "gen_key_mismatch_capex",
+ "gen_corrupt_rebootless_apex",
+ "gen_corrupt_superblock_apex",
+ "gen_manifest_mismatch_apex_no_hashtree",
+ "apexer_test_host_tools",
+ "com.android.apex.cts.shim.debug.pem",
+ "com.android.apex.cts.shim.debug.pubkey",
+ "com.android.apex.cts.shim.pem",
+ "com.android.apex.cts.shim.pubkey",
+ "com.android.apex.cts.shim.v2_no_pb",
+ "com.android.apex.cts.shim.v2_signed_bob",
+ "com.android.apex.cts.shim.v2_signed_bob_rot",
+ "com.android.apex.cts.shim.v2_signed_bob_rot_rollback",
+ "com.android.apex.cts.shim.v2_unsigned_apk_container",
+ "com.android.apex.cts.shim.v3_signed_bob",
+ "com.android.apex.cts.shim.v3_signed_bob_rot",
+ "com.android.apex.cts.shim_not_pre_installed.pem",
+ "com.android.apex.cts.shim_not_pre_installed.pubkey",
+ "com.android.apex.rotation.key.bob.pem",
+ "com.android.apex.rotation.key.bob.pk8",
+ "com.android.apex.rotation.key.bob.rot.rollback",
+ "com.android.apex.rotation.key.bob.rot",
+ "com.android.apex.rotation.key.bob.x509.pem",
+ "generate_hash_v1",
+ "ue_unittest_erofs_imgs",
+ "ue_unittest_erofs_imgs",
+ "ue_unittest_erofs_imgs",
+ "vts_vndk_abi_dump_zip",
+ "atest_integration_fake_src",
+ "VehicleServerProtoStub_cc@2.0-grpc-trout",
+ "VehicleServerProtoStub_cc@default-grpc",
+ "VehicleServerProtoStub_h@default-grpc",
+ "VehicleServerProtoStub_h@2.0-grpc-trout",
+ "chre_atoms_log.h",
+ "checkIn-service-stub-lite",
+ "seller-frontend-service-stub-lite",
}
SandboxingDenyPathList = []string{
"art/test",
"external/perfetto",
+ "external/cronet",
}
)
diff --git a/java/androidmk.go b/java/androidmk.go
index b7e2d2f..97b303d 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -20,6 +20,8 @@
"strings"
"android/soong/android"
+
+ "github.com/google/blueprint/proptools"
)
func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
@@ -79,7 +81,7 @@
} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
// Platform variant. If not available for the platform, we don't need Make module.
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
- } else if library.properties.Headers_only {
+ } else if proptools.Bool(library.properties.Headers_only) {
// If generating headers only then don't expose to Make.
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
} else {
diff --git a/java/base.go b/java/base.go
index c685fba..03198b5 100644
--- a/java/base.go
+++ b/java/base.go
@@ -134,7 +134,7 @@
// supported at compile time. It should only be needed to compile tests in
// packages that exist in libcore and which are inconvenient to move
// elsewhere.
- Patch_module *string `android:"arch_variant"`
+ Patch_module *string
Jacoco struct {
// List of classes to include for instrumentation with jacoco to collect coverage
@@ -194,7 +194,7 @@
Generated_srcjars []android.Path `android:"mutated"`
// If true, then only the headers are built and not the implementation jar.
- Headers_only bool
+ Headers_only *bool
}
// Properties that are specific to device modules. Host module factories should not add these when
@@ -582,7 +582,7 @@
func (j *Module) checkHeadersOnly(ctx android.ModuleContext) {
if _, ok := ctx.Module().(android.SdkContext); ok {
- headersOnly := proptools.Bool(&j.properties.Headers_only)
+ headersOnly := proptools.Bool(j.properties.Headers_only)
installable := proptools.Bool(j.properties.Installable)
if headersOnly && installable {
@@ -1180,7 +1180,7 @@
flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)
// If compiling headers then compile them and skip the rest
- if j.properties.Headers_only {
+ if proptools.Bool(j.properties.Headers_only) {
if srcFiles.HasExt(".kt") {
ctx.ModuleErrorf("Compiling headers_only with .kt not supported")
}
diff --git a/java/java.go b/java/java.go
index 2a3da93..35fd7c2 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1693,6 +1693,12 @@
// Version of previously released API file for compatibility check.
Previous_api *string `android:"path"`
+
+ // java_system_modules module providing the jar to be added to the
+ // bootclasspath when compiling the stubs.
+ // The jar will also be passed to metalava as a classpath to
+ // generate compilable stubs.
+ System_modules *string
}
func ApiLibraryFactory() android.Module {
@@ -1712,7 +1718,8 @@
}
func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
- srcs android.Paths, homeDir android.WritablePath) *android.RuleBuilderCommand {
+ srcs android.Paths, homeDir android.WritablePath,
+ classpath android.Paths) *android.RuleBuilderCommand {
rule.Command().Text("rm -rf").Flag(homeDir.String())
rule.Command().Text("mkdir -p").Flag(homeDir.String())
@@ -1751,12 +1758,17 @@
FlagWithArg("--hide ", "InvalidNullabilityOverride").
FlagWithArg("--hide ", "ChangedDefault")
- // The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
- // classes on the classpath when an API file contains missing classes. However, as this command
- // does not specify `--classpath` this is not needed for that. However, this is also used as a
- // signal to the special metalava code for generating stubs from text files that it needs to add
- // some additional items into the API (e.g. default constructors).
- cmd.FlagWithArg("--api-class-resolution ", "api")
+ if len(classpath) == 0 {
+ // The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
+ // classes on the classpath when an API file contains missing classes. However, as this command
+ // does not specify `--classpath` this is not needed for that. However, this is also used as a
+ // signal to the special metalava code for generating stubs from text files that it needs to add
+ // some additional items into the API (e.g. default constructors).
+ cmd.FlagWithArg("--api-class-resolution ", "api")
+ } else {
+ cmd.FlagWithArg("--api-class-resolution ", "api:classpath")
+ cmd.FlagWithInputList("--classpath ", classpath, ":")
+ }
return cmd
}
@@ -1819,6 +1831,9 @@
if al.properties.Full_api_surface_stub != nil {
ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Full_api_surface_stub))
}
+ if al.properties.System_modules != nil {
+ ctx.AddVariationDependencies(nil, systemModulesTag, String(al.properties.System_modules))
+ }
}
// Map where key is the api scope name and value is the int value
@@ -1858,6 +1873,7 @@
var classPaths android.Paths
var staticLibs android.Paths
var depApiSrcsStubsJar android.Path
+ var systemModulesPaths android.Paths
ctx.VisitDirectDeps(func(dep android.Module) {
tag := ctx.OtherModuleDependencyTag(dep)
switch tag {
@@ -1876,6 +1892,9 @@
case depApiSrcsTag:
provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
depApiSrcsStubsJar = provider.HeaderJars[0]
+ case systemModulesTag:
+ module := dep.(SystemModulesProvider)
+ systemModulesPaths = append(systemModulesPaths, module.HeaderJars()...)
}
})
@@ -1889,7 +1908,7 @@
ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
}
- cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)
+ cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths)
al.stubsFlags(ctx, cmd, stubsDir)
@@ -1921,6 +1940,7 @@
flags.javaVersion = getStubsJavaVersion()
flags.javacFlags = strings.Join(al.properties.Javacflags, " ")
flags.classpath = classpath(classPaths)
+ flags.bootClasspath = classpath(systemModulesPaths)
annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar")
diff --git a/java/java_test.go b/java/java_test.go
index d51604a..6b8b735 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -2447,3 +2447,39 @@
"default/java/api/module-lib-current.txt default/java/api/system-server-current.txt"
android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag)
}
+
+func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("foo"),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.SetApiLibraries([]string{"foo"})
+ }),
+ android.FixtureMergeMockFs(
+ map[string][]byte{
+ "A.java": nil,
+ },
+ ),
+ ).RunTestWithBp(t, `
+ java_library {
+ name: "bar",
+ srcs: ["a.java"],
+ }
+ java_system_modules {
+ name: "baz",
+ libs: ["bar"],
+ }
+ java_sdk_library {
+ name: "foo",
+ srcs: ["A.java"],
+ system_modules: "baz",
+ }
+ `)
+ m := result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common")
+ manifest := m.Output("metalava.sbox.textproto")
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest)
+ manifestCommand := sboxProto.Commands[0].GetCommand()
+ classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/.intermediates/bar/android_common/turbine-combined/bar.jar"
+ android.AssertStringDoesContain(t, "command expected to contain classpath flag", manifestCommand, classPathFlag)
+}
diff --git a/java/proto.go b/java/proto.go
index 48adadc..c88d3d7 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -159,6 +159,8 @@
Sdk_version bazel.StringAttribute
Java_version bazel.StringAttribute
+
+ Plugin bazel.LabelAttribute
}
func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute, AdditionalProtoDeps bazel.LabelListAttribute) *bazel.Label {
@@ -189,12 +191,18 @@
ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
}
+ plugin := bazel.LabelAttribute{}
+ if m.protoProperties.Proto.Plugin != nil {
+ plugin.SetValue(android.BazelLabelForModuleDepSingle(ctx, "protoc-gen-"+*m.protoProperties.Proto.Plugin))
+ }
+
protoAttrs := &protoAttributes{
Deps: bazel.MakeLabelListAttribute(protoInfo.Proto_libs),
Transitive_deps: bazel.MakeLabelListAttribute(protoInfo.Transitive_proto_libs),
Additional_proto_deps: AdditionalProtoDeps,
Java_version: bazel.StringAttribute{Value: m.properties.Java_version},
Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version},
+ Plugin: plugin,
}
name := m.Name() + suffix
diff --git a/java/robolectric.go b/java/robolectric.go
index 0041af4..af56339 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -34,7 +34,7 @@
var robolectricDefaultLibs = []string{
"mockito-robolectric-prebuilt",
- "truth-prebuilt",
+ "truth",
// TODO(ccross): this is not needed at link time
"junitxml",
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e410a41..f72c608 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1837,6 +1837,7 @@
Libs []string
Static_libs []string
Full_api_surface_stub *string
+ System_modules *string
}{}
props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope))
@@ -1875,6 +1876,8 @@
props.Full_api_surface_stub = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + "_full.from-text")
}
+ props.System_modules = module.deviceProperties.System_modules
+
mctx.CreateModule(ApiLibraryFactory, &props)
}
diff --git a/java/testing.go b/java/testing.go
index 98bea7f..0b7e685 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -410,6 +410,7 @@
"stub-annotations",
"aconfig-annotations-lib",
+ "unsupportedappusage",
}
for _, extra := range extraModules {
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 8225df6..78ab771 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -635,6 +635,13 @@
case "+=":
asgn.flavor = asgnAppend
case "?=":
+ if _, ok := lhs.(*productConfigVariable); ok {
+ // Make sets all product configuration variables to empty strings before running product
+ // config makefiles. ?= will have no effect on a variable that has been assigned before,
+ // even if assigned to an empty string. So just skip emitting any code for this
+ // assignment.
+ return nil
+ }
asgn.flavor = asgnMaybeSet
default:
panic(fmt.Errorf("unexpected assignment type %s", a.Type))
@@ -941,6 +948,8 @@
func (ctx *parseContext) handleInclude(v *mkparser.Directive) []starlarkNode {
loadAlways := v.Name[0] != '-'
+ v.Args.TrimRightSpaces()
+ v.Args.TrimLeftSpaces()
return ctx.handleSubConfig(v, ctx.parseMakeString(v, v.Args), loadAlways, func(im inheritedModule) starlarkNode {
return &includeNode{im, loadAlways}
})
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 7e68026..0c4d213 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -193,6 +193,31 @@
},
{
+ desc: "Include with trailing whitespace",
+ mkname: "product.mk",
+ in: `
+# has a trailing whitespace after cfg.mk
+include vendor/$(foo)/cfg.mk
+`,
+ expected: `# has a trailing whitespace after cfg.mk
+load("//build/make/core:product_config.rbc", "rblf")
+load("//vendor/foo1:cfg.star|init", _cfg_init = "init")
+load("//vendor/bar/baz:cfg.star|init", _cfg1_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ _entry = {
+ "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init),
+ "vendor/bar/baz/cfg.mk": ("vendor/bar/baz/cfg", _cfg1_init),
+ }.get("vendor/%s/cfg.mk" % _foo)
+ (_varmod, _varmod_init) = _entry if _entry else (None, None)
+ if not _varmod_init:
+ rblf.mkerror("product.mk", "Cannot find %s" % ("vendor/%s/cfg.mk" % _foo))
+ _varmod_init(g, handle)
+`,
+ },
+
+ {
desc: "Synonymous inherited configurations",
mkname: "path/product.mk",
in: `
@@ -898,8 +923,6 @@
cfg["PRODUCT_LIST2"] += ["a"]
cfg["PRODUCT_LIST1"] += ["b"]
cfg["PRODUCT_LIST2"] += ["b"]
- if cfg.get("PRODUCT_LIST3") == None:
- cfg["PRODUCT_LIST3"] = ["a"]
cfg["PRODUCT_LIST1"] = ["c"]
g.setdefault("PLATFORM_LIST", [])
g["PLATFORM_LIST"] += ["x"]
@@ -941,9 +964,10 @@
PRODUCT_LIST2 ?= a $(PRODUCT_LIST2)
PRODUCT_LIST3 += a
-# Now doing them again should not have a setdefault because they've already been set
+# Now doing them again should not have a setdefault because they've already been set, except 2
+# which did not emit an assignment before
PRODUCT_LIST1 = a $(PRODUCT_LIST1)
-PRODUCT_LIST2 ?= a $(PRODUCT_LIST2)
+PRODUCT_LIST2 = a $(PRODUCT_LIST2)
PRODUCT_LIST3 += a
`,
expected: `# All of these should have a setdefault because they're self-referential and not defined before
@@ -954,18 +978,15 @@
rblf.setdefault(handle, "PRODUCT_LIST1")
cfg["PRODUCT_LIST1"] = (["a"] +
cfg.get("PRODUCT_LIST1", []))
- if cfg.get("PRODUCT_LIST2") == None:
- rblf.setdefault(handle, "PRODUCT_LIST2")
- cfg["PRODUCT_LIST2"] = (["a"] +
- cfg.get("PRODUCT_LIST2", []))
rblf.setdefault(handle, "PRODUCT_LIST3")
cfg["PRODUCT_LIST3"] += ["a"]
- # Now doing them again should not have a setdefault because they've already been set
+ # Now doing them again should not have a setdefault because they've already been set, except 2
+ # which did not emit an assignment before
cfg["PRODUCT_LIST1"] = (["a"] +
cfg["PRODUCT_LIST1"])
- if cfg.get("PRODUCT_LIST2") == None:
- cfg["PRODUCT_LIST2"] = (["a"] +
- cfg["PRODUCT_LIST2"])
+ rblf.setdefault(handle, "PRODUCT_LIST2")
+ cfg["PRODUCT_LIST2"] = (["a"] +
+ cfg.get("PRODUCT_LIST2", []))
cfg["PRODUCT_LIST3"] += ["a"]
`,
},
diff --git a/mk2rbc/variable.go b/mk2rbc/variable.go
index 0a26ed8..95e1f8e 100644
--- a/mk2rbc/variable.go
+++ b/mk2rbc/variable.go
@@ -109,14 +109,11 @@
}
emitAppend()
case asgnMaybeSet:
- gctx.writef("if cfg.get(%q) == None:", pcv.nam)
- gctx.indentLevel++
- gctx.newLine()
- if needsSetDefault {
- emitSetDefault()
- }
- emitAssignment()
- gctx.indentLevel--
+ // In mk2rbc.go we never emit a maybeSet assignment for product config variables, because
+ // they are set to empty strings before running product config.
+ panic("Should never get here")
+ default:
+ panic("Unknown assignment flavor")
}
gctx.setHasBeenAssigned(&pcv)
diff --git a/rust/bindgen.go b/rust/bindgen.go
index a80a587..ffe532f 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -124,18 +124,20 @@
ctx.PropertyErrorf("c_std", "c_std and cpp_std cannot both be defined at the same time.")
}
- if String(b.ClangProperties.Cpp_std) != "" {
+ if b.ClangProperties.Cpp_std != nil {
+ isCpp = true
if String(b.ClangProperties.Cpp_std) == "experimental" {
stdVersion = cc_config.ExperimentalCppStdVersion
- } else if String(b.ClangProperties.Cpp_std) == "default" {
+ } else if String(b.ClangProperties.Cpp_std) == "default" || String(b.ClangProperties.Cpp_std) == "" {
stdVersion = cc_config.CppStdVersion
} else {
stdVersion = String(b.ClangProperties.Cpp_std)
}
} else if b.ClangProperties.C_std != nil {
+ isCpp = false
if String(b.ClangProperties.C_std) == "experimental" {
stdVersion = cc_config.ExperimentalCStdVersion
- } else if String(b.ClangProperties.C_std) == "default" {
+ } else if String(b.ClangProperties.C_std) == "default" || String(b.ClangProperties.C_std) == "" {
stdVersion = cc_config.CStdVersion
} else {
stdVersion = String(b.ClangProperties.C_std)
diff --git a/rust/bindgen_test.go b/rust/bindgen_test.go
index 12cdb3c..0ba0ff8 100644
--- a/rust/bindgen_test.go
+++ b/rust/bindgen_test.go
@@ -115,7 +115,7 @@
ctx := testRust(t, `
rust_bindgen {
name: "libbindgen_cstd",
- wrapper_src: "src/any.h",
+ wrapper_src: "src/any.hpp",
crate_name: "bindgen",
stem: "libbindgen",
source_stem: "bindings",
@@ -141,6 +141,16 @@
if !strings.Contains(libbindgen_cppstd.Args["cflags"], "-std=foo") {
t.Errorf("cpp_std value not passed in to rust_bindgen as a clang flag")
}
+
+ // Make sure specifying cpp_std emits the '-x c++' flag
+ if !strings.Contains(libbindgen_cppstd.Args["cflags"], "-x c++") {
+ t.Errorf("Setting cpp_std should cause the '-x c++' flag to be emitted")
+ }
+
+ // Make sure specifying c_std omits the '-x c++' flag
+ if strings.Contains(libbindgen_cstd.Args["cflags"], "-x c++") {
+ t.Errorf("Setting c_std should not cause the '-x c++' flag to be emitted")
+ }
}
func TestBindgenDisallowedFlags(t *testing.T) {
diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go
index 564168b..6c021c7 100644
--- a/rust/config/arm64_device.go
+++ b/rust/config/arm64_device.go
@@ -54,6 +54,7 @@
strings.Join(rustFlags, " "))
}
+ ExportedVars.ExportStringListStaticVariable("DEVICE_ARM64_RUSTC_FLAGS", Arm64RustFlags)
}
type toolchainArm64 struct {
diff --git a/rust/config/global.go b/rust/config/global.go
index c37ac4e..4397d58 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -23,7 +23,7 @@
var (
pctx = android.NewPackageContext("android/soong/rust/config")
- exportedVars = android.NewExportedVariables(pctx)
+ ExportedVars = android.NewExportedVariables(pctx)
RustDefaultVersion = "1.72.0"
RustDefaultBase = "prebuilts/rust/"
@@ -111,9 +111,17 @@
pctx.StaticVariable("DeviceGlobalLinkFlags", strings.Join(deviceGlobalLinkFlags, " "))
- exportedVars.ExportStringStaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion)
- exportedVars.ExportStringListStaticVariable("GLOBAL_RUSTC_FLAGS", GlobalRustFlags)
- exportedVars.ExportStringListStaticVariable("LINUX_HOST_GLOBAL_LINK_FLAGS", LinuxHostGlobalLinkFlags)
+ ExportedVars.ExportStringStaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion)
+ ExportedVars.ExportStringListStaticVariable("GLOBAL_RUSTC_FLAGS", GlobalRustFlags)
+ ExportedVars.ExportStringListStaticVariable("LINUX_HOST_GLOBAL_LINK_FLAGS", LinuxHostGlobalLinkFlags)
+
+ ExportedVars.ExportStringListStaticVariable("DEVICE_GLOBAL_RUSTC_FLAGS", deviceGlobalRustFlags)
+ ExportedVars.ExportStringListStaticVariable("DEVICE_GLOBAL_LINK_FLAGS",
+ android.RemoveListFromList(deviceGlobalLinkFlags, []string{
+ // The cc_config flags are retrieved from cc_toolchain by rust rules.
+ "${cc_config.DeviceGlobalLldflags}",
+ "-B${cc_config.ClangBin}",
+ }))
}
func HostPrebuiltTag(config android.Config) string {
@@ -137,5 +145,5 @@
// BazelRustToolchainVars returns a string with
func BazelRustToolchainVars(config android.Config) string {
- return android.BazelToolchainVars(config, exportedVars)
+ return android.BazelToolchainVars(config, ExportedVars)
}
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 79a885f..2e869f4 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -575,12 +575,12 @@
}
type bazelShTestAttributes struct {
- Srcs bazel.LabelListAttribute
- Data bazel.LabelListAttribute
- Tags bazel.StringListAttribute
- Test_config *string
- Test_config_template *string
- Auto_gen_config *bool
+ Srcs bazel.LabelListAttribute
+ Data bazel.LabelListAttribute
+ Data_bins bazel.LabelListAttribute
+ Tags bazel.StringListAttribute
+ Runs_on bazel.StringListAttribute
+ tradefed.TestConfigAttributes
}
func (m *ShBinary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
@@ -615,28 +615,42 @@
srcs := bazel.MakeLabelListAttribute(
android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src}))
- combinedData := append(m.testProperties.Data, m.testProperties.Data_bins...)
- combinedData = append(combinedData, m.testProperties.Data_libs...)
+ dataBins := bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.testProperties.Data_bins))
- data := bazel.MakeLabelListAttribute(
- android.BazelLabelForModuleSrc(ctx, combinedData))
+ var combinedData bazel.LabelList
+ combinedData.Append(android.BazelLabelForModuleSrc(ctx, m.testProperties.Data))
+ combinedData.Append(android.BazelLabelForModuleDeps(ctx, m.testProperties.Data_bins))
+ combinedData.Append(android.BazelLabelForModuleDeps(ctx, m.testProperties.Data_libs))
+ data := bazel.MakeLabelListAttribute(combinedData)
tags := bazel.MakeStringListAttribute(
m.testProperties.Test_options.Tags)
- test_config := m.testProperties.Test_config
+ testConfigAttributes := tradefed.GetTestConfigAttributes(
+ ctx,
+ m.testProperties.Test_config,
+ []string{},
+ m.testProperties.Auto_gen_config,
+ m.testProperties.Test_suites,
+ m.testProperties.Test_config_template,
+ nil,
+ nil,
+ )
- test_config_template := m.testProperties.Test_config_template
+ unitTest := m.testProperties.Test_options.Unit_test
- auto_gen_config := m.testProperties.Auto_gen_config
+ runs_on := bazel.MakeStringListAttribute(android.RunsOn(
+ m.ModuleBase.HostSupported(),
+ m.ModuleBase.DeviceSupported(),
+ (unitTest != nil && *unitTest)))
attrs := &bazelShTestAttributes{
Srcs: srcs,
Data: data,
+ Data_bins: dataBins,
Tags: tags,
- Test_config: test_config,
- Test_config_template: test_config_template,
- Auto_gen_config: auto_gen_config,
+ Runs_on: runs_on,
+ TestConfigAttributes: testConfigAttributes,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index 223baa4..8045591 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -10,6 +10,7 @@
"$TOP/build/soong/tests/persistent_bazel_test.sh"
"$TOP/build/soong/tests/soong_test.sh"
"$TOP/build/soong/tests/stale_metrics_files_test.sh"
+"$TOP/build/soong/tests/symlink_forest_rerun_test.sh"
"$TOP/prebuilts/build-tools/linux-x86/bin/py3-cmd" "$TOP/build/bazel/ci/rbc_dashboard.py" aosp_arm64-userdebug
# The following tests build against the full source tree and don't rely on the
diff --git a/tests/symlink_forest_rerun_test.sh b/tests/symlink_forest_rerun_test.sh
new file mode 100755
index 0000000..74e779e
--- /dev/null
+++ b/tests/symlink_forest_rerun_test.sh
@@ -0,0 +1,43 @@
+#!/bin/bash -eu
+
+set -o pipefail
+
+# Tests that symlink forest will replant if soong_build has changed
+# Any change to the build system should trigger a rerun
+
+source "$(dirname "$0")/lib.sh"
+
+function test_symlink_forest_reruns {
+ setup
+
+ mkdir -p a
+ touch a/g.txt
+ cat > a/Android.bp <<'EOF'
+filegroup {
+ name: "g",
+ srcs: ["g.txt"],
+ }
+EOF
+
+ run_soong g
+
+ mtime=`cat out/soong/workspace/soong_build_mtime`
+ # rerun with no changes - ensure that it hasn't changed
+ run_soong g
+ newmtime=`cat out/soong/workspace/soong_build_mtime`
+ if [[ ! "$mtime" == "$mtime" ]]; then
+ fail "symlink forest reran when it shouldn't have"
+ fi
+
+ # change exit codes to force a soong_build rebuild.
+ sed -i 's/os.Exit(1)/os.Exit(2)/g' build/soong/bp2build/symlink_forest.go
+
+ run_soong g
+ newmtime=`cat out/soong/workspace/soong_build_mtime`
+ if [[ "$mtime" == "$newmtime" ]]; then
+ fail "symlink forest did not rerun when it should have"
+ fi
+
+}
+
+scan_and_run_tests