diff options
| -rw-r--r-- | android/allowlists/allowlists.go | 110 | ||||
| -rw-r--r-- | android/bazel_paths.go | 3 | ||||
| -rw-r--r-- | android/config.go | 4 | ||||
| -rw-r--r-- | android/prebuilt_build_tool.go | 6 | ||||
| -rw-r--r-- | android/rule_builder.go | 47 | ||||
| -rw-r--r-- | android/rule_builder_test.go | 86 | ||||
| -rw-r--r-- | android/variable.go | 10 | ||||
| -rw-r--r-- | bp2build/aar_conversion_test.go | 52 | ||||
| -rw-r--r-- | bp2build/android_app_conversion_test.go | 38 | ||||
| -rw-r--r-- | bp2build/bp2build_product_config.go | 93 | ||||
| -rw-r--r-- | bp2build/build_conversion.go | 8 | ||||
| -rw-r--r-- | cc/ndk_library.go | 11 | ||||
| -rw-r--r-- | cc/sanitize.go | 9 | ||||
| -rw-r--r-- | cc/sanitize_test.go | 120 | ||||
| -rw-r--r-- | cc/testing.go | 1 | ||||
| -rw-r--r-- | cmd/sbox/sbox.go | 3 | ||||
| -rw-r--r-- | java/aar.go | 26 | ||||
| -rwxr-xr-x | java/app.go | 39 | ||||
| -rw-r--r-- | java/base.go | 13 | ||||
| -rw-r--r-- | rust/binary.go | 9 | ||||
| -rw-r--r-- | rust/compiler.go | 11 | ||||
| -rw-r--r-- | rust/config/global.go | 16 | ||||
| -rw-r--r-- | rust/library.go | 18 | ||||
| -rw-r--r-- | rust/protobuf.go | 21 | ||||
| -rw-r--r-- | rust/protobuf_test.go | 52 | ||||
| -rw-r--r-- | rust/rust.go | 77 | ||||
| -rw-r--r-- | rust/toolchain_library.go | 70 |
27 files changed, 804 insertions, 149 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 1f678a074..f35fe3dc0 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -75,14 +75,17 @@ var ( "build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir "build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue, "build/soong/cc/symbolfile": Bp2BuildDefaultTrue, + "build/soong/jar": Bp2BuildDefaultTrue, "build/soong/licenses": Bp2BuildDefaultTrue, "build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively, + "build/soong/response": Bp2BuildDefaultTrue, "build/soong/scripts": Bp2BuildDefaultTrueRecursively, + "build/soong/third_party/zip": Bp2BuildDefaultTrue, "cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively, - "cts/libs/json": Bp2BuildDefaultTrueRecursively, - "cts/tests/tests/gesture": Bp2BuildDefaultTrueRecursively, - "platform_testing/libraries/annotations": Bp2BuildDefaultTrueRecursively, + "cts/flags/cc_tests": Bp2BuildDefaultTrueRecursively, + "cts/libs/json": Bp2BuildDefaultTrueRecursively, + "cts/tests/tests/gesture": Bp2BuildDefaultTrueRecursively, "dalvik/tools/dexdeps": Bp2BuildDefaultTrueRecursively, @@ -139,6 +142,7 @@ var ( "external/bzip2": Bp2BuildDefaultTrueRecursively, "external/clang/lib": Bp2BuildDefaultTrue, "external/conscrypt": Bp2BuildDefaultTrue, + "external/dexmaker": Bp2BuildDefaultTrueRecursively, "external/e2fsprogs": Bp2BuildDefaultTrueRecursively, "external/eigen": Bp2BuildDefaultTrueRecursively, "external/erofs-utils": Bp2BuildDefaultTrueRecursively, @@ -191,6 +195,7 @@ var ( "external/lzma/C": Bp2BuildDefaultTrueRecursively, "external/mdnsresponder": Bp2BuildDefaultTrueRecursively, "external/minijail": Bp2BuildDefaultTrueRecursively, + "external/mockito": Bp2BuildDefaultTrueRecursively, "external/musl": Bp2BuildDefaultTrueRecursively, "external/objenesis": Bp2BuildDefaultTrueRecursively, "external/openscreen": Bp2BuildDefaultTrueRecursively, @@ -213,6 +218,7 @@ var ( "external/tinyalsa": Bp2BuildDefaultTrueRecursively, "external/tinyalsa_new": Bp2BuildDefaultTrueRecursively, "external/toybox": Bp2BuildDefaultTrueRecursively, + "external/xz-java": Bp2BuildDefaultTrueRecursively, "external/zlib": Bp2BuildDefaultTrueRecursively, "external/zopfli": Bp2BuildDefaultTrueRecursively, "external/zstd": Bp2BuildDefaultTrueRecursively, @@ -230,9 +236,11 @@ var ( "frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively, "frameworks/base/apex/jobscheduler/service/jni": Bp2BuildDefaultTrueRecursively, "frameworks/base/core/java": Bp2BuildDefaultTrue, + "frameworks/base/core/res": Bp2BuildDefaultTrueRecursively, "frameworks/base/libs/androidfw": Bp2BuildDefaultTrue, "frameworks/base/libs/services": Bp2BuildDefaultTrue, "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue, + "frameworks/base/mime": Bp2BuildDefaultTrueRecursively, "frameworks/base/proto": Bp2BuildDefaultTrue, "frameworks/base/services/tests/servicestests/aidl": Bp2BuildDefaultTrue, "frameworks/base/startop/apps/test": Bp2BuildDefaultTrue, @@ -242,6 +250,8 @@ var ( "frameworks/base/tools/codegen": Bp2BuildDefaultTrueRecursively, "frameworks/base/tools/locked_region_code_injection": Bp2BuildDefaultTrueRecursively, "frameworks/base/tools/streaming_proto": Bp2BuildDefaultTrueRecursively, + "frameworks/hardware/interfaces": Bp2BuildDefaultTrue, + "frameworks/hardware/interfaces/displayservice": Bp2BuildDefaultTrueRecursively, "frameworks/hardware/interfaces/stats/aidl": Bp2BuildDefaultTrue, "frameworks/libs/modules-utils/build": Bp2BuildDefaultTrueRecursively, "frameworks/libs/modules-utils/java": Bp2BuildDefaultTrue, @@ -307,6 +317,9 @@ var ( "hardware/interfaces/neuralnetworks/1.2/vts": Bp2BuildDefaultFalseRecursively, "hardware/interfaces/neuralnetworks/1.3/vts": Bp2BuildDefaultFalseRecursively, "hardware/interfaces/neuralnetworks/1.4/vts": Bp2BuildDefaultFalseRecursively, + "hardware/interfaces/tests": Bp2BuildDefaultTrueRecursively, + "hardware/interfaces/tests/extension": Bp2BuildDefaultFalseRecursively, // missing deps + "hardware/interfaces/tests/msgq": Bp2BuildDefaultFalseRecursively, // missing deps "libnativehelper": Bp2BuildDefaultTrueRecursively, @@ -335,7 +348,9 @@ var ( "packages/screensavers/Basic": Bp2BuildDefaultTrue, "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321) - "platform_testing/tests/example": Bp2BuildDefaultTrueRecursively, + "platform_testing/libraries/annotations": Bp2BuildDefaultTrueRecursively, + "platform_testing/libraries/flag-helpers/libflagtest": Bp2BuildDefaultTrueRecursively, + "platform_testing/tests/example": Bp2BuildDefaultTrueRecursively, "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively, "prebuilts/gradle-plugin": Bp2BuildDefaultTrueRecursively, @@ -399,8 +414,7 @@ var ( "system/libhidl/transport/manager/1.0": Bp2BuildDefaultTrue, "system/libhidl/transport/manager/1.1": Bp2BuildDefaultTrue, "system/libhidl/transport/manager/1.2": Bp2BuildDefaultTrue, - "system/libhidl/transport/memory/1.0": Bp2BuildDefaultTrue, - "system/libhidl/transport/memory/token/1.0": Bp2BuildDefaultTrue, + "system/libhidl/transport/memory": Bp2BuildDefaultTrueRecursively, "system/libhidl/transport/safe_union/1.0": Bp2BuildDefaultTrue, "system/libhidl/transport/token/1.0": Bp2BuildDefaultTrue, "system/libhidl/transport/token/1.0/utils": Bp2BuildDefaultTrue, @@ -410,14 +424,14 @@ var ( "system/libziparchive": Bp2BuildDefaultTrueRecursively, "system/logging": Bp2BuildDefaultTrueRecursively, "system/media": Bp2BuildDefaultTrue, - "system/media/audio": Bp2BuildDefaultTrueRecursively, "system/media/alsa_utils": Bp2BuildDefaultTrueRecursively, + "system/media/audio": Bp2BuildDefaultTrueRecursively, "system/media/audio_utils": Bp2BuildDefaultTrueRecursively, "system/media/camera": Bp2BuildDefaultTrueRecursively, "system/memory/libion": Bp2BuildDefaultTrueRecursively, "system/memory/libmemunreachable": Bp2BuildDefaultTrueRecursively, - "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively, "system/security/fsverity": Bp2BuildDefaultTrueRecursively, + "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively, "system/testing/gtest_extras": Bp2BuildDefaultTrueRecursively, "system/timezone/apex": Bp2BuildDefaultTrueRecursively, "system/timezone/output_data": Bp2BuildDefaultTrueRecursively, @@ -425,13 +439,14 @@ var ( "system/timezone/testing": Bp2BuildDefaultTrueRecursively, "system/tools/aidl/build/tests_bp2build": Bp2BuildDefaultTrue, "system/tools/aidl/metadata": Bp2BuildDefaultTrue, - "system/tools/hidl/metadata": Bp2BuildDefaultTrue, - "system/tools/hidl/utils": Bp2BuildDefaultTrue, + "system/tools/hidl": Bp2BuildDefaultTrueRecursively, "system/tools/mkbootimg": Bp2BuildDefaultTrueRecursively, "system/tools/sysprop": Bp2BuildDefaultTrue, "system/tools/xsdc/utils": Bp2BuildDefaultTrueRecursively, "system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively, + "test/vts/vts_hal_hidl_target": Bp2BuildDefaultTrueRecursively, + "tools/apifinder": Bp2BuildDefaultTrue, "tools/apksig": Bp2BuildDefaultTrue, "tools/dexter/slicer": Bp2BuildDefaultTrueRecursively, @@ -439,6 +454,7 @@ var ( "tools/metalava": Bp2BuildDefaultTrueRecursively, "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively, "tools/platform-compat/java/androidprocessor": Bp2BuildDefaultTrueRecursively, + "tools/tradefederation/core/util_apps": Bp2BuildDefaultTrueRecursively, "tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively, } @@ -464,6 +480,7 @@ var ( "external/bazelbuild-rules_go":/* recursive = */ true, "external/bazelbuild-rules_python":/* recursive = */ true, "external/bazelbuild-rules_rust":/* recursive = */ true, + "external/bazelbuild-rules_testing":/* recursive = */ true, "external/bazelbuild-kotlin-rules":/* recursive = */ true, "external/bazel-skylib":/* recursive = */ true, "external/protobuf":/* recursive = */ false, @@ -557,13 +574,8 @@ var ( // ext "tagsoup", - // framework-res - "remote-color-resources-compile-public", - "remote-color-resources-compile-colors", - // framework-minus-apex "ImmutabilityAnnotationProcessor", - "android.mime.types.minimized", "debian.mime.types.minimized", "framework-javastream-protos", "libview-inspector-annotation-processor", @@ -572,7 +584,6 @@ var ( "apache-commons-math", "cbor-java", "icu4j_calendar_astronomer", - "remote-color-resources-compile-public", "statslog-art-java-gen", "AndroidCommonLint", @@ -924,9 +935,7 @@ var ( "androidx.test.annotation-nodeps", // jni deps of an internal android_test (b/297405812) - "libdexmakerjvmtiagent", "libopenjdkjvmti_headers", - "libstaticjvmtiagent", // tradefed deps "tradefed-protos", @@ -950,6 +959,33 @@ var ( "GsonBuildConfig.java", "gson_version_generator", "lab-resource-grpc", + "blueprint-deptools", + "protoc-gen-grpc-java-plugin", + "perfetto_trace-full", + "tf-remote-client", + "truth", + "tradefed-lite", + "tradefed-isolation-protos", + "snakeyaml_patched_src_files", + "asuite_proto_java", + "tradefed-service-grpc-lib", + "tradefed-invocation-grpc", + "tradefed-external-dependencies", + "tradefed-dynamic-sharding-grpc", + "tradefed-device-manager-grpc", + "statsd_internal_protos", + "snakeyaml", + "loganalysis", + "junit-params", + "grpc-java-testing", + "grpc-java-netty-shaded", + "aoa-helper", + "test-services.apk", + "test-composers", + "py3-stdlib-prebuilt-srcs", + "platformprotos", + "perfetto_metrics-full", + "test-services-normalized.apk", } Bp2buildModuleTypeAlwaysConvertList = []string{ @@ -1063,20 +1099,22 @@ var ( "libtombstoned_client_rust_bridge_code", "libtombstoned_client_wrapper", // rust conversions are not supported // unconverted deps - "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib - "adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi - "android_icu4j_srcgen", // depends on unconverted modules: currysrc - "android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc - "apex_compression_test", // depends on unconverted modules: soong_zip, com.android.example.apex - "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full - "apexer_with_DCLA_preprocessing_test", // depends on unconverted modules: apexer_test_host_tools, com.android.example.apex - "art-script", // depends on unconverted modules: dalvikvm, dex2oat - "bin2c_fastdeployagent", // depends on unconverted modules: deployagent - "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig - "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9 - "dex2oat-script", // depends on unconverted modules: dex2oat - "generated_android_icu4j_resources", // depends on unconverted modules: android_icu4j_srcgen_binary - "generated_android_icu4j_test_resources", // depends on unconverted modules: android_icu4j_srcgen_binary + "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib + "adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi + "android_icu4j_srcgen", // depends on unconverted modules: currysrc + "android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc + "apex_compression_test", // depends on unconverted modules: soong_zip, com.android.example.apex + "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full + "apexer_with_DCLA_preprocessing_test", // depends on unconverted modules: apexer_test_host_tools, com.android.example.apex + "art-script", // depends on unconverted modules: dalvikvm, dex2oat + "bin2c_fastdeployagent", // depends on unconverted modules: deployagent + "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig + "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9 + "dex2oat-script", // depends on unconverted modules: dex2oat + "generated_android_icu4j_resources", // depends on unconverted modules: android_icu4j_srcgen_binary + "generated_android_icu4j_test_resources", // depends on unconverted modules: android_icu4j_srcgen_binary + "hidl_system_api_test", + "hidl_test_java", "host-libprotobuf-java-nano", // b/220869005, depends on libprotobuf-java-nano "jacoco-stubs", // b/245767077, depends on droidstubs "libapexutil", // depends on unconverted modules: apex-info-list-tinyxml @@ -1659,6 +1697,7 @@ var ( // python_test_host with test data "sbom_writers_test", + "hidl_test", // TODO(B/283193845): tradefed and its java_test_host dependents "tradefed", @@ -1716,6 +1755,13 @@ var ( "NanoAndroidTest", "MtsLibnativehelperTestCases", + // Depends on androidx.test.rules + "DexmakerTests", + "dexmaker-tests-lib", + "dexmaker-mockmaker-tests", + "dexmaker-inline-mockmaker-tests", + "dexmaker-extended-mockmaker-tests", + // android_test_helper_app from allowlisted packages, but with unconverted deps "SharedLibraryInfoTestApp", } diff --git a/android/bazel_paths.go b/android/bazel_paths.go index 4ac58403c..d8effaa12 100644 --- a/android/bazel_paths.go +++ b/android/bazel_paths.go @@ -442,6 +442,9 @@ func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string, otherLabel := labelFromModule(ctx, m) // TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets. + if tag != "" && m.Name() == "framework-res" { + otherLabel += tag + } if samePackage(label, otherLabel) { otherLabel = bazelShortLabel(otherLabel) diff --git a/android/config.go b/android/config.go index f9d616d9a..b3ff86b49 100644 --- a/android/config.go +++ b/android/config.go @@ -2080,3 +2080,7 @@ func (c *config) Bp2buildMode() bool { func (c *deviceConfig) CheckVendorSeappViolations() bool { return Bool(c.config.productVariables.CheckVendorSeappViolations) } + +func (c *deviceConfig) NextReleaseHideFlaggedApi() bool { + return Bool(c.config.productVariables.NextReleaseHideFlaggedApi) +} diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go index aeae20f48..17b323067 100644 --- a/android/prebuilt_build_tool.go +++ b/android/prebuilt_build_tool.go @@ -17,7 +17,7 @@ package android import "path/filepath" func init() { - RegisterModuleType("prebuilt_build_tool", prebuiltBuildToolFactory) + RegisterModuleType("prebuilt_build_tool", NewPrebuiltBuildTool) } type prebuiltBuildToolProperties struct { @@ -101,10 +101,6 @@ var _ HostToolProvider = &prebuiltBuildTool{} // prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use // in genrules with the "tools" property. -func prebuiltBuildToolFactory() Module { - return NewPrebuiltBuildTool() -} - func NewPrebuiltBuildTool() Module { module := &prebuiltBuildTool{} module.AddProperties(&module.properties) diff --git a/android/rule_builder.go b/android/rule_builder.go index 777c1cfc3..245b759ca 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -474,13 +474,23 @@ func (r *RuleBuilder) depFileMergerCmd(depFiles WritablePaths) *RuleBuilderComma Inputs(depFiles.Paths()) } +// BuildWithNinjaVars adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for +// Outputs. This function will not escape Ninja variables, so it may be used to write sandbox manifests using Ninja variables. +func (r *RuleBuilder) BuildWithUnescapedNinjaVars(name string, desc string) { + r.build(name, desc, false) +} + // Build adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for // Outputs. func (r *RuleBuilder) Build(name string, desc string) { + r.build(name, desc, true) +} + +func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString bool) { name = ninjaNameEscape(name) if len(r.missingDeps) > 0 { - r.ctx.Build(pctx, BuildParams{ + r.ctx.Build(r.pctx, BuildParams{ Rule: ErrorRule, Outputs: r.Outputs(), Description: desc, @@ -619,12 +629,35 @@ func (r *RuleBuilder) Build(name string, desc string) { name, r.sboxManifestPath.String(), r.outDir.String()) } - // Create a rule to write the manifest as a the textproto. + // Create a rule to write the manifest as textproto. pbText, err := prototext.Marshal(&manifest) if err != nil { ReportPathErrorf(r.ctx, "sbox manifest failed to marshal: %q", err) } - WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText)) + if ninjaEscapeCommandString { + WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText)) + } else { + // We need to have a rule to write files that is + // defined on the RuleBuilder's pctx in order to + // write Ninja variables in the string. + // The WriteFileRule function above rule can only write + // raw strings because it is defined on the android + // package's pctx, and it can't access variables defined + // in another context. + r.ctx.Build(r.pctx, BuildParams{ + Rule: r.ctx.Rule(r.pctx, "unescapedWriteFile", blueprint.RuleParams{ + Command: `rm -rf ${out} && cat ${out}.rsp > ${out}`, + Rspfile: "${out}.rsp", + RspfileContent: "${content}", + Description: "write file", + }, "content"), + Output: r.sboxManifestPath, + Description: "write sbox manifest " + r.sboxManifestPath.Base(), + Args: map[string]string{ + "content": string(pbText), + }, + }) + } // Generate a new string to use as the command line of the sbox rule. This uses // a RuleBuilderCommand as a convenience method of building the command line, then @@ -723,9 +756,13 @@ func (r *RuleBuilder) Build(name string, desc string) { pool = localPool } + if ninjaEscapeCommandString { + commandString = proptools.NinjaEscape(commandString) + } + r.ctx.Build(r.pctx, BuildParams{ - Rule: r.ctx.Rule(pctx, name, blueprint.RuleParams{ - Command: proptools.NinjaEscape(commandString), + Rule: r.ctx.Rule(r.pctx, name, blueprint.RuleParams{ + Command: commandString, CommandDeps: proptools.NinjaEscapeList(tools.Strings()), Restat: r.restat, Rspfile: proptools.NinjaEscape(rspFile), diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go index 86647eb22..a6b3a27a1 100644 --- a/android/rule_builder_test.go +++ b/android/rule_builder_test.go @@ -28,6 +28,17 @@ import ( "android/soong/shared" ) +var ( + pctx_ruleBuilderTest = NewPackageContext("android/soong/rule_builder") + pctx_ruleBuilderTestSubContext = NewPackageContext("android/soong/rule_builder/config") +) + +func init() { + pctx_ruleBuilderTest.Import("android/soong/rule_builder/config") + pctx_ruleBuilderTest.StaticVariable("cmdFlags", "${config.ConfigFlags}") + pctx_ruleBuilderTestSubContext.StaticVariable("ConfigFlags", "--some-clang-flag") +} + func builderContext() BuilderContext { return BuilderContextForTesting(TestConfig("out", nil, "", map[string][]byte{ "ld": nil, @@ -496,11 +507,13 @@ func testRuleBuilderFactory() Module { type testRuleBuilderModule struct { ModuleBase properties struct { - Srcs []string + Srcs []string + Flags []string - Restat bool - Sbox bool - Sbox_inputs bool + Restat bool + Sbox bool + Sbox_inputs bool + Unescape_ninja_vars bool } } @@ -518,8 +531,9 @@ func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) { rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) manifestPath := PathForModuleOut(ctx, "sbox.textproto") - testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir, - manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs, + testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, t.properties.Flags, + out, outDep, outDir, + manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs, t.properties.Unescape_ninja_vars, rspFile, rspFileContents, rspFile2, rspFileContents2) } @@ -543,17 +557,18 @@ func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) { rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) manifestPath := PathForOutput(ctx, "singleton/sbox.textproto") - testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir, - manifestPath, true, false, false, + testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, nil, out, outDep, outDir, + manifestPath, true, false, false, false, rspFile, rspFileContents, rspFile2, rspFileContents2) } func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path, + flags []string, out, outDep, outDir, manifestPath WritablePath, - restat, sbox, sboxInputs bool, + restat, sbox, sboxInputs, unescapeNinjaVars bool, rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) { - rule := NewRuleBuilder(pctx, ctx) + rule := NewRuleBuilder(pctx_ruleBuilderTest, ctx) if sbox { rule.Sbox(outDir, manifestPath) @@ -564,6 +579,7 @@ func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, va rule.Command(). Tool(PathForSource(ctx, "cp")). + Flags(flags). Inputs(in). Implicit(implicit). OrderOnly(orderOnly). @@ -577,7 +593,11 @@ func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, va rule.Restat() } - rule.Build("rule", "desc") + if unescapeNinjaVars { + rule.BuildWithUnescapedNinjaVars("rule", "desc") + } else { + rule.Build("rule", "desc") + } } var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) { @@ -792,3 +812,47 @@ func TestRuleBuilderHashInputs(t *testing.T) { }) } } + +func TestRuleBuilderWithNinjaVarEscaping(t *testing.T) { + bp := ` + rule_builder_test { + name: "foo_sbox_escaped_ninja", + flags: ["${cmdFlags}"], + sbox: true, + sbox_inputs: true, + } + rule_builder_test { + name: "foo_sbox", + flags: ["${cmdFlags}"], + sbox: true, + sbox_inputs: true, + unescape_ninja_vars: true, + } + ` + result := GroupFixturePreparers( + prepareForRuleBuilderTest, + FixtureWithRootAndroidBp(bp), + ).RunTest(t) + + escapedNinjaMod := result.ModuleForTests("foo_sbox_escaped_ninja", "").Rule("writeFile") + AssertStringDoesContain( + t, + "", + escapedNinjaMod.BuildParams.Args["content"], + "$${cmdFlags}", + ) + + unescapedNinjaMod := result.ModuleForTests("foo_sbox", "").Rule("unescapedWriteFile") + AssertStringDoesContain( + t, + "", + unescapedNinjaMod.BuildParams.Args["content"], + "${cmdFlags}", + ) + AssertStringDoesNotContain( + t, + "", + unescapedNinjaMod.BuildParams.Args["content"], + "$${cmdFlags}", + ) +} diff --git a/android/variable.go b/android/variable.go index 6af0f18d0..73a4b2c61 100644 --- a/android/variable.go +++ b/android/variable.go @@ -488,6 +488,8 @@ type ProductVariables struct { // PartitionVarsForBazelMigrationOnlyDoNotUse are extra variables that are used to define the // partition images. They should not be read from soong modules. PartitionVarsForBazelMigrationOnlyDoNotUse PartitionVariables `json:",omitempty"` + + NextReleaseHideFlaggedApi *bool `json:",omitempty"` } type PartitionVariables struct { @@ -512,6 +514,12 @@ type PartitionVariables struct { ProductBaseFsPath string `json:",omitempty"` ProductHeadroom string `json:",omitempty"` ProductVerityPartition string `json:",omitempty"` + + BoardAvbAddHashtreeFooterArgs string `json:",omitempty"` + BoardAvbKeyPath string `json:",omitempty"` + BoardAvbAlgorithm string `json:",omitempty"` + BoardAvbRollbackIndex string `json:",omitempty"` + BoardAvbRollbackIndexLocation string `json:",omitempty"` } TargetUserimagesUseExt2 bool `json:",omitempty"` TargetUserimagesUseExt3 bool `json:",omitempty"` @@ -534,6 +542,8 @@ type PartitionVariables struct { BoardBuildGkiBootImageWithoutRamdisk bool `json:",omitempty"` ProductUseDynamicPartitionSize bool `json:",omitempty"` CopyImagesForTargetFilesZip bool `json:",omitempty"` + + BoardAvbEnable bool `json:",omitempty"` } func boolPtr(v bool) *bool { diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go index 40356a196..57c38db97 100644 --- a/bp2build/aar_conversion_test.go +++ b/bp2build/aar_conversion_test.go @@ -21,6 +21,17 @@ import ( "android/soong/java" ) +func runAndroidLibraryImportTestWithRegistrationCtxFunc(t *testing.T, registrationCtxFunc func(ctx android.RegistrationContext), tc Bp2buildTestCase) { + t.Helper() + (&tc).ModuleTypeUnderTest = "android_library_import" + (&tc).ModuleTypeUnderTestFactory = java.AARImportFactory + RunBp2BuildTestCase(t, registrationCtxFunc, tc) +} + +func runAndroidLibraryImportTest(t *testing.T, tc Bp2buildTestCase) { + runAndroidLibraryImportTestWithRegistrationCtxFunc(t, func(ctx android.RegistrationContext) {}, tc) +} + func TestConvertAndroidLibrary(t *testing.T) { t.Helper() RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{ @@ -75,7 +86,7 @@ android_library { func TestConvertAndroidLibraryWithNoSources(t *testing.T) { t.Helper() RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{ - Description: "Android Library - modules with deps must have sources", + Description: "Android Library - modules will deps when there are no sources", ModuleTypeUnderTest: "android_library", ModuleTypeUnderTestFactory: java.AndroidLibraryFactory, Filesystem: map[string]string{ @@ -91,25 +102,28 @@ android_library { sdk_version: "current", } `, - ExpectedBazelTargets: []string{}, + ExpectedBazelTargets: []string{ + MakeBazelTarget( + "android_library", + "TestLib", + AttrNameToString{ + "manifest": `"AndroidManifest.xml"`, + "resource_files": `["res/res.png"]`, + "sdk_version": `"current"`, // use as default + }, + ), + MakeNeverlinkDuplicateTarget("android_library", "TestLib"), + }, }) } func TestConvertAndroidLibraryImport(t *testing.T) { - t.Helper() - RunBp2BuildTestCase( - t, + runAndroidLibraryImportTestWithRegistrationCtxFunc(t, func(ctx android.RegistrationContext) { ctx.RegisterModuleType("android_library", java.AndroidLibraryFactory) }, Bp2buildTestCase{ - Description: "Android Library Import", - ModuleTypeUnderTest: "android_library_import", - ModuleTypeUnderTestFactory: java.AARImportFactory, - Filesystem: map[string]string{ - "import.aar": "", - "dep.aar": "", - }, + Description: "Android Library Import", StubbedBuildDefinitions: []string{"static_lib_dep", "static_import_dep", "static_import_dep-neverlink"}, // Bazel's aar_import can only export *_import targets, so we expect // only "static_import_dep" in exports, but both "static_lib_dep" and @@ -122,7 +136,6 @@ android_library_import { sdk_version: "current", } -// TODO: b/301007952 - This dep is needed because android_library_import must have aars set. android_library_import { name: "static_import_dep", aars: ["import.aar"], @@ -220,3 +233,16 @@ android_library { MakeNeverlinkDuplicateTarget("android_library", "TestLib"), }}) } + +func TestAarImportFailsToConvertNoAars(t *testing.T) { + runAndroidLibraryImportTest(t, + Bp2buildTestCase{ + Description: "Android Library Import with no aars does not convert.", + Blueprint: ` +android_library_import { + name: "no_aar_import", +} +`, + ExpectedBazelTargets: []string{}, + }) +} diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go index 8ec4b3566..afe6dcd55 100644 --- a/bp2build/android_app_conversion_test.go +++ b/bp2build/android_app_conversion_test.go @@ -478,3 +478,41 @@ android_app { }), }}) } + +func TestFrameworkResConversion(t *testing.T) { + runAndroidAppTestCase(t, Bp2buildTestCase{ + Description: "Framework Res custom conversion", + ModuleTypeUnderTest: "android_app", + ModuleTypeUnderTestFactory: java.AndroidAppFactory, + Filesystem: map[string]string{ + "res/values/attrs.xml": "", + "resource_zip.zip": "", + }, + Blueprint: ` +android_app { + name: "framework-res", + resource_zips: [ + "resource_zip.zip", + ], + certificate: "platform", +} + +filegroup { + name: "framework-res-package-jar", + srcs: [":framework-res{.export-package.apk}"], +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("framework_resources", "framework-res", AttrNameToString{ + "certificate_name": `"platform"`, + "manifest": `"AndroidManifest.xml"`, + "resource_files": `["res/values/attrs.xml"]`, + "resource_zips": `["resource_zip.zip"]`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + }), + MakeBazelTargetNoRestrictions("filegroup", "framework-res-package-jar", AttrNameToString{ + "srcs": `[":framework-res.export-package.apk"]`, + }), + }}) + +} diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go index b724f5783..3e004534e 100644 --- a/bp2build/bp2build_product_config.go +++ b/bp2build/bp2build_product_config.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "reflect" + "sort" "strings" "android/soong/android" @@ -28,6 +29,22 @@ type bazelLabel struct { target string } +func (l *bazelLabel) Less(other *bazelLabel) bool { + if l.repo < other.repo { + return true + } + if l.repo > other.repo { + return false + } + if l.pkg < other.pkg { + return true + } + if l.pkg > other.pkg { + return false + } + return l.target < other.target +} + func (l *bazelLabel) String() string { return fmt.Sprintf("@%s//%s:%s", l.repo, l.pkg, l.target) } @@ -229,9 +246,16 @@ func platformMappingContent( mergedConvertedModulePathMap[k] = v } + productLabels := make([]bazelLabel, 0, len(productLabelToVariables)) + for k := range productLabelToVariables { + productLabels = append(productLabels, k) + } + sort.Slice(productLabels, func(i, j int) bool { + return productLabels[i].Less(&productLabels[j]) + }) result.WriteString("platforms:\n") - for productLabel, productVariables := range productLabelToVariables { - platformMappingSingleProduct(productLabel, productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result) + for _, productLabel := range productLabels { + platformMappingSingleProduct(productLabel, productLabelToVariables[productLabel], soongConfigDefinitions, mergedConvertedModulePathMap, &result) } return result.String(), nil } @@ -267,11 +291,22 @@ func platformMappingSingleProduct( defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":generated_android_certificate_directory" } + // TODO: b/301598690 - commas can't be escaped in a string-list passed in a platform mapping, + // so commas are switched for ":" here, and must be back-substituted into commas + // wherever the AAPTCharacteristics product config variable is used. + AAPTConfig := []string{} + for _, conf := range productVariables.AAPTConfig { + AAPTConfig = append(AAPTConfig, strings.Replace(conf, ",", ":", -1)) + } + for _, suffix := range bazelPlatformSuffixes { result.WriteString(" ") result.WriteString(label.String()) result.WriteString(suffix) result.WriteString("\n") + result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:aapt_characteristics=%s\n", proptools.String(productVariables.AAPTCharacteristics))) + result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:aapt_config=%s\n", strings.Join(AAPTConfig, ","))) + result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:aapt_preferred_config=%s\n", proptools.String(productVariables.AAPTPreferredConfig))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:always_use_prebuilt_sdks=%t\n", proptools.Bool(productVariables.Always_use_prebuilt_sdks))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:arc=%t\n", proptools.Bool(productVariables.Arc))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride))) @@ -302,6 +337,8 @@ func platformMappingSingleProduct( result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:manifest_package_name_overrides=%s\n", strings.Join(productVariables.ManifestPackageNameOverrides, ","))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:native_coverage=%t\n", proptools.Bool(productVariables.Native_coverage))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_sdk_final=%t\n", proptools.Bool(productVariables.Platform_sdk_final))) + result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_security_patch=%s\n", proptools.String(productVariables.Platform_security_patch))) + result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_version_last_stable=%s\n", proptools.String(productVariables.Platform_version_last_stable))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_version_name=%s\n", proptools.String(productVariables.Platform_version_name))) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_brand=%s\n", productVariables.ProductBrand)) result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_manufacturer=%s\n", productVariables.ProductManufacturer)) @@ -328,8 +365,9 @@ func platformMappingSingleProduct( } } - for namespace, namespaceContents := range productVariables.VendorVars { - for variable, value := range namespaceContents { + for _, namespace := range android.SortedKeys(productVariables.VendorVars) { + for _, variable := range android.SortedKeys(productVariables.VendorVars[namespace]) { + value := productVariables.VendorVars[namespace][variable] key := namespace + "__" + variable _, hasBool := soongConfigDefinitions.BoolVars[key] _, hasString := soongConfigDefinitions.StringVars[key] @@ -442,6 +480,7 @@ func starlarkMapToProductVariables(in map[string]starlark.Value) (android.Produc func createTargets(productLabelsToVariables map[bazelLabel]*android.ProductVariables, res map[string]BazelTargets) { createGeneratedAndroidCertificateDirectories(productLabelsToVariables, res) + createAvbKeyFilegroups(productLabelsToVariables, res) for label, variables := range productLabelsToVariables { createSystemPartition(label, &variables.PartitionVarsForBazelMigrationOnlyDoNotUse, res) } @@ -476,10 +515,39 @@ func createGeneratedAndroidCertificateDirectories(productLabelsToVariables map[b } } +func createAvbKeyFilegroups(productLabelsToVariables map[bazelLabel]*android.ProductVariables, targets map[string]BazelTargets) { + var allAvbKeys []string + for _, productVariables := range productLabelsToVariables { + for _, partitionVariables := range productVariables.PartitionVarsForBazelMigrationOnlyDoNotUse.PartitionQualifiedVariables { + if partitionVariables.BoardAvbKeyPath != "" { + if !android.InList(partitionVariables.BoardAvbKeyPath, allAvbKeys) { + allAvbKeys = append(allAvbKeys, partitionVariables.BoardAvbKeyPath) + } + } + } + } + for _, key := range allAvbKeys { + dir := filepath.Dir(key) + name := filepath.Base(key) + content := fmt.Sprintf(`filegroup( + name = "%s_filegroup", + srcs = ["%s"], + visibility = ["//visibility:public"], +)`, name, name) + targets[dir] = append(targets[dir], BazelTarget{ + name: name + "_filegroup", + packageName: dir, + content: content, + ruleClass: "filegroup", + }) + } +} + func createSystemPartition(platformLabel bazelLabel, variables *android.PartitionVariables, targets map[string]BazelTargets) { if !variables.PartitionQualifiedVariables["system"].BuildingImage { return } + qualifiedVariables := variables.PartitionQualifiedVariables["system"] imageProps := generateImagePropDictionary(variables, "system") imageProps["skip_fsck"] = "true" @@ -492,6 +560,19 @@ func createSystemPartition(platformLabel bazelLabel, variables *android.Partitio properties.WriteRune('\n') } + var extraProperties strings.Builder + if variables.BoardAvbEnable { + extraProperties.WriteString(" avb_enable = True,\n") + extraProperties.WriteString(fmt.Sprintf(" avb_add_hashtree_footer_args = %q,\n", qualifiedVariables.BoardAvbAddHashtreeFooterArgs)) + keypath := qualifiedVariables.BoardAvbKeyPath + if keypath != "" { + extraProperties.WriteString(fmt.Sprintf(" avb_key = \"//%s:%s\",\n", filepath.Dir(keypath), filepath.Base(keypath)+"_filegroup")) + extraProperties.WriteString(fmt.Sprintf(" avb_algorithm = %q,\n", qualifiedVariables.BoardAvbAlgorithm)) + extraProperties.WriteString(fmt.Sprintf(" avb_rollback_index = %s,\n", qualifiedVariables.BoardAvbRollbackIndex)) + extraProperties.WriteString(fmt.Sprintf(" avb_rollback_index_location = %s,\n", qualifiedVariables.BoardAvbRollbackIndexLocation)) + } + } + targets[platformLabel.pkg] = append(targets[platformLabel.pkg], BazelTarget{ name: "system_image", packageName: platformLabel.pkg, @@ -500,11 +581,13 @@ func createSystemPartition(platformLabel bazelLabel, variables *android.Partitio base_staging_dir = "//build/bazel/bazel_sandwich:system_staging_dir", base_staging_dir_file_list = "//build/bazel/bazel_sandwich:system_staging_dir_file_list", root_dir = "//build/bazel/bazel_sandwich:root_staging_dir", + selinux_file_contexts = "//build/bazel/bazel_sandwich:selinux_file_contexts", image_properties = """ %s """, +%s type = "system", -)`, properties.String()), +)`, properties.String(), extraProperties.String()), ruleClass: "partition", loads: []BazelLoad{{ file: "//build/bazel/rules/partitions:partition.bzl", diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go index ce2a95552..f53588d76 100644 --- a/bp2build/build_conversion.go +++ b/bp2build/build_conversion.go @@ -783,13 +783,13 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers } else if glib, ok := m.(*bootstrap.GoPackage); ok { targets, targetErrs = generateBazelTargetsGoPackage(bpCtx, glib, nameToGoLibMap) errs = append(errs, targetErrs...) - metrics.IncrementRuleClassCount("go_library") - metrics.AddConvertedModule(glib, "go_library", dir) + metrics.IncrementRuleClassCount("bootstrap_go_package") + metrics.AddConvertedModule(glib, "bootstrap_go_package", dir) } else if gbin, ok := m.(*bootstrap.GoBinary); ok { targets, targetErrs = generateBazelTargetsGoBinary(bpCtx, gbin, nameToGoLibMap) errs = append(errs, targetErrs...) - metrics.IncrementRuleClassCount("go_binary") - metrics.AddConvertedModule(gbin, "go_binary", dir) + metrics.IncrementRuleClassCount("blueprint_go_binary") + metrics.AddConvertedModule(gbin, "blueprint_go_binary", dir) } else { metrics.AddUnconvertedModule(m, moduleType, dir, android.UnconvertedReason{ ReasonType: int(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED), diff --git a/cc/ndk_library.go b/cc/ndk_library.go index b3bb2da15..56c57b94c 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -386,9 +386,11 @@ func (this *stubDecorator) diffAbi(ctx ModuleContext) { // level. abiDiffPath := android.PathForModuleOut(ctx, "stgdiff.timestamp") prebuiltAbiDump := this.findPrebuiltAbiDump(ctx, this.apiLevel) + missingPrebuiltErrorTemplate := + "Did not find prebuilt ABI dump for %q (%q). Generate with " + + "//development/tools/ndk/update_ndk_abi.sh." missingPrebuiltError := fmt.Sprintf( - "Did not find prebuilt ABI dump for %q (%q). Generate with "+ - "//development/tools/ndk/update_ndk_abi.sh.", this.libraryName(ctx), + missingPrebuiltErrorTemplate, this.libraryName(ctx), prebuiltAbiDump.InvalidReason()) if !prebuiltAbiDump.Valid() { ctx.Build(pctx, android.BuildParams{ @@ -424,12 +426,15 @@ func (this *stubDecorator) diffAbi(ctx ModuleContext) { nextAbiDiffPath := android.PathForModuleOut(ctx, "abidiff_next.timestamp") nextAbiDump := this.findPrebuiltAbiDump(ctx, *nextApiLevel) + missingNextPrebuiltError := fmt.Sprintf( + missingPrebuiltErrorTemplate, this.libraryName(ctx), + nextAbiDump.InvalidReason()) if !nextAbiDump.Valid() { ctx.Build(pctx, android.BuildParams{ Rule: android.ErrorRule, Output: nextAbiDiffPath, Args: map[string]string{ - "error": missingPrebuiltError, + "error": missingNextPrebuiltError, }, }) } else { diff --git a/cc/sanitize.go b/cc/sanitize.go index 9ceb1c8a0..6329e9769 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -1113,12 +1113,15 @@ func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t SanitizerType) bool { // indirectly (via a mutator) sets the bool ptr to true, and you can't // distinguish between the cases. It isn't needed though - both cases can be // treated identically. -func (sanitize *sanitize) isSanitizerEnabled(t SanitizerType) bool { - if sanitize == nil { +func (s *sanitize) isSanitizerEnabled(t SanitizerType) bool { + if s == nil { + return false + } + if proptools.Bool(s.Properties.SanitizeMutated.Never) { return false } - sanitizerVal := sanitize.getSanitizerBoolPtr(t) + sanitizerVal := s.getSanitizerBoolPtr(t) return sanitizerVal != nil && *sanitizerVal == true } diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go index 49117a082..31e668ea9 100644 --- a/cc/sanitize_test.go +++ b/cc/sanitize_test.go @@ -16,6 +16,7 @@ package cc import ( "fmt" + "reflect" "runtime" "strings" "testing" @@ -1273,3 +1274,122 @@ func TestCfi(t *testing.T) { t.Errorf("non-CFI variant of baz not expected to contain CFI flags ") } } + +func TestHwasan(t *testing.T) { + t.Parallel() + + bp := ` + cc_library_shared { + name: "shared_with_hwaddress", + static_libs: [ + "static_dep_with_hwaddress", + "static_dep_no_hwaddress", + ], + sanitize: { + hwaddress: true, + }, + sdk_version: "current", + stl: "c++_shared", + } + + cc_library_static { + name: "static_dep_with_hwaddress", + sanitize: { + hwaddress: true, + }, + sdk_version: "current", + stl: "c++_shared", + } + + cc_library_static { + name: "static_dep_no_hwaddress", + sdk_version: "current", + stl: "c++_shared", + } +` + + androidArm := "android_arm_armv7-a-neon" + androidArm64 := "android_arm64_armv8-a" + androidX86 := "android_x86_silvermont" + sharedSuffix := "_shared" + hwasanSuffix := "_hwasan" + staticSuffix := "_static" + sdkSuffix := "_sdk" + + sharedWithHwasanVariant := sharedSuffix + hwasanSuffix + sharedWithSdkVariant := sdkSuffix + sharedSuffix + staticWithHwasanVariant := staticSuffix + hwasanSuffix + staticWithSdkVariant := sdkSuffix + staticSuffix + + testCases := []struct { + buildOs string + extraPreparer android.FixturePreparer + expectedVariants map[string][]string + }{ + { + buildOs: androidArm64, + expectedVariants: map[string][]string{ + "shared_with_hwaddress": []string{ + androidArm64 + sharedWithHwasanVariant, + androidArm64 + sharedWithSdkVariant, + androidArm + sharedSuffix, + androidArm + sharedWithSdkVariant, + }, + "static_dep_with_hwaddress": []string{ + androidArm64 + staticSuffix, + androidArm64 + staticWithHwasanVariant, + androidArm64 + staticWithSdkVariant, + androidArm + staticSuffix, + androidArm + staticWithSdkVariant, + }, + "static_dep_no_hwaddress": []string{ + androidArm64 + staticSuffix, + androidArm64 + staticWithHwasanVariant, + androidArm64 + staticWithSdkVariant, + androidArm + staticSuffix, + androidArm + staticWithSdkVariant, + }, + }, + }, + { + buildOs: androidX86, + extraPreparer: android.FixtureModifyConfig(func(config android.Config) { + config.Targets[android.Android] = []android.Target{ + { + android.Android, + android.Arch{ + ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, android.NativeBridgeDisabled, "", "", false}, + } + }), + expectedVariants: map[string][]string{ + "shared_with_hwaddress": []string{ + androidX86 + sharedSuffix, + androidX86 + sharedWithSdkVariant, + }, + "static_dep_with_hwaddress": []string{ + androidX86 + staticSuffix, + androidX86 + staticWithSdkVariant, + }, + "static_dep_no_hwaddress": []string{ + androidX86 + staticSuffix, + androidX86 + staticWithSdkVariant, + }, + }, + }, + } + + for _, tc := range testCases { + preparer := android.GroupFixturePreparers( + prepareForCcTest, + android.OptionalFixturePreparer(tc.extraPreparer), + ) + result := preparer.RunTestWithBp(t, bp) + + for m, v := range tc.expectedVariants { + variants := result.ModuleVariantsForTests(m) + if !reflect.DeepEqual(variants, v) { + t.Errorf("Expected variants of %q to be %q, but got %q", m, v, variants) + } + } + } +} diff --git a/cc/testing.go b/cc/testing.go index 7531f6db8..71d986b4f 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -35,6 +35,7 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) { multitree.RegisterApiImportsModule(ctx) + ctx.RegisterModuleType("prebuilt_build_tool", android.NewPrebuiltBuildTool) ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory) ctx.RegisterModuleType("cc_object", ObjectFactory) ctx.RegisterModuleType("cc_genrule", GenRuleFactory) diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go index fc56dd526..3364f503f 100644 --- a/cmd/sbox/sbox.go +++ b/cmd/sbox/sbox.go @@ -119,6 +119,9 @@ func run() error { } manifest, err := readManifest(manifestFile) + if err != nil { + return err + } if len(manifest.Commands) == 0 { return fmt.Errorf("at least one commands entry is required in %q", manifestFile) diff --git a/java/aar.go b/java/aar.go index 8f5deab39..44496dc57 100644 --- a/java/aar.go +++ b/java/aar.go @@ -1223,6 +1223,7 @@ func AARImportFactory() android.Module { type bazelAapt struct { Manifest bazel.Label Resource_files bazel.LabelListAttribute + Resource_zips bazel.LabelListAttribute Assets_dir bazel.StringAttribute Assets bazel.LabelListAttribute } @@ -1267,15 +1268,30 @@ func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.Bp2buildMutatorContext) assets = bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))) } + var resourceZips bazel.LabelList + if len(a.aaptProperties.Resource_zips) > 0 { + if ctx.ModuleName() == "framework-res" { + resourceZips = android.BazelLabelForModuleSrc(ctx, a.aaptProperties.Resource_zips) + } else { + //TODO: b/301593550 - Implement support for this + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "resource_zips") + return &bazelAapt{}, false + } + } return &bazelAapt{ android.BazelLabelForModuleSrcSingle(ctx, manifest), bazel.MakeLabelListAttribute(resourceFiles), + bazel.MakeLabelListAttribute(resourceZips), assetsDir, bazel.MakeLabelListAttribute(assets), }, true } func (a *AARImport) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { + if len(a.properties.Aars) == 0 { + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "aars can't be empty") + return + } aars := android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Aars, []string{}) exportableStaticLibs := []string{} // TODO(b/240716882): investigate and handle static_libs deps that are not imports. They are not supported for export by Bazel. @@ -1340,10 +1356,12 @@ func (a *AndroidLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) if !commonAttrs.Srcs.IsEmpty() { deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them } else if !depLabels.Deps.IsEmpty() { - ctx.MarkBp2buildUnconvertible( - bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, - "Module has direct dependencies but no sources. Bazel will not allow this.") - return + // android_library does not accept deps when there are no srcs because + // there is no compilation happening, but it accepts exports. + // The non-empty deps here are unnecessary as deps on the android_library + // since they aren't being propagated to any dependencies. + // So we can drop deps here. + deps = bazel.LabelListAttribute{} } name := a.Name() props := AndroidLibraryBazelTargetModuleProperties() diff --git a/java/app.go b/java/app.go index 10ffa7a3f..166c22d94 100755 --- a/java/app.go +++ b/java/app.go @@ -1683,22 +1683,25 @@ func convertWithBp2build(ctx android.Bp2buildMutatorContext, a *AndroidApp) (boo Updatable: a.appProperties.Updatable, } + // As framework-res has no sources, no deps in the Bazel sense, and java compilation, dexing and optimization is skipped by + // Soong specifically for it, return early here before any of the conversion work for the above is attempted. + if ctx.ModuleName() == "framework-res" { + appAttrs.bazelAapt = aapt + return true, android.CommonAttributes{Name: a.Name(), SkipData: proptools.BoolPtr(true)}, appAttrs + } + // Optimization is.. // - enabled by default for android_app, android_test_helper_app // - disabled by default for android_test // // TODO(b/192032291): Disable android_test_helper_app optimization by // default after auditing downstream usage. - if a.dexProperties.Optimize.Enabled == nil { - // Property was not explicitly defined. - a.dexProperties.Optimize.Enabled = &a.dexProperties.Optimize.EnabledByDefault - } - if Bool(a.dexProperties.Optimize.Enabled) { - if !a.dexProperties.Optimize.EnabledByDefault { - // explicitly enable optimize for module types that disable it by default - appAttrs.Optimize = proptools.BoolPtr(true) - } + if a.dexProperties.Optimize.EnabledByDefault != a.dexer.effectiveOptimizeEnabled() { + // Property is explicitly defined by default from default, so emit the Bazel attribute. + appAttrs.Optimize = proptools.BoolPtr(a.dexer.effectiveOptimizeEnabled()) + } + if a.dexer.effectiveOptimizeEnabled() { handCraftedFlags := "" if Bool(a.dexProperties.Optimize.Ignore_warnings) { handCraftedFlags += "-ignorewarning " @@ -1728,9 +1731,6 @@ func convertWithBp2build(ctx android.Bp2buildMutatorContext, a *AndroidApp) (boo }) appAttrs.Proguard_specs.Add(bazel.MakeLabelAttribute(":" + generatedFlagFileRuleName)) } - } else if a.dexProperties.Optimize.EnabledByDefault { - // explicitly disable optimize for module types that enable it by default - appAttrs.Optimize = proptools.BoolPtr(false) } commonAttrs, bp2BuildInfo, supported := a.convertLibraryAttrsBp2Build(ctx) @@ -1791,11 +1791,18 @@ func convertWithBp2build(ctx android.Bp2buildMutatorContext, a *AndroidApp) (boo // ConvertWithBp2build is used to convert android_app to Bazel. func (a *AndroidApp) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { if ok, commonAttrs, appAttrs := convertWithBp2build(ctx, a); ok { - props := bazel.BazelTargetModuleProperties{ - Rule_class: "android_binary", - Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl", + var props bazel.BazelTargetModuleProperties + if ctx.ModuleName() == "framework-res" { + props = bazel.BazelTargetModuleProperties{ + Rule_class: "framework_resources", + Bzl_load_location: "//build/bazel/rules/android:framework_resources.bzl", + } + } else { + props = bazel.BazelTargetModuleProperties{ + Rule_class: "android_binary", + Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl", + } } - ctx.CreateBazelTargetModule(props, commonAttrs, appAttrs) } diff --git a/java/base.go b/java/base.go index fe81776be..db237dac0 100644 --- a/java/base.go +++ b/java/base.go @@ -1346,10 +1346,17 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath jars = append(jars, classes) } } + // Assume approximately 5 sources per srcjar. + // For framework-minus-apex in AOSP at the time this was written, there are 266 srcjars, with a mean + // of 5.8 sources per srcjar, but a median of 1, a standard deviation of 10, and a max of 48 source files. if len(srcJars) > 0 { - classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs), - nil, srcJars, flags, extraJarDeps) - jars = append(jars, classes) + startIdx := len(shardSrcs) + shardSrcJarsList := android.ShardPaths(srcJars, shardSize/5) + for idx, shardSrcJars := range shardSrcJarsList { + classes := j.compileJavaClasses(ctx, jarName, startIdx+idx, + nil, shardSrcJars, flags, extraJarDeps) + jars = append(jars, classes) + } } } else { classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps) diff --git a/rust/binary.go b/rust/binary.go index 1408ff17b..aee4da699 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -138,9 +138,14 @@ func (binary *binaryDecorator) preferRlib() bool { func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix() - srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs) outputFile := android.PathForModuleOut(ctx, fileName) ret := buildOutput{outputFile: outputFile} + var crateRootPath android.Path + if binary.baseCompiler.Properties.Crate_root == nil { + crateRootPath, _ = srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs) + } else { + crateRootPath = android.PathForModuleSrc(ctx, *binary.baseCompiler.Properties.Crate_root) + } flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) @@ -155,7 +160,7 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path } binary.baseCompiler.unstrippedOutputFile = outputFile - ret.kytheFile = TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile).kytheFile + ret.kytheFile = TransformSrcToBinary(ctx, crateRootPath, deps, flags, outputFile).kytheFile return ret } diff --git a/rust/compiler.go b/rust/compiler.go index e6a7a9356..d6c52e8d4 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -73,6 +73,15 @@ type BaseCompilerProperties struct { // If no source file is defined, a single generated source module can be defined to be used as the main source. Srcs []string `android:"path,arch_variant"` + // Entry point that is passed to rustc to begin the compilation. E.g. main.rs or lib.rs. + // When this property is set, + // * sandboxing is enabled for this module, and + // * the srcs attribute is interpreted as a list of all source files potentially + // used in compilation, including the entrypoint, and + // * compile_data can be used to add additional files used in compilation that + // not directly used as source files. + Crate_root *string `android:"path,arch_variant"` + // name of the lint set that should be used to validate this module. // // Possible values are "default" (for using a sensible set of lints @@ -511,6 +520,8 @@ func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, andr ctx.PropertyErrorf("srcs", "only a single generated source module can be defined without a main source file.") } + // TODO: b/297264540 - once all modules are sandboxed, we need to select the proper + // entry point file from Srcs rather than taking the first one paths := android.PathsForModuleSrc(ctx, srcs) return paths[srcIndex], paths[1:] } diff --git a/rust/config/global.go b/rust/config/global.go index c976617f1..f397ce90d 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -81,13 +81,7 @@ var ( func init() { pctx.SourcePathVariable("RustDefaultBase", RustDefaultBase) - pctx.VariableConfigMethod("HostPrebuiltTag", func(config android.Config) string { - if config.UseHostMusl() { - return "linux-musl-x86" - } else { - return config.PrebuiltOS() - } - }) + pctx.VariableConfigMethod("HostPrebuiltTag", HostPrebuiltTag) pctx.VariableFunc("RustBase", func(ctx android.PackageVarContext) string { if override := ctx.Config().Getenv("RUST_PREBUILTS_BASE"); override != "" { @@ -109,6 +103,14 @@ func init() { exportedVars.ExportStringStaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion) } +func HostPrebuiltTag(config android.Config) string { + if config.UseHostMusl() { + return "linux-musl-x86" + } else { + return config.PrebuiltOS() + } +} + func getRustVersionPctx(ctx android.PackageVarContext) string { return GetRustVersion(ctx) } diff --git a/rust/library.go b/rust/library.go index 035708674..f4a2b5441 100644 --- a/rust/library.go +++ b/rust/library.go @@ -489,7 +489,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa var outputFile android.ModuleOutPath var ret buildOutput var fileName string - srcPath := library.srcPath(ctx, deps) + crateRootPath := library.crateRootPath(ctx, deps) if library.sourceProvider != nil { deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...) @@ -536,13 +536,13 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa // Call the appropriate builder for this library type if library.rlib() { - ret.kytheFile = TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile).kytheFile + ret.kytheFile = TransformSrctoRlib(ctx, crateRootPath, deps, flags, outputFile).kytheFile } else if library.dylib() { - ret.kytheFile = TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile).kytheFile + ret.kytheFile = TransformSrctoDylib(ctx, crateRootPath, deps, flags, outputFile).kytheFile } else if library.static() { - ret.kytheFile = TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile).kytheFile + ret.kytheFile = TransformSrctoStatic(ctx, crateRootPath, deps, flags, outputFile).kytheFile } else if library.shared() { - ret.kytheFile = TransformSrctoShared(ctx, srcPath, deps, flags, outputFile).kytheFile + ret.kytheFile = TransformSrctoShared(ctx, crateRootPath, deps, flags, outputFile).kytheFile } if library.rlib() || library.dylib() { @@ -585,13 +585,15 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa return ret } -func (library *libraryDecorator) srcPath(ctx ModuleContext, _ PathDeps) android.Path { +func (library *libraryDecorator) crateRootPath(ctx ModuleContext, _ PathDeps) android.Path { if library.sourceProvider != nil { // Assume the first source from the source provider is the library entry point. return library.sourceProvider.Srcs()[0] - } else { + } else if library.baseCompiler.Properties.Crate_root == nil { path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs) return path + } else { + return android.PathForModuleSrc(ctx, *library.baseCompiler.Properties.Crate_root) } } @@ -606,7 +608,7 @@ func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags, return android.OptionalPath{} } - return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps), + return android.OptionalPathForPath(Rustdoc(ctx, library.crateRootPath(ctx, deps), deps, flags)) } diff --git a/rust/protobuf.go b/rust/protobuf.go index c3aa8dc64..2982efdf2 100644 --- a/rust/protobuf.go +++ b/rust/protobuf.go @@ -20,6 +20,7 @@ import ( "android/soong/android" "android/soong/bazel" + "android/soong/cc" "github.com/google/blueprint/proptools" ) @@ -59,14 +60,18 @@ type ProtobufProperties struct { // Use protobuf version 3.x. This will be deleted once we migrate all current users // of protobuf off of 2.x. Use_protobuf3 *bool + + // List of exported include paths containing proto files for dependent rust_protobuf modules. + Exported_include_dirs []string } type protobufDecorator struct { *BaseSourceProvider - Properties ProtobufProperties - protoNames []string - grpcNames []string + Properties ProtobufProperties + protoNames []string + additionalCrates []string + grpcNames []string grpcProtoFlags android.ProtoFlags protoFlags android.ProtoFlags @@ -184,6 +189,10 @@ func (proto *protobufDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) // stemFile must be first here as the first path in BaseSourceProvider.OutputFiles is the library entry-point. proto.BaseSourceProvider.OutputFiles = append(android.Paths{stemFile}, outputs.Paths()...) + ctx.SetProvider(cc.FlagExporterInfoProvider, cc.FlagExporterInfo{ + IncludeDirs: android.PathsForModuleSrc(ctx, proto.Properties.Exported_include_dirs), + }) + // mod_stem.rs is the entry-point for our library modules, so this is what we return. return stemFile } @@ -192,10 +201,16 @@ func (proto *protobufDecorator) genModFileContents() string { lines := []string{ "// @Soong generated Source", } + for _, protoName := range proto.protoNames { lines = append(lines, fmt.Sprintf("pub mod %s;", protoName)) } + for _, crate := range proto.additionalCrates { + lines = append(lines, fmt.Sprintf("pub use %s::*;", crate)) + + } + for _, grpcName := range proto.grpcNames { lines = append(lines, fmt.Sprintf("pub mod %s;", grpcName)) lines = append(lines, fmt.Sprintf("pub mod %s%s;", grpcName, grpcSuffix)) diff --git a/rust/protobuf_test.go b/rust/protobuf_test.go index b723f3f1a..9dca0290f 100644 --- a/rust/protobuf_test.go +++ b/rust/protobuf_test.go @@ -118,6 +118,58 @@ func TestRustProtobuf3(t *testing.T) { } } +func TestRustProtobufInclude(t *testing.T) { + ctx := testRust(t, ` + rust_protobuf { + name: "librust_proto", + protos: ["proto.proto"], + crate_name: "rust_proto", + source_stem: "proto", + use_protobuf3: true, + rustlibs: ["librust_exported_proto", "libfoo"], + } + rust_protobuf { + name: "librust_exported_proto", + protos: ["proto.proto"], + crate_name: "rust_exported_proto", + source_stem: "exported_proto", + use_protobuf3: true, + exported_include_dirs: ["proto"] + } + rust_library { + name: "libfoo", + crate_name: "foo", + srcs: ["foo.rs"], + } + `) + // Check that librust_exported_proto is added as additional crate to generate source. + librust_proto := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Module().(*Module).sourceProvider.(*protobufDecorator) + if !android.InList("rust_exported_proto", librust_proto.additionalCrates) { + t.Errorf("librust_proto should have librust_exported_proto included as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates) + } + + // Make sure the default crates aren't being included. + if android.InList("std", librust_proto.additionalCrates) { + t.Errorf("librust_proto should not have included libstd as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates) + } + if android.InList("protobuf", librust_proto.additionalCrates) { + t.Errorf("librust_proto should not have included libprotobuf as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates) + } + + // And make sure that non-protobuf crates aren't getting included either. + if android.InList("foo", librust_proto.additionalCrates) { + t.Errorf("librust_proto should not have included libfoo as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates) + } + + // Check librust_proto args includes -Iproto + librust_proto_rule := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Output("proto.rs") + cmd := librust_proto_rule.RuleParams.Command + if w := "-Iproto"; !strings.Contains(cmd, w) { + t.Errorf("expected %q in %q", w, cmd) + } + +} + func TestRustGrpc(t *testing.T) { ctx := testRust(t, ` rust_protobuf { diff --git a/rust/rust.go b/rust/rust.go index 250e39857..49a7ff353 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -267,6 +267,15 @@ func (mod *Module) Dylib() bool { return false } +func (mod *Module) Source() bool { + if mod.compiler != nil { + if library, ok := mod.compiler.(libraryInterface); ok && mod.sourceProvider != nil { + return library.source() + } + } + return false +} + func (mod *Module) RlibStd() bool { if mod.compiler != nil { if library, ok := mod.compiler.(libraryInterface); ok && library.rlib() { @@ -1156,6 +1165,13 @@ func rustMakeLibName(ctx android.ModuleContext, c cc.LinkableInterface, dep cc.L return cc.MakeLibName(ctx, c, dep, depName) } +func collectIncludedProtos(mod *Module, dep *Module) { + if protoMod, ok := mod.sourceProvider.(*protobufDecorator); ok { + if _, ok := dep.sourceProvider.(*protobufDecorator); ok { + protoMod.additionalCrates = append(protoMod.additionalCrates, dep.CrateName()) + } + } +} func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { var depPaths PathDeps @@ -1268,6 +1284,11 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { case procMacroDepTag: directProcMacroDeps = append(directProcMacroDeps, rustDep) mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName) + + case sourceDepTag: + if _, ok := mod.sourceProvider.(*protobufDecorator); ok { + collectIncludedProtos(mod, rustDep) + } } transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs) @@ -1308,7 +1329,14 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { lib.exportLinkDirs(linkDir) } } - + if depTag == sourceDepTag { + if _, ok := mod.sourceProvider.(*protobufDecorator); ok && mod.Source() { + if _, ok := rustDep.sourceProvider.(*protobufDecorator); ok { + exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo) + depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) + } + } + } } else if ccDep, ok := dep.(cc.LinkableInterface); ok { //Handle C dependencies makeLibName := cc.MakeLibName(ctx, mod, ccDep, depName) @@ -1572,30 +1600,43 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { } // rustlibs - if deps.Rustlibs != nil && !mod.compiler.Disabled() { - autoDep := mod.compiler.(autoDeppable).autoDep(ctx) - for _, lib := range deps.Rustlibs { - if autoDep.depTag == rlibDepTag { - // Handle the rlib deptag case - addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations) - } else { - // autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however. - // Check for the existence of the dylib deptag variant. Select it if available, - // otherwise select the rlib variant. - autoDepVariations := append(commonDepVariations, - blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}) + if deps.Rustlibs != nil { + if !mod.compiler.Disabled() { + for _, lib := range deps.Rustlibs { + autoDep := mod.compiler.(autoDeppable).autoDep(ctx) + if autoDep.depTag == rlibDepTag { + // Handle the rlib deptag case + addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations) + } else { + // autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however. + // Check for the existence of the dylib deptag variant. Select it if available, + // otherwise select the rlib variant. + autoDepVariations := append(commonDepVariations, + blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}) + + replacementLib := cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Dylibs) + if actx.OtherModuleDependencyVariantExists(autoDepVariations, replacementLib) { + addDylibDependency(actx, lib, mod, &snapshotInfo, autoDepVariations, autoDep.depTag) + } else { + // If there's no dylib dependency available, try to add the rlib dependency instead. + addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations) + } + } + } + } else if _, ok := mod.sourceProvider.(*protobufDecorator); ok { + for _, lib := range deps.Rustlibs { replacementLib := cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Dylibs) + srcProviderVariations := append(commonDepVariations, + blueprint.Variation{Mutator: "rust_libraries", Variation: "source"}) - if actx.OtherModuleDependencyVariantExists(autoDepVariations, replacementLib) { - addDylibDependency(actx, lib, mod, &snapshotInfo, autoDepVariations, autoDep.depTag) - } else { - // If there's no dylib dependency available, try to add the rlib dependency instead. - addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations) + if actx.OtherModuleDependencyVariantExists(srcProviderVariations, replacementLib) { + actx.AddVariationDependencies(srcProviderVariations, sourceDepTag, lib) } } } } + // stdlibs if deps.Stdlibs != nil { if mod.compiler.stdLinkage(ctx) == RlibLinkage { diff --git a/rust/toolchain_library.go b/rust/toolchain_library.go index 326d52924..054104ccc 100644 --- a/rust/toolchain_library.go +++ b/rust/toolchain_library.go @@ -18,9 +18,12 @@ package rust import ( "path" + "path/filepath" "android/soong/android" "android/soong/rust/config" + + "github.com/google/blueprint/proptools" ) // This module is used to compile the rust toolchain libraries @@ -33,11 +36,15 @@ func init() { rustToolchainLibraryRlibFactory) android.RegisterModuleType("rust_toolchain_library_dylib", rustToolchainLibraryDylibFactory) + android.RegisterModuleType("rust_toolchain_rustc_prebuilt", + rustToolchainRustcPrebuiltFactory) } type toolchainLibraryProperties struct { - // path to the toolchain source, relative to the top of the toolchain source - Toolchain_src *string `android:"arch_variant"` + // path to the toolchain crate root, relative to the top of the toolchain source + Toolchain_crate_root *string `android:"arch_variant"` + // path to the rest of the toolchain srcs, relative to the top of the toolchain source + Toolchain_srcs []string `android:"arch_variant"` } type toolchainLibraryDecorator struct { @@ -82,16 +89,21 @@ func initToolchainLibrary(module *Module, library *libraryDecorator) android.Mod func rustSetToolchainSource(ctx android.LoadHookContext) { if toolchainLib, ok := ctx.Module().(*Module).compiler.(*toolchainLibraryDecorator); ok { - prefix := "linux-x86/" + GetRustPrebuiltVersion(ctx) - newSrcs := []string{path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_src))} + prefix := filepath.Join("linux-x86", GetRustPrebuiltVersion(ctx)) + versionedCrateRoot := path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_crate_root)) + versionedSrcs := make([]string, len(toolchainLib.Properties.Toolchain_srcs)) + for i, src := range toolchainLib.Properties.Toolchain_srcs { + versionedSrcs[i] = path.Join(prefix, src) + } type props struct { - Srcs []string + Crate_root *string + Srcs []string } p := &props{} - p.Srcs = newSrcs + p.Crate_root = &versionedCrateRoot + p.Srcs = versionedSrcs ctx.AppendProperties(p) - } else { ctx.ModuleErrorf("Called rustSetToolchainSource on a non-Rust Module.") } @@ -101,3 +113,47 @@ func rustSetToolchainSource(ctx android.LoadHookContext) { func GetRustPrebuiltVersion(ctx android.LoadHookContext) string { return ctx.AConfig().GetenvWithDefault("RUST_PREBUILTS_VERSION", config.RustDefaultVersion) } + +type toolchainRustcPrebuiltProperties struct { + // path to rustc prebuilt, relative to the top of the toolchain source + Toolchain_prebuilt_src *string + // path to deps, relative to the top of the toolchain source + Toolchain_deps []string + // path to deps, relative to module directory + Deps []string +} + +func rustToolchainRustcPrebuiltFactory() android.Module { + module := android.NewPrebuiltBuildTool() + module.AddProperties(&toolchainRustcPrebuiltProperties{}) + android.AddLoadHook(module, func(ctx android.LoadHookContext) { + var toolchainProps *toolchainRustcPrebuiltProperties + for _, p := range ctx.Module().GetProperties() { + toolchainProperties, ok := p.(*toolchainRustcPrebuiltProperties) + if ok { + toolchainProps = toolchainProperties + } + } + + if toolchainProps.Toolchain_prebuilt_src == nil { + ctx.PropertyErrorf("toolchain_prebuilt_src", "must set path to rustc prebuilt") + } + + prefix := filepath.Join(config.HostPrebuiltTag(ctx.Config()), GetRustPrebuiltVersion(ctx)) + deps := make([]string, 0, len(toolchainProps.Toolchain_deps)+len(toolchainProps.Deps)) + for _, d := range toolchainProps.Toolchain_deps { + deps = append(deps, path.Join(prefix, d)) + } + deps = append(deps, toolchainProps.Deps...) + + props := struct { + Src *string + Deps []string + }{ + Src: proptools.StringPtr(path.Join(prefix, *toolchainProps.Toolchain_prebuilt_src)), + Deps: deps, + } + ctx.AppendProperties(&props) + }) + return module +} |