diff options
30 files changed, 316 insertions, 168 deletions
@@ -26,8 +26,6 @@ review request is enough. For more substantial changes, file a bug in our [bug tracker](https://issuetracker.google.com/issues/new?component=381517) or or write us at android-building@googlegroups.com . -For Googlers, see our [internal documentation](http://go/soong). - ## Android.bp file format By design, Android.bp files are very simple. There are no conditionals or diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index fb2e0d7c7..e82e754ae 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -178,6 +178,7 @@ var ( "external/libjpeg-turbo": Bp2BuildDefaultTrueRecursively, "external/libmpeg2": Bp2BuildDefaultTrueRecursively, "external/libpng": Bp2BuildDefaultTrueRecursively, + "external/libphonenumber": Bp2BuildDefaultTrueRecursively, "external/libvpx": Bp2BuildDefaultTrueRecursively, "external/libyuv": Bp2BuildDefaultTrueRecursively, "external/lz4/lib": Bp2BuildDefaultTrue, @@ -285,13 +286,9 @@ var ( "hardware/interfaces/health/2.1": Bp2BuildDefaultTrue, "hardware/interfaces/health/aidl": Bp2BuildDefaultTrue, "hardware/interfaces/health/utils": Bp2BuildDefaultTrueRecursively, - "hardware/interfaces/media/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/media/bufferpool": Bp2BuildDefaultTrueRecursively, + "hardware/interfaces/media": Bp2BuildDefaultTrueRecursively, "hardware/interfaces/media/bufferpool/aidl/default/tests": Bp2BuildDefaultFalseRecursively, - "hardware/interfaces/media/c2/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/media/c2/1.1": Bp2BuildDefaultTrue, - "hardware/interfaces/media/c2/1.2": Bp2BuildDefaultTrue, - "hardware/interfaces/media/omx/1.0": Bp2BuildDefaultTrue, + "hardware/interfaces/media/omx/1.0/vts": Bp2BuildDefaultFalseRecursively, "hardware/interfaces/neuralnetworks": Bp2BuildDefaultTrueRecursively, "hardware/interfaces/neuralnetworks/aidl/vts": Bp2BuildDefaultFalseRecursively, "hardware/interfaces/neuralnetworks/1.0/vts": Bp2BuildDefaultFalseRecursively, @@ -414,6 +411,7 @@ var ( "system/tools/aidl/build/tests_bp2build": Bp2BuildDefaultTrue, "system/tools/aidl/metadata": Bp2BuildDefaultTrue, "system/tools/hidl/metadata": Bp2BuildDefaultTrue, + "system/tools/hidl/utils": Bp2BuildDefaultTrue, "system/tools/mkbootimg": Bp2BuildDefaultTrueRecursively, "system/tools/sysprop": Bp2BuildDefaultTrue, "system/tools/xsdc/utils": Bp2BuildDefaultTrueRecursively, @@ -422,7 +420,7 @@ var ( "tools/apifinder": Bp2BuildDefaultTrue, "tools/apksig": Bp2BuildDefaultTrue, "tools/external_updater": Bp2BuildDefaultTrueRecursively, - "tools/metalava": Bp2BuildDefaultTrue, + "tools/metalava": Bp2BuildDefaultTrueRecursively, "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively, "tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively, } @@ -1051,6 +1049,7 @@ var ( "libgmock_ndk", // depends on unconverted modules: libgtest_ndk_c++ "libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libnativetesthelper_jni, libgmock_ndk "libnativetesthelper_jni", // depends on unconverted modules: libgtest_ndk_c++ + "libphonenumber_test", // depends on android.test.mock "libstatslog", // depends on unconverted modules: libstatspull, statsd-aidl-ndk "libstatslog_art", // depends on unconverted modules: statslog_art.cpp, statslog_art.h "linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_* @@ -1636,10 +1635,6 @@ var ( // depends on libart-unstripped and new module type llvm_prebuilt_build_tool "check_cfi", - // TODO(b/297070571): cannot convert prebuilts_etc module which possess identical name and src properties - "boringssl_self_test.zygote64.rc", - "boringssl_self_test.zygote64_32.rc", - // depends on unconverted module tradefed "HelloWorldPerformanceTest", diff --git a/android/apex.go b/android/apex.go index 6119b0836..d84499b9d 100644 --- a/android/apex.go +++ b/android/apex.go @@ -934,6 +934,19 @@ func CheckMinSdkVersion(ctx ModuleContext, minSdkVersion ApiLevel, walk WalkPayl }) } +// Construct ApiLevel object from min_sdk_version string value +func MinSdkVersionFromValue(ctx EarlyModuleContext, value string) ApiLevel { + if value == "" { + return NoneApiLevel + } + apiLevel, err := ApiLevelFromUser(ctx, value) + if err != nil { + ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) + return NoneApiLevel + } + return apiLevel +} + // Implemented by apexBundle. type ApexTestInterface interface { // Return true if the apex bundle is an apex_test diff --git a/android/variable.go b/android/variable.go index 02eff25f9..524cdf75c 100644 --- a/android/variable.go +++ b/android/variable.go @@ -438,16 +438,17 @@ type ProductVariables struct { ShippingApiLevel *string `json:",omitempty"` - BuildBrokenPluginValidation []string `json:",omitempty"` - BuildBrokenClangAsFlags bool `json:",omitempty"` - BuildBrokenClangCFlags bool `json:",omitempty"` - BuildBrokenClangProperty bool `json:",omitempty"` - GenruleSandboxing *bool `json:",omitempty"` - BuildBrokenEnforceSyspropOwner bool `json:",omitempty"` - BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"` - BuildBrokenUsesSoongPython2Modules bool `json:",omitempty"` - BuildBrokenVendorPropertyNamespace bool `json:",omitempty"` - BuildBrokenInputDirModules []string `json:",omitempty"` + BuildBrokenPluginValidation []string `json:",omitempty"` + BuildBrokenClangAsFlags bool `json:",omitempty"` + BuildBrokenClangCFlags bool `json:",omitempty"` + BuildBrokenClangProperty bool `json:",omitempty"` + GenruleSandboxing *bool `json:",omitempty"` + BuildBrokenEnforceSyspropOwner bool `json:",omitempty"` + BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"` + BuildBrokenUsesSoongPython2Modules bool `json:",omitempty"` + BuildBrokenVendorPropertyNamespace bool `json:",omitempty"` + BuildBrokenIncorrectPartitionImages bool `json:",omitempty"` + BuildBrokenInputDirModules []string `json:",omitempty"` BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"` diff --git a/apex/apex.go b/apex/apex.go index 1e65b0ffe..a116b85ee 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -18,6 +18,7 @@ package apex import ( "fmt" + "log" "path/filepath" "regexp" "sort" @@ -991,6 +992,13 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) { return false } } + + //TODO: b/296491928 Vendor APEX should use libbinder.ndk instead of libbinder once VNDK is fully deprecated. + if useVndk && mctx.Config().IsVndkDeprecated() && child.Name() == "libbinder" { + log.Print("Libbinder is linked from Vendor APEX ", a.Name(), " with module ", parent.Name()) + return false + } + // By default, all the transitive dependencies are collected, unless filtered out // above. return true @@ -2225,6 +2233,11 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk") return false } + + //TODO: b/296491928 Vendor APEX should use libbinder.ndk instead of libbinder once VNDK is fully deprecated. + if ch.UseVndk() && ctx.Config().IsVndkDeprecated() && child.Name() == "libbinder" { + return false + } af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs) af.transitiveDep = true @@ -2730,13 +2743,13 @@ func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string { // Only override the minSdkVersion value on Apexes which already specify // a min_sdk_version (it's optional for non-updatable apexes), and that its // min_sdk_version value is lower than the one to override with. - minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version)) + minApiLevel := android.MinSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version)) if minApiLevel.IsNone() { return "" } overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride() - overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue) + overrideApiLevel := android.MinSdkVersionFromValue(ctx, overrideMinSdkValue) if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 { minApiLevel = overrideApiLevel } @@ -2751,20 +2764,7 @@ func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLe // Returns apex's min_sdk_version ApiLevel, honoring overrides func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { - return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx)) -} - -// Construct ApiLevel object from min_sdk_version string value -func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel { - if value == "" { - return android.NoneApiLevel - } - apiLevel, err := android.ApiLevelFromUser(ctx, value) - if err != nil { - ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) - return android.NoneApiLevel - } - return apiLevel + return android.MinSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx)) } // Ensures that a lib providing stub isn't statically linked diff --git a/bazel/aquery.go b/bazel/aquery.go index 76cd97254..c35571239 100644 --- a/bazel/aquery.go +++ b/bazel/aquery.go @@ -177,6 +177,21 @@ func newAqueryHandler(aqueryResult *analysis_v2_proto.ActionGraphContainer) (*aq if err != nil { return nil, err } + if artifact.IsTreeArtifact && + !strings.HasPrefix(artifactPath, "bazel-out/io_bazel_rules_go/") && + !strings.HasPrefix(artifactPath, "bazel-out/rules_java_builtin/") { + // Since we're using ninja as an executor, we can't use tree artifacts. Ninja only + // considers a file/directory "dirty" when it's mtime changes. Directories' mtimes will + // only change when a file in the directory is added/removed, but not when files in + // the directory are changed, or when files in subdirectories are changed/added/removed. + // Bazel handles this by walking the directory and generating a hash for it after the + // action runs, which we would have to do as well if we wanted to support these + // artifacts in mixed builds. + // + // However, there are some bazel built-in rules that use tree artifacts. Allow those, + // but keep in mind that they'll have incrementality issues. + return nil, fmt.Errorf("tree artifacts are currently not supported in mixed builds: " + artifactPath) + } artifactIdToPath[artifactId(artifact.Id)] = artifactPath } diff --git a/bp2build/api_domain_conversion_test.go b/bp2build/api_domain_conversion_test.go deleted file mode 100644 index 224008fef..000000000 --- a/bp2build/api_domain_conversion_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2022 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package bp2build - -import ( - "testing" - - "android/soong/android" - "android/soong/cc" -) - -func registerApiDomainModuleTypes(ctx android.RegistrationContext) { - android.RegisterApiDomainBuildComponents(ctx) - cc.RegisterNdkModuleTypes(ctx) - cc.RegisterLibraryBuildComponents(ctx) -} - -func TestApiDomainContributionsTest(t *testing.T) { - bp := ` - api_domain { - name: "system", - cc_api_contributions: [ - "libfoo.ndk", - "libbar", - ], - } - ` - fs := map[string]string{ - "libfoo/Android.bp": ` - ndk_library { - name: "libfoo", - } - `, - "libbar/Android.bp": ` - cc_library { - name: "libbar", - } - `, - } - expectedBazelTarget := MakeBazelTargetNoRestrictions( - "api_domain", - "system", - AttrNameToString{ - "cc_api_contributions": `[ - "//libfoo:libfoo.ndk.contribution", - "//libbar:libbar.contribution", - ]`, - "target_compatible_with": `["//build/bazel/platforms/os:android"]`, - }, - ) - RunApiBp2BuildTestCase(t, registerApiDomainModuleTypes, Bp2buildTestCase{ - Blueprint: bp, - ExpectedBazelTargets: []string{expectedBazelTarget}, - Filesystem: fs, - }) -} diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go index 77179934f..20355d736 100644 --- a/bp2build/bp2build_product_config.go +++ b/bp2build/bp2build_product_config.go @@ -12,6 +12,7 @@ import ( "android/soong/android/soongconfig" "android/soong/starlark_import" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" "go.starlark.net/starlark" ) @@ -45,6 +46,15 @@ func CreateProductConfigFiles( return nil, nil, err } + // Visit all modules to determine the list of ndk libraries + // This list will be used to add additional flags for cc stub generation + ndkLibsStringFormatted := []string{} + ctx.Context().VisitAllModules(func(m blueprint.Module) { + if ctx.Context().ModuleType(m) == "ndk_library" { + ndkLibsStringFormatted = append(ndkLibsStringFormatted, fmt.Sprintf(`"%s"`, m.Name())) // name will be `"libc.ndk"` + } + }) + // TODO(b/249685973): the name is product_config_platforms because product_config // was already used for other files. Deduplicate them. currentProductFolder := fmt.Sprintf("product_config_platforms/products/%s-%s", targetProduct, targetBuildVariant) @@ -154,6 +164,11 @@ build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_lin productReplacer.Replace(` build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_darwin_x86_64 `)), + newFile( + "cc_toolchain", + "ndk_libs.bzl", + fmt.Sprintf("ndk_libs = [%v]", strings.Join(ndkLibsStringFormatted, ", ")), + ), } bp2buildDirFiles := []BazelFile{ newFile( @@ -246,6 +261,7 @@ func platformMappingSingleProduct( result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:binder32bit=%t\n", proptools.Bool(productVariables.Binder32bit))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_from_text_stub=%t\n", proptools.Bool(productVariables.Build_from_text_stub))) + result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_broken_incorrect_partition_images=%t\n", productVariables.BuildBrokenIncorrectPartitionImages)) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_id=%s\n", proptools.String(productVariables.BuildId))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_version_tags=%s\n", strings.Join(productVariables.BuildVersionTags, ","))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:cfi_exclude_paths=%s\n", strings.Join(productVariables.CFIExcludePaths, ","))) diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 246f1693e..9bb171330 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -2867,7 +2867,6 @@ cc_library { ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{ "implementation_dynamic_deps": `select({ "//build/bazel/rules/apex:foo": ["@api_surfaces//module-libapi/current:barlib"], - "//build/bazel/rules/apex:system": ["@api_surfaces//module-libapi/current:barlib"], "//conditions:default": [":barlib"], })`, "local_includes": `["."]`, @@ -2925,10 +2924,6 @@ cc_library { "@api_surfaces//module-libapi/current:barlib", "@api_surfaces//module-libapi/current:quxlib", ], - "//build/bazel/rules/apex:system": [ - "@api_surfaces//module-libapi/current:barlib", - "@api_surfaces//module-libapi/current:quxlib", - ], "//conditions:default": [ ":barlib", ":quxlib", diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 90b13b03f..44b97227e 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -661,7 +661,7 @@ cc_library_shared { ":libapexfoo_stable", ], "//build/bazel/rules/apex:system": [ - "@api_surfaces//module-libapi/current:libplatform_stable", + ":libplatform_stable", "@api_surfaces//module-libapi/current:libapexfoo_stable", ], "//conditions:default": [ diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go index 7429ae6df..512c1e102 100644 --- a/bp2build/java_library_conversion_test.go +++ b/bp2build/java_library_conversion_test.go @@ -441,12 +441,13 @@ func TestJavaLibraryResourcesExcludeFile(t *testing.T) { func TestJavaLibraryResourcesWithMultipleDirs(t *testing.T) { runJavaLibraryTestCase(t, Bp2buildTestCase{ Filesystem: map[string]string{ - "res/a.res": "", - "res1/b.res": "", + "res/a.res": "", + "res1/b.res": "", + "res2/b.java": "", }, Blueprint: `java_library { name: "java-lib-1", - java_resource_dirs: ["res", "res1"], + java_resource_dirs: ["res", "res1", "res2"], sdk_version: "current", }`, ExpectedBazelTargets: []string{ @@ -1046,3 +1047,14 @@ filegroup { ctx.RegisterModuleType("filegroup", android.FileGroupFactory) }) } + +func TestJavaSdkVersionCorePlatformDoesNotConvert(t *testing.T) { + runJavaLibraryTestCase(t, Bp2buildTestCase{ + Blueprint: `java_library { + name: "java-lib-1", + sdk_version: "core_platform", + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{}, + }) +} diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go index 5b2d609ac..e2373038a 100644 --- a/bp2build/prebuilt_etc_conversion_test.go +++ b/bp2build/prebuilt_etc_conversion_test.go @@ -346,3 +346,17 @@ prebuilt_etc { ExpectedErr: fmt.Errorf("label attribute could not be collapsed"), }) } + +func TestPrebuiltEtcNoConversionIfSrcEqualsName(t *testing.T) { + runPrebuiltEtcTestCase(t, Bp2buildTestCase{ + Description: "", + Filesystem: map[string]string{}, + Blueprint: ` +prebuilt_etc { + name: "foo", + filename: "fooFilename", + src: "foo", +}`, + ExpectedBazelTargets: []string{}, + }) +} diff --git a/cc/bp2build.go b/cc/bp2build.go index 83553c8c2..62416f79d 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -1624,6 +1624,11 @@ func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.C if linkable, ok := ctx.Module().(LinkableInterface); ok && linkable.Bootstrap() { sameApiDomain = true } + // If dependency has `apex_available: ["//apex_available:platform]`, then the platform variant of rdep should link against its impl. + // https://cs.android.com/android/_/android/platform/build/soong/+/main:cc/cc.go;l=3617;bpv=1;bpt=0;drc=c6a93d853b37ec90786e745b8d282145e6d3b589 + if depApexAvailable := dep.(*Module).ApexAvailable(); len(depApexAvailable) == 1 && depApexAvailable[0] == android.AvailableToPlatform { + sameApiDomain = true + } } else { sameApiDomain = android.InList(apiDomain, dep.(*Module).ApexAvailable()) } diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index 370a4235b..c48bafa26 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -40,6 +40,7 @@ import ( "android/soong/bazel" "android/soong/bazel/cquery" "android/soong/snapshot" + "android/soong/ui/metrics/bp2build_metrics_proto" ) var pctx = android.NewPackageContext("android/soong/etc") @@ -711,7 +712,7 @@ type bazelPrebuiltFileAttributes struct { // Bp2buildHelper returns a bazelPrebuiltFileAttributes used for the conversion // of prebuilt_* modules. bazelPrebuiltFileAttributes has the common attributes // used by both prebuilt_etc_xml and other prebuilt_* moodules -func (module *PrebuiltEtc) Bp2buildHelper(ctx android.TopDownMutatorContext) *bazelPrebuiltFileAttributes { +func (module *PrebuiltEtc) Bp2buildHelper(ctx android.TopDownMutatorContext) (*bazelPrebuiltFileAttributes, bool) { var src bazel.LabelAttribute for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltEtcProperties{}) { for config, p := range configToProps { @@ -720,7 +721,12 @@ func (module *PrebuiltEtc) Bp2buildHelper(ctx android.TopDownMutatorContext) *ba continue } if props.Src != nil { - label := android.BazelLabelForModuleSrcSingle(ctx, *props.Src) + srcStr := proptools.String(props.Src) + if srcStr == ctx.ModuleName() { + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "src == name") + return &bazelPrebuiltFileAttributes{}, false + } + label := android.BazelLabelForModuleSrcSingle(ctx, srcStr) src.SetSelectValue(axis, config, label) } } @@ -779,8 +785,7 @@ func (module *PrebuiltEtc) Bp2buildHelper(ctx android.TopDownMutatorContext) *ba attrs.Filename_from_src = bazel.BoolAttribute{Value: moduleProps.Filename_from_src} } - return attrs - + return attrs, true } // ConvertWithBp2build performs bp2build conversion of PrebuiltEtc @@ -793,7 +798,10 @@ func (module *PrebuiltEtc) ConvertWithBp2build(ctx android.TopDownMutatorContext return } - attrs := module.Bp2buildHelper(ctx) + attrs, convertible := module.Bp2buildHelper(ctx) + if !convertible { + return + } props := bazel.BazelTargetModuleProperties{ Rule_class: "prebuilt_file", diff --git a/java/app.go b/java/app.go index d71cd777c..d533b713a 100755 --- a/java/app.go +++ b/java/app.go @@ -316,6 +316,17 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.generateJavaUsedByApex(ctx) } +func (a *AndroidApp) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + defaultMinSdkVersion := a.Module.MinSdkVersion(ctx) + if proptools.Bool(a.appProperties.Updatable) { + overrideApiLevel := android.MinSdkVersionFromValue(ctx, ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()) + if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(defaultMinSdkVersion) > 0 { + return overrideApiLevel + } + } + return defaultMinSdkVersion +} + func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) { if a.Updatable() { if !a.SdkVersion(ctx).Stable() { diff --git a/java/app_import.go b/java/app_import.go index ad1765e9d..1718d936c 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -277,6 +277,14 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext a.hideApexVariantFromMake = true } + if Bool(a.properties.Preprocessed) { + if a.properties.Presigned != nil && !*a.properties.Presigned { + ctx.ModuleErrorf("Setting preprocessed: true implies presigned: true, so you cannot set presigned to false") + } + t := true + a.properties.Presigned = &t + } + numCertPropsSet := 0 if String(a.properties.Certificate) != "" { numCertPropsSet++ @@ -288,11 +296,9 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext numCertPropsSet++ } if numCertPropsSet != 1 { - ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set") + ctx.ModuleErrorf("One and only one of certficate, presigned (implied by preprocessed), and default_dev_cert properties must be set") } - _, _, certificates := collectAppDeps(ctx, a, false, false) - // TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK // TODO: LOCAL_PACKAGE_SPLITS @@ -365,6 +371,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext } else if !Bool(a.properties.Presigned) { // If the certificate property is empty at this point, default_dev_cert must be set to true. // Which makes processMainCert's behavior for the empty cert string WAI. + _, _, certificates := collectAppDeps(ctx, a, false, false) a.certificate, certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx) signed := android.PathForModuleOut(ctx, "signed", apkFilename) var lineageFile android.Path @@ -377,8 +384,13 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext SignAppPackage(ctx, signed, jnisUncompressed, certificates, nil, lineageFile, rotationMinSdkVersion) a.outputFile = signed } else { + // Presigned without Preprocessed shouldn't really be a thing, currently we disallow + // it for apps with targetSdk >= 30, because on those targetSdks you must be using signature + // v2 or later, and signature v2 would be wrecked by uncompressing libs / zipaligning. + // But ideally we would disallow it for all prebuilt apks, and remove the presigned property. + targetSdkCheck := a.validateTargetSdkLessThan30(ctx, srcApk) alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename) - TransformZipAlign(ctx, alignedApk, jnisUncompressed) + TransformZipAlign(ctx, alignedApk, jnisUncompressed, []android.Path{targetSdkCheck}) a.outputFile = alignedApk a.certificate = PresignedCertificate } @@ -432,6 +444,16 @@ func (a *AndroidAppImport) validatePreprocessedApk(ctx android.ModuleContext, sr }) } +func (a *AndroidAppImport) validateTargetSdkLessThan30(ctx android.ModuleContext, srcApk android.Path) android.Path { + alignmentStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "old_target_sdk.stamp") + ctx.Build(pctx, android.BuildParams{ + Rule: checkBelowTargetSdk30ForNonPreprocessedApks, + Input: srcApk, + Output: alignmentStamp, + }) + return alignmentStamp +} + func (a *AndroidAppImport) Prebuilt() *android.Prebuilt { return &a.prebuilt } diff --git a/java/app_import_test.go b/java/app_import_test.go index bb8fab93b..506c7344b 100644 --- a/java/app_import_test.go +++ b/java/app_import_test.go @@ -629,31 +629,21 @@ func TestAndroidTestImport_Preprocessed(t *testing.T) { presigned: true, preprocessed: true, } - - android_test_import { - name: "foo_cert", - apk: "prebuilts/apk/app.apk", - certificate: "cert/new_cert", - preprocessed: true, - } `) - testModules := []string{"foo", "foo_cert"} - for _, m := range testModules { - apkName := m + ".apk" - variant := ctx.ModuleForTests(m, "android_common") - jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String() - if jniRule != android.Cp.String() { - t.Errorf("Unexpected JNI uncompress rule: " + jniRule) - } + apkName := "foo.apk" + variant := ctx.ModuleForTests("foo", "android_common") + jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String() + if jniRule != android.Cp.String() { + t.Errorf("Unexpected JNI uncompress rule: " + jniRule) + } - // Make sure signing and aligning were skipped. - if variant.MaybeOutput("signed/"+apkName).Rule != nil { - t.Errorf("signing rule shouldn't be included for preprocessed.") - } - if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil { - t.Errorf("aligning rule shouldn't be for preprocessed") - } + // Make sure signing and aligning were skipped. + if variant.MaybeOutput("signed/"+apkName).Rule != nil { + t.Errorf("signing rule shouldn't be included for preprocessed.") + } + if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil { + t.Errorf("aligning rule shouldn't be for preprocessed") } } diff --git a/java/app_test.go b/java/app_test.go index 8474ea7d6..fc57f444a 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -4137,3 +4137,49 @@ func TestPrivappAllowlistAndroidMk(t *testing.T) { "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml", ) } + +func TestApexGlobalMinSdkVersionOverride(t *testing.T) { + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.ApexGlobalMinSdkVersionOverride = proptools.StringPtr("Tiramisu") + }), + ).RunTestWithBp(t, ` + android_app { + name: "com.android.bar", + srcs: ["a.java"], + sdk_version: "current", + } + android_app { + name: "com.android.foo", + srcs: ["a.java"], + sdk_version: "current", + min_sdk_version: "S", + updatable: true, + } + override_android_app { + name: "com.android.go.foo", + base: "com.android.foo", + } + `) + foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer") + fooOverride := result.ModuleForTests("com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer") + bar := result.ModuleForTests("com.android.bar", "android_common").Rule("manifestFixer") + + android.AssertStringDoesContain(t, + "expected manifest fixer to set com.android.bar minSdkVersion to S", + bar.BuildParams.Args["args"], + "--minSdkVersion S", + ) + android.AssertStringDoesContain(t, + "com.android.foo: expected manifest fixer to set minSdkVersion to T", + foo.BuildParams.Args["args"], + "--minSdkVersion T", + ) + android.AssertStringDoesContain(t, + "com.android.go.foo: expected manifest fixer to set minSdkVersion to T", + fooOverride.BuildParams.Args["args"], + "--minSdkVersion T", + ) + +} diff --git a/java/base.go b/java/base.go index 2c0b3ea7c..8f483989e 100644 --- a/java/base.go +++ b/java/base.go @@ -1608,7 +1608,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath false, nil, nil) if *j.dexProperties.Uncompress_dex { combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName).OutputPath - TransformZipAlign(ctx, combinedAlignedJar, combinedJar) + TransformZipAlign(ctx, combinedAlignedJar, combinedJar, nil) dexOutputFile = combinedAlignedJar } else { dexOutputFile = combinedJar diff --git a/java/builder.go b/java/builder.go index debf49a00..bf919175d 100644 --- a/java/builder.go +++ b/java/builder.go @@ -277,6 +277,14 @@ var ( Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} -x 'META-INF/services/**/*'`, CommandDeps: []string{"${config.Zip2ZipCmd}"}, }) + + checkBelowTargetSdk30ForNonPreprocessedApks = pctx.AndroidStaticRule("checkBelowTargetSdk30ForNonPreprocessedApks", + blueprint.RuleParams{ + Command: "build/soong/scripts/check_target_sdk_less_than_30.py ${config.Aapt2Cmd} $in $out", + CommandDeps: []string{"build/soong/scripts/check_target_sdk_less_than_30.py", "${config.Aapt2Cmd}"}, + Description: "Check prebuilt target sdk version", + }, + ) ) func init() { @@ -689,12 +697,13 @@ func GenerateMainClassManifest(ctx android.ModuleContext, outputFile android.Wri android.WriteFileRule(ctx, outputFile, "Main-Class: "+mainClass+"\n") } -func TransformZipAlign(ctx android.ModuleContext, outputFile android.WritablePath, inputFile android.Path) { +func TransformZipAlign(ctx android.ModuleContext, outputFile android.WritablePath, inputFile android.Path, validations android.Paths) { ctx.Build(pctx, android.BuildParams{ Rule: zipalign, Description: "align", Input: inputFile, Output: outputFile, + Validations: validations, }) } diff --git a/java/dex.go b/java/dex.go index 21937e1a5..5b8cf3dfb 100644 --- a/java/dex.go +++ b/java/dex.go @@ -450,7 +450,7 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam } if proptools.Bool(d.dexProperties.Uncompress_dex) { alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath - TransformZipAlign(ctx, alignedJavalibJar, javalibJar) + TransformZipAlign(ctx, alignedJavalibJar, javalibJar, nil) javalibJar = alignedJavalibJar } diff --git a/java/hiddenapi.go b/java/hiddenapi.go index 4d08b8307..fe3fe7b61 100644 --- a/java/hiddenapi.go +++ b/java/hiddenapi.go @@ -305,7 +305,7 @@ func hiddenAPIEncodeDex(ctx android.ModuleContext, dexInput, flagsCSV android.Pa }) if uncompressDex { - TransformZipAlign(ctx, output, encodeRuleOutput) + TransformZipAlign(ctx, output, encodeRuleOutput, nil) } return output diff --git a/java/java.go b/java/java.go index 521aef301..99bb1b3ee 100644 --- a/java/java.go +++ b/java/java.go @@ -2826,7 +2826,7 @@ func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorConte if resourceStripPrefix == nil && i == 0 { resourceStripPrefix = resAttr.Resource_strip_prefix resources = resAttr.Resources.Value - } else { + } else if !resAttr.Resources.IsEmpty() { ctx.CreateBazelTargetModule( bazel.BazelTargetModuleProperties{ Rule_class: "java_resources", @@ -2904,8 +2904,13 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) var staticDeps bazel.LabelListAttribute if proptools.String(m.deviceProperties.Sdk_version) == "" && m.DeviceSupported() { + // TODO(b/297356704): handle platform apis in bp2build ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "sdk_version unset") return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false + } else if proptools.String(m.deviceProperties.Sdk_version) == "core_platform" { + // TODO(b/297356582): handle core_platform in bp2build + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "sdk_version core_platform") + return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false } archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{}) diff --git a/java/sdk_library.go b/java/sdk_library.go index b1ddde093..d1620af9f 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1633,7 +1633,7 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext }{} props.Name = proptools.StringPtr(module.sourceStubLibraryModuleName(apiScope)) - props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility) + props.Visibility = []string{"//visibility:override", "//visibility:private"} // sources are generated from the droiddoc props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)} sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope) @@ -1829,7 +1829,7 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, }{} props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope)) - props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility) + props.Visibility = []string{"//visibility:override", "//visibility:private"} apiContributions := []string{} diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 118f8b68c..868d697ce 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -1474,3 +1474,32 @@ func TestJavaSdkLibrary_ApiLibrary(t *testing.T) { android.AssertStringEquals(t, "Module expected to contain full api surface api library", c.fullApiSurfaceStub, *m.properties.Full_api_surface_stub) } } + +func TestStaticDepStubLibrariesVisibility(t *testing.T) { + android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + android.FixtureMergeMockFs( + map[string][]byte{ + "A.java": nil, + "dir/Android.bp": []byte( + ` + java_library { + name: "bar", + srcs: ["A.java"], + libs: ["foo.stubs.from-source"], + } + `), + "dir/A.java": nil, + }, + ).ExtendWithErrorHandler( + android.FixtureExpectsAtLeastOneErrorMatchingPattern( + `module "bar" variant "android_common": depends on //.:foo.stubs.from-source which is not visible to this module`)), + ).RunTestWithBp(t, ` + java_sdk_library { + name: "foo", + srcs: ["A.java"], + } + `) +} diff --git a/rust/bindgen.go b/rust/bindgen.go index 407f2754f..a80a587f1 100644 --- a/rust/bindgen.go +++ b/rust/bindgen.go @@ -29,7 +29,7 @@ var ( defaultBindgenFlags = []string{""} // bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures. - bindgenClangVersion = "clang-r498229" + bindgenClangVersion = "clang-r498229b" _ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string { if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" { diff --git a/scripts/check_target_sdk_less_than_30.py b/scripts/check_target_sdk_less_than_30.py new file mode 100755 index 000000000..69b0bf011 --- /dev/null +++ b/scripts/check_target_sdk_less_than_30.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +import subprocess +import argparse +import re +import sys + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('aapt2', help = "the path to the aapt2 executable") + parser.add_argument('apk', help = "the apk to check") + parser.add_argument('stampfile', help = "a file to touch if successful") + args = parser.parse_args() + + regex = re.compile(r"targetSdkVersion: *'([0-9]+)'") + output = subprocess.check_output([args.aapt2, "dump", "badging", args.apk], text=True) + targetSdkVersion = None + for line in output.splitlines(): + match = regex.fullmatch(line.strip()) + if match: + targetSdkVersion = int(match.group(1)) + break + + if targetSdkVersion is None or targetSdkVersion >= 30: + sys.exit(args.apk + ": Prebuilt, presigned apks with targetSdkVersion >= 30 (or a codename targetSdkVersion) must set preprocessed: true in the Android.bp definition (because they must be signed with signature v2, and the build system would wreck that signature otherwise)") + + subprocess.check_call(["touch", args.stampfile]) + +if __name__ == "__main__": + main() diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh index 9de9b97ff..73fbeabbd 100755 --- a/tests/sbom_test.sh +++ b/tests/sbom_test.sh @@ -47,13 +47,10 @@ function run_soong { } function diff_files { - file_list_file="$1"; shift - files_in_spdx_file="$1"; shift - partition_name="$1"; shift - exclude= - if [ -v 'diff_excludes[$partition_name]' ]; then - exclude=${diff_excludes[$partition_name]} - fi + local file_list_file="$1"; shift + local files_in_spdx_file="$1"; shift + local partition_name="$1"; shift + local exclude="$1"; shift diff "$file_list_file" "$files_in_spdx_file" $exclude if [ $? != "0" ]; then @@ -84,9 +81,6 @@ function test_sbom_aosp_cf_x86_64_phone { dump_erofs=$out_dir/host/linux-x86/bin/dump.erofs lz4=$out_dir/host/linux-x86/bin/lz4 - declare -A diff_excludes - diff_excludes[system]="-I /system/bin/hwservicemanager" - # Example output of dump.erofs is as below, and the data used in the test start # at line 11. Column 1 is inode id, column 2 is inode type and column 3 is name. # Each line is captured in variable "entry", awk is used to get type and name. @@ -158,7 +152,7 @@ function test_sbom_aosp_cf_x86_64_phone { sort -n -o "$files_in_spdx_file" "$files_in_spdx_file" echo ============ Diffing files in $f and SBOM - diff_files "$file_list_file" "$files_in_spdx_file" "$partition_name" + diff_files "$file_list_file" "$files_in_spdx_file" "$partition_name" "" done RAMDISK_IMAGES="$product_out/ramdisk.img" @@ -176,7 +170,7 @@ function test_sbom_aosp_cf_x86_64_phone { grep "FileName: /${partition_name}/" $product_out/sbom.spdx | sed 's/^FileName: //' | sort -n > "$files_in_spdx_file" echo ============ Diffing files in $f and SBOM - diff_files "$file_list_file" "$files_in_spdx_file" "$partition_name" + diff_files "$file_list_file" "$files_in_spdx_file" "$partition_name" "" done verify_package_verification_code "$product_out/sbom.spdx" diff --git a/ui/build/ninja.go b/ui/build/ninja.go index 61aaad86b..b69e938f8 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -194,6 +194,10 @@ func runNinjaForBuild(ctx Context, config Config) { // LLVM compiler wrapper options "TOOLCHAIN_RUSAGE_OUTPUT", + + // We don't want this build broken flag to cause reanalysis, so allow it through to the + // actions. + "BUILD_BROKEN_INCORRECT_PARTITION_IMAGES", }, config.BuildBrokenNinjaUsesEnvVars()...)...) } diff --git a/xml/xml.go b/xml/xml.go index 8c0c07282..20a26f562 100644 --- a/xml/xml.go +++ b/xml/xml.go @@ -146,7 +146,11 @@ type bazelPrebuiltEtcXmlAttributes struct { } func (p *prebuiltEtcXml) ConvertWithBp2build(ctx android.TopDownMutatorContext) { - baseAttrs := p.PrebuiltEtc.Bp2buildHelper(ctx) + baseAttrs, convertible := p.PrebuiltEtc.Bp2buildHelper(ctx) + + if !convertible { + return + } var schema *string if p.properties.Schema != nil { |