diff options
| -rw-r--r-- | android/allowlists/allowlists.go | 4 | ||||
| -rw-r--r-- | android/sdk_version.go | 4 | ||||
| -rw-r--r-- | apex/apex_test.go | 12 | ||||
| -rw-r--r-- | apex/builder.go | 29 | ||||
| -rw-r--r-- | bp2build/Android.bp | 1 | ||||
| -rw-r--r-- | bp2build/java_host_for_device_conversion_test.go | 63 | ||||
| -rw-r--r-- | bp2build/java_library_conversion_test.go | 18 | ||||
| -rw-r--r-- | bp2build/symlink_forest.go | 90 | ||||
| -rw-r--r-- | cc/afdo.go | 6 | ||||
| -rw-r--r-- | cc/config/global.go | 6 | ||||
| -rw-r--r-- | cc/library.go | 4 | ||||
| -rw-r--r-- | cc/ndk_library.go | 23 | ||||
| -rw-r--r-- | cc/ndk_sysroot.go | 7 | ||||
| -rw-r--r-- | cc/object.go | 30 | ||||
| -rw-r--r-- | cc/object_test.go | 2 | ||||
| -rw-r--r-- | java/core-libraries/TxtStubLibraries.bp | 26 | ||||
| -rw-r--r-- | java/device_host_converter.go | 30 | ||||
| -rw-r--r-- | java/java.go | 25 | ||||
| -rw-r--r-- | java/sdk.go | 4 | ||||
| -rw-r--r-- | java/testing.go | 29 | ||||
| -rwxr-xr-x | tests/sbom_test.sh | 21 |
21 files changed, 364 insertions, 70 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index d7bcc8171..1ece9fa7d 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -132,6 +132,7 @@ var ( "external/f2fs-tools": Bp2BuildDefaultTrue, "external/flac": Bp2BuildDefaultTrueRecursively, "external/fmtlib": Bp2BuildDefaultTrueRecursively, + "external/guava": Bp2BuildDefaultTrueRecursively, "external/google-benchmark": Bp2BuildDefaultTrueRecursively, "external/googletest": Bp2BuildDefaultTrueRecursively, "external/gwp_asan": Bp2BuildDefaultTrueRecursively, @@ -397,7 +398,6 @@ var ( "external/bazelbuild-rules_license":/* recursive = */ true, "external/bazelbuild-kotlin-rules":/* recursive = */ true, "external/bazel-skylib":/* recursive = */ true, - "external/guava":/* recursive = */ true, "external/protobuf":/* recursive = */ false, "external/python/absl-py":/* recursive = */ true, @@ -711,6 +711,8 @@ var ( // allowlisting for kotlinx_coroutines "kotlinx_coroutines", + "kotlinx_coroutines-device", + "kotlinx_coroutines-host", "annotations", "kotlinx-coroutines-android-annotation-stubs", diff --git a/android/sdk_version.go b/android/sdk_version.go index 1f01dc64f..0ae807352 100644 --- a/android/sdk_version.go +++ b/android/sdk_version.go @@ -86,7 +86,7 @@ func (k SdkKind) String() string { // JavaLibraryName returns the soong module containing the Java APIs of that API surface. func (k SdkKind) JavaLibraryName(c Config) string { - name := k.defaultJavaLibraryName() + name := k.DefaultJavaLibraryName() return JavaApiLibraryName(c, name) } @@ -100,7 +100,7 @@ func JavaApiLibraryName(c Config, name string) string { return name } -func (k SdkKind) defaultJavaLibraryName() string { +func (k SdkKind) DefaultJavaLibraryName() string { switch k { case SdkPublic: return "android_stubs_current" diff --git a/apex/apex_test.go b/apex/apex_test.go index 05c888abe..8a02a4a7f 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -7101,7 +7101,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { native_shared_libs: ["mylib"], java_libs: ["myjar"], updatable: true, - min_sdk_version: "current", + min_sdk_version: "33", } apex_key { @@ -7124,7 +7124,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } cc_library { @@ -7137,7 +7137,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } cc_library { @@ -7151,7 +7151,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } java_library { @@ -7165,7 +7165,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } java_library { @@ -7178,7 +7178,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } ` diff --git a/apex/builder.go b/apex/builder.go index e3b6f8e48..94aef496e 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -71,6 +71,9 @@ func init() { pctx.HostBinToolVariable("make_erofs", "make_erofs") pctx.HostBinToolVariable("apex_compression_tool", "apex_compression_tool") pctx.HostBinToolVariable("dexdeps", "dexdeps") + pctx.HostBinToolVariable("apex_sepolicy_tests", "apex_sepolicy_tests") + pctx.HostBinToolVariable("deapexer", "deapexer") + pctx.HostBinToolVariable("debugfs_static", "debugfs_static") pctx.SourcePathVariable("genNdkUsedbyApexPath", "build/soong/scripts/gen_ndk_usedby_apex.sh") } @@ -226,7 +229,12 @@ var ( Description: "Generate symbol list used by Apex", }, "image_dir", "readelf") - // Don't add more rules here. Consider using android.NewRuleBuilder instead. + apexSepolicyTestsRule = pctx.StaticRule("apexSepolicyTestsRule", blueprint.RuleParams{ + Command: `${deapexer} --debugfs_path ${debugfs_static} list -Z ${in} > ${out}.fc` + + `&& ${apex_sepolicy_tests} -f ${out}.fc && touch ${out}`, + CommandDeps: []string{"${apex_sepolicy_tests}", "${deapexer}", "${debugfs_static}"}, + Description: "run apex_sepolicy_tests", + }) ) // buildManifest creates buile rules to modify the input apex_manifest.json to add information @@ -872,6 +880,10 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { args["implicits"] = strings.Join(implicits.Strings(), ",") args["outCommaList"] = signedOutputFile.String() } + var validations android.Paths + if suffix == imageApexSuffix { + validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile.OutputPath)) + } ctx.Build(pctx, android.BuildParams{ Rule: rule, Description: "signapk", @@ -879,6 +891,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { Input: unsignedOutputFile, Implicits: implicits, Args: args, + Validations: validations, }) if suffix == imageApexSuffix { a.outputApexFile = signedOutputFile @@ -1172,3 +1185,17 @@ func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.Outp return cannedFsConfig.OutputPath } + +// Runs apex_sepolicy_tests +// +// $ deapexer list -Z {apex_file} > {file_contexts} +// $ apex_sepolicy_tests -f {file_contexts} +func runApexSepolicyTests(ctx android.ModuleContext, apexFile android.OutputPath) android.Path { + timestamp := android.PathForModuleOut(ctx, "sepolicy_tests.timestamp") + ctx.Build(pctx, android.BuildParams{ + Rule: apexSepolicyTestsRule, + Input: apexFile, + Output: timestamp, + }) + return timestamp +} diff --git a/bp2build/Android.bp b/bp2build/Android.bp index 6edd78aef..598ca323d 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -61,6 +61,7 @@ bootstrap_go_package { "genrule_conversion_test.go", "gensrcs_conversion_test.go", "java_binary_host_conversion_test.go", + "java_host_for_device_conversion_test.go", "java_import_conversion_test.go", "java_library_conversion_test.go", "java_library_host_conversion_test.go", diff --git a/bp2build/java_host_for_device_conversion_test.go b/bp2build/java_host_for_device_conversion_test.go new file mode 100644 index 000000000..d908d0002 --- /dev/null +++ b/bp2build/java_host_for_device_conversion_test.go @@ -0,0 +1,63 @@ +// Copyright 2023 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/java" +) + +func runJavaHostForDeviceTestCaseWithRegistrationCtxFunc(t *testing.T, tc Bp2buildTestCase, registrationCtxFunc func(ctx android.RegistrationContext)) { + t.Helper() + (&tc).ModuleTypeUnderTest = "java_host_for_device" + (&tc).ModuleTypeUnderTestFactory = java.HostForDeviceFactory + RunBp2BuildTestCase(t, registrationCtxFunc, tc) +} + +func runJavaHostForDeviceTestCase(t *testing.T, tc Bp2buildTestCase) { + t.Helper() + runJavaHostForDeviceTestCaseWithRegistrationCtxFunc(t, tc, func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("java_library", java.LibraryFactory) + }) +} + +func TestJavaHostForDevice(t *testing.T) { + runJavaHostForDeviceTestCase(t, Bp2buildTestCase{ + Description: "java_host_for_device test", + Blueprint: `java_host_for_device { + name: "java-lib-1", + libs: ["java-lib-2"], + bazel_module: { bp2build_available: true }, +} + +java_library { + name: "java-lib-2", + srcs: ["b.java"], + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_host_for_device", "java-lib-1", AttrNameToString{ + "deps": `[":java-lib-2"]`, + }), + MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"), + MakeBazelTarget("java_library", "java-lib-2", AttrNameToString{ + "srcs": `["b.java"]`, + }), + MakeNeverlinkDuplicateTarget("java_library", "java-lib-2"), + }, + }) +} diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go index 69d0db91c..683ee27cc 100644 --- a/bp2build/java_library_conversion_test.go +++ b/bp2build/java_library_conversion_test.go @@ -740,7 +740,7 @@ func TestJavaLibraryKotlinCommonSrcs(t *testing.T) { }) } -func TestJavaLibraryArchVariantLibs(t *testing.T) { +func TestJavaLibraryArchVariantDeps(t *testing.T) { runJavaLibraryTestCase(t, Bp2buildTestCase{ Description: "java_library with arch variant libs", Blueprint: `java_library { @@ -750,6 +750,7 @@ func TestJavaLibraryArchVariantLibs(t *testing.T) { target: { android: { libs: ["java-lib-3"], + static_libs: ["java-lib-4"], }, }, bazel_module: { bp2build_available: true }, @@ -762,12 +763,23 @@ func TestJavaLibraryArchVariantLibs(t *testing.T) { java_library{ name: "java-lib-3", } + + java_library{ + name: "java-lib-4", +} `, ExpectedBazelTargets: []string{ MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{ "srcs": `["a.java"]`, + "exports": `select({ + "//build/bazel/platforms/os:android": [":java-lib-4"], + "//conditions:default": [], + })`, "deps": `[":java-lib-2-neverlink"] + select({ - "//build/bazel/platforms/os:android": [":java-lib-3-neverlink"], + "//build/bazel/platforms/os:android": [ + ":java-lib-3-neverlink", + ":java-lib-4", + ], "//conditions:default": [], })`, }), @@ -776,6 +788,8 @@ func TestJavaLibraryArchVariantLibs(t *testing.T) { MakeNeverlinkDuplicateTarget("java_library", "java-lib-2"), MakeBazelTarget("java_library", "java-lib-3", AttrNameToString{}), MakeNeverlinkDuplicateTarget("java_library", "java-lib-3"), + MakeBazelTarget("java_library", "java-lib-4", AttrNameToString{}), + MakeNeverlinkDuplicateTarget("java_library", "java-lib-4"), }, }) } diff --git a/bp2build/symlink_forest.go b/bp2build/symlink_forest.go index aac5e7d2c..5c333085d 100644 --- a/bp2build/symlink_forest.go +++ b/bp2build/symlink_forest.go @@ -21,10 +21,13 @@ import ( "path/filepath" "regexp" "sort" + "strconv" + "strings" "sync" "sync/atomic" "android/soong/shared" + "github.com/google/blueprint/pathtools" ) @@ -35,6 +38,13 @@ import ( // 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 = 1 + type instructionsNode struct { name string excluded bool // If false, this is just an intermediate node @@ -123,6 +133,34 @@ func mergeBuildFiles(output string, srcBuildFile string, generatedBuildFile stri } newContents = append(newContents, srcBuildFileContent...) + // Say you run bp2build 4 times: + // - The first time there's only an Android.bp file. bp2build will convert it to a build file + // under out/soong/bp2build, then symlink from the forest to that generated file + // - Then you add a handcrafted BUILD file in the same directory. bp2build will merge this with + // the generated one, and write the result to the output file in the forest. But the output + // file was a symlink to out/soong/bp2build from the previous step! So we erroneously update + // the file in out/soong/bp2build instead. So far this doesn't cause any problems... + // - You run a 3rd bp2build with no relevant changes. Everything continues to work. + // - You then add a comment to the handcrafted BUILD file. This causes a merge with the + // generated file again. But since we wrote to the generated file in step 2, the generated + // file has an old copy of the handcrafted file in it! This probably causes duplicate bazel + // targets. + // To solve this, if we see that the output file is a symlink from a previous build, remove it. + stat, err := os.Lstat(output) + if err != nil && !os.IsNotExist(err) { + return err + } else if err == nil { + if stat.Mode()&os.ModeSymlink == os.ModeSymlink { + if verbose { + fmt.Fprintf(os.Stderr, "Removing symlink so that we can replace it with a merged file: %s\n", output) + } + err = os.Remove(output) + if err != nil { + return err + } + } + } + return pathtools.WriteFileIfChanged(output, newContents, 0666) } @@ -202,6 +240,46 @@ func isDir(path string, fi os.FileInfo) bool { 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 + } + 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 + } + } + return 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) + if err != nil { + if !os.IsNotExist(err) { + return err + } + err = os.WriteFile(versionFilePath, []byte(strconv.Itoa(symlinkForestVersion)+"\n"), 0666) + if err != nil { + return err + } + } + return nil +} + // Recursively plants a symlink forest at forestDir. The symlink tree will // contain every file in buildFilesDir and srcDir excluding the files in // instructions. Collects every directory encountered during the traversal of @@ -395,6 +473,12 @@ func PlantSymlinkForest(verbose bool, topdir string, forest string, buildFiles s symlinkCount: atomic.Uint64{}, } + err := maybeCleanSymlinkForest(topdir, forest, verbose) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + instructions := instructionsFromExcludePathList(exclude) go func() { context.wg.Add(1) @@ -407,5 +491,11 @@ func PlantSymlinkForest(verbose bool, topdir string, forest string, buildFiles s deps = append(deps, dep) } + err = maybeWriteVersionFile(topdir, forest) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + return deps, context.mkdirCount.Load(), context.symlinkCount.Load() } diff --git a/cc/afdo.go b/cc/afdo.go index 4a8498bc7..be4f50adb 100644 --- a/cc/afdo.go +++ b/cc/afdo.go @@ -71,10 +71,10 @@ func (afdo *afdo) afdoEnabled() bool { func (afdo *afdo) flags(ctx ModuleContext, flags Flags) Flags { if path := afdo.Properties.FdoProfilePath; path != nil { + // The flags are prepended to allow overriding. profileUseFlag := fmt.Sprintf(afdoCFlagsFormat, *path) - flags.Local.CFlags = append(flags.Local.CFlags, profileUseFlag) - flags.Local.LdFlags = append(flags.Local.LdFlags, profileUseFlag) - flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-no-warn-sample-unused=true") + flags.Local.CFlags = append([]string{profileUseFlag}, flags.Local.CFlags...) + flags.Local.LdFlags = append([]string{profileUseFlag, "-Wl,-mllvm,-no-warn-sample-unused=true"}, flags.Local.LdFlags...) // Update CFlagsDeps and LdFlagsDeps so the module is rebuilt // if profileFile gets updated diff --git a/cc/config/global.go b/cc/config/global.go index 5b2191af7..4277bcf57 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -111,6 +111,9 @@ var ( // Turn off FMA which got enabled by default in clang-r445002 (http://b/218805949) "-ffp-contract=off", + + // Turn off stack protector check for noreturn calls. (http://b/264965700) + "-mllvm -disable-check-noreturn-call", } commonGlobalConlyflags = []string{} @@ -147,6 +150,9 @@ var ( commonGlobalLldflags = []string{ "-fuse-ld=lld", "-Wl,--icf=safe", + + // Turn off stack protector check for noreturn calls. (http://b/264965700) + "-Wl,-mllvm,-disable-check-noreturn-call", } deviceGlobalCppflags = []string{ diff --git a/cc/library.go b/cc/library.go index a9ada97d9..7504302fd 100644 --- a/cc/library.go +++ b/cc/library.go @@ -26,7 +26,6 @@ import ( "android/soong/android" "android/soong/bazel" "android/soong/bazel/cquery" - "android/soong/cc/config" "github.com/google/blueprint" "github.com/google/blueprint/pathtools" @@ -2261,8 +2260,7 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { !ctx.useVndk() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && ctx.Device() && library.baseLinker.sanitize.isUnsanitizedVariant() && ctx.isForPlatform() && !ctx.isPreventInstall() { - installPath := getNdkSysrootBase(ctx).Join( - ctx, "usr/lib", config.NDKTriple(ctx.toolchain()), file.Base()) + installPath := getUnversionedLibraryInstallPath(ctx).Join(ctx, file.Base()) ctx.ModuleBuild(pctx, android.ModuleBuildParams{ Rule: android.Cp, diff --git a/cc/ndk_library.go b/cc/ndk_library.go index 2473ba2a3..a82436135 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -528,17 +528,20 @@ func (stub *stubDecorator) nativeCoverage() bool { return false } -func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) { - arch := ctx.Target().Arch.ArchType.Name - // arm64 isn't actually a multilib toolchain, so unlike the other LP64 - // architectures it's just installed to lib. - libDir := "lib" - if ctx.toolchain().Is64Bit() && arch != "arm64" { - libDir = "lib64" - } +// Returns the install path for unversioned NDK libraries (currently only static +// libraries). +func getUnversionedLibraryInstallPath(ctx ModuleContext) android.InstallPath { + return getNdkSysrootBase(ctx).Join(ctx, "usr/lib", config.NDKTriple(ctx.toolchain())) +} - installDir := getNdkInstallBase(ctx).Join(ctx, fmt.Sprintf( - "platforms/android-%s/arch-%s/usr/%s", stub.apiLevel, arch, libDir)) +// Returns the install path for versioned NDK libraries. These are most often +// stubs, but the same paths are used for CRT objects. +func getVersionedLibraryInstallPath(ctx ModuleContext, apiLevel android.ApiLevel) android.InstallPath { + return getUnversionedLibraryInstallPath(ctx).Join(ctx, apiLevel.String()) +} + +func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) { + installDir := getVersionedLibraryInstallPath(ctx, stub.apiLevel) stub.installPath = ctx.InstallFile(installDir, path.Base(), path) } diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go index 622558edf..dffc6c614 100644 --- a/cc/ndk_sysroot.go +++ b/cc/ndk_sysroot.go @@ -142,6 +142,13 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { staticLibInstallPaths, library.ndkSysrootPath) } } + + if object, ok := m.linker.(*objectLinker); ok { + if object.ndkSysrootPath != nil { + staticLibInstallPaths = append( + staticLibInstallPaths, object.ndkSysrootPath) + } + } } }) diff --git a/cc/object.go b/cc/object.go index ef4446746..d65cdea74 100644 --- a/cc/object.go +++ b/cc/object.go @@ -44,6 +44,10 @@ var ccObjectSdkMemberType = &librarySdkMemberType{ type objectLinker struct { *baseLinker Properties ObjectLinkerProperties + + // Location of the object in the sysroot. Empty if the object is not + // included in the NDK. + ndkSysrootPath android.Path } type objectBazelHandler struct { @@ -99,6 +103,10 @@ type ObjectLinkerProperties struct { // Indicates that this module is a CRT object. CRT objects will be split // into a variant per-API level between min_sdk_version and current. Crt *bool + + // Indicates that this module should not be included in the NDK sysroot. + // Only applies to CRT objects. Defaults to false. + Exclude_from_ndk_sysroot *bool } func newObject(hod android.HostOrDeviceSupported) *Module { @@ -268,17 +276,28 @@ func (object *objectLinker) link(ctx ModuleContext, objs = objs.Append(deps.Objs) - var outputFile android.Path + var output android.WritablePath builderFlags := flagsToBuilderFlags(flags) outputName := ctx.ModuleName() if !strings.HasSuffix(outputName, objectExtension) { outputName += objectExtension } - if len(objs.objFiles) == 1 && String(object.Properties.Linker_script) == "" { - output := android.PathForModuleOut(ctx, outputName) - outputFile = output + // isForPlatform is terribly named and actually means isNotApex. + if Bool(object.Properties.Crt) && + !Bool(object.Properties.Exclude_from_ndk_sysroot) && ctx.useSdk() && + ctx.isSdkVariant() && ctx.isForPlatform() { + output = getVersionedLibraryInstallPath(ctx, + nativeApiLevelOrPanic(ctx, ctx.sdkVersion())).Join(ctx, outputName) + object.ndkSysrootPath = output + } else { + output = android.PathForModuleOut(ctx, outputName) + } + + outputFile := output + + if len(objs.objFiles) == 1 && String(object.Properties.Linker_script) == "" { if String(object.Properties.Prefix_symbols) != "" { transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), objs.objFiles[0], builderFlags, output) @@ -290,9 +309,6 @@ func (object *objectLinker) link(ctx ModuleContext, }) } } else { - output := android.PathForModuleOut(ctx, outputName) - outputFile = output - if String(object.Properties.Prefix_symbols) != "" { input := android.PathForModuleOut(ctx, "unprefixed", outputName) transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), input, diff --git a/cc/object_test.go b/cc/object_test.go index 5359a357a..b1e2a0fd2 100644 --- a/cc/object_test.go +++ b/cc/object_test.go @@ -65,7 +65,7 @@ func TestUseCrtObjectOfCorrectVersion(t *testing.T) { variant := "android_arm64_armv8-a_sdk" crt := ctx.ModuleForTests("bin", variant).Rule("ld").Args["crtBegin"] android.AssertStringDoesContain(t, "crt dep of sdk variant", crt, - variant+"_29/crtbegin_dynamic.o") + "29/crtbegin_dynamic.o") // platform variant uses the crt object built for platform variant = "android_arm64_armv8-a" diff --git a/java/core-libraries/TxtStubLibraries.bp b/java/core-libraries/TxtStubLibraries.bp index b63ce4204..813187e54 100644 --- a/java/core-libraries/TxtStubLibraries.bp +++ b/java/core-libraries/TxtStubLibraries.bp @@ -33,8 +33,8 @@ java_library { "system-modules-no-annotations", ], static_libs: [ - "core.current.stubs.from-txt", - "core-lambda-stubs-for-system-modules", + "core.current.stubs.from-text", + "core-lambda-stubs.from-text", ], // TODO: Enable after stub generation from .txt file is available enabled: false, @@ -58,8 +58,8 @@ java_library { "system-modules-no-annotations", ], static_libs: [ - "core.module_lib.stubs.txt", - "core-lambda-stubs-for-system-modules", + "core.module_lib.stubs.from-text", + "core-lambda-stubs.from-text", ], // TODO: Enable after stub generation from .txt file is available enabled: false, @@ -89,7 +89,7 @@ java_system_modules { visibility: core_platform_visibility, libs: [ "legacy.core.platform.api.no.annotations.stubs.from-text", - "core-lambda-stubs-for-system-modules", + "core-lambda-stubs.from-text", ], // TODO: Enable after stub generation from .txt file is available enabled: false, @@ -118,7 +118,7 @@ java_system_modules { visibility: core_platform_visibility, libs: [ "stable.core.platform.api.no.annotations.stubs.from-text", - "core-lambda-stubs-for-system-modules", + "core-lambda-stubs.from-text", ], // TODO: Enable after stub generation from .txt file is available enabled: false, @@ -140,3 +140,17 @@ java_library { // TODO: Enable after stub generation from .txt file is available enabled: false, } + +java_api_library { + name: "core-lambda-stubs.from-text", + api_surface: "toolchain", + api_contributions: [ + "art.module.toolchain.api.api.contribution", + ], + libs: [ + // LambdaMetaFactory depends on CallSite etc. which is part of the Core API surface + "core.current.stubs.from-text", + ], + // TODO: Enable after stub generation from .txt file is available + enabled: false, +} diff --git a/java/device_host_converter.go b/java/device_host_converter.go index 4abdcc6e9..656c866ed 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -19,12 +19,14 @@ import ( "io" "android/soong/android" + "android/soong/bazel" "android/soong/dexpreopt" ) type DeviceHostConverter struct { android.ModuleBase android.DefaultableModuleBase + android.BazelModuleBase properties DeviceHostConverterProperties @@ -76,6 +78,7 @@ func HostForDeviceFactory() android.Module { module.AddProperties(&module.properties) InitJavaModule(module, android.DeviceSupported) + android.InitBazelModule(module) return module } @@ -186,3 +189,30 @@ func (d *DeviceHostConverter) AndroidMk() android.AndroidMkData { }, } } + +type bazelDeviceHostConverterAttributes struct { + Deps bazel.LabelListAttribute +} + +func (d *DeviceHostConverter) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "java_host_for_device", + Bzl_load_location: "//build/bazel/rules/java:host_for_device.bzl", + }, + android.CommonAttributes{Name: d.Name()}, + &bazelDeviceHostConverterAttributes{ + Deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, d.properties.Libs)), + }, + ) + neverlinkProp := true + neverLinkAttrs := &javaLibraryAttributes{ + Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + d.Name()}), + Neverlink: bazel.BoolAttribute{Value: &neverlinkProp}, + } + ctx.CreateBazelTargetModule( + javaLibraryBazelTargetModuleProperties(), + android.CommonAttributes{Name: d.Name() + "-neverlink"}, + neverLinkAttrs) + +} diff --git a/java/java.go b/java/java.go index 97d55146c..d400b0cfb 100644 --- a/java/java.go +++ b/java/java.go @@ -1612,7 +1612,7 @@ func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleCon } type JavaApiLibraryDepsInfo struct { - StubsJar android.Path + JavaInfo StubsSrcJar android.Path } @@ -1821,7 +1821,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { staticLibs = append(staticLibs, provider.HeaderJars...) case depApiSrcsTag: provider := ctx.OtherModuleProvider(dep, JavaApiLibraryDepsProvider).(JavaApiLibraryDepsInfo) - classPaths = append(classPaths, provider.StubsJar) + classPaths = append(classPaths, provider.HeaderJars...) depApiSrcsStubsSrcJar = provider.StubsSrcJar } }) @@ -1900,7 +1900,9 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { }) ctx.SetProvider(JavaApiLibraryDepsProvider, JavaApiLibraryDepsInfo{ - StubsJar: al.stubsJar, + JavaInfo: JavaInfo{ + HeaderJars: android.PathsIfNonNil(al.stubsJar), + }, StubsSrcJar: al.stubsSrcJar, }) } @@ -2905,10 +2907,6 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } } - if m.properties.Static_libs != nil { - staticDeps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Static_libs)))) - } - protoDepLabel := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition]) // Soong does not differentiate between a java_library and the Bazel equivalent of // a java_proto_library + proto_library pair. Instead, in Soong proto sources are @@ -2920,7 +2918,18 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) depLabels := &javaDependencyLabels{} depLabels.Deps = deps - depLabels.StaticDeps = bazel.MakeLabelListAttribute(staticDeps) + + for axis, configToProps := range archVariantProps { + for config, _props := range configToProps { + if archProps, ok := _props.(*CommonProperties); ok { + archStaticLibs := android.BazelLabelForModuleDeps( + ctx, + android.LastUniqueStrings(android.CopyOf(archProps.Static_libs))) + depLabels.StaticDeps.SetSelectValue(axis, config, archStaticLibs) + } + } + } + depLabels.StaticDeps.Value.Append(staticDeps) hasKotlin := !kotlinSrcs.IsEmpty() commonAttrs.kotlinAttributes = &kotlinAttributes{ diff --git a/java/sdk.go b/java/sdk.go index 1b18ba40a..8b4918add 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -151,7 +151,7 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) systemModules := android.JavaApiLibraryName(ctx.Config(), fmt.Sprintf("core-%s-stubs-system-modules", systemModulesKind)) return sdkDep{ useModule: true, - bootclasspath: []string{module, config.DefaultLambdaStubsLibrary}, + bootclasspath: []string{module, android.JavaApiLibraryName(ctx.Config(), config.DefaultLambdaStubsLibrary)}, systemModules: systemModules, java9Classpath: []string{module}, frameworkResModule: "framework-res", @@ -197,7 +197,7 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) case android.SdkCore: return sdkDep{ useModule: true, - bootclasspath: []string{android.SdkCore.JavaLibraryName(ctx.Config()), config.DefaultLambdaStubsLibrary}, + bootclasspath: []string{android.SdkCore.JavaLibraryName(ctx.Config()), android.JavaApiLibraryName(ctx.Config(), config.DefaultLambdaStubsLibrary)}, systemModules: android.JavaApiLibraryName(ctx.Config(), "core-public-stubs-system-modules"), noFrameworksLibs: true, } diff --git a/java/testing.go b/java/testing.go index 8a0db9cb1..0764d264a 100644 --- a/java/testing.go +++ b/java/testing.go @@ -368,14 +368,6 @@ func gatherRequiredDepsForTest() string { "core.current.stubs", "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs", - "android_stubs_current.from-text", - "android_system_stubs_current.from-text", - "android_test_stubs_current.from-text", - "android_module_lib_stubs_current.from-text", - "android_system_server_stubs_current.from-text", - "core.current.stubs.from-text", - "legacy.core.platform.api.stubs.from-text", - "stable.core.platform.api.stubs.from-text", "kotlin-stdlib", "kotlin-stdlib-jdk7", @@ -396,6 +388,27 @@ func gatherRequiredDepsForTest() string { `, extra) } + extraApiLibraryModules := map[string]string{ + "android_stubs_current.from-text": "api/current.txt", + "android_system_stubs_current.from-text": "api/system-current.txt", + "android_test_stubs_current.from-text": "api/test-current.txt", + "android_module_lib_stubs_current.from-text": "api/module-lib-current.txt", + "android_system_server_stubs_current.from-text": "api/system-server-current.txt", + "core.current.stubs.from-text": "api/current.txt", + "legacy.core.platform.api.stubs.from-text": "api/current.txt", + "stable.core.platform.api.stubs.from-text": "api/current.txt", + "core-lambda-stubs.from-text": "api/current.txt", + } + + for libName, apiFile := range extraApiLibraryModules { + bp += fmt.Sprintf(` + java_api_library { + name: "%s", + api_files: ["%s"], + } + `, libName, apiFile) + } + bp += ` java_library { name: "framework", diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh index a507349b8..2f154cde5 100755 --- a/tests/sbom_test.sh +++ b/tests/sbom_test.sh @@ -98,19 +98,15 @@ diff_excludes[system]=\ -I /system/lib64/libkm_compat.so \ -I /system/lib64/vndk-29 \ -I /system/lib64/vndk-sp-29 \ - -I /system/lib/modules \ -I /system/lib/vndk-29 \ -I /system/lib/vndk-sp-29 \ - -I /system/product \ - -I /system/system_ext \ -I /system/usr/icu \ - -I /system/vendor \ -I /vendor_dlkm/etc" - function diff_files { - file_list_file="$1"; - files_in_spdx_file="$2" - partition_name="$3" +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]} @@ -168,9 +164,9 @@ for f in $EROFS_IMAGES; do all_dirs=$(echo "$all_dirs" | cut -d ' ' -f1 --complement -s) entries=$($dump_erofs --ls --path "$dir" $f | tail -n +11) while read -r entry; do - type=$(echo $entry | awk -F ' ' '{print $2}') + inode_type=$(echo $entry | awk -F ' ' '{print $2}') name=$(echo $entry | awk -F ' ' '{print $3}') - case $type in + case $inode_type in "2") # directory all_dirs=$(echo "$all_dirs $dir/$name" | sed 's/^\s*//') ;; @@ -204,6 +200,11 @@ for f in $RAMDISK_IMAGES; do partition_name=$(basename $f | cut -d. -f1) file_list_file="${sbom_test}/sbom-${partition_name}-files.txt" files_in_spdx_file="${sbom_test}/sbom-${partition_name}-files-in-spdx.txt" + # lz4 decompress $f to stdout + # cpio list all entries like ls -l + # grep filter normal files and symlinks + # awk get entry names + # sed remove partition name from entry names $lz4 -c -d $f | cpio -tv 2>/dev/null | grep '^[-l]' | awk -F ' ' '{print $9}' | sed "s:^:/$partition_name/:" | sort -n > "$file_list_file" grep "FileName: /${partition_name}/" $product_out/sbom.spdx | sed 's/^FileName: //' | sort -n > "$files_in_spdx_file" |