Merge "Have the sanitizers trap rather than abort." into main
diff --git a/README.md b/README.md
index 22daa95..5e9e04a 100644
--- a/README.md
+++ b/README.md
@@ -648,8 +648,8 @@
SOONG_DELVE=2345 SOONG_DELVE_STEPS='build,modulegraph' m
```
results in only `build` (main build step) and `modulegraph` being run in the debugger.
-The allowed step names are `api_bp2build`, `bp2build_files`, `bp2build_workspace`,
-`build`, `modulegraph`, `queryview`, `soong_docs`.
+The allowed step names are `bp2build_files`, `bp2build_workspace`, `build`,
+`modulegraph`, `queryview`, `soong_docs`.
Note setting or unsetting `SOONG_DELVE` causes a recompilation of `soong_build`. This
is because in order to debug the binary, it needs to be built with debug
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 6014deb..1e7bc5e 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -324,30 +324,31 @@
"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/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/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)
"platform_testing/libraries/annotations": Bp2BuildDefaultTrueRecursively,
"platform_testing/libraries/flag-helpers/libflagtest": Bp2BuildDefaultTrueRecursively,
@@ -524,7 +525,6 @@
}
Bp2buildModuleAlwaysConvertList = []string{
- "AconfigJavaHostTest",
// aconfig
"libonce_cell",
"libanyhow",
@@ -578,6 +578,7 @@
"tagsoup",
// framework-minus-apex
+ "AndroidFrameworkLintChecker",
"ImmutabilityAnnotationProcessor",
"debian.mime.types.minimized",
"framework-javastream-protos",
@@ -634,7 +635,6 @@
"libneuralnetworks",
"libneuralnetworks_static",
"libgraphicsenv",
- "libhardware",
"libhardware_headers",
"libnativeloader-headers",
"libnativewindow_headers",
@@ -673,6 +673,7 @@
// prebuilts
"prebuilt_stats-log-api-gen",
+ "prebuilt_aapt2",
// fastboot
"fastboot",
@@ -854,6 +855,7 @@
"kotlinx_coroutines",
"kotlinx_coroutines-device",
"kotlinx_coroutines-host",
+ "kotlinx_coroutines_android",
// for building com.android.neuralnetworks
"libimapper_stablec",
@@ -994,6 +996,7 @@
"tradefed-result-interfaces",
"tradefed-device-build-interfaces",
"tradefed-invocation-interfaces",
+ "tradefed-lib-core",
}
Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -1020,6 +1023,7 @@
"ndk_headers",
"ndk_library",
"sysprop_library",
+ "versioned_ndk_headers",
"xsd_config",
// go/keep-sorted end
}
@@ -1046,6 +1050,8 @@
"libfsverity_rs",
"libtombstoned_client_rust",
+ "libhardware", //Depends on unconverted libapexsupport
+
// TODO(b/263326760): Failed already.
"minijail_compiler_unittest",
"minijail_parser_unittest",
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/api_domain.go b/android/api_domain.go
index 0603c70..0a66c3d 100644
--- a/android/api_domain.go
+++ b/android/api_domain.go
@@ -14,20 +14,6 @@
package android
-import (
- "github.com/google/blueprint"
-
- "android/soong/bazel"
-)
-
-func init() {
- RegisterApiDomainBuildComponents(InitRegistrationContext)
-}
-
-func RegisterApiDomainBuildComponents(ctx RegistrationContext) {
- ctx.RegisterModuleType("api_domain", ApiDomainFactory)
-}
-
type ApiSurface int
// TODO(b/246656800): Reconcile with android.SdkKind
@@ -50,60 +36,3 @@
return "invalid"
}
}
-
-type apiDomain struct {
- ModuleBase
- BazelModuleBase
-
- properties apiDomainProperties
-}
-
-type apiDomainProperties struct {
- // cc library contributions (.h files/.map.txt) of this API domain
- // This dependency is a no-op in Soong, but the corresponding Bazel target in the api_bp2build workspace
- // will provide a `CcApiContributionInfo` provider
- Cc_api_contributions []string
-
- // java library contributions (as .txt) of this API domain
- // This dependency is a no-op in Soong, but the corresponding Bazel target in the api_bp2build workspace
- // will provide a `JavaApiContributionInfo` provider
- Java_api_contributions []string
-}
-
-func ApiDomainFactory() Module {
- m := &apiDomain{}
- m.AddProperties(&m.properties)
- InitAndroidArchModule(m, DeviceSupported, MultilibBoth)
- return m
-}
-
-// Do not create any dependency edges in Soong for now to skip visibility checks for some systemapi libraries.
-// Currently, all api_domain modules reside in build/orchestrator/apis/Android.bp
-// However, cc libraries like libsigchain (com.android.art) restrict their visibility to art/*
-// When the api_domain module types are collocated with their contributions, this dependency edge can be restored
-func (a *apiDomain) DepsMutator(ctx BottomUpMutatorContext) {
-}
-
-// API domain does not have any builld actions yet
-func (a *apiDomain) GenerateAndroidBuildActions(ctx ModuleContext) {
-}
-
-const (
- apiContributionSuffix = ".contribution"
-)
-
-// ApiContributionTargetName returns the name of the bp2build target (e.g. cc_api_contribution) of contribution modules (e.g. ndk_library)
-// A suffix is necessary to prevent a name collision with the base target in the same bp2build bazel package
-func ApiContributionTargetName(moduleName string) string {
- return moduleName + apiContributionSuffix
-}
-
-// For each contributing cc_library, format the name to its corresponding contribution bazel target in the bp2build workspace
-func contributionBazelAttributes(ctx TopDownMutatorContext, contributions []string) bazel.LabelListAttribute {
- addSuffix := func(ctx BazelConversionPathContext, module blueprint.Module) string {
- baseLabel := BazelModuleLabel(ctx, module)
- return ApiContributionTargetName(baseLabel)
- }
- bazelLabels := BazelLabelForModuleDepsWithFn(ctx, contributions, addSuffix)
- return bazel.MakeLabelListAttribute(bazelLabels)
-}
diff --git a/android/bazel.go b/android/bazel.go
index 5df12f0..b4e7ae5 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -625,7 +625,18 @@
ctx.BottomUp("bp2build_conversion", bp2buildConversionMutator).Parallel()
}
+func registerBp2buildDepsMutator(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("bp2build_deps", bp2buildDepsMutator).Parallel()
+}
+
func bp2buildConversionMutator(ctx BottomUpMutatorContext) {
+ // If an existing BUILD file in the module directory has a target defined
+ // with this same name as this module, assume that this is an existing
+ // definition for this target.
+ if ctx.Config().HasBazelBuildTargetInSource(ctx.ModuleDir(), ctx.ModuleName()) {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE, ctx.ModuleName())
+ return
+ }
bModule, ok := ctx.Module().(Bazelable)
if !ok {
ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
@@ -659,6 +670,10 @@
panic(fmt.Errorf("illegal bp2build invariant: module '%s' was neither converted nor marked unconvertible", ctx.ModuleName()))
}
+ // If an existing BUILD file in the module directory has a target defined
+ // with the same name as any target generated by this module, assume that this
+ // is an existing definition for this target. (These generated target names
+ // may be different than the module name, as checked at the beginning of this function!)
for _, targetInfo := range ctx.Module().base().Bp2buildTargets() {
if ctx.Config().HasBazelBuildTargetInSource(targetInfo.TargetPackage(), targetInfo.TargetName()) {
// Defer to the BUILD target. Generating an additional target would
@@ -669,6 +684,39 @@
}
}
+// TODO: b/285631638 - Add this as a new mutator to the bp2build conversion mutators.
+// Currently, this only exists to prepare test coverage for the launch of this feature.
+func bp2buildDepsMutator(ctx BottomUpMutatorContext) {
+ if ctx.Module().base().GetUnconvertedReason() != nil {
+ return
+ }
+
+ if len(ctx.Module().GetMissingBp2buildDeps()) > 0 {
+ exampleDep := ctx.Module().GetMissingBp2buildDeps()[0]
+ ctx.MarkBp2buildUnconvertible(
+ bp2build_metrics_proto.UnconvertedReasonType_UNCONVERTED_DEP, exampleDep)
+ }
+
+ // Transitively mark modules unconvertible with the following set of conditions.
+ ctx.VisitDirectDeps(func(dep Module) {
+ if dep.base().GetUnconvertedReason() == nil {
+ return
+ }
+
+ if dep.base().GetUnconvertedReason().ReasonType ==
+ int(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE) {
+ return
+ }
+
+ if ctx.OtherModuleDependencyTag(dep) != Bp2buildDepTag {
+ return
+ }
+
+ ctx.MarkBp2buildUnconvertible(
+ bp2build_metrics_proto.UnconvertedReasonType_UNCONVERTED_DEP, dep.Name())
+ })
+}
+
// GetMainClassInManifest scans the manifest file specified in filepath and returns
// the value of attribute Main-Class in the manifest file if it exists, or returns error.
// WARNING: this is for bp2build converters of java_* modules only.
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 09580a7..d272ec2 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -102,8 +102,8 @@
// BazelLabelForModuleDeps expects a list of reference to other modules, ("<module>"
// or ":<module>") and returns a Bazel-compatible label which corresponds to dependencies on the
// module within the given ctx.
-func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList {
- return BazelLabelForModuleDepsWithFn(ctx, modules, BazelModuleLabel)
+func BazelLabelForModuleDeps(ctx Bp2buildMutatorContext, modules []string) bazel.LabelList {
+ return BazelLabelForModuleDepsWithFn(ctx, modules, BazelModuleLabel, /*markAsDeps=*/true)
}
// BazelLabelForModuleWholeDepsExcludes expects two lists: modules (containing modules to include in
@@ -112,15 +112,16 @@
// list which corresponds to dependencies on the module within the given ctx, and the excluded
// dependencies. Prebuilt dependencies will be appended with _alwayslink so they can be handled as
// whole static libraries.
-func BazelLabelForModuleDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func BazelLabelForModuleDepsExcludes(ctx Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
return BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, BazelModuleLabel)
}
// BazelLabelForModuleDepsWithFn expects a list of reference to other modules, ("<module>"
// or ":<module>") and applies moduleToLabelFn to determine and return a Bazel-compatible label
// which corresponds to dependencies on the module within the given ctx.
-func BazelLabelForModuleDepsWithFn(ctx BazelConversionPathContext, modules []string,
- moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string) bazel.LabelList {
+func BazelLabelForModuleDepsWithFn(ctx Bp2buildMutatorContext, modules []string,
+ moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string,
+ markAsDeps bool) bazel.LabelList {
var labels bazel.LabelList
// In some cases, a nil string list is different than an explicitly empty list.
if len(modules) == 0 && modules != nil {
@@ -134,7 +135,7 @@
module = ":" + module
}
if m, t := SrcIsModuleWithTag(module); m != "" {
- l := getOtherModuleLabel(ctx, m, t, moduleToLabelFn)
+ l := getOtherModuleLabel(ctx, m, t, moduleToLabelFn, markAsDeps)
if l != nil {
l.OriginalModuleName = bpText
labels.Includes = append(labels.Includes, *l)
@@ -151,27 +152,27 @@
// to other modules, ("<module>" or ":<module>"). It applies moduleToLabelFn to determine and return a
// Bazel-compatible label list which corresponds to dependencies on the module within the given ctx, and
// the excluded dependencies.
-func BazelLabelForModuleDepsExcludesWithFn(ctx BazelConversionPathContext, modules, excludes []string,
+func BazelLabelForModuleDepsExcludesWithFn(ctx Bp2buildMutatorContext, modules, excludes []string,
moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string) bazel.LabelList {
- moduleLabels := BazelLabelForModuleDepsWithFn(ctx, RemoveListFromList(modules, excludes), moduleToLabelFn)
+ moduleLabels := BazelLabelForModuleDepsWithFn(ctx, RemoveListFromList(modules, excludes), moduleToLabelFn, /*markAsDeps=*/true)
if len(excludes) == 0 {
return moduleLabels
}
- excludeLabels := BazelLabelForModuleDepsWithFn(ctx, excludes, moduleToLabelFn)
+ excludeLabels := BazelLabelForModuleDepsWithFn(ctx, excludes, moduleToLabelFn, /*markAsDeps=*/false)
return bazel.LabelList{
Includes: moduleLabels.Includes,
Excludes: excludeLabels.Includes,
}
}
-func BazelLabelForModuleSrcSingle(ctx BazelConversionPathContext, path string) bazel.Label {
+func BazelLabelForModuleSrcSingle(ctx Bp2buildMutatorContext, path string) bazel.Label {
if srcs := BazelLabelForModuleSrcExcludes(ctx, []string{path}, []string(nil)).Includes; len(srcs) > 0 {
return srcs[0]
}
return bazel.Label{}
}
-func BazelLabelForModuleDepSingle(ctx BazelConversionPathContext, path string) bazel.Label {
+func BazelLabelForModuleDepSingle(ctx Bp2buildMutatorContext, path string) bazel.Label {
if srcs := BazelLabelForModuleDepsExcludes(ctx, []string{path}, []string(nil)).Includes; len(srcs) > 0 {
return srcs[0]
}
@@ -184,7 +185,7 @@
// relative if within the same package).
// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
// will have already been handled by the pathdeps mutator.
-func BazelLabelForModuleSrc(ctx BazelConversionPathContext, paths []string) bazel.LabelList {
+func BazelLabelForModuleSrc(ctx Bp2buildMutatorContext, paths []string) bazel.LabelList {
return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil))
}
@@ -194,13 +195,13 @@
// (absolute if in a different package or relative if within the same package).
// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
// will have already been handled by the pathdeps mutator.
-func BazelLabelForModuleSrcExcludes(ctx BazelConversionPathContext, paths, excludes []string) bazel.LabelList {
- excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil))
+func BazelLabelForModuleSrcExcludes(ctx Bp2buildMutatorContext, paths, excludes []string) bazel.LabelList {
+ excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil), false)
excluded := make([]string, 0, len(excludeLabels.Includes))
for _, e := range excludeLabels.Includes {
excluded = append(excluded, e.Label)
}
- labels := expandSrcsForBazel(ctx, paths, excluded)
+ labels := expandSrcsForBazel(ctx, paths, excluded, true)
labels.Excludes = excludeLabels.Includes
labels = TransformSubpackagePaths(ctx.Config(), ctx.ModuleDir(), labels)
return labels
@@ -361,6 +362,12 @@
return newPaths
}
+var Bp2buildDepTag bp2buildDepTag
+
+type bp2buildDepTag struct {
+ blueprint.BaseDependencyTag
+}
+
// expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local source
// directory and Bazel target labels, excluding those included in the excludes argument (which
// should already be expanded to resolve references to Soong-modules). Valid elements of paths
@@ -383,7 +390,7 @@
// Properties passed as the paths or excludes argument must have been annotated with struct tag
// `android:"path"` so that dependencies on other modules will have already been handled by the
// pathdeps mutator.
-func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes []string) bazel.LabelList {
+func expandSrcsForBazel(ctx Bp2buildMutatorContext, paths, expandedExcludes []string, markAsDeps bool) bazel.LabelList {
if paths == nil {
return bazel.LabelList{}
}
@@ -400,7 +407,7 @@
for _, p := range paths {
if m, tag := SrcIsModuleWithTag(p); m != "" {
- l := getOtherModuleLabel(ctx, m, tag, BazelModuleLabel)
+ l := getOtherModuleLabel(ctx, m, tag, BazelModuleLabel, markAsDeps)
if l != nil && !InList(l.Label, expandedExcludes) {
if strings.HasPrefix(m, "//") {
// this is a module in a soong namespace
@@ -432,8 +439,9 @@
// getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the
// module. The label will be relative to the current directory if appropriate. The dependency must
// already be resolved by either deps mutator or path deps mutator.
-func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string,
- labelFromModule func(BazelConversionPathContext, blueprint.Module) string) *bazel.Label {
+func getOtherModuleLabel(ctx Bp2buildMutatorContext, dep, tag string,
+ labelFromModule func(BazelConversionPathContext, blueprint.Module) string,
+ markAsDep bool) *bazel.Label {
m, _ := ctx.ModuleFromName(dep)
// The module was not found in an Android.bp file, this is often due to:
// * a limited manifest
@@ -444,6 +452,35 @@
Label: ":" + dep + "__BP2BUILD__MISSING__DEP",
}
}
+ // 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" {
+ 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 ed9b7b0..a7a96b7 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,6 +306,9 @@
// 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
@@ -675,7 +687,6 @@
"framework-media": {},
"framework-mediaprovider": {},
"framework-ondevicepersonalization": {},
- "framework-pdf": {},
"framework-permission": {},
"framework-permission-s": {},
"framework-scheduling": {},
@@ -1435,16 +1446,12 @@
return String(c.config.productVariables.Platform_vndk_version)
}
-func (c *deviceConfig) ProductVndkVersion() string {
- return String(c.config.productVariables.ProductVndkVersion)
-}
-
func (c *deviceConfig) ExtraVndkVersions() []string {
return c.config.productVariables.ExtraVndkVersions
}
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/filegroup.go b/android/filegroup.go
index b6e37a5..856c50e 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -50,7 +50,7 @@
// ignoring case, checks for proto or protos as an independent word in the name, whether at the
// beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match
filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)")
- filegroupLikelyAidlPattern = regexp.MustCompile("(?i)(^|[^a-z])aidl([^a-z]|$)")
+ filegroupLikelyAidlPattern = regexp.MustCompile("(?i)(^|[^a-z])aidl(s)?([^a-z]|$)")
ProtoSrcLabelPartition = bazel.LabelPartition{
Extensions: []string{".proto"},
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 57ff1e0..3d59655 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -35,6 +35,9 @@
// 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)
}
@@ -226,6 +229,15 @@
BazelConversionPathContext
BaseMutatorContext
+ // AddDependency adds a dependency to the given module. It returns a slice of modules for each
+ // dependency (some entries may be nil).
+ //
+ // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
+ // new dependencies have had the current mutator called on them. If the mutator is not
+ // parallel this method does not affect the ordering of the current mutator pass, but will
+ // be ordered correctly for all future mutator passes.
+ AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
+
// CreateBazelTargetModule creates a BazelTargetModule by calling the
// factory method, just like in CreateModule, but also requires
// BazelTargetModuleProperties containing additional metadata for the
@@ -294,15 +306,6 @@
BaseMutatorContext
Bp2buildMutatorContext
- // AddDependency adds a dependency to the given module. It returns a slice of modules for each
- // dependency (some entries may be nil).
- //
- // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
- // new dependencies have had the current mutator called on them. If the mutator is not
- // parallel this method does not affect the ordering of the current mutator pass, but will
- // be ordered correctly for all future mutator passes.
- AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
-
// AddReverseDependency adds a dependency from the destination to the given module.
// Does not affect the ordering of the current mutator pass, but will be ordered
// correctly for all future mutator passes. All reverse dependencies for a destination module are
diff --git a/android/register.go b/android/register.go
index f1c2986..6182159 100644
--- a/android/register.go
+++ b/android/register.go
@@ -181,8 +181,7 @@
return ctx
}
-// Helper function to register the module types used in bp2build and
-// api_bp2build.
+// Helper function to register the module types used in bp2build.
func registerModuleTypes(ctx *Context) {
for _, t := range moduleTypes {
t.register(ctx)
diff --git a/android/test_asserts.go b/android/test_asserts.go
index 3a2cb1a..c33ade5 100644
--- a/android/test_asserts.go
+++ b/android/test_asserts.go
@@ -148,7 +148,7 @@
return
}
if !ok {
- t.Errorf("%s does not match regular expression %s", s, expectedRex)
+ t.Errorf("%s: %s does not match regular expression %s", message, s, expectedRex)
}
}
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 3a5ad63..006a77f 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -418,8 +418,6 @@
ProductPublicSepolicyDirs []string `json:",omitempty"`
ProductPrivateSepolicyDirs []string `json:",omitempty"`
- ProductVndkVersion *string `json:",omitempty"`
-
TargetFSConfigGen []string `json:",omitempty"`
EnforceProductPartitionInterface *bool `json:",omitempty"`
@@ -481,6 +479,8 @@
ReleaseAconfigFlagDefaultPermission string `json:",omitempty"`
+ ReleaseDefaultModuleBuildFromSource *bool `json:",omitempty"`
+
KeepVndk *bool `json:",omitempty"`
CheckVendorSeappViolations *bool `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 090d9c4..f903373 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -736,7 +736,7 @@
vndkVersion = deviceConfig.VndkVersion()
} else if a.ProductSpecific() {
prefix = cc.ProductVariationPrefix
- vndkVersion = deviceConfig.ProductVndkVersion()
+ vndkVersion = deviceConfig.PlatformVndkVersion()
}
}
if vndkVersion == "current" {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 9475f5d..e70d3af 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -948,7 +948,7 @@
// Ensure that stub dependency from a rust module is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
// The rust module is linked to the stub cc library
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"]
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
@@ -1024,7 +1024,7 @@
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"]
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
}
@@ -3088,10 +3088,7 @@
apex_available: ["myapex"],
srcs: ["foo.cpp"],
}
- `, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.ProductVndkVersion = proptools.StringPtr("current")
- }),
- )
+ `)
cflags := strings.Fields(
ctx.ModuleForTests("foo", "android_product.29_arm64_armv8-a_myapex").Rule("cc").Args["cFlags"])
@@ -10521,6 +10518,7 @@
min_sdk_version: "29",
recovery_available: true,
vendor_available: true,
+ product_available: true,
}
api_imports {
name: "api_imports",
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
index 2b86e53..e2aee96 100644
--- a/apex/vndk_test.go
+++ b/apex/vndk_test.go
@@ -115,12 +115,7 @@
})
t.Run("VNDK APEX gathers only vendor variants even if product variants are available", func(t *testing.T) {
- ctx := testApex(t, bp,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // Now product variant is available
- variables.ProductVndkVersion = proptools.StringPtr("current")
- }),
- )
+ ctx := testApex(t, bp)
files := getFiles(t, ctx, "com.android.vndk.current", "android_common")
ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.29_arm_armv7-a-neon_shared/libfoo.so")
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.go b/bp2build/build_conversion.go
index f53588d..53c37b9 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -576,7 +576,7 @@
Dir: ctx.ModuleDir(m),
Deps: m.(*bootstrap.GoPackage).Deps(),
}
- } else if moduleType == "ndk_headers" {
+ } else if moduleType == "ndk_headers" || moduleType == "versioned_ndk_headers" {
ndkHeaders = append(ndkHeaders, m)
}
})
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index afbfffa..8e51d98 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",
@@ -2101,3 +2088,219 @@
})
}
+
+func TestBp2buildDepsMutator_missingTransitiveDep(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ }
+
+ custom {
+ name: "has_deps",
+ arch_paths: [":has_missing_dep", ":foo"],
+ }
+
+ custom {
+ name: "has_missing_dep",
+ arch_paths: [":missing"],
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Skipping conversion of a target with missing transitive dep",
+ DepsMutator: true,
+ })
+}
+
+func TestBp2buildDepsMutator_missingDirectDep(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ arch_paths: [":exists"],
+ }
+ custom {
+ name: "exists",
+ }
+
+ custom {
+ name: "has_missing_dep",
+ arch_paths: [":missing"],
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{"arch_paths": `[":exists"]`},
+ ),
+ MakeBazelTarget(
+ "custom",
+ "exists",
+ AttrNameToString{},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Skipping conversion of a target with missing direct dep",
+ DepsMutator: true,
+ })
+}
+
+func TestBp2buildDepsMutator_unconvertedDirectDep(t *testing.T) {
+ bp := `
+ custom {
+ name: "has_unconverted_dep",
+ arch_paths: [":unconvertible"],
+ }
+
+ custom {
+ name: "unconvertible",
+ does_not_convert_to_bazel: true
+ }
+ `
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: []string{},
+ Description: "Skipping conversion of a target with unconverted direct dep",
+ DepsMutator: true,
+ })
+}
+
+func TestBp2buildDepsMutator_unconvertedTransitiveDep(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ arch_paths: [":has_unconverted_dep", ":bar"],
+ }
+
+ custom {
+ name: "bar",
+ }
+
+ custom {
+ name: "has_unconverted_dep",
+ arch_paths: [":unconvertible"],
+ }
+
+ custom {
+ name: "unconvertible",
+ does_not_convert_to_bazel: true
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "bar",
+ AttrNameToString{},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Skipping conversion of a target with unconverted transitive dep",
+ DepsMutator: true,
+ })
+}
+
+func TestBp2buildDepsMutator_alreadyExistsBuildDeps(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ arch_paths: [":bar"],
+ }
+ custom {
+ name: "bar",
+ arch_paths: [":checked_in"],
+ }
+ custom {
+ name: "checked_in",
+ arch_paths: [":checked_in"],
+ does_not_convert_to_bazel: true
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{"arch_paths": `[":bar"]`},
+ ),
+ MakeBazelTarget(
+ "custom",
+ "bar",
+ AttrNameToString{"arch_paths": `[":checked_in"]`},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"checked_in"},
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Convert target with already-existing build dep",
+ DepsMutator: true,
+ })
+}
+
+// Tests that deps of libc are always considered valid for libc. This circumvents
+// an issue that, in a variantless graph (such as bp2build's), libc has the
+// unique predicament that it depends on itself.
+func TestBp2buildDepsMutator_depOnLibc(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ arch_paths: [":libc"],
+ }
+ custom {
+ name: "libc",
+ arch_paths: [":libc_dep"],
+ }
+ custom {
+ name: "libc_dep",
+ does_not_convert_to_bazel: true
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{"arch_paths": `[":libc"]`},
+ ),
+ MakeBazelTarget(
+ "custom",
+ "libc",
+ AttrNameToString{"arch_paths": `[":libc_dep"]`},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"checked_in"},
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Convert target with dep on libc",
+ DepsMutator: true,
+ })
+}
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 402d4b0..645298f 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -95,6 +95,7 @@
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"dir": attr.string(),
+ "does_not_convert_to_bazel": attr.bool(),
"embedded_prop": attr.string(),
"int64_ptr_prop": attr.int(),
# nested_props start
@@ -128,6 +129,7 @@
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"dir": attr.string(),
+ "does_not_convert_to_bazel": attr.bool(),
"embedded_prop": attr.string(),
"int64_ptr_prop": attr.int(),
# nested_props start
@@ -161,6 +163,7 @@
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"dir": attr.string(),
+ "does_not_convert_to_bazel": attr.bool(),
"embedded_prop": attr.string(),
"int64_ptr_prop": attr.int(),
# nested_props start
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 3cce430..5c9cbf2 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": `["."]`,
}),
@@ -5214,3 +5220,88 @@
}
runCcLibraryTestCase(t, tc)
}
+
+func TestVersionedNdkHeadersConversion(t *testing.T) {
+ tc := Bp2buildTestCase{
+ Description: "versioned_ndk_headers conversion",
+ ModuleTypeUnderTest: "versioned_ndk_headers",
+ ModuleTypeUnderTestFactory: cc.VersionedNdkHeadersFactory,
+ Blueprint: `
+versioned_ndk_headers {
+ name: "libfoo_headers",
+ from: "from",
+ to: "to",
+}
+`,
+ Filesystem: map[string]string{
+ "from/foo.h": "",
+ "from/foo_other.h": "",
+ },
+ ExpectedBazelTargets: []string{
+ MakeBazelTargetNoRestrictions("ndk_headers", "libfoo_headers", AttrNameToString{
+ "strip_import_prefix": `"from"`,
+ "import_prefix": `"to"`,
+ "hdrs": `[
+ "from/foo.h",
+ "from/foo_other.h",
+ ]`,
+ "run_versioner": "True",
+ }),
+ },
+ }
+ 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"]`,
+ }),
+ },
+ })
+}
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/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_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index 7e4e44e..426dffa 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -567,12 +567,20 @@
"b.aidl",
],
}
+filegroup {
+ name: "aidls_files",
+ srcs: [
+ "a.aidl",
+ "b.aidl",
+ ],
+}
java_library {
name: "example_lib",
srcs: [
"a.java",
"b.java",
":aidl_files",
+ ":aidls_files",
":random_other_files",
],
sdk_version: "current",
@@ -586,8 +594,18 @@
]`,
"tags": `["apex_available=//apex_available:anyapex"]`,
}),
+ MakeBazelTargetNoRestrictions("aidl_library", "aidls_files", AttrNameToString{
+ "srcs": `[
+ "a.aidl",
+ "b.aidl",
+ ]`,
+ "tags": `["apex_available=//apex_available:anyapex"]`,
+ }),
MakeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
- "deps": `[":aidl_files"]`,
+ "deps": `[
+ ":aidl_files",
+ ":aidls_files",
+ ]`,
}),
MakeBazelTarget("java_library", "example_lib", AttrNameToString{
"deps": `[":example_lib_java_aidl_library"]`,
@@ -617,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 {
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/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 d26b346..6907487 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -124,25 +124,37 @@
// 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) {
t.Helper()
- bp2buildSetup := android.GroupFixturePreparers(
+ preparers := []android.FixturePreparer{
android.FixtureRegisterWithContext(registerModuleTypes),
- android.FixtureModifyContext(modifyContext),
- SetBp2BuildTestRunner,
+ }
+ 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...,
)
runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
}
func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
t.Helper()
- bp2buildSetup := android.GroupFixturePreparers(
- android.FixtureRegisterWithContext(registerModuleTypes),
- SetBp2BuildTestRunner,
- )
- runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
+ RunBp2BuildTestCaseExtraContext(t, registerModuleTypes, nil, tc)
}
func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) {
@@ -400,6 +412,10 @@
// Prop used to indicate this conversion should be 1 module -> multiple targets
One_to_many_prop *bool
+ // Prop used to simulate an unsupported property in bp2build conversion. If this
+ // is true, this module should be treated as "unconvertible" via bp2build.
+ Does_not_convert_to_bazel *bool
+
Api *string // File describing the APIs of this module
Test_config_setting *bool // Used to test generation of config_setting targets
@@ -535,6 +551,10 @@
}
func (m *customModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ if p := m.props.Does_not_convert_to_bazel; p != nil && *p {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "")
+ return
+ }
if p := m.props.One_to_many_prop; p != nil && *p {
customBp2buildOneToMany(ctx, m)
return
diff --git a/cc/Android.bp b/cc/Android.bp
index c32d854..8fa0fbe 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -18,6 +18,7 @@
"soong-genrule",
"soong-multitree",
"soong-snapshot",
+ "soong-sysprop-bp2build",
"soong-tradefed",
],
srcs: [
@@ -49,7 +50,6 @@
"snapshot_utils.go",
"stl.go",
"strip.go",
- "sysprop.go",
"tidy.go",
"util.go",
"vendor_snapshot.go",
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 7738487..ec5d522 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -99,7 +99,7 @@
Tidy_timeout_srcs bazel.LabelListAttribute
}
-func (m *Module) convertTidyAttributes(ctx android.BaseMutatorContext, moduleAttrs *tidyAttributes) {
+func (m *Module) convertTidyAttributes(ctx android.Bp2buildMutatorContext, moduleAttrs *tidyAttributes) {
for _, f := range m.features {
if tidy, ok := f.(*tidyFeature); ok {
var tidyAttr *string
@@ -246,9 +246,9 @@
implementation bazel.LabelList
}
-type bazelLabelForDepsFn func(android.BazelConversionPathContext, []string) bazel.LabelList
+type bazelLabelForDepsFn func(android.Bp2buildMutatorContext, []string) bazel.LabelList
-func maybePartitionExportedAndImplementationsDeps(ctx android.BazelConversionPathContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
+func maybePartitionExportedAndImplementationsDeps(ctx android.Bp2buildMutatorContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
if !exportsDeps {
return depsPartition{
implementation: fn(ctx, allDeps),
@@ -263,9 +263,9 @@
}
}
-type bazelLabelForDepsExcludesFn func(android.BazelConversionPathContext, []string, []string) bazel.LabelList
+type bazelLabelForDepsExcludesFn func(android.Bp2buildMutatorContext, []string, []string) bazel.LabelList
-func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.BazelConversionPathContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
+func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.Bp2buildMutatorContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
if !exportsDeps {
return depsPartition{
implementation: fn(ctx, allDeps, excludes),
@@ -352,7 +352,7 @@
Enabled bazel.BoolAttribute
}
-func parseSrc(ctx android.BazelConversionPathContext, srcLabelAttribute *bazel.LabelAttribute, axis bazel.ConfigurationAxis, config string, srcs []string) {
+func parseSrc(ctx android.Bp2buildMutatorContext, srcLabelAttribute *bazel.LabelAttribute, axis bazel.ConfigurationAxis, config string, srcs []string) {
srcFileError := func() {
ctx.ModuleErrorf("parseSrc: Expected at most one source file for %s %s\n", axis, config)
}
@@ -370,7 +370,7 @@
}
// NOTE: Used outside of Soong repo project, in the clangprebuilts.go bootstrap_go_package
-func Bp2BuildParsePrebuiltLibraryProps(ctx android.BazelConversionPathContext, module *Module, isStatic bool) prebuiltAttributes {
+func Bp2BuildParsePrebuiltLibraryProps(ctx android.Bp2buildMutatorContext, module *Module, isStatic bool) prebuiltAttributes {
var srcLabelAttribute bazel.LabelAttribute
bp2BuildPropParseHelper(ctx, module, &prebuiltLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
@@ -407,7 +407,7 @@
}
}
-func bp2BuildParsePrebuiltBinaryProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
+func bp2BuildParsePrebuiltBinaryProps(ctx android.Bp2buildMutatorContext, module *Module) prebuiltAttributes {
var srcLabelAttribute bazel.LabelAttribute
bp2BuildPropParseHelper(ctx, module, &prebuiltLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
if props, ok := props.(*prebuiltLinkerProperties); ok {
@@ -420,7 +420,7 @@
}
}
-func bp2BuildParsePrebuiltObjectProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
+func bp2BuildParsePrebuiltObjectProps(ctx android.Bp2buildMutatorContext, module *Module) prebuiltAttributes {
var srcLabelAttribute bazel.LabelAttribute
bp2BuildPropParseHelper(ctx, module, &prebuiltObjectProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
if props, ok := props.(*prebuiltObjectProperties); ok {
@@ -555,7 +555,7 @@
return result
}
-func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis, config string, props *BaseCompilerProperties) {
+func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.Bp2buildMutatorContext, axis bazel.ConfigurationAxis, config string, props *BaseCompilerProperties) {
// If there's arch specific srcs or exclude_srcs, generate a select entry for it.
// TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
srcsList, ok := parseSrcs(ctx, props)
@@ -680,7 +680,7 @@
}
// Parse srcs from an arch or OS's props value.
-func parseSrcs(ctx android.BazelConversionPathContext, props *BaseCompilerProperties) (bazel.LabelList, bool) {
+func parseSrcs(ctx android.Bp2buildMutatorContext, props *BaseCompilerProperties) (bazel.LabelList, bool) {
anySrcs := false
// Add srcs-like dependencies such as generated files.
// First create a LabelList containing these dependencies, then merge the values with srcs.
@@ -1265,7 +1265,7 @@
// resolveTargetApex re-adds the shared and static libs in target.apex.exclude_shared|static_libs props to non-apex variant
// since all libs are already excluded by default
-func (la *linkerAttributes) resolveTargetApexProp(ctx android.BazelConversionPathContext, props *BaseLinkerProperties) {
+func (la *linkerAttributes) resolveTargetApexProp(ctx android.Bp2buildMutatorContext, props *BaseLinkerProperties) {
excludeSharedLibs := bazelLabelForSharedDeps(ctx, props.Target.Apex.Exclude_shared_libs)
sharedExcludes := bazel.LabelList{Excludes: excludeSharedLibs.Includes}
sharedExcludesLabelList := bazel.LabelListAttribute{}
@@ -1696,7 +1696,7 @@
})
}
-func (la *linkerAttributes) convertProductVariables(ctx android.BazelConversionPathContext, productVariableProps android.ProductConfigProperties) {
+func (la *linkerAttributes) convertProductVariables(ctx android.Bp2buildMutatorContext, productVariableProps android.ProductConfigProperties) {
type productVarDep struct {
// the name of the corresponding excludes field, if one exists
@@ -1704,7 +1704,7 @@
// reference to the bazel attribute that should be set for the given product variable config
attribute *bazel.LabelListAttribute
- depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
+ depResolutionFunc func(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList
}
// an intermediate attribute that holds Header_libs info, and will be appended to
@@ -1762,7 +1762,7 @@
la.implementationDeps.Append(headerDeps)
}
-func (la *linkerAttributes) finalize(ctx android.BazelConversionPathContext) {
+func (la *linkerAttributes) finalize(ctx android.Bp2buildMutatorContext) {
// if system dynamic deps have the default value, any use of a system dynamic library used will
// result in duplicate library errors for bionic OSes. Here, we explicitly exclude those libraries
// from bionic OSes and the no config case as these libraries only build for bionic OSes.
@@ -1903,39 +1903,39 @@
return xsd.CppBp2buildTargetName()
}
-func bazelLabelForWholeDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
- return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticWholeModuleDeps)
+func bazelLabelForWholeDeps(ctx android.Bp2buildMutatorContext, modules []string) bazel.LabelList {
+ return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticWholeModuleDeps, /*markAsDeps=*/true)
}
-func bazelLabelForWholeDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func bazelLabelForWholeDepsExcludes(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticWholeModuleDeps)
}
-func bazelLabelForStaticDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func bazelLabelForStaticDepsExcludes(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticModule)
}
-func bazelLabelForStaticDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
- return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticModule)
+func bazelLabelForStaticDeps(ctx android.Bp2buildMutatorContext, modules []string) bazel.LabelList {
+ return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticModule, /*markAsDeps=*/true)
}
-func bazelLabelForSharedDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
- return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForSharedModule)
+func bazelLabelForSharedDeps(ctx android.Bp2buildMutatorContext, modules []string) bazel.LabelList {
+ return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForSharedModule, /*markAsDeps=*/true)
}
-func bazelLabelForHeaderDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
+func bazelLabelForHeaderDeps(ctx android.Bp2buildMutatorContext, modules []string) bazel.LabelList {
// This is not elegant, but bp2build's shared library targets only propagate
// their header information as part of the normal C++ provider.
return bazelLabelForSharedDeps(ctx, modules)
}
-func bazelLabelForHeaderDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func bazelLabelForHeaderDepsExcludes(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
// This is only used when product_variable header_libs is processed, to follow
// the pattern of depResolutionFunc
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
}
-func bazelLabelForSharedDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func bazelLabelForSharedDepsExcludes(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
}
diff --git a/cc/cc.go b/cc/cc.go
index 1896766..8c248f9 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1895,8 +1895,7 @@
// do not add a name suffix because it is a base module.
return ""
}
- vndkVersion = ctx.DeviceConfig().ProductVndkVersion()
- nameSuffix = ProductSuffix
+ return ProductSuffix
} else {
vndkVersion = ctx.DeviceConfig().VndkVersion()
nameSuffix = VendorSuffix
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 7ce0f37..794c5ee 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -41,7 +41,6 @@
PrepareForTestWithCcIncludeVndk,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
- variables.ProductVndkVersion = StringPtr("current")
variables.Platform_vndk_version = StringPtr("29")
}),
)
@@ -104,33 +103,6 @@
return result.TestContext
}
-// testCcNoVndk runs tests using the prepareForCcTest
-//
-// See testCc for an explanation as to how to stop using this deprecated method.
-//
-// deprecated
-func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
- t.Helper()
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
-
- return testCcWithConfig(t, config)
-}
-
-// testCcNoProductVndk runs tests using the prepareForCcTest
-//
-// See testCc for an explanation as to how to stop using this deprecated method.
-//
-// deprecated
-func testCcNoProductVndk(t *testing.T, bp string) *android.TestContext {
- t.Helper()
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
-
- return testCcWithConfig(t, config)
-}
-
// testCcErrorWithConfig runs tests using the prepareForCcTest
//
// See testCc for an explanation as to how to stop using this deprecated method.
@@ -167,7 +139,6 @@
t.Helper()
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("29")
testCcErrorWithConfig(t, pattern, config)
return
@@ -523,7 +494,6 @@
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("29")
ctx := testCcWithConfig(t, config)
@@ -707,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"})
@@ -889,63 +860,6 @@
}
}
-func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
- t.Parallel()
- ctx := testCcNoVndk(t, `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
- cc_library {
- name: "libvndk-private",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libllndk",
- llndk: {
- symbol_file: "libllndk.map.txt",
- export_llndk_headers: ["libllndk_headers"],
- }
- }
-
- cc_library_headers {
- name: "libllndk_headers",
- llndk: {
- symbol_file: "libllndk.map.txt",
- },
- export_include_dirs: ["include"],
- }
- `)
-
- checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
- "LLNDK: libc.so",
- "LLNDK: libdl.so",
- "LLNDK: libft2.so",
- "LLNDK: libllndk.so",
- "LLNDK: libm.so",
- "VNDK-SP: libc++.so",
- "VNDK-core: libvndk-private.so",
- "VNDK-core: libvndk.so",
- "VNDK-private: libft2.so",
- "VNDK-private: libvndk-private.so",
- "VNDK-product: libc++.so",
- "VNDK-product: libvndk-private.so",
- "VNDK-product: libvndk.so",
- })
-}
-
func TestVndkModuleError(t *testing.T) {
t.Parallel()
// Check the error message for vendor_available and product_available properties.
@@ -1111,6 +1025,7 @@
cc_library {
name: "libnonvndk",
vendor_available: true,
+ product_available: true,
nocrt: true,
}
`)
@@ -1132,6 +1047,7 @@
cc_library {
name: "libnonvndk",
vendor_available: true,
+ product_available: true,
nocrt: true,
}
`)
@@ -1153,6 +1069,7 @@
cc_library {
name: "libnonvndk",
vendor_available: true,
+ product_available: true,
nocrt: true,
}
`)
@@ -1175,6 +1092,7 @@
cc_library {
name: "libnonvndk",
vendor_available: true,
+ product_available: true,
nocrt: true,
}
`)
@@ -1390,6 +1308,7 @@
cc_library {
name: "libanothervndksp",
vendor_available: true,
+ product_available: true,
}
`)
}
@@ -1467,7 +1386,6 @@
`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("29")
ctx := testCcWithConfig(t, config)
@@ -1482,70 +1400,6 @@
assertString(t, mod_product.outputFile.Path().Base(), "libvndk2-suffix.so")
}
-func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
- t.Parallel()
- // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
- ctx := testCcNoVndk(t, `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
- `)
-
- // Ensures that the core variant of "libvndk_ext" can be found.
- mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
- if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
- t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
- }
-}
-
-func TestVndkExtWithoutProductVndkVersion(t *testing.T) {
- t.Parallel()
- // This test checks the VNDK-Ext properties when PRODUCT_PRODUCT_VNDK_VERSION is not set.
- ctx := testCcNoProductVndk(t, `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext_product",
- product_specific: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
- `)
-
- // Ensures that the core variant of "libvndk_ext_product" can be found.
- mod := ctx.ModuleForTests("libvndk_ext_product", coreVariant).Module().(*Module)
- if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
- t.Errorf("\"libvndk_ext_product\" must extend from \"libvndk\" but get %q", extends)
- }
-}
-
func TestVndkExtError(t *testing.T) {
t.Parallel()
// This test ensures an error is emitted in ill-formed vndk-ext definition.
@@ -1920,7 +1774,6 @@
`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("29")
testCcWithConfig(t, config)
@@ -3034,24 +2887,6 @@
checkRuntimeLibs(t, nil, module)
}
-func TestRuntimeLibsNoVndk(t *testing.T) {
- t.Parallel()
- ctx := testCcNoVndk(t, runtimeLibAndroidBp)
-
- // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
-
- variant := "android_arm64_armv8-a_shared"
-
- module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available"}, module)
-
- module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available", "libvendor1", "libproduct_vendor"}, module)
-
- module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available", "libproduct1", "libproduct_vendor"}, module)
-}
-
func checkStaticLibs(t *testing.T, expected []string, module *Module) {
t.Helper()
actual := module.Properties.AndroidMkStaticLibs
diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go
index e048622..d5bc760 100644
--- a/cc/config/riscv64_device.go
+++ b/cc/config/riscv64_device.go
@@ -27,6 +27,9 @@
"-Werror=implicit-function-declaration",
"-fno-emulated-tls",
"-march=rv64gcv_zba_zbb_zbs",
+ // Equivalent to "-munaligned-access", but our clang doesn't have that yet.
+ "-Xclang -target-feature -Xclang +unaligned-scalar-mem",
+ "-Xclang -target-feature -Xclang +unaligned-vector-mem",
}
riscv64ArchVariantCflags = map[string][]string{}
@@ -34,6 +37,9 @@
riscv64Ldflags = []string{
"-Wl,--hash-style=gnu",
"-march=rv64gcv_zba_zbb_zbs",
+ // Equivalent to "-munaligned-access", but our clang doesn't have that yet.
+ "-Xclang -target-feature -Xclang +unaligned-scalar-mem",
+ "-Xclang -target-feature -Xclang +unaligned-vector-mem",
}
riscv64Lldflags = append(riscv64Ldflags,
diff --git a/cc/gen.go b/cc/gen.go
index b15f164..151f23d 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -20,6 +20,7 @@
"android/soong/aidl_library"
"android/soong/bazel"
+ "android/soong/sysprop/bp2build"
"github.com/google/blueprint"
@@ -240,12 +241,13 @@
}
func bp2buildCcSysprop(ctx android.Bp2buildMutatorContext, moduleName string, minSdkVersion *string, srcs bazel.LabelListAttribute) *bazel.LabelAttribute {
- labels := SyspropLibraryLabels{
- SyspropLibraryLabel: moduleName + "_sysprop_library",
- StaticLibraryLabel: moduleName + "_cc_sysprop_library_static",
+ labels := bp2build.SyspropLibraryLabels{
+ SyspropLibraryLabel: moduleName + "_sysprop_library",
+ CcStaticLibraryLabel: moduleName + "_cc_sysprop_library_static",
}
- Bp2buildSysprop(ctx, labels, srcs, minSdkVersion)
- return createLabelAttributeCorrespondingToSrcs(":"+labels.StaticLibraryLabel, srcs)
+ bp2build.Bp2buildBaseSyspropLibrary(ctx, labels.SyspropLibraryLabel, srcs)
+ bp2build.Bp2buildSyspropCc(ctx, labels, minSdkVersion)
+ return createLabelAttributeCorrespondingToSrcs(":"+labels.CcStaticLibraryLabel, srcs)
}
// Creates a LabelAttribute for a given label where the value is only set for
diff --git a/cc/genrule.go b/cc/genrule.go
index d1c4c2a..63c728c 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -84,7 +84,7 @@
return true
}
- if ctx.DeviceConfig().ProductVndkVersion() != "" && ctx.ProductSpecific() {
+ if ctx.ProductSpecific() {
return false
}
@@ -134,15 +134,8 @@
}
}
- if ctx.DeviceConfig().ProductVndkVersion() == "" {
- return variants
- }
-
if Bool(g.Product_available) || ctx.ProductSpecific() {
variants = append(variants, ProductVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
- if vndkVersion := ctx.DeviceConfig().ProductVndkVersion(); vndkVersion != "current" {
- variants = append(variants, ProductVariationPrefix+vndkVersion)
- }
}
return variants
diff --git a/cc/image.go b/cc/image.go
index f91762a..239f1db 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -427,7 +427,6 @@
platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
boardVndkVersion := mctx.DeviceConfig().VndkVersion()
- productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
recoverySnapshotVersion != ""
@@ -444,9 +443,6 @@
if boardVndkVersion == "current" {
boardVndkVersion = platformVndkVersion
}
- if productVndkVersion == "current" {
- productVndkVersion = platformVndkVersion
- }
if m.NeedsLlndkVariants() {
// This is an LLNDK library. The implementation of the library will be on /system,
@@ -462,9 +458,6 @@
if needVndkVersionVendorVariantForLlndk {
vendorVariants = append(vendorVariants, boardVndkVersion)
}
- if productVndkVersion != "" {
- productVariants = append(productVariants, productVndkVersion)
- }
} else if m.NeedsVendorPublicLibraryVariants() {
// A vendor public library has the implementation on /vendor, with stub variants
// for system and product.
@@ -473,9 +466,6 @@
if platformVndkVersion != "" {
productVariants = append(productVariants, platformVndkVersion)
}
- if productVndkVersion != "" {
- productVariants = append(productVariants, productVndkVersion)
- }
} else if boardVndkVersion == "" {
// If the device isn't compiling against the VNDK, we always
// use the core mode.
@@ -507,10 +497,6 @@
// product_available modules are available to /product.
if m.HasProductVariant() {
productVariants = append(productVariants, platformVndkVersion)
- // VNDK is always PLATFORM_VNDK_VERSION
- if !m.IsVndk() {
- productVariants = append(productVariants, productVndkVersion)
- }
}
} else if vendorSpecific && m.SdkVersion() == "" {
// This will be available in /vendor (or /odm) only
@@ -538,17 +524,10 @@
coreVariantNeeded = true
}
- if boardVndkVersion != "" && productVndkVersion != "" {
- if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
- // The module has "product_specific: true" that does not create core variant.
- coreVariantNeeded = false
- productVariants = append(productVariants, productVndkVersion)
- }
- } else {
- // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
- // restriction to use system libs.
- // No product variants defined in this case.
- productVariants = []string{}
+ if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
+ // The module has "product_specific: true" that does not create core variant.
+ coreVariantNeeded = false
+ productVariants = append(productVariants, platformVndkVersion)
}
if m.RamdiskAvailable() {
diff --git a/cc/library.go b/cc/library.go
index e66ce08..6acd7ae 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,11 @@
Deps: baseAttributes.deps,
Api_surface: proptools.StringPtr("module-libapi"),
}
- ctx.CreateBazelTargetModule(stubSuitesProps,
- android.CommonAttributes{Name: m.Name() + "_stub_libs"},
+ 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
@@ -547,54 +554,6 @@
includes.attrs.Deps.Append(lla)
}
-// includes provided to the module-lib API surface. This API surface is used by apexes.
-func getModuleLibApiIncludes(ctx android.TopDownMutatorContext, c *Module) apiIncludes {
- flagProps := c.library.(*libraryDecorator).flagExporter.Properties
- linkProps := c.library.(*libraryDecorator).baseLinker.Properties
- includes := android.FirstUniqueStrings(flagProps.Export_include_dirs)
- systemIncludes := android.FirstUniqueStrings(flagProps.Export_system_include_dirs)
- headerLibs := android.FirstUniqueStrings(linkProps.Export_header_lib_headers)
- attrs := bazelCcLibraryHeadersAttributes{
- Export_includes: bazel.MakeStringListAttribute(includes),
- Export_system_includes: bazel.MakeStringListAttribute(systemIncludes),
- Deps: bazel.MakeLabelListAttribute(apiHeaderLabels(ctx, headerLibs)),
- }
-
- return apiIncludes{
- name: c.Name() + ".module-libapi.headers",
- attrs: bazelCcApiLibraryHeadersAttributes{
- bazelCcLibraryHeadersAttributes: attrs,
- },
- }
-}
-
-func getVendorApiIncludes(ctx android.TopDownMutatorContext, c *Module) apiIncludes {
- baseProps := c.library.(*libraryDecorator).flagExporter.Properties
- llndkProps := c.library.(*libraryDecorator).Properties.Llndk
- includes := baseProps.Export_include_dirs
- systemIncludes := baseProps.Export_system_include_dirs
- // LLNDK can override the base includes
- if llndkIncludes := llndkProps.Override_export_include_dirs; llndkIncludes != nil {
- includes = llndkIncludes
- }
- if proptools.Bool(llndkProps.Export_headers_as_system) {
- systemIncludes = append(systemIncludes, includes...)
- includes = nil
- }
-
- attrs := bazelCcLibraryHeadersAttributes{
- Export_includes: bazel.MakeStringListAttribute(includes),
- Export_system_includes: bazel.MakeStringListAttribute(systemIncludes),
- Deps: bazel.MakeLabelListAttribute(apiHeaderLabels(ctx, llndkProps.Export_llndk_headers)),
- }
- return apiIncludes{
- name: c.Name() + ".vendorapi.headers",
- attrs: bazelCcApiLibraryHeadersAttributes{
- bazelCcLibraryHeadersAttributes: attrs,
- },
- }
-}
-
// cc_library creates both static and/or shared libraries for a device and/or
// host. By default, a cc_library has a single variant that targets the device.
// Specifying `host_supported: true` also creates a library that targets the
@@ -2983,7 +2942,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 {
diff --git a/cc/library_headers.go b/cc/library_headers.go
index fccdf99..4da2b48 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -161,18 +161,3 @@
Tags: tags,
}, attrs)
}
-
-// Append .contribution suffix to input labels
-func apiBazelTargets(ll bazel.LabelList) bazel.LabelList {
- labels := make([]bazel.Label, 0)
- for _, l := range ll.Includes {
- labels = append(labels, bazel.Label{
- Label: android.ApiContributionTargetName(l.Label),
- })
- }
- return bazel.MakeLabelList(labels)
-}
-
-var (
- allArches = []string{"arm", "arm64", "x86", "x86_64"}
-)
diff --git a/cc/lto.go b/cc/lto.go
index df9ca0a..281b527 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.
+ // First, determine the module independent default LTO mode.
ltoDefault := GlobalThinLTO(ctx)
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
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_headers.go b/cc/ndk_headers.go
index da5db1c..461aa96 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -19,6 +19,7 @@
"path/filepath"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/bazel"
@@ -151,6 +152,7 @@
Strip_import_prefix *string
Import_prefix *string
Hdrs bazel.LabelListAttribute
+ Run_versioner *bool
}
func (h *headerModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
@@ -217,6 +219,7 @@
// Note that this is really only built to handle bionic/libc/include.
type versionedHeaderModule struct {
android.ModuleBase
+ android.BazelModuleBase
properties versionedHeaderProperties
@@ -255,6 +258,25 @@
processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, m.srcPaths, installPaths)
}
+func (h *versionedHeaderModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "ndk_headers",
+ Bzl_load_location: "//build/bazel/rules/cc:ndk_headers.bzl",
+ }
+ globPattern := headerGlobPattern(proptools.String(h.properties.From))
+ attrs := &bazelNdkHeadersAttributes{
+ Strip_import_prefix: h.properties.From,
+ Import_prefix: h.properties.To,
+ Run_versioner: proptools.BoolPtr(true),
+ Hdrs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{globPattern})),
+ }
+ ctx.CreateBazelTargetModule(
+ props,
+ android.CommonAttributes{Name: h.Name()},
+ attrs,
+ )
+}
+
func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path,
srcPaths android.Paths, installPaths []android.WritablePath) android.Path {
// The versioner depends on a dependencies directory to simplify determining include paths
@@ -298,12 +320,13 @@
// Unlike the ndk_headers soong module, versioned_ndk_headers operates on a
// directory level specified in `from` property. This is only used to process
// the bionic/libc/include directory.
-func versionedNdkHeadersFactory() android.Module {
+func VersionedNdkHeadersFactory() android.Module {
module := &versionedHeaderModule{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
+ android.InitBazelModule(module)
return module
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 56c57b9..4936559 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)",
+ 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")
@@ -580,15 +580,6 @@
Library_name string
}
-// Names of the cc_api_header targets in the bp2build workspace
-func apiHeaderLabels(ctx android.TopDownMutatorContext, hdrLibs []string) bazel.LabelList {
- addSuffix := func(ctx android.BazelConversionPathContext, module blueprint.Module) string {
- label := android.BazelModuleLabel(ctx, module)
- return android.ApiContributionTargetName(label)
- }
- return android.BazelLabelForModuleDepsWithFn(ctx, hdrLibs, addSuffix)
-}
-
func ndkLibraryBp2build(ctx android.Bp2buildMutatorContext, c *Module) {
ndk, _ := c.linker.(*stubDecorator)
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index 54a2ee2..483d23b 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -64,7 +64,7 @@
func RegisterNdkModuleTypes(ctx android.RegistrationContext) {
ctx.RegisterModuleType("ndk_headers", NdkHeadersFactory)
ctx.RegisterModuleType("ndk_library", NdkLibraryFactory)
- ctx.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory)
+ ctx.RegisterModuleType("versioned_ndk_headers", VersionedNdkHeadersFactory)
ctx.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory)
ctx.RegisterParallelSingletonType("ndk", NdkSingleton)
}
diff --git a/cc/sysprop.go b/cc/sysprop.go
deleted file mode 100644
index be03004..0000000
--- a/cc/sysprop.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cc
-
-import (
- "android/soong/android"
- "android/soong/bazel"
-)
-
-// TODO(b/240463568): Additional properties will be added for API validation
-type bazelSyspropLibraryAttributes struct {
- Srcs bazel.LabelListAttribute
- Tags bazel.StringListAttribute
-}
-
-type bazelCcSyspropLibraryAttributes struct {
- Dep bazel.LabelAttribute
- Min_sdk_version *string
- Tags bazel.StringListAttribute
-}
-
-type SyspropLibraryLabels struct {
- SyspropLibraryLabel string
- SharedLibraryLabel string
- StaticLibraryLabel string
-}
-
-func Bp2buildSysprop(ctx android.Bp2buildMutatorContext, labels SyspropLibraryLabels, srcs bazel.LabelListAttribute, minSdkVersion *string) {
- apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx, ctx.Module())
- ctx.CreateBazelTargetModule(
- bazel.BazelTargetModuleProperties{
- Rule_class: "sysprop_library",
- Bzl_load_location: "//build/bazel/rules/sysprop:sysprop_library.bzl",
- },
- android.CommonAttributes{Name: labels.SyspropLibraryLabel},
- &bazelSyspropLibraryAttributes{
- Srcs: srcs,
- Tags: apexAvailableTags,
- },
- )
-
- attrs := &bazelCcSyspropLibraryAttributes{
- Dep: *bazel.MakeLabelAttribute(":" + labels.SyspropLibraryLabel),
- Min_sdk_version: minSdkVersion,
- Tags: apexAvailableTags,
- }
-
- if labels.SharedLibraryLabel != "" {
- ctx.CreateBazelTargetModule(
- bazel.BazelTargetModuleProperties{
- Rule_class: "cc_sysprop_library_shared",
- Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
- },
- android.CommonAttributes{Name: labels.SharedLibraryLabel},
- attrs)
- }
-
- ctx.CreateBazelTargetModule(
- bazel.BazelTargetModuleProperties{
- Rule_class: "cc_sysprop_library_static",
- Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
- },
- android.CommonAttributes{Name: labels.StaticLibraryLabel},
- attrs)
-}
diff --git a/cc/test.go b/cc/test.go
index 8c63dc6..f128187 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -799,7 +799,7 @@
// cc_test that builds using gtest needs some additional deps
// addImplicitGtestDeps makes these deps explicit in the generated BUILD files
-func addImplicitGtestDeps(ctx android.BazelConversionPathContext, attrs *testBinaryAttributes, gtest, gtestIsolated bool) {
+func addImplicitGtestDeps(ctx android.Bp2buildMutatorContext, attrs *testBinaryAttributes, gtest, gtestIsolated bool) {
addDepsAndDedupe := func(lla *bazel.LabelListAttribute, modules []string) {
moduleLabels := android.BazelLabelForModuleDeps(ctx, modules)
lla.Value.Append(moduleLabels)
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..3e92706 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -135,10 +135,125 @@
"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",
}
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/config/kotlin.go b/java/config/kotlin.go
index fc63f4d..e5e187c 100644
--- a/java/config/kotlin.go
+++ b/java/config/kotlin.go
@@ -49,8 +49,5 @@
"-J--add-opens=java.base/java.util=ALL-UNNAMED", // https://youtrack.jetbrains.com/issue/KT-43704
}, " "))
- pctx.StaticVariable("KotlincGlobalFlags", strings.Join([]string{
- // b/222162908: prevent kotlinc from reading /tmp/build.txt
- "-Didea.plugins.compatible.build=999.SNAPSHOT",
- }, " "))
+ pctx.StaticVariable("KotlincGlobalFlags", strings.Join([]string{}, " "))
}
diff --git a/java/dex.go b/java/dex.go
index 3468a70..348c939 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -140,9 +140,7 @@
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
`rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` +
`mkdir -p $$(dirname ${outUsage}) && ` +
- `mkdir -p $$(dirname $tmpJar) && ` +
- `${config.Zip2ZipCmd} -i $in -o $tmpJar -x '**/*.dex' && ` +
- `$r8Template${config.R8Cmd} ${config.R8Flags} -injars $tmpJar --output $outDir ` +
+ `$r8Template${config.R8Cmd} ${config.R8Flags} -injars $in --output $outDir ` +
`--no-data-resources ` +
`-printmapping ${outDict} ` +
`-printconfiguration ${outConfig} ` +
@@ -154,7 +152,7 @@
`rm -rf ${outUsageDir} && ` +
`$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
`${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` +
- `rm -f "$tmpJar" "$outDir/classes*.dex" "$outDir/classes.dex.jar"`,
+ `rm -f "$outDir/classes*.dex" "$outDir/classes.dex.jar"`,
Depfile: "${out}.d",
Deps: blueprint.DepsGCC,
CommandDeps: []string{
@@ -187,7 +185,7 @@
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
},
}, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
- "r8Flags", "zipFlags", "tmpJar", "mergeZipsFlags"}, []string{"implicits"})
+ "r8Flags", "zipFlags", "mergeZipsFlags"}, []string{"implicits"})
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
dexParams *compileDexParams) (flags []string, deps android.Paths) {
@@ -370,7 +368,6 @@
// Compile classes.jar into classes.dex and then javalib.jar
javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath
outDir := android.PathForModuleOut(ctx, "dex")
- tmpJar := android.PathForModuleOut(ctx, "withres-withoutdex", dexParams.jarName)
zipFlags := "--ignore_missing_files"
if proptools.Bool(d.dexProperties.Uncompress_dex) {
@@ -408,7 +405,6 @@
"outUsage": proguardUsage.String(),
"outUsageZip": proguardUsageZip.String(),
"outDir": outDir.String(),
- "tmpJar": tmpJar.String(),
"mergeZipsFlags": mergeZipsFlags,
}
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") {
@@ -428,6 +424,7 @@
Args: args,
})
} else {
+ tmpJar := android.PathForModuleOut(ctx, "withres-withoutdex", dexParams.jarName)
d8Flags, d8Deps := d8Flags(dexParams.flags)
d8Deps = append(d8Deps, commonDeps...)
rule := d8
diff --git a/java/droiddoc.go b/java/droiddoc.go
index d5547d0..87588f3 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -136,6 +136,9 @@
// At some point, this might be improved to show more warnings.
Todo_file *string `android:"path"`
+ // A file containing a baseline for allowed lint errors.
+ Lint_baseline *string `android:"path"`
+
// directory under current module source that provide additional resources (images).
Resourcesdir *string
@@ -665,6 +668,10 @@
ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
}
+ if String(d.properties.Lint_baseline) != "" {
+ cmd.FlagWithInput("-lintbaseline ", android.PathForModuleSrc(ctx, String(d.properties.Lint_baseline)))
+ }
+
if String(d.properties.Resourcesdir) != "" {
// TODO: should we add files under resourcesDir to the implicits? It seems that
// resourcesDir is one sub dir of htmlDir
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/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 8225df6..3a6854c 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -941,6 +941,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..a9b6197 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: `
diff --git a/rust/binary.go b/rust/binary.go
index aee4da6..860dc94 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -77,14 +77,11 @@
func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
flags = binary.baseCompiler.compilerFlags(ctx, flags)
- if ctx.Os().Linux() {
- flags.LinkFlags = append(flags.LinkFlags, "-Wl,--gc-sections")
- }
-
if ctx.toolchain().Bionic() {
// no-undefined-version breaks dylib compilation since __rust_*alloc* functions aren't defined,
// but we can apply this to binaries.
flags.LinkFlags = append(flags.LinkFlags,
+ "-Wl,--gc-sections",
"-Wl,-z,nocopyreloc",
"-Wl,--no-undefined-version")
@@ -149,7 +146,7 @@
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
if binary.stripper.NeedsStrip(ctx) {
strippedOutputFile := outputFile
diff --git a/rust/binary_test.go b/rust/binary_test.go
index dff94ac..ef93037 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -150,7 +150,7 @@
bootstrap: true,
}`)
- foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustLink")
+ foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64"
if !strings.Contains(foo.Args["linkFlags"], flag) {
@@ -167,11 +167,10 @@
}`)
fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc")
- fizzOutLink := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustLink")
fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
flags := fizzOut.Args["rustcFlags"]
- linkFlags := fizzOutLink.Args["linkFlags"]
+ linkFlags := fizzOut.Args["linkFlags"]
if !strings.Contains(flags, "-C relocation-model=static") {
t.Errorf("static binary missing '-C relocation-model=static' in rustcFlags, found: %#v", flags)
}
@@ -201,7 +200,7 @@
name: "libfoo",
}`)
- fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustLink")
+ fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustc")
linkFlags := fizzBuzz.Args["linkFlags"]
if !strings.Contains(linkFlags, "/libfoo.so") {
t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags)
diff --git a/rust/builder.go b/rust/builder.go
index 9614d4f..bea8ff7 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -26,14 +26,14 @@
var (
_ = pctx.SourcePathVariable("rustcCmd", "${config.RustBin}/rustc")
- _ = pctx.SourcePathVariable("mkcraterspCmd", "build/soong/scripts/mkcratersp.py")
rustc = pctx.AndroidStaticRule("rustc",
blueprint.RuleParams{
Command: "$envVars $rustcCmd " +
- "-C linker=$mkcraterspCmd " +
+ "-C linker=${config.RustLinker} " +
+ "-C link-args=\"${crtBegin} ${earlyLinkFlags} ${linkFlags} ${crtEnd}\" " +
"--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" +
" && grep \"^$out:\" $out.d.raw > $out.d",
- CommandDeps: []string{"$rustcCmd", "$mkcraterspCmd"},
+ CommandDeps: []string{"$rustcCmd"},
// Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633
// Rustc emits unneeded dependency lines for the .d and input .rs files.
// Those extra lines cause ninja warning:
@@ -42,12 +42,7 @@
Deps: blueprint.DepsGCC,
Depfile: "$out.d",
},
- "rustcFlags", "libFlags", "envVars")
- rustLink = pctx.AndroidStaticRule("rustLink",
- blueprint.RuleParams{
- Command: "${config.RustLinker} -o $out ${crtBegin} ${earlyLinkFlags} @$in ${linkFlags} ${crtEnd}",
- },
- "earlyLinkFlags", "linkFlags", "crtBegin", "crtEnd")
+ "rustcFlags", "earlyLinkFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars")
_ = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc")
rustdoc = pctx.AndroidStaticRule("rustdoc",
@@ -106,13 +101,14 @@
`KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative ` +
`$rustExtractor $envVars ` +
`$rustcCmd ` +
- `-C linker=true ` +
+ `-C linker=${config.RustLinker} ` +
+ `-C link-args="${crtBegin} ${linkFlags} ${crtEnd}" ` +
`$in ${libFlags} $rustcFlags`,
CommandDeps: []string{"$rustExtractor", "$kytheVnames"},
Rspfile: "${out}.rsp",
RspfileContent: "$in",
},
- "rustcFlags", "libFlags", "envVars")
+ "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars")
)
type buildOutput struct {
@@ -242,12 +238,6 @@
}
}
- envVars = append(envVars, "AR=${cc_config.ClangBin}/llvm-ar")
-
- if ctx.Darwin() {
- envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
- }
-
return envVars
}
@@ -255,7 +245,8 @@
outputFile android.WritablePath, crateType string) buildOutput {
var inputs android.Paths
- var implicits, linkImplicits, linkOrderOnly android.Paths
+ var implicits android.Paths
+ var orderOnly android.Paths
var output buildOutput
var rustcFlags, linkFlags []string
var earlyLinkFlags string
@@ -319,15 +310,15 @@
implicits = append(implicits, rustLibsToPaths(deps.RLibs)...)
implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...)
implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
- implicits = append(implicits, deps.AfdoProfiles...)
+ implicits = append(implicits, deps.StaticLibs...)
+ implicits = append(implicits, deps.SharedLibDeps...)
implicits = append(implicits, deps.srcProviderFiles...)
- implicits = append(implicits, deps.WholeStaticLibs...)
+ implicits = append(implicits, deps.AfdoProfiles...)
- linkImplicits = append(linkImplicits, deps.LibDeps...)
- linkImplicits = append(linkImplicits, deps.CrtBegin...)
- linkImplicits = append(linkImplicits, deps.CrtEnd...)
+ implicits = append(implicits, deps.CrtBegin...)
+ implicits = append(implicits, deps.CrtEnd...)
- linkOrderOnly = append(linkOrderOnly, deps.linkObjects...)
+ orderOnly = append(orderOnly, deps.SharedLibs...)
if len(deps.SrcDeps) > 0 {
moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
@@ -353,14 +344,29 @@
implicits = append(implicits, outputs.Paths()...)
}
+ envVars = append(envVars, "ANDROID_RUST_VERSION="+config.GetRustVersion(ctx))
+
+ if ctx.RustModule().compiler.CargoEnvCompat() {
+ if _, ok := ctx.RustModule().compiler.(*binaryDecorator); ok {
+ envVars = append(envVars, "CARGO_BIN_NAME="+strings.TrimSuffix(outputFile.Base(), outputFile.Ext()))
+ }
+ envVars = append(envVars, "CARGO_CRATE_NAME="+ctx.RustModule().CrateName())
+ pkgVersion := ctx.RustModule().compiler.CargoPkgVersion()
+ if pkgVersion != "" {
+ envVars = append(envVars, "CARGO_PKG_VERSION="+pkgVersion)
+ }
+ }
+
if flags.Clippy {
clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
ctx.Build(pctx, android.BuildParams{
- Rule: clippyDriver,
- Description: "clippy " + main.Rel(),
- Output: clippyFile,
- Inputs: inputs,
- Implicits: implicits,
+ Rule: clippyDriver,
+ Description: "clippy " + main.Rel(),
+ Output: clippyFile,
+ ImplicitOutputs: nil,
+ Inputs: inputs,
+ Implicits: implicits,
+ OrderOnly: orderOnly,
Args: map[string]string{
"rustcFlags": strings.Join(rustcFlags, " "),
"libFlags": strings.Join(libFlags, " "),
@@ -372,49 +378,24 @@
implicits = append(implicits, clippyFile)
}
- rustcOutputFile := outputFile
- var rustcImplicitOutputs android.WritablePaths
- usesLinker := crateType == "bin" || crateType == "dylib" || crateType == "cdylib" || crateType == "proc-macro"
- if usesLinker {
- rustcOutputFile = android.PathForModuleOut(ctx, outputFile.Base()+".rsp")
- rustcImplicitOutputs = android.WritablePaths{
- android.PathForModuleOut(ctx, rustcOutputFile.Base()+".whole.a"),
- android.PathForModuleOut(ctx, rustcOutputFile.Base()+".a"),
- }
-
- }
-
ctx.Build(pctx, android.BuildParams{
- Rule: rustc,
- Description: "rustc " + main.Rel(),
- Output: rustcOutputFile,
- Inputs: inputs,
- Implicits: implicits,
- ImplicitOutputs: rustcImplicitOutputs,
+ Rule: rustc,
+ Description: "rustc " + main.Rel(),
+ Output: outputFile,
+ Inputs: inputs,
+ Implicits: implicits,
+ OrderOnly: orderOnly,
Args: map[string]string{
- "rustcFlags": strings.Join(rustcFlags, " "),
- "libFlags": strings.Join(libFlags, " "),
- "envVars": strings.Join(envVars, " "),
+ "rustcFlags": strings.Join(rustcFlags, " "),
+ "earlyLinkFlags": earlyLinkFlags,
+ "linkFlags": strings.Join(linkFlags, " "),
+ "libFlags": strings.Join(libFlags, " "),
+ "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
+ "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
+ "envVars": strings.Join(envVars, " "),
},
})
- if usesLinker {
- ctx.Build(pctx, android.BuildParams{
- Rule: rustLink,
- Description: "rustLink " + main.Rel(),
- Output: outputFile,
- Inputs: android.Paths{rustcOutputFile},
- Implicits: linkImplicits,
- OrderOnly: linkOrderOnly,
- Args: map[string]string{
- "earlyLinkFlags": earlyLinkFlags,
- "linkFlags": strings.Join(linkFlags, " "),
- "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
- "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
- },
- })
- }
-
if flags.EmitXrefs {
kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip")
ctx.Build(pctx, android.BuildParams{
@@ -423,9 +404,13 @@
Output: kytheFile,
Inputs: inputs,
Implicits: implicits,
+ OrderOnly: orderOnly,
Args: map[string]string{
"rustcFlags": strings.Join(rustcFlags, " "),
+ "linkFlags": strings.Join(linkFlags, " "),
"libFlags": strings.Join(libFlags, " "),
+ "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
+ "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
"envVars": strings.Join(envVars, " "),
},
})
diff --git a/rust/builder_test.go b/rust/builder_test.go
index 1fd675f..639f6d4 100644
--- a/rust/builder_test.go
+++ b/rust/builder_test.go
@@ -76,9 +76,6 @@
expectedFiles: []string{
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so.clippy",
- "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so.rsp",
- "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so.rsp.a",
- "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so.rsp.whole.a",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/unstripped/libfizz_buzz.dylib.so",
"out/soong/target/product/test_device/system/lib64/libfizz_buzz.dylib.so",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/meta_lic",
@@ -112,9 +109,6 @@
expectedFiles: []string{
"out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz",
"out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz.clippy",
- "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz.rsp",
- "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz.rsp.a",
- "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz.rsp.whole.a",
"out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/unstripped/fizz_buzz",
"out/soong/target/product/test_device/system/bin/fizz_buzz",
"out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/meta_lic",
@@ -138,9 +132,6 @@
expectedFiles: []string{
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so",
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so.clippy",
- "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so.rsp",
- "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so.rsp.a",
- "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so.rsp.whole.a",
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/unstripped/librust_ffi.so",
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/unstripped/librust_ffi.so.toc",
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/meta_lic",
diff --git a/rust/compiler.go b/rust/compiler.go
index d6c52e8..b3f574d 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -327,10 +327,15 @@
flags.LinkFlags = append(flags.LinkFlags, cc.RpathFlags(ctx)...)
}
- if !ctx.toolchain().Bionic() && ctx.Os() != android.LinuxMusl && !ctx.Windows() {
- // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device
- // builds. This is irrelevant for the Windows target as these are Posix specific.
+ if ctx.Os() == android.Linux {
+ // Add -lc, -lrt, -ldl, -lpthread, -lm and -lgcc_s to glibc builds to match
+ // the default behavior of device builds.
+ flags.LinkFlags = append(flags.LinkFlags, config.LinuxHostGlobalLinkFlags...)
+ } else if ctx.Os() == android.Darwin {
+ // Add -lc, -ldl, -lpthread and -lm to glibc darwin builds to match the default
+ // behavior of device builds.
flags.LinkFlags = append(flags.LinkFlags,
+ "-lc",
"-ldl",
"-lpthread",
"-lm",
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 f397ce9..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/"
@@ -52,11 +52,22 @@
"-C force-unwind-tables=yes",
// Use v0 mangling to distinguish from C++ symbols
"-C symbol-mangling-version=v0",
- "--color always",
+ // This flag requires to have no space so that when it's exported to bazel
+ // it can be removed. See aosp/2768339
+ "--color=always",
"-Zdylib-lto",
"-Z link-native-libraries=no",
}
+ LinuxHostGlobalLinkFlags = []string{
+ "-lc",
+ "-lrt",
+ "-ldl",
+ "-lpthread",
+ "-lm",
+ "-lgcc_s",
+ }
+
deviceGlobalRustFlags = []string{
"-C panic=abort",
// Generate additional debug info for AutoFDO
@@ -100,7 +111,17 @@
pctx.StaticVariable("DeviceGlobalLinkFlags", strings.Join(deviceGlobalLinkFlags, " "))
- exportedVars.ExportStringStaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion)
+ 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 {
@@ -124,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/rust/coverage.go b/rust/coverage.go
index 5216d60..bc6504d 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -65,7 +65,7 @@
"-C instrument-coverage", "-g")
flags.LinkFlags = append(flags.LinkFlags,
profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open")
- deps.LibDeps = append(deps.LibDeps, coverage.OutputFile().Path())
+ deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path())
// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() {
diff --git a/rust/coverage_test.go b/rust/coverage_test.go
index 64077cf..0f599d7 100644
--- a/rust/coverage_test.go
+++ b/rust/coverage_test.go
@@ -55,10 +55,6 @@
libbarNoCov := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc")
fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
- libfooCovLink := ctx.ModuleForTests("libfoo_cov", "android_arm64_armv8-a_dylib_cov").Rule("rustLink")
- libbarNoCovLink := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustLink")
- fizzCovLink := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustLink")
- buzzNoCovLink := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustLink")
rustcCoverageFlags := []string{"-C instrument-coverage", " -g "}
for _, flag := range rustcCoverageFlags {
@@ -84,17 +80,17 @@
missingErrorStr := "missing rust linker flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
containsErrorStr := "contains rust linker flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
- if !strings.Contains(fizzCovLink.Args["linkFlags"], flag) {
- t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCovLink.Args["linkFlags"])
+ if !strings.Contains(fizzCov.Args["linkFlags"], flag) {
+ t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCov.Args["linkFlags"])
}
- if !strings.Contains(libfooCovLink.Args["linkFlags"], flag) {
- t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCovLink.Args["linkFlags"])
+ if !strings.Contains(libfooCov.Args["linkFlags"], flag) {
+ t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCov.Args["linkFlags"])
}
- if strings.Contains(buzzNoCovLink.Args["linkFlags"], flag) {
- t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCovLink.Args["linkFlags"])
+ if strings.Contains(buzzNoCov.Args["linkFlags"], flag) {
+ t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCov.Args["linkFlags"])
}
- if strings.Contains(libbarNoCovLink.Args["linkFlags"], flag) {
- t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCovLink.Args["linkFlags"])
+ if strings.Contains(libbarNoCov.Args["linkFlags"], flag) {
+ t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCov.Args["linkFlags"])
}
}
@@ -107,7 +103,7 @@
srcs: ["foo.rs"],
}`)
- fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustLink")
+ fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustc")
if !strings.Contains(fizz.Args["linkFlags"], "libprofile-clang-extras.a") {
t.Fatalf("missing expected coverage 'libprofile-clang-extras' dependency in linkFlags: %#v", fizz.Args["linkFlags"])
}
diff --git a/rust/library.go b/rust/library.go
index f4a2b54..c598473 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -525,7 +525,7 @@
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
if library.dylib() {
// We need prefer-dynamic for now to avoid linking in the static stdlib. See:
@@ -548,7 +548,6 @@
if library.rlib() || library.dylib() {
library.flagExporter.exportLinkDirs(deps.linkDirs...)
library.flagExporter.exportLinkObjects(deps.linkObjects...)
- library.flagExporter.exportLibDeps(deps.LibDeps...)
}
if library.static() || library.shared() {
diff --git a/rust/library_test.go b/rust/library_test.go
index 30ef333..e03074d 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -148,7 +148,7 @@
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared")
- libfooOutput := libfoo.Rule("rustLink")
+ libfooOutput := libfoo.Rule("rustc")
if !strings.Contains(libfooOutput.Args["linkFlags"], "-Wl,-soname=libfoo.so") {
t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v",
libfooOutput.Args["linkFlags"])
diff --git a/rust/rust.go b/rust/rust.go
index 49a7ff3..ba63613 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -447,12 +447,13 @@
}
type PathDeps struct {
- DyLibs RustLibraries
- RLibs RustLibraries
- LibDeps android.Paths
- WholeStaticLibs android.Paths
- ProcMacros RustLibraries
- AfdoProfiles android.Paths
+ DyLibs RustLibraries
+ RLibs RustLibraries
+ SharedLibs android.Paths
+ SharedLibDeps android.Paths
+ StaticLibs android.Paths
+ ProcMacros RustLibraries
+ AfdoProfiles android.Paths
// depFlags and depLinkFlags are rustc and linker (clang) flags.
depFlags []string
@@ -461,7 +462,7 @@
// linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker.
// Both of these are exported and propagate to dependencies.
linkDirs []string
- linkObjects android.Paths
+ linkObjects []string
// Used by bindgen modules which call clang
depClangFlags []string
@@ -524,7 +525,7 @@
type exportedFlagsProducer interface {
exportLinkDirs(...string)
- exportLinkObjects(...android.Path)
+ exportLinkObjects(...string)
}
type xref interface {
@@ -533,27 +534,21 @@
type flagExporter struct {
linkDirs []string
- linkObjects android.Paths
- libDeps android.Paths
+ linkObjects []string
}
func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
}
-func (flagExporter *flagExporter) exportLinkObjects(flags ...android.Path) {
- flagExporter.linkObjects = android.FirstUniquePaths(append(flagExporter.linkObjects, flags...))
-}
-
-func (flagExporter *flagExporter) exportLibDeps(paths ...android.Path) {
- flagExporter.libDeps = android.FirstUniquePaths(append(flagExporter.libDeps, paths...))
+func (flagExporter *flagExporter) exportLinkObjects(flags ...string) {
+ flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...))
}
func (flagExporter *flagExporter) setProvider(ctx ModuleContext) {
ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
LinkDirs: flagExporter.linkDirs,
LinkObjects: flagExporter.linkObjects,
- LibDeps: flagExporter.libDeps,
})
}
@@ -566,8 +561,7 @@
type FlagExporterInfo struct {
Flags []string
LinkDirs []string // TODO: this should be android.Paths
- LinkObjects android.Paths
- LibDeps android.Paths
+ LinkObjects []string // TODO: this should be android.Paths
}
var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{})
@@ -1319,7 +1313,6 @@
depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...)
depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...)
- depPaths.LibDeps = append(depPaths.LibDeps, exportedInfo.LibDeps...)
}
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
@@ -1375,7 +1368,6 @@
depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", linkObject.Path().String(), "-Wl,--no-whole-archive"}...)
} else if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName)
- depPaths.WholeStaticLibs = append(depPaths.WholeStaticLibs, linkObject.Path())
} else {
ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName())
}
@@ -1383,7 +1375,7 @@
// Add this to linkObjects to pass the library directly to the linker as well. This propagates
// to dependencies to avoid having to redeclare static libraries for dependents of the dylib variant.
- depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...)
+ depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
@@ -1417,7 +1409,7 @@
linkPath = linkPathFromFilePath(linkObject.Path())
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
- depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...)
+ depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
@@ -1443,9 +1435,7 @@
// Make sure these dependencies are propagated
if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep {
lib.exportLinkDirs(linkPath)
- if linkObject.Valid() {
- lib.exportLinkObjects(linkObject.Path())
- }
+ lib.exportLinkObjects(linkObject.String())
}
} else {
switch {
@@ -1479,16 +1469,19 @@
procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
}
- var libDepFiles android.Paths
+ var staticLibDepFiles android.Paths
for _, dep := range directStaticLibDeps {
- libDepFiles = append(libDepFiles, dep.OutputFile().Path())
+ staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path())
}
+ var sharedLibFiles android.Paths
+ var sharedLibDepFiles android.Paths
for _, dep := range directSharedLibDeps {
+ sharedLibFiles = append(sharedLibFiles, dep.SharedLibrary)
if dep.TableOfContents.Valid() {
- libDepFiles = append(libDepFiles, dep.TableOfContents.Path())
+ sharedLibDepFiles = append(sharedLibDepFiles, dep.TableOfContents.Path())
} else {
- libDepFiles = append(libDepFiles, dep.SharedLibrary)
+ sharedLibDepFiles = append(sharedLibDepFiles, dep.SharedLibrary)
}
}
@@ -1504,13 +1497,15 @@
depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
- depPaths.LibDeps = append(depPaths.LibDeps, libDepFiles...)
+ depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibFiles...)
+ depPaths.SharedLibDeps = append(depPaths.SharedLibDeps, sharedLibDepFiles...)
+ depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...)
depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...)
depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...)
// Dedup exported flags from dependencies
depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
- depPaths.linkObjects = android.FirstUniquePaths(depPaths.linkObjects)
+ depPaths.linkObjects = android.FirstUniqueStrings(depPaths.linkObjects)
depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 835114c..d609c2f 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -40,7 +40,6 @@
PrepareForTestWithRustIncludeVndk,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
- variables.ProductVndkVersion = StringPtr("current")
variables.Platform_vndk_version = StringPtr("29")
}),
)
@@ -105,7 +104,6 @@
android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr(device_version)
- variables.ProductVndkVersion = StringPtr(product_version)
variables.Platform_vndk_version = StringPtr(vndk_version)
},
),
@@ -173,7 +171,6 @@
android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
- variables.ProductVndkVersion = StringPtr("current")
variables.Platform_vndk_version = StringPtr("VER")
},
),
@@ -256,7 +253,6 @@
`)
module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
rustc := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
- rustLink := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustLink")
// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
if !android.InList("librlib.rlib-std", module.Properties.AndroidMkRlibs) {
@@ -279,16 +275,16 @@
t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.Args["rustcFlags"])
}
- if !strings.Contains(rustLink.Args["linkFlags"], "cc_stubs_dep.so") {
- t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustLink.Args["linkFlags"])
+ if !strings.Contains(rustc.Args["linkFlags"], "cc_stubs_dep.so") {
+ t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustc.Args["linkFlags"])
}
- if !android.SuffixInList(rustLink.OrderOnly.Strings(), "cc_stubs_dep.so") {
- t.Errorf("shared cc dep not being passed as order-only to rustc %#v", rustLink.OrderOnly.Strings())
+ if !android.SuffixInList(rustc.OrderOnly.Strings(), "cc_stubs_dep.so") {
+ t.Errorf("shared cc dep not being passed as order-only to rustc %#v", rustc.OrderOnly.Strings())
}
- if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so.toc") {
- t.Errorf("shared cc dep TOC not being passed as implicit to rustc %#v", rustLink.Implicits.Strings())
+ if !android.SuffixInList(rustc.Implicits.Strings(), "cc_stubs_dep.so.toc") {
+ t.Errorf("shared cc dep TOC not being passed as implicit to rustc %#v", rustc.Implicits.Strings())
}
}
diff --git a/rust/sanitize_test.go b/rust/sanitize_test.go
index 43e95f4..d6a14b2 100644
--- a/rust/sanitize_test.go
+++ b/rust/sanitize_test.go
@@ -35,7 +35,7 @@
note_sync := "note_memtag_heap_sync"
found := None
- implicits := m.Rule("rustLink").Implicits
+ implicits := m.Rule("rustc").Implicits
for _, lib := range implicits {
if strings.Contains(lib.Rel(), note_async) {
found = Async
diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go
index 1e7e7d3..4f45799 100644
--- a/rust/vendor_snapshot_test.go
+++ b/rust/vendor_snapshot_test.go
@@ -1051,7 +1051,7 @@
ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31")
// libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot
- libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustLink").Args["linkFlags"]
+ libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustc").Args["linkFlags"]
for _, input := range [][]string{
[]string{sharedVariant, "libvndk.vndk.30.arm64"},
[]string{staticVariant, "libvendor.vendor_static.30.arm64"},
@@ -1119,7 +1119,7 @@
t.Errorf("Unexpected rust rlib name in AndroidMk: %q, expected: %q\n", rustVendorBinMkDylibName, expectedRustVendorSnapshotName)
}
- binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustLink").Args["linkFlags"]
+ binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustc").Args["linkFlags"]
libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"})
if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
diff --git a/scripts/conv_linker_config.py b/scripts/conv_linker_config.py
index c6aa3d0..c6e6e30 100644
--- a/scripts/conv_linker_config.py
+++ b/scripts/conv_linker_config.py
@@ -62,8 +62,8 @@
if args.source:
for input in args.source.split(':'):
pb.MergeFrom(LoadJsonMessage(input))
- with open(args.output, 'wb') as f:
- f.write(pb.SerializeToString())
+
+ ValidateAndWriteAsPbFile(pb, args.output)
def Print(args):
@@ -90,8 +90,8 @@
for item in installed_libraries:
if item not in getattr(pb, 'provideLibs'):
getattr(pb, 'provideLibs').append(item)
- with open(args.output, 'wb') as f:
- f.write(pb.SerializeToString())
+
+ ValidateAndWriteAsPbFile(pb, args.output)
def Append(args):
@@ -106,8 +106,8 @@
else:
setattr(pb, args.key, args.value)
- with open(args.output, 'wb') as f:
- f.write(pb.SerializeToString())
+ ValidateAndWriteAsPbFile(pb, args.output)
+
def Merge(args):
@@ -116,8 +116,7 @@
with open(other, 'rb') as f:
pb.MergeFromString(f.read())
- with open(args.out, 'wb') as f:
- f.write(pb.SerializeToString())
+ ValidateAndWriteAsPbFile(pb, args.output)
def Validate(args):
@@ -151,6 +150,29 @@
sys.exit(f'Unknown type: {args.type}')
+def ValidateAndWriteAsPbFile(pb, output_path):
+ ValidateConfiguration(pb)
+ with open(output_path, 'wb') as f:
+ f.write(pb.SerializeToString())
+
+
+def ValidateConfiguration(pb):
+ """
+ Validate if the configuration is valid to be used as linker configuration
+ """
+
+ # Validate if provideLibs and requireLibs have common module
+ provideLibs = set(getattr(pb, 'provideLibs'))
+ requireLibs = set(getattr(pb, 'requireLibs'))
+
+ intersectLibs = provideLibs.intersection(requireLibs)
+
+ if intersectLibs:
+ for lib in intersectLibs:
+ print(f'{lib} exists both in requireLibs and provideLibs', file=sys.stderr)
+ sys.exit(1)
+
+
def GetArgParser():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
diff --git a/scripts/mkcratersp.py b/scripts/mkcratersp.py
deleted file mode 100755
index 6ef01eb..0000000
--- a/scripts/mkcratersp.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2023 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-This script is used as a replacement for the Rust linker. It converts a linker
-command line into a rspfile that can be used during the link phase.
-"""
-
-import os
-import shutil
-import subprocess
-import sys
-
-def create_archive(out, objects, archives):
- mricmd = f'create {out}\n'
- for o in objects:
- mricmd += f'addmod {o}\n'
- for a in archives:
- mricmd += f'addlib {a}\n'
- mricmd += 'save\nend\n'
- subprocess.run([os.getenv('AR'), '-M'], encoding='utf-8', input=mricmd, check=True)
-
-objects = []
-archives = []
-linkdirs = []
-libs = []
-temp_archives = []
-version_script = None
-
-for i, arg in enumerate(sys.argv):
- if arg == '-o':
- out = sys.argv[i+1]
- if arg == '-L':
- linkdirs.append(sys.argv[i+1])
- if arg.startswith('-l') or arg == '-shared':
- libs.append(arg)
- if os.getenv('ANDROID_RUST_DARWIN') and (arg == '-dylib' or arg == '-dynamiclib'):
- libs.append(arg)
- if arg.startswith('-Wl,--version-script='):
- version_script = arg[21:]
- if arg[0] == '-':
- continue
- if arg.endswith('.o') or arg.endswith('.rmeta'):
- objects.append(arg)
- if arg.endswith('.rlib'):
- if arg.startswith(os.getenv('TMPDIR')):
- temp_archives.append(arg)
- else:
- archives.append(arg)
-
-create_archive(f'{out}.whole.a', objects, [])
-create_archive(f'{out}.a', [], temp_archives)
-
-with open(out, 'w') as f:
- if os.getenv("ANDROID_RUST_DARWIN"):
- print(f'-force_load', file=f)
- print(f'{out}.whole.a', file=f)
- else:
- print(f'-Wl,--whole-archive', file=f)
- print(f'{out}.whole.a', file=f)
- print(f'-Wl,--no-whole-archive', file=f)
- print(f'{out}.a', file=f)
- for a in archives:
- print(a, file=f)
- for linkdir in linkdirs:
- print(f'-L{linkdir}', file=f)
- for l in libs:
- print(l, file=f)
- if version_script:
- shutil.copyfile(version_script, f'{out}.version_script')
- print(f'-Wl,--version-script={out}.version_script', file=f)
diff --git a/sysprop/Android.bp b/sysprop/Android.bp
index e5263fe..7f51000 100644
--- a/sysprop/Android.bp
+++ b/sysprop/Android.bp
@@ -12,6 +12,7 @@
"soong-bp2build",
"soong-cc",
"soong-java",
+ "soong-sysprop-bp2build",
],
srcs: [
"sysprop_library.go",
diff --git a/sysprop/bp2build/Android.bp b/sysprop/bp2build/Android.bp
new file mode 100644
index 0000000..1b9eda8
--- /dev/null
+++ b/sysprop/bp2build/Android.bp
@@ -0,0 +1,16 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-sysprop-bp2build",
+ pkgPath: "android/soong/sysprop/bp2build",
+ deps: [
+ "soong-android",
+ "soong-bazel",
+ ],
+ srcs: [
+ "bp2build.go",
+ ],
+ pluginFor: ["soong_build"],
+}
diff --git a/sysprop/bp2build/bp2build.go b/sysprop/bp2build/bp2build.go
new file mode 100644
index 0000000..18991de
--- /dev/null
+++ b/sysprop/bp2build/bp2build.go
@@ -0,0 +1,106 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package bp2build
+
+import (
+ "android/soong/android"
+ "android/soong/bazel"
+)
+
+type SyspropLibraryLabels struct {
+ SyspropLibraryLabel string
+ CcSharedLibraryLabel string
+ CcStaticLibraryLabel string
+ JavaLibraryLabel string
+}
+
+// TODO(b/240463568): Additional properties will be added for API validation
+type bazelSyspropLibraryAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Tags bazel.StringListAttribute
+}
+
+func Bp2buildBaseSyspropLibrary(ctx android.Bp2buildMutatorContext, name string, srcs bazel.LabelListAttribute) {
+ apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.Bp2buildMutatorContext), ctx.Module())
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "sysprop_library",
+ Bzl_load_location: "//build/bazel/rules/sysprop:sysprop_library.bzl",
+ },
+ android.CommonAttributes{Name: name},
+ &bazelSyspropLibraryAttributes{
+ Srcs: srcs,
+ Tags: apexAvailableTags,
+ },
+ )
+}
+
+type bazelCcSyspropLibraryAttributes struct {
+ Dep bazel.LabelAttribute
+ Min_sdk_version *string
+ Tags bazel.StringListAttribute
+}
+
+func Bp2buildSyspropCc(ctx android.Bp2buildMutatorContext, labels SyspropLibraryLabels, minSdkVersion *string) {
+ apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.Bp2buildMutatorContext), ctx.Module())
+
+ attrs := &bazelCcSyspropLibraryAttributes{
+ Dep: *bazel.MakeLabelAttribute(":" + labels.SyspropLibraryLabel),
+ Min_sdk_version: minSdkVersion,
+ Tags: apexAvailableTags,
+ }
+
+ if labels.CcSharedLibraryLabel != "" {
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_sysprop_library_shared",
+ Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
+ },
+ android.CommonAttributes{Name: labels.CcSharedLibraryLabel},
+ attrs)
+ }
+ if labels.CcStaticLibraryLabel != "" {
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_sysprop_library_static",
+ Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
+ },
+ android.CommonAttributes{Name: labels.CcStaticLibraryLabel},
+ attrs)
+ }
+}
+
+type bazelJavaLibraryAttributes struct {
+ Dep bazel.LabelAttribute
+ Min_sdk_version *string
+ Tags bazel.StringListAttribute
+}
+
+func Bp2buildSyspropJava(ctx android.Bp2buildMutatorContext, labels SyspropLibraryLabels, minSdkVersion *string) {
+ apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.Bp2buildMutatorContext), ctx.Module())
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "java_sysprop_library",
+ Bzl_load_location: "//build/bazel/rules/java:java_sysprop_library.bzl",
+ },
+ android.CommonAttributes{Name: labels.JavaLibraryLabel},
+ &bazelJavaLibraryAttributes{
+ Dep: *bazel.MakeLabelAttribute(":" + labels.SyspropLibraryLabel),
+ Min_sdk_version: minSdkVersion,
+ Tags: apexAvailableTags,
+ })
+}
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index d16bf32..13cf68f 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -24,6 +24,8 @@
"sync"
"android/soong/bazel"
+ "android/soong/sysprop/bp2build"
+ "android/soong/ui/metrics/bp2build_metrics_proto"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -230,6 +232,10 @@
return m.BaseModuleName() + "_java_gen_public"
}
+func (m *syspropLibrary) bp2buildJavaImplementationModuleName() string {
+ return m.BaseModuleName() + "_java_library"
+}
+
func (m *syspropLibrary) BaseModuleName() string {
return m.ModuleBase.Name()
}
@@ -431,6 +437,7 @@
Min_sdk_version *string
Bazel_module struct {
Bp2build_available *bool
+ Label *string
}
}
@@ -551,8 +558,10 @@
Min_sdk_version: m.properties.Java.Min_sdk_version,
Bazel_module: struct {
Bp2build_available *bool
+ Label *string
}{
- Bp2build_available: proptools.BoolPtr(false),
+ Label: proptools.StringPtr(
+ fmt.Sprintf("//%s:%s", ctx.ModuleDir(), m.bp2buildJavaImplementationModuleName())),
},
})
@@ -573,6 +582,7 @@
Stem: proptools.StringPtr(m.BaseModuleName()),
Bazel_module: struct {
Bp2build_available *bool
+ Label *string
}{
Bp2build_available: proptools.BoolPtr(false),
},
@@ -592,13 +602,17 @@
// TODO(b/240463568): Additional properties will be added for API validation
func (m *syspropLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
- labels := cc.SyspropLibraryLabels{
- SyspropLibraryLabel: m.BaseModuleName(),
- SharedLibraryLabel: m.CcImplementationModuleName(),
- StaticLibraryLabel: cc.BazelLabelNameForStaticModule(m.CcImplementationModuleName()),
+ if m.Owner() != "Platform" {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, "Only sysprop libraries owned by platform are supported at this time")
+ return
}
- cc.Bp2buildSysprop(ctx,
- labels,
- bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Srcs)),
- m.properties.Cpp.Min_sdk_version)
+ labels := bp2build.SyspropLibraryLabels{
+ SyspropLibraryLabel: m.BaseModuleName(),
+ CcSharedLibraryLabel: m.CcImplementationModuleName(),
+ CcStaticLibraryLabel: cc.BazelLabelNameForStaticModule(m.CcImplementationModuleName()),
+ JavaLibraryLabel: m.bp2buildJavaImplementationModuleName(),
+ }
+ bp2build.Bp2buildBaseSyspropLibrary(ctx, labels.SyspropLibraryLabel, bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Srcs)))
+ bp2build.Bp2buildSyspropCc(ctx, labels, m.properties.Cpp.Min_sdk_version)
+ bp2build.Bp2buildSyspropJava(ctx, labels, m.properties.Java.Min_sdk_version)
}
diff --git a/sysprop/sysprop_library_conversion_test.go b/sysprop/sysprop_library_conversion_test.go
index 89adf7d..dabcc92 100644
--- a/sysprop/sysprop_library_conversion_test.go
+++ b/sysprop/sysprop_library_conversion_test.go
@@ -58,13 +58,18 @@
bp2build.AttrNameToString{
"dep": `":sysprop_foo"`,
}),
+ bp2build.MakeBazelTargetNoRestrictions("java_sysprop_library",
+ "sysprop_foo_java_library",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ }),
},
})
}
func TestSyspropLibraryCppMinSdkVersion(t *testing.T) {
bp2build.RunBp2BuildTestCaseSimple(t, bp2build.Bp2buildTestCase{
- Description: "sysprop_library with min_sdk_version",
+ Description: "sysprop_library with cpp min_sdk_version",
ModuleTypeUnderTest: "sysprop_library",
ModuleTypeUnderTestFactory: syspropLibraryFactory,
Filesystem: map[string]string{
@@ -105,6 +110,86 @@
"dep": `":sysprop_foo"`,
"min_sdk_version": `"5"`,
}),
+ bp2build.MakeBazelTargetNoRestrictions("java_sysprop_library",
+ "sysprop_foo_java_library",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ }),
},
})
}
+
+func TestSyspropLibraryJavaMinSdkVersion(t *testing.T) {
+ bp2build.RunBp2BuildTestCaseSimple(t, bp2build.Bp2buildTestCase{
+ Description: "sysprop_library with java min_sdk_version",
+ ModuleTypeUnderTest: "sysprop_library",
+ ModuleTypeUnderTestFactory: syspropLibraryFactory,
+ Filesystem: map[string]string{
+ "foo.sysprop": "",
+ "bar.sysprop": "",
+ },
+ Blueprint: `
+sysprop_library {
+ name: "sysprop_foo",
+ srcs: [
+ "foo.sysprop",
+ "bar.sysprop",
+ ],
+ java: {
+ min_sdk_version: "5",
+ },
+ property_owner: "Platform",
+}
+`,
+ ExpectedBazelTargets: []string{
+ bp2build.MakeBazelTargetNoRestrictions("sysprop_library",
+ "sysprop_foo",
+ bp2build.AttrNameToString{
+ "srcs": `[
+ "foo.sysprop",
+ "bar.sysprop",
+ ]`,
+ }),
+ bp2build.MakeBazelTargetNoRestrictions("cc_sysprop_library_shared",
+ "libsysprop_foo",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ }),
+ bp2build.MakeBazelTargetNoRestrictions("cc_sysprop_library_static",
+ "libsysprop_foo_bp2build_cc_library_static",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ }),
+ bp2build.MakeBazelTargetNoRestrictions("java_sysprop_library",
+ "sysprop_foo_java_library",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ "min_sdk_version": `"5"`,
+ }),
+ },
+ })
+}
+
+func TestSyspropLibraryOwnerNotPlatformUnconvertible(t *testing.T) {
+ bp2build.RunBp2BuildTestCaseSimple(t, bp2build.Bp2buildTestCase{
+ Description: "sysprop_library simple",
+ ModuleTypeUnderTest: "sysprop_library",
+ ModuleTypeUnderTestFactory: syspropLibraryFactory,
+ Filesystem: map[string]string{
+ "foo.sysprop": "",
+ "bar.sysprop": "",
+ },
+ Blueprint: `
+sysprop_library {
+ name: "sysprop_foo",
+ srcs: [
+ "foo.sysprop",
+ "bar.sysprop",
+ ],
+ property_owner: "Vendor",
+ device_specific: true,
+}
+`,
+ ExpectedBazelTargets: []string{},
+ })
+}
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 80b86e0..e51fe39 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -42,6 +42,7 @@
cc_library_headers {
name: "libbase_headers",
vendor_available: true,
+ product_available: true,
recovery_available: true,
}
@@ -250,6 +251,16 @@
result.ModuleForTests("libsysprop-odm", variant)
}
+ // product variant of vendor-owned sysprop_library
+ for _, variant := range []string{
+ "android_product.29_arm_armv7-a-neon_shared",
+ "android_product.29_arm_armv7-a-neon_static",
+ "android_product.29_arm64_armv8-a_shared",
+ "android_product.29_arm64_armv8-a_static",
+ } {
+ result.ModuleForTests("libsysprop-vendor-on-product", variant)
+ }
+
for _, variant := range []string{
"android_arm_armv7-a-neon_shared",
"android_arm_armv7-a-neon_static",
@@ -259,9 +270,6 @@
library := result.ModuleForTests("libsysprop-platform", variant).Module().(*cc.Module)
expectedApexAvailableOnLibrary := []string{"//apex_available:platform"}
android.AssertDeepEquals(t, "apex available property on libsysprop-platform", expectedApexAvailableOnLibrary, library.ApexProperties.Apex_available)
-
- // product variant of vendor-owned sysprop_library
- result.ModuleForTests("libsysprop-vendor-on-product", variant)
}
result.ModuleForTests("sysprop-platform", "android_common")
@@ -272,15 +280,15 @@
// Check for exported includes
coreVariant := "android_arm64_armv8-a_static"
vendorVariant := "android_vendor.29_arm64_armv8-a_static"
+ productVariant := "android_product.29_arm64_armv8-a_static"
platformInternalPath := "libsysprop-platform/android_arm64_armv8-a_static/gen/sysprop/include"
- platformPublicCorePath := "libsysprop-platform/android_arm64_armv8-a_static/gen/sysprop/public/include"
platformPublicVendorPath := "libsysprop-platform/android_vendor.29_arm64_armv8-a_static/gen/sysprop/public/include"
- platformOnProductPath := "libsysprop-platform-on-product/android_arm64_armv8-a_static/gen/sysprop/public/include"
+ platformOnProductPath := "libsysprop-platform-on-product/android_product.29_arm64_armv8-a_static/gen/sysprop/public/include"
vendorInternalPath := "libsysprop-vendor/android_vendor.29_arm64_armv8-a_static/gen/sysprop/include"
- vendorPublicPath := "libsysprop-vendor-on-product/android_arm64_armv8-a_static/gen/sysprop/public/include"
+ vendorOnProductPath := "libsysprop-vendor-on-product/android_product.29_arm64_armv8-a_static/gen/sysprop/public/include"
platformClient := result.ModuleForTests("cc-client-platform", coreVariant)
platformFlags := platformClient.Rule("cc").Args["cFlags"]
@@ -294,14 +302,14 @@
// platform-static should use platform's internal header
android.AssertStringDoesContain(t, "flags for platform-static", platformStaticFlags, platformInternalPath)
- productClient := result.ModuleForTests("cc-client-product", coreVariant)
+ productClient := result.ModuleForTests("cc-client-product", productVariant)
productFlags := productClient.Rule("cc").Args["cFlags"]
// Product should use platform's and vendor's public headers
if !strings.Contains(productFlags, platformOnProductPath) ||
- !strings.Contains(productFlags, vendorPublicPath) {
+ !strings.Contains(productFlags, vendorOnProductPath) {
t.Errorf("flags for product must contain %#v and %#v, but was %#v.",
- platformPublicCorePath, vendorPublicPath, productFlags)
+ platformOnProductPath, vendorOnProductPath, productFlags)
}
vendorClient := result.ModuleForTests("cc-client-vendor", vendorVariant)
diff --git a/tests/lib.sh b/tests/lib.sh
index 0766d85..fb3b374 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -8,6 +8,11 @@
REAL_TOP="$(readlink -f "$(dirname "$0")"/../../..)"
+function make_mock_top {
+ mock=$(mktemp -t -d st.XXXXX)
+ echo "$mock"
+}
+
if [[ -n "$HARDWIRED_MOCK_TOP" ]]; then
MOCK_TOP="$HARDWIRED_MOCK_TOP"
else
@@ -158,6 +163,7 @@
symlink_directory external/bazelbuild-rules_python
symlink_directory external/bazelbuild-rules_java
symlink_directory external/bazelbuild-rules_rust
+ symlink_directory external/bazelbuild-rules_testing
symlink_directory external/rust/crates/tinyjson
symlink_file WORKSPACE
@@ -197,3 +203,11 @@
info "Completed test case \e[96;1m$f\e[0m"
done
}
+
+function move_mock_top {
+ MOCK_TOP2=$(make_mock_top)
+ rm -rf $MOCK_TOP2
+ mv $MOCK_TOP $MOCK_TOP2
+ MOCK_TOP=$MOCK_TOP2
+ trap cleanup_mock_top EXIT
+}
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index 6b9ff8b..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
@@ -23,4 +24,4 @@
"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_cf_arm64_phone" "armv8-a" "cortex-a53"
"$TOP/build/bazel/ci/b_test.sh"
-
+"$TOP/build/soong/tests/symlinks_path_test.sh"
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
diff --git a/tests/symlinks_path_test.sh b/tests/symlinks_path_test.sh
new file mode 100755
index 0000000..ed42911
--- /dev/null
+++ b/tests/symlinks_path_test.sh
@@ -0,0 +1,51 @@
+#!/bin/bash -eu
+
+set -o pipefail
+
+# Test that relative symlinks work by recreating the bug in b/259191764
+# In some cases, developers prefer to move their checkouts. This causes
+# issues in that symlinked files (namely, the bazel wrapper script)
+# cannot be found. As such, we implemented relative symlinks so that a
+# moved checkout doesn't need a full clean before rebuilding.
+# The bazel output base will still need to be removed, as Starlark
+# doesn't seem to support relative symlinks yet.
+
+source "$(dirname "$0")/lib.sh"
+
+function check_link_has_mock_top_prefix {
+ input_link=$1
+ link_target=`readlink $input_link`
+ if [[ $link_target != "$MOCK_TOP"* ]]; then
+ echo "Symlink for file $input_link -> $link_target doesn't start with $MOCK_TOP"
+ exit 1
+ fi
+}
+
+function test_symlinks_updated_when_top_dir_changed {
+ setup
+
+ mkdir -p a
+ touch a/g.txt
+ cat > a/Android.bp <<'EOF'
+filegroup {
+ name: "g",
+ srcs: ["g.txt"],
+ bazel_module: {bp2build_available: true},
+}
+EOF
+ # A directory under $MOCK_TOP
+ outdir=out2
+
+ # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
+ (export OUT_DIR=$MOCK_TOP/$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
+
+ g_txt="out2/soong/workspace/a/g.txt"
+ check_link_has_mock_top_prefix "$g_txt"
+
+ move_mock_top
+
+ (export OUT_DIR=$MOCK_TOP/$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
+ check_link_has_mock_top_prefix "$g_txt"
+}
+
+scan_and_run_tests
\ No newline at end of file
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 44c20a0..ac9bf3a 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -16,10 +16,13 @@
import (
"fmt"
+ "io/fs"
"os"
"path/filepath"
"strconv"
"strings"
+ "sync"
+ "sync/atomic"
"android/soong/bazel"
"android/soong/ui/metrics"
@@ -50,6 +53,13 @@
bootstrapEpoch = 1
)
+var (
+ // Used during parallel update of symlinks in out directory to reflect new
+ // TOP dir.
+ symlinkWg sync.WaitGroup
+ numFound, numUpdated uint32
+)
+
func writeEnvironmentFile(_ Context, envFile string, envDeps map[string]string) error {
data, err := shared.EnvFileContents(envDeps)
if err != nil {
@@ -465,10 +475,118 @@
}
}
+func updateSymlinks(ctx Context, dir, prevCWD, cwd string) error {
+ defer symlinkWg.Done()
+
+ visit := func(path string, d fs.DirEntry, err error) error {
+ if d.IsDir() && path != dir {
+ symlinkWg.Add(1)
+ go updateSymlinks(ctx, path, prevCWD, cwd)
+ return filepath.SkipDir
+ }
+ f, err := d.Info()
+ if err != nil {
+ return err
+ }
+ // If the file is not a symlink, we don't have to update it.
+ if f.Mode()&os.ModeSymlink != os.ModeSymlink {
+ return nil
+ }
+
+ atomic.AddUint32(&numFound, 1)
+ target, err := os.Readlink(path)
+ if err != nil {
+ return err
+ }
+ if strings.HasPrefix(target, prevCWD) &&
+ (len(target) == len(prevCWD) || target[len(prevCWD)] == '/') {
+ target = filepath.Join(cwd, target[len(prevCWD):])
+ if err := os.Remove(path); err != nil {
+ return err
+ }
+ if err := os.Symlink(target, path); err != nil {
+ return err
+ }
+ atomic.AddUint32(&numUpdated, 1)
+ }
+ return nil
+ }
+
+ if err := filepath.WalkDir(dir, visit); err != nil {
+ return err
+ }
+ return nil
+}
+
+func fixOutDirSymlinks(ctx Context, config Config, outDir string) error {
+ cwd, err := os.Getwd()
+ if err != nil {
+ return err
+ }
+
+ // Record the .top as the very last thing in the function.
+ tf := filepath.Join(outDir, ".top")
+ defer func() {
+ if err := os.WriteFile(tf, []byte(cwd), 0644); err != nil {
+ fmt.Fprintf(os.Stderr, fmt.Sprintf("Unable to log CWD: %v", err))
+ }
+ }()
+
+ // Find the previous working directory if it was recorded.
+ var prevCWD string
+ pcwd, err := os.ReadFile(tf)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // No previous working directory recorded, nothing to do.
+ return nil
+ }
+ return err
+ }
+ prevCWD = strings.Trim(string(pcwd), "\n")
+
+ if prevCWD == cwd {
+ // We are in the same source dir, nothing to update.
+ return nil
+ }
+
+ symlinkWg.Add(1)
+ if err := updateSymlinks(ctx, outDir, prevCWD, cwd); err != nil {
+ return err
+ }
+ symlinkWg.Wait()
+ ctx.Println(fmt.Sprintf("Updated %d/%d symlinks in dir %v", numUpdated, numFound, outDir))
+ return nil
+}
+
+func migrateOutputSymlinks(ctx Context, config Config) error {
+ // Figure out the real out directory ("out" could be a symlink).
+ outDir := config.OutDir()
+ s, err := os.Lstat(outDir)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // No out dir exists, no symlinks to migrate.
+ return nil
+ }
+ return err
+ }
+ if s.Mode()&os.ModeSymlink == os.ModeSymlink {
+ target, err := filepath.EvalSymlinks(outDir)
+ if err != nil {
+ return err
+ }
+ outDir = target
+ }
+ return fixOutDirSymlinks(ctx, config, outDir)
+}
+
func runSoong(ctx Context, config Config) {
ctx.BeginTrace(metrics.RunSoong, "soong")
defer ctx.EndTrace()
+ if err := migrateOutputSymlinks(ctx, config); err != nil {
+ ctx.Fatalf("failed to migrate output directory to current TOP dir: %v", err)
+ }
+
// We have two environment files: .available is the one with every variable,
// .used with the ones that were actually used. The latter is used to
// determine whether Soong needs to be re-run since why re-run it if only