diff options
30 files changed, 414 insertions, 170 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 33209c397..892e21873 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -375,8 +375,9 @@ var ( "system/tools/xsdc/utils": Bp2BuildDefaultTrueRecursively, "system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively, - "tools/apksig": Bp2BuildDefaultTrue, - "tools/metalava": Bp2BuildDefaultTrue, + "tools/apksig": Bp2BuildDefaultTrue, + "tools/external_updater": Bp2BuildDefaultTrueRecursively, + "tools/metalava": Bp2BuildDefaultTrue, "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively, "tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively, } @@ -408,8 +409,6 @@ var ( // this BUILD file is globbed by //external/icu/icu4c/source:icu4c_test_data's "data/**/*". "external/icu/icu4c/source/data/unidata/norm2":/* recursive = */ false, - "frameworks/ex/common":/* recursive = */ true, - // Building manually due to b/179889880: resource files cross package boundary "packages/apps/Music":/* recursive = */ true, @@ -690,7 +689,6 @@ var ( "libcodec2_soft_common", // kotlin srcs in java libs - "CtsPkgInstallerConstants", "kotlinx_atomicfu", // kotlin srcs in java binary @@ -703,6 +701,9 @@ var ( //kotlin srcs in android_binary "MusicKotlin", + // java_library with prebuilt sdk_version + "android-common", + // checked in current.txt for merged_txts "non-updatable-current.txt", "non-updatable-system-current.txt", @@ -725,7 +726,6 @@ var ( // min_sdk_version in android_app "CtsShimUpgrade", - "fake-framework", } Bp2buildModuleTypeAlwaysConvertList = []string{ @@ -779,7 +779,8 @@ var ( "tjbench", // TODO(b/240563612): Stem property // java bugs - "libbase_ndk", // TODO(b/186826477): fails to link libctscamera2_jni for device (required for CtsCameraTestCases) + "libbase_ndk", // TODO(b/186826477): fails to link libctscamera2_jni for device (required for CtsCameraTestCases) + "bouncycastle", // TODO(b/274474005): Need support for custom system_modules. // python protos "libprotobuf-python", // Has a handcrafted alternative @@ -846,7 +847,6 @@ 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++ - "libprotobuf-java-nano", // b/220869005, depends on non-public_current SDK "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_* @@ -1396,6 +1396,16 @@ var ( // TODO(b/266459895): depends on libunwindstack "libutils_test", + + // TODO(b/274805756): Support core_platform and current java APIs + "fake-framework", + + // TODO(b/277616982): These modules depend on private java APIs, but maybe they don't need to. + "StreamingProtoTest", + "textclassifierprotoslite", + "styleprotoslite", + "CtsPkgInstallerConstants", + "guava-android-testlib", } MixedBuildsDisabledList = []string{ diff --git a/apex/apex_test.go b/apex/apex_test.go index 8a02a4a7f..557265ce2 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -1001,7 +1001,7 @@ func TestApexWithStubs(t *testing.T) { // 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("rustc").Args["linkFlags"] + rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").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") @@ -1077,7 +1077,7 @@ func TestApexCanUsePrivateApis(t *testing.T) { 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("rustc").Args["linkFlags"] + rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").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") } @@ -7515,6 +7515,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi "some-updatable-apex", ], permitted_packages: ["some.updatable.apex.lib"], + min_sdk_version: "33", } java_library { @@ -7554,6 +7555,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi ], hostdex: true, compile_dex: true, + min_sdk_version: "33", } apex { @@ -7561,7 +7563,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi key: "some-updatable-apex.key", java_libs: ["some-updatable-apex-lib"], updatable: true, - min_sdk_version: "current", + min_sdk_version: "33", } apex { @@ -7584,7 +7586,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi key: "com.android.art.debug.key", bootclasspath_fragments: ["art-bootclasspath-fragment"], updatable: true, - min_sdk_version: "current", + min_sdk_version: "33", } bootclasspath_fragment { diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go index 6020ee599..09d9dc103 100644 --- a/bp2build/aar_conversion_test.go +++ b/bp2build/aar_conversion_test.go @@ -66,9 +66,12 @@ android_library { "resource_files": `["res/res.png"]`, "deps": `[":static_lib_dep"]`, "exports": `[":static_lib_dep"]`, - "javacopts": `["-source 1.7 -target 1.7"]`, + "java_version": `"7"`, }), - MakeNeverlinkDuplicateTarget("android_library", "TestLib"), + MakeNeverlinkDuplicateTargetWithAttrs( + "android_library", + "TestLib", + AttrNameToString{"java_version": `"7"`}), }}) } diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go index ef3f12472..928a1f2e1 100644 --- a/bp2build/android_app_conversion_test.go +++ b/bp2build/android_app_conversion_test.go @@ -53,6 +53,7 @@ android_app { "srcs": `["app.java"]`, "manifest": `"AndroidManifest.xml"`, "resource_files": `["res/res.png"]`, + "sdk_version": `"current"`, }), }}) } @@ -91,7 +92,8 @@ android_app { ]`, "custom_package": `"com.google"`, "deps": `[":static_lib_dep"]`, - "javacopts": `["-source 1.7 -target 1.7"]`, + "java_version": `"7"`, + "sdk_version": `"current"`, "certificate_name": `"foocert"`, }), }}) @@ -131,6 +133,7 @@ android_app { })`, "manifest": `"AndroidManifest.xml"`, "resource_files": `["res/res.png"]`, + "sdk_version": `"current"`, }), }}) } @@ -365,6 +368,7 @@ android_app { "manifest_values": `{ "minSdkVersion": "24", }`, + "sdk_version": `"current"`, }), }}) } @@ -388,6 +392,7 @@ android_app { "manifest_values": `{ "minSdkVersion": "30", }`, + "sdk_version": `"30"`, }), }}) } diff --git a/bp2build/java_binary_host_conversion_test.go b/bp2build/java_binary_host_conversion_test.go index 1b9777cae..c821f590e 100644 --- a/bp2build/java_binary_host_conversion_test.go +++ b/bp2build/java_binary_host_conversion_test.go @@ -57,24 +57,24 @@ func TestJavaBinaryHost(t *testing.T) { }`, ExpectedBazelTargets: []string{ MakeBazelTarget("java_library", "java-binary-host-1_lib", AttrNameToString{ - "srcs": `["a.java"]`, - "deps": `["//other:jni-lib-1"]`, - "javacopts": `[ - "-Xdoclint:all/protected", - "-source 1.8 -target 1.8", - ]`, + "srcs": `["a.java"]`, + "deps": `["//other:jni-lib-1"]`, + "java_version": `"8"`, + "javacopts": `["-Xdoclint:all/protected"]`, "target_compatible_with": `select({ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], "//conditions:default": [], - })`}), + })`, + }), MakeBazelTarget("java_binary", "java-binary-host-1", AttrNameToString{ - "main_class": `"com.android.test.MainClass"`, - "jvm_flags": `["-Djava.library.path=$${RUNPATH}other"]`, - "runtime_deps": `[":java-binary-host-1_lib"]`, + "main_class": `"com.android.test.MainClass"`, + "jvm_flags": `["-Djava.library.path=$${RUNPATH}other"]`, "target_compatible_with": `select({ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], "//conditions:default": [], - })`}), + })`, + "runtime_deps": `[":java-binary-host-1_lib"]`, + }), }, }) } diff --git a/bp2build/java_host_for_device_conversion_test.go b/bp2build/java_host_for_device_conversion_test.go index d908d0002..448cba461 100644 --- a/bp2build/java_host_for_device_conversion_test.go +++ b/bp2build/java_host_for_device_conversion_test.go @@ -51,9 +51,11 @@ java_library { }`, ExpectedBazelTargets: []string{ MakeBazelTarget("java_host_for_device", "java-lib-1", AttrNameToString{ - "deps": `[":java-lib-2"]`, + "exports": `[":java-lib-2"]`, + }), + MakeNeverlinkDuplicateTargetWithAttrs("java_library", "java-lib-1", AttrNameToString{ + "sdk_version": `"none"`, }), - MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"), MakeBazelTarget("java_library", "java-lib-2", AttrNameToString{ "srcs": `["b.java"]`, }), diff --git a/bp2build/java_import_conversion_test.go b/bp2build/java_import_conversion_test.go index a5c01cb4f..5661620e2 100644 --- a/bp2build/java_import_conversion_test.go +++ b/bp2build/java_import_conversion_test.go @@ -49,8 +49,9 @@ java_import { "jars": `["import.jar"]`, }), MakeBazelTarget("java_library", "example_import-neverlink", AttrNameToString{ - "exports": `[":example_import"]`, - "neverlink": `True`, + "exports": `[":example_import"]`, + "neverlink": `True`, + "sdk_version": `"none"`, }), }}) } @@ -86,8 +87,9 @@ java_import { })`, }), MakeBazelTarget("java_library", "example_import-neverlink", AttrNameToString{ - "exports": `[":example_import"]`, - "neverlink": `True`, + "exports": `[":example_import"]`, + "neverlink": `True`, + "sdk_version": `"none"`, }), }}) } @@ -112,8 +114,9 @@ java_import_host { "jars": `["import.jar"]`, }), MakeBazelTarget("java_library", "example_import-neverlink", AttrNameToString{ - "exports": `[":example_import"]`, - "neverlink": `True`, + "exports": `[":example_import"]`, + "neverlink": `True`, + "sdk_version": `"none"`, }), }}) } diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go index 683ee27cc..24b763bcf 100644 --- a/bp2build/java_library_conversion_test.go +++ b/bp2build/java_library_conversion_test.go @@ -172,10 +172,13 @@ func TestJavaLibraryJavaVersion(t *testing.T) { }`, ExpectedBazelTargets: []string{ MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{ - "srcs": `["a.java"]`, - "javacopts": `["-source 11 -target 11"]`, + "srcs": `["a.java"]`, + "java_version": `"11"`, }), - MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"), + MakeNeverlinkDuplicateTargetWithAttrs( + "java_library", + "java-lib-1", + AttrNameToString{"java_version": `"11"`}), }, }) } diff --git a/bp2build/java_library_host_conversion_test.go b/bp2build/java_library_host_conversion_test.go index 14854c06a..9e47b0972 100644 --- a/bp2build/java_library_host_conversion_test.go +++ b/bp2build/java_library_host_conversion_test.go @@ -63,8 +63,8 @@ java_library_host { })`, }), MakeBazelTarget("java_library", "java-lib-host-2", AttrNameToString{ - "javacopts": `["-source 1.9 -target 1.9"]`, - "srcs": `["c.java"]`, + "java_version": `"9"`, + "srcs": `["c.java"]`, "target_compatible_with": `select({ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], "//conditions:default": [], @@ -77,6 +77,7 @@ java_library_host { "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], "//conditions:default": [], })`, + "java_version": `"9"`, }), }, }) diff --git a/bp2build/java_plugin_conversion_test.go b/bp2build/java_plugin_conversion_test.go index 8c6337b49..f2b6f20a4 100644 --- a/bp2build/java_plugin_conversion_test.go +++ b/bp2build/java_plugin_conversion_test.go @@ -67,7 +67,7 @@ java_library { "a.java", "b.java", ]`, - "javacopts": `["-source 1.7 -target 1.7"]`, + "java_version": `"7"`, }), }, }) diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go index d25b7c4ee..f546cf45d 100644 --- a/bp2build/java_proto_conversion_test.go +++ b/bp2build/java_proto_conversion_test.go @@ -114,13 +114,17 @@ func TestJavaProtoDefault(t *testing.T) { "java_lite_proto_library", "java-protos_java_proto_lite", AttrNameToString{ - "deps": `[":java-protos_proto"]`, + "deps": `[":java-protos_proto"]`, + "java_version": `"7"`, }), MakeBazelTarget("java_library", "java-protos", AttrNameToString{ - "exports": `[":java-protos_java_proto_lite"]`, - "javacopts": `["-source 1.7 -target 1.7"]`, + "exports": `[":java-protos_java_proto_lite"]`, + "java_version": `"7"`, }), - MakeNeverlinkDuplicateTarget("java_library", "java-protos"), + MakeNeverlinkDuplicateTargetWithAttrs( + "java_library", + "java-protos", + AttrNameToString{"java_version": `"7"`}), }, }) } diff --git a/bp2build/testing.go b/bp2build/testing.go index 856b6eed9..6e919db2b 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -642,10 +642,14 @@ func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string { } func MakeNeverlinkDuplicateTarget(moduleType string, name string) string { - return MakeBazelTarget(moduleType, name+"-neverlink", AttrNameToString{ - "neverlink": `True`, - "exports": `[":` + name + `"]`, - }) + return MakeNeverlinkDuplicateTargetWithAttrs(moduleType, name, AttrNameToString{}) +} + +func MakeNeverlinkDuplicateTargetWithAttrs(moduleType string, name string, extraAttrs AttrNameToString) string { + attrs := extraAttrs + attrs["neverlink"] = `True` + attrs["exports"] = `[":` + name + `"]` + return MakeBazelTarget(moduleType, name+"-neverlink", attrs) } func getTargetName(targetContent string) string { diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go index 718186d92..29b17d415 100644 --- a/cc/sanitize_test.go +++ b/cc/sanitize_test.go @@ -1166,3 +1166,83 @@ func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) { checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync) checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync) } + +func TestCfi(t *testing.T) { + t.Parallel() + + bp := ` + cc_library_shared { + name: "shared_with_cfi", + static_libs: [ + "static_dep_with_cfi", + "static_dep_no_cfi", + ], + sanitize: { + cfi: true, + }, + } + + cc_library_shared { + name: "shared_no_cfi", + static_libs: [ + "static_dep_with_cfi", + "static_dep_no_cfi", + ], + } + + cc_library_static { + name: "static_dep_with_cfi", + sanitize: { + cfi: true, + }, + } + + cc_library_static { + name: "static_dep_no_cfi", + } + + cc_library_shared { + name: "shared_rdep_no_cfi", + static_libs: ["static_dep_with_cfi_2"], + } + + cc_library_static { + name: "static_dep_with_cfi_2", + sanitize: { + cfi: true, + }, + } +` + preparer := android.GroupFixturePreparers( + prepareForCcTest, + ) + result := preparer.RunTestWithBp(t, bp) + ctx := result.TestContext + + buildOs := "android_arm64_armv8-a" + shared_suffix := "_shared" + cfi_suffix := "_cfi" + static_suffix := "_static" + + sharedWithCfiLib := result.ModuleForTests("shared_with_cfi", buildOs+shared_suffix+cfi_suffix) + sharedNoCfiLib := result.ModuleForTests("shared_no_cfi", buildOs+shared_suffix) + staticWithCfiLib := result.ModuleForTests("static_dep_with_cfi", buildOs+static_suffix) + staticWithCfiLibCfiVariant := result.ModuleForTests("static_dep_with_cfi", buildOs+static_suffix+cfi_suffix) + staticNoCfiLib := result.ModuleForTests("static_dep_no_cfi", buildOs+static_suffix) + staticNoCfiLibCfiVariant := result.ModuleForTests("static_dep_no_cfi", buildOs+static_suffix+cfi_suffix) + sharedRdepNoCfi := result.ModuleForTests("shared_rdep_no_cfi", buildOs+shared_suffix) + staticDepWithCfi2Lib := result.ModuleForTests("static_dep_with_cfi_2", buildOs+static_suffix) + + // Confirm assumptions about propagation of CFI enablement + expectStaticLinkDep(t, ctx, sharedWithCfiLib, staticWithCfiLibCfiVariant) + expectStaticLinkDep(t, ctx, sharedNoCfiLib, staticWithCfiLib) + expectStaticLinkDep(t, ctx, sharedWithCfiLib, staticNoCfiLibCfiVariant) + expectStaticLinkDep(t, ctx, sharedNoCfiLib, staticNoCfiLib) + expectStaticLinkDep(t, ctx, sharedRdepNoCfi, staticDepWithCfi2Lib) + + // Confirm that non-CFI variants do not add CFI flags + bazLibCflags := staticWithCfiLib.Rule("cc").Args["cFlags"] + if strings.Contains(bazLibCflags, "-fsanitize-cfi-cross-dso") { + t.Errorf("non-CFI variant of baz not expected to contain CFI flags ") + } +} diff --git a/java/aar.go b/java/aar.go index 47e6efae3..f1b137de1 100644 --- a/java/aar.go +++ b/java/aar.go @@ -1015,9 +1015,10 @@ type bazelAndroidLibrary struct { } type bazelAndroidLibraryImport struct { - Aar bazel.Label - Deps bazel.LabelListAttribute - Exports bazel.LabelListAttribute + Aar bazel.Label + Deps bazel.LabelListAttribute + Exports bazel.LabelListAttribute + Sdk_version bazel.StringAttribute } func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) *bazelAapt { @@ -1059,9 +1060,10 @@ func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) { }, android.CommonAttributes{Name: name}, &bazelAndroidLibraryImport{ - Aar: aars.Includes[0], - Deps: bazel.MakeLabelListAttribute(deps), - Exports: bazel.MakeLabelListAttribute(exports), + Aar: aars.Includes[0], + Deps: bazel.MakeLabelListAttribute(deps), + Exports: bazel.MakeLabelListAttribute(exports), + Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version}, }, ) @@ -1073,6 +1075,9 @@ func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) { javaLibraryAttributes: &javaLibraryAttributes{ Neverlink: bazel.BoolAttribute{Value: &neverlink}, Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version}, + }, }, }, ) @@ -1119,6 +1124,10 @@ func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) javaLibraryAttributes: &javaLibraryAttributes{ Neverlink: bazel.BoolAttribute{Value: &neverlink}, Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: a.deviceProperties.Sdk_version}, + Java_version: bazel.StringAttribute{Value: a.properties.Java_version}, + }, }, }, ) diff --git a/java/app.go b/java/app.go index 52caf6d38..03e233059 100755 --- a/java/app.go +++ b/java/app.go @@ -1565,6 +1565,9 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { appAttrs.bazelAapt = &bazelAapt{Manifest: aapt.Manifest} appAttrs.Deps = bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + ktName}) + appAttrs.javaCommonAttributes = &javaCommonAttributes{ + Sdk_version: commonAttrs.Sdk_version, + } } ctx.CreateBazelTargetModule( diff --git a/java/device_host_converter.go b/java/device_host_converter.go index 656c866ed..3581040f8 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -21,6 +21,8 @@ import ( "android/soong/android" "android/soong/bazel" "android/soong/dexpreopt" + + "github.com/google/blueprint/proptools" ) type DeviceHostConverter struct { @@ -191,7 +193,7 @@ func (d *DeviceHostConverter) AndroidMk() android.AndroidMkData { } type bazelDeviceHostConverterAttributes struct { - Deps bazel.LabelListAttribute + Exports bazel.LabelListAttribute } func (d *DeviceHostConverter) ConvertWithBp2build(ctx android.TopDownMutatorContext) { @@ -202,13 +204,15 @@ func (d *DeviceHostConverter) ConvertWithBp2build(ctx android.TopDownMutatorCont }, android.CommonAttributes{Name: d.Name()}, &bazelDeviceHostConverterAttributes{ - Deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, d.properties.Libs)), + Exports: 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}, + Neverlink: bazel.BoolAttribute{Value: proptools.BoolPtr(true)}, + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: proptools.StringPtr("none")}, + }, } ctx.CreateBazelTargetModule( javaLibraryBazelTargetModuleProperties(), diff --git a/java/java.go b/java/java.go index d400b0cfb..2de4ea97e 100644 --- a/java/java.go +++ b/java/java.go @@ -2740,9 +2740,11 @@ func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorConte type javaCommonAttributes struct { *javaResourcesAttributes *kotlinAttributes - Srcs bazel.LabelListAttribute - Plugins bazel.LabelListAttribute - Javacopts bazel.StringListAttribute + Srcs bazel.LabelListAttribute + Plugins bazel.LabelListAttribute + Javacopts bazel.StringListAttribute + Sdk_version bazel.StringAttribute + Java_version bazel.StringAttribute } type javaDependencyLabels struct { @@ -2873,10 +2875,6 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) if m.properties.Javacflags != nil { javacopts = append(javacopts, m.properties.Javacflags...) } - if m.properties.Java_version != nil { - javaVersion := normalizeJavaVersion(ctx, *m.properties.Java_version).String() - javacopts = append(javacopts, fmt.Sprintf("-source %s -target %s", javaVersion, javaVersion)) - } epEnabled := m.properties.Errorprone.Enabled //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable @@ -2890,7 +2888,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) Plugins: bazel.MakeLabelListAttribute( android.BazelLabelForModuleDeps(ctx, m.properties.Plugins), ), - Javacopts: bazel.MakeStringListAttribute(javacopts), + Javacopts: bazel.MakeStringListAttribute(javacopts), + Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, + Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, } for axis, configToProps := range archVariantProps { @@ -2981,19 +2981,9 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { deps := depLabels.Deps if !commonAttrs.Srcs.IsEmpty() { deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them - - sdkVersion := m.SdkVersion(ctx) - if sdkVersion.Kind == android.SdkPublic && sdkVersion.ApiLevel == android.FutureApiLevel { - // TODO(b/220869005) remove forced dependency on current public android.jar - deps.Add(bazel.MakeLabelAttribute("//prebuilts/sdk:public_current_android_sdk_java_import")) - } else if sdkVersion.Kind == android.SdkSystem && sdkVersion.ApiLevel == android.FutureApiLevel { - // TODO(b/215230098) remove forced dependency on current public android.jar - deps.Add(bazel.MakeLabelAttribute("//prebuilts/sdk:system_current_android_sdk_java_import")) - } } else if !deps.IsEmpty() { ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") } - var props bazel.BazelTargetModuleProperties attrs := &javaLibraryAttributes{ javaCommonAttributes: commonAttrs, @@ -3013,6 +3003,10 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { neverLinkAttrs := &javaLibraryAttributes{ Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), Neverlink: bazel.BoolAttribute{Value: &neverlinkProp}, + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, + Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, + }, } ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name + "-neverlink"}, neverLinkAttrs) @@ -3152,6 +3146,9 @@ func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) { neverlinkAttrs := &javaLibraryAttributes{ Neverlink: bazel.BoolAttribute{Value: &neverlink}, Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: proptools.StringPtr("none")}, + }, } ctx.CreateBazelTargetModule( javaLibraryBazelTargetModuleProperties(), diff --git a/java/proto.go b/java/proto.go index 5280077f1..c732d9842 100644 --- a/java/proto.go +++ b/java/proto.go @@ -143,7 +143,9 @@ func protoFlags(ctx android.ModuleContext, j *CommonProperties, p *android.Proto } type protoAttributes struct { - Deps bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Sdk_version bazel.StringAttribute + Java_version bazel.StringAttribute } func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) *bazel.Label { @@ -175,8 +177,11 @@ func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs baze } protoLabel := bazel.Label{Label: ":" + m.Name() + "_proto"} - var protoAttrs protoAttributes - protoAttrs.Deps.SetValue(bazel.LabelList{Includes: []bazel.Label{protoLabel}}) + protoAttrs := &protoAttributes{ + Deps: bazel.MakeSingleLabelListAttribute(protoLabel), + Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, + Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, + } name := m.Name() + suffix @@ -186,7 +191,7 @@ func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs baze Bzl_load_location: "//build/bazel/rules/java:proto.bzl", }, android.CommonAttributes{Name: name}, - &protoAttrs) + protoAttrs) return &bazel.Label{Label: ":" + name} } diff --git a/rust/binary.go b/rust/binary.go index 056888ef2..2de92c17f 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -72,11 +72,14 @@ func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator 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") @@ -136,7 +139,7 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) - flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...) + flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...) if binary.stripper.NeedsStrip(ctx) { strippedOutputFile := outputFile diff --git a/rust/binary_test.go b/rust/binary_test.go index 7dac2490a..dd4f99314 100644 --- a/rust/binary_test.go +++ b/rust/binary_test.go @@ -123,7 +123,7 @@ func TestBootstrap(t *testing.T) { bootstrap: true, }`) - foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc") + foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustLink") flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64" if !strings.Contains(foo.Args["linkFlags"], flag) { @@ -140,10 +140,11 @@ func TestStaticBinaryFlags(t *testing.T) { }`) 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 := fizzOut.Args["linkFlags"] + linkFlags := fizzOutLink.Args["linkFlags"] if !strings.Contains(flags, "-C relocation-model=static") { t.Errorf("static binary missing '-C relocation-model=static' in rustcFlags, found: %#v", flags) } @@ -173,7 +174,7 @@ func TestLinkObjects(t *testing.T) { name: "libfoo", }`) - fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustc") + fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustLink") 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 0aef13d44..0aa2225f7 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -26,14 +26,14 @@ import ( 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=${config.RustLinker} " + - "-C link-args=\"${crtBegin} ${config.RustLinkerArgs} ${linkFlags} ${crtEnd}\" " + + "-C linker=$mkcraterspCmd " + "--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" + " && grep \"^$out:\" $out.d.raw > $out.d", - CommandDeps: []string{"$rustcCmd"}, + CommandDeps: []string{"$rustcCmd", "$mkcraterspCmd"}, // 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,7 +42,12 @@ var ( Deps: blueprint.DepsGCC, Depfile: "$out.d", }, - "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars") + "rustcFlags", "libFlags", "envVars") + rustLink = pctx.AndroidStaticRule("rustLink", + blueprint.RuleParams{ + Command: "${config.RustLinker} -o $out ${crtBegin} ${config.RustLinkerArgs} @$in ${linkFlags} ${crtEnd}", + }, + "linkFlags", "crtBegin", "crtEnd") _ = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc") rustdoc = pctx.AndroidStaticRule("rustdoc", @@ -101,14 +106,13 @@ var ( `KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative ` + `$rustExtractor $envVars ` + `$rustcCmd ` + - `-C linker=${config.RustLinker} ` + - `-C link-args="${crtBegin} ${config.RustLinkerArgs} ${linkFlags} ${crtEnd}" ` + + `-C linker=true ` + `$in ${libFlags} $rustcFlags`, CommandDeps: []string{"$rustExtractor", "$kytheVnames"}, Rspfile: "${out}.rsp", RspfileContent: "$in", }, - "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars") + "rustcFlags", "libFlags", "envVars") ) type buildOutput struct { @@ -220,11 +224,9 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl outputFile android.WritablePath, crateType string) buildOutput { var inputs android.Paths - var implicits android.Paths - var orderOnly android.Paths + var implicits, linkImplicits, linkOrderOnly android.Paths var output buildOutput var rustcFlags, linkFlags []string - var implicitOutputs android.WritablePaths output.outputFile = outputFile crateName := ctx.RustModule().CrateName() @@ -281,15 +283,15 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl implicits = append(implicits, rustLibsToPaths(deps.RLibs)...) implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...) implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...) - implicits = append(implicits, deps.StaticLibs...) - implicits = append(implicits, deps.SharedLibDeps...) - implicits = append(implicits, deps.srcProviderFiles...) implicits = append(implicits, deps.AfdoProfiles...) + implicits = append(implicits, deps.srcProviderFiles...) + implicits = append(implicits, deps.WholeStaticLibs...) - implicits = append(implicits, deps.CrtBegin...) - implicits = append(implicits, deps.CrtEnd...) + linkImplicits = append(linkImplicits, deps.LibDeps...) + linkImplicits = append(linkImplicits, deps.CrtBegin...) + linkImplicits = append(linkImplicits, deps.CrtEnd...) - orderOnly = append(orderOnly, deps.SharedLibs...) + linkOrderOnly = append(linkOrderOnly, deps.linkObjects...) if len(deps.SrcDeps) > 0 { moduleGenDir := ctx.RustModule().compiler.CargoOutDir() @@ -328,16 +330,16 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl } } + envVars = append(envVars, "AR=${cc_config.ClangBin}/llvm-ar") + if flags.Clippy { clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy") ctx.Build(pctx, android.BuildParams{ - Rule: clippyDriver, - Description: "clippy " + main.Rel(), - Output: clippyFile, - ImplicitOutputs: nil, - Inputs: inputs, - Implicits: implicits, - OrderOnly: orderOnly, + Rule: clippyDriver, + Description: "clippy " + main.Rel(), + Output: clippyFile, + Inputs: inputs, + Implicits: implicits, Args: map[string]string{ "rustcFlags": strings.Join(rustcFlags, " "), "libFlags": strings.Join(libFlags, " "), @@ -349,24 +351,41 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl implicits = append(implicits, clippyFile) } + rustcOutputFile := outputFile + usesLinker := crateType == "bin" || crateType == "dylib" || crateType == "cdylib" || crateType == "proc-macro" + if usesLinker { + rustcOutputFile = android.PathForModuleOut(ctx, outputFile.Base()+".rsp") + } + ctx.Build(pctx, android.BuildParams{ - Rule: rustc, - Description: "rustc " + main.Rel(), - Output: outputFile, - ImplicitOutputs: implicitOutputs, - Inputs: inputs, - Implicits: implicits, - OrderOnly: orderOnly, + Rule: rustc, + Description: "rustc " + main.Rel(), + Output: rustcOutputFile, + Inputs: inputs, + Implicits: implicits, 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, " "), }, }) + 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{ + "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{ @@ -375,13 +394,9 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl 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/coverage.go b/rust/coverage.go index bc6504ddc..5216d6098 100644 --- a/rust/coverage.go +++ b/rust/coverage.go @@ -65,7 +65,7 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags "-C instrument-coverage", "-g") flags.LinkFlags = append(flags.LinkFlags, profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open") - deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path()) + deps.LibDeps = append(deps.LibDeps, 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 0f599d745..64077cf00 100644 --- a/rust/coverage_test.go +++ b/rust/coverage_test.go @@ -55,6 +55,10 @@ func TestCoverageFlags(t *testing.T) { 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 { @@ -80,17 +84,17 @@ func TestCoverageFlags(t *testing.T) { 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(fizzCov.Args["linkFlags"], flag) { - t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCov.Args["linkFlags"]) + if !strings.Contains(fizzCovLink.Args["linkFlags"], flag) { + t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCovLink.Args["linkFlags"]) } - if !strings.Contains(libfooCov.Args["linkFlags"], flag) { - t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCov.Args["linkFlags"]) + if !strings.Contains(libfooCovLink.Args["linkFlags"], flag) { + t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCovLink.Args["linkFlags"]) } - if strings.Contains(buzzNoCov.Args["linkFlags"], flag) { - t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCov.Args["linkFlags"]) + if strings.Contains(buzzNoCovLink.Args["linkFlags"], flag) { + t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCovLink.Args["linkFlags"]) } - if strings.Contains(libbarNoCov.Args["linkFlags"], flag) { - t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCov.Args["linkFlags"]) + if strings.Contains(libbarNoCovLink.Args["linkFlags"], flag) { + t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCovLink.Args["linkFlags"]) } } @@ -103,7 +107,7 @@ func TestCoverageDeps(t *testing.T) { srcs: ["foo.rs"], }`) - fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustc") + fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustLink") 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 bc9c9aa38..a3a567281 100644 --- a/rust/library.go +++ b/rust/library.go @@ -520,7 +520,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) - flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...) + flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...) if library.dylib() { // We need prefer-dynamic for now to avoid linking in the static stdlib. See: @@ -543,6 +543,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa 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 e3e4d0f03..d4b525f2e 100644 --- a/rust/library_test.go +++ b/rust/library_test.go @@ -148,7 +148,7 @@ func TestSharedLibrary(t *testing.T) { libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared") - libfooOutput := libfoo.Rule("rustc") + libfooOutput := libfoo.Rule("rustLink") 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 56b463160..7b520cdb0 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -420,13 +420,12 @@ type Deps struct { } type PathDeps struct { - DyLibs RustLibraries - RLibs RustLibraries - SharedLibs android.Paths - SharedLibDeps android.Paths - StaticLibs android.Paths - ProcMacros RustLibraries - AfdoProfiles android.Paths + DyLibs RustLibraries + RLibs RustLibraries + LibDeps android.Paths + WholeStaticLibs android.Paths + ProcMacros RustLibraries + AfdoProfiles android.Paths // depFlags and depLinkFlags are rustc and linker (clang) flags. depFlags []string @@ -435,7 +434,7 @@ type PathDeps struct { // 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 []string + linkObjects android.Paths // Used by bindgen modules which call clang depClangFlags []string @@ -498,7 +497,7 @@ type compiler interface { type exportedFlagsProducer interface { exportLinkDirs(...string) - exportLinkObjects(...string) + exportLinkObjects(...android.Path) } type xref interface { @@ -507,21 +506,27 @@ type xref interface { type flagExporter struct { linkDirs []string - linkObjects []string + linkObjects android.Paths + libDeps android.Paths } func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) { flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...)) } -func (flagExporter *flagExporter) exportLinkObjects(flags ...string) { - flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...)) +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) setProvider(ctx ModuleContext) { ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{ LinkDirs: flagExporter.linkDirs, LinkObjects: flagExporter.linkObjects, + LibDeps: flagExporter.libDeps, }) } @@ -534,7 +539,8 @@ func NewFlagExporter() *flagExporter { type FlagExporterInfo struct { Flags []string LinkDirs []string // TODO: this should be android.Paths - LinkObjects []string // TODO: this should be android.Paths + LinkObjects android.Paths + LibDeps android.Paths } var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{}) @@ -1250,6 +1256,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { 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 { @@ -1293,6 +1300,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { 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()) } @@ -1300,7 +1308,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // 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.String()) + depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...) depPaths.linkDirs = append(depPaths.linkDirs, linkPath) exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo) @@ -1326,7 +1334,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { linkPath = linkPathFromFilePath(linkObject.Path()) depPaths.linkDirs = append(depPaths.linkDirs, linkPath) - depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String()) + depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...) depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) @@ -1352,7 +1360,9 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // Make sure these dependencies are propagated if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep { lib.exportLinkDirs(linkPath) - lib.exportLinkObjects(linkObject.String()) + if linkObject.Valid() { + lib.exportLinkObjects(linkObject.Path()) + } } } else { switch { @@ -1384,19 +1394,16 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) } - var staticLibDepFiles android.Paths + var libDepFiles android.Paths for _, dep := range directStaticLibDeps { - staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path()) + libDepFiles = append(libDepFiles, dep.OutputFile().Path()) } - var sharedLibFiles android.Paths - var sharedLibDepFiles android.Paths for _, dep := range directSharedLibDeps { - sharedLibFiles = append(sharedLibFiles, dep.SharedLibrary) if dep.TableOfContents.Valid() { - sharedLibDepFiles = append(sharedLibDepFiles, dep.TableOfContents.Path()) + libDepFiles = append(libDepFiles, dep.TableOfContents.Path()) } else { - sharedLibDepFiles = append(sharedLibDepFiles, dep.SharedLibrary) + libDepFiles = append(libDepFiles, dep.SharedLibrary) } } @@ -1412,15 +1419,13 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...) depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...) - depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibFiles...) - depPaths.SharedLibDeps = append(depPaths.SharedLibDeps, sharedLibDepFiles...) - depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...) + depPaths.LibDeps = append(depPaths.LibDeps, libDepFiles...) 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.FirstUniqueStrings(depPaths.linkObjects) + depPaths.linkObjects = android.FirstUniquePaths(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 e8e58009b..2a38b8983 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -258,6 +258,7 @@ func TestDepsTracking(t *testing.T) { `) 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("libdylib", module.Properties.AndroidMkDylibs) { @@ -284,16 +285,16 @@ func TestDepsTracking(t *testing.T) { t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.Args["rustcFlags"]) } - 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 !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 !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.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.Implicits.Strings(), "cc_stubs_dep.so.toc") { - t.Errorf("shared cc dep TOC not being passed as implicit to rustc %#v", rustc.Implicits.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()) } } diff --git a/rust/sanitize_test.go b/rust/sanitize_test.go index d6a14b295..43e95f477 100644 --- a/rust/sanitize_test.go +++ b/rust/sanitize_test.go @@ -35,7 +35,7 @@ func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNo note_sync := "note_memtag_heap_sync" found := None - implicits := m.Rule("rustc").Implicits + implicits := m.Rule("rustLink").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 e1b3c86a2..2e7a33027 100644 --- a/rust/vendor_snapshot_test.go +++ b/rust/vendor_snapshot_test.go @@ -941,7 +941,7 @@ func TestVendorSnapshotUse(t *testing.T) { 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("rustc").Args["linkFlags"] + libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustLink").Args["linkFlags"] for _, input := range [][]string{ []string{sharedVariant, "libvndk.vndk.30.arm64"}, []string{staticVariant, "libvendor.vendor_static.30.arm64"}, @@ -997,7 +997,7 @@ func TestVendorSnapshotUse(t *testing.T) { t.Errorf("Unexpected rust rlib name in AndroidMk: %q, expected: %q\n", rustVendorBinMkRlibName, expectedRustVendorSnapshotName) } - binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustc").Args["linkFlags"] + binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustLink").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/mkcratersp.py b/scripts/mkcratersp.py new file mode 100755 index 000000000..86b4aa3fb --- /dev/null +++ b/scripts/mkcratersp.py @@ -0,0 +1,79 @@ +#!/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 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: + 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) |