Merge "support aidl bp2build changes" into main
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index caca5b0..64cb2fa 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -83,9 +83,9 @@
"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,
@@ -142,6 +142,7 @@
"external/bzip2": Bp2BuildDefaultTrueRecursively,
"external/clang/lib": Bp2BuildDefaultTrue,
"external/conscrypt": Bp2BuildDefaultTrue,
+ "external/dexmaker": Bp2BuildDefaultTrueRecursively,
"external/e2fsprogs": Bp2BuildDefaultTrueRecursively,
"external/eigen": Bp2BuildDefaultTrueRecursively,
"external/erofs-utils": Bp2BuildDefaultTrueRecursively,
@@ -194,6 +195,7 @@
"external/lzma/C": Bp2BuildDefaultTrueRecursively,
"external/mdnsresponder": Bp2BuildDefaultTrueRecursively,
"external/minijail": Bp2BuildDefaultTrueRecursively,
+ "external/mockito": Bp2BuildDefaultTrueRecursively,
"external/musl": Bp2BuildDefaultTrueRecursively,
"external/objenesis": Bp2BuildDefaultTrueRecursively,
"external/openscreen": Bp2BuildDefaultTrueRecursively,
@@ -234,9 +236,11 @@
"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,
@@ -345,7 +349,9 @@
"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,
@@ -449,6 +455,7 @@
"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,
}
@@ -474,6 +481,7 @@
"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,
@@ -567,13 +575,8 @@
// 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",
@@ -582,7 +585,6 @@
"apache-commons-math",
"cbor-java",
"icu4j_calendar_astronomer",
- "remote-color-resources-compile-public",
"statslog-art-java-gen",
"AndroidCommonLint",
@@ -933,9 +935,7 @@
"androidx.test.annotation-nodeps",
// jni deps of an internal android_test (b/297405812)
- "libdexmakerjvmtiagent",
"libopenjdkjvmti_headers",
- "libstaticjvmtiagent",
// tradefed deps
"tradefed-protos",
@@ -1755,6 +1755,13 @@
"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 4ac5840..d8effaa 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -442,6 +442,9 @@
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/prebuilt_build_tool.go b/android/prebuilt_build_tool.go
index aeae20f..17b3230 100644
--- a/android/prebuilt_build_tool.go
+++ b/android/prebuilt_build_tool.go
@@ -17,7 +17,7 @@
import "path/filepath"
func init() {
- RegisterModuleType("prebuilt_build_tool", prebuiltBuildToolFactory)
+ RegisterModuleType("prebuilt_build_tool", NewPrebuiltBuildTool)
}
type prebuiltBuildToolProperties struct {
@@ -101,10 +101,6 @@
// 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 777c1cf..245b759 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -474,13 +474,23 @@
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 @@
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 @@
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 86647eb..a6b3a27 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -28,6 +28,17 @@
"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 @@
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 @@
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 @@
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 @@
rule.Command().
Tool(PathForSource(ctx, "cp")).
+ Flags(flags).
Inputs(in).
Implicit(implicit).
OrderOnly(orderOnly).
@@ -577,7 +593,11 @@
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 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 44a8fd7..73a4b2c 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -514,6 +514,12 @@
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"`
@@ -536,6 +542,8 @@
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 0ca5c4e..57c38db 100644
--- a/bp2build/aar_conversion_test.go
+++ b/bp2build/aar_conversion_test.go
@@ -86,7 +86,7 @@
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{
@@ -102,7 +102,18 @@
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"),
+ },
})
}
diff --git a/bp2build/aconfig_conversion_test.go b/bp2build/aconfig_conversion_test.go
index cbf42ac..51f0b2f 100644
--- a/bp2build/aconfig_conversion_test.go
+++ b/bp2build/aconfig_conversion_test.go
@@ -105,7 +105,6 @@
cc_library {
name: "server_configurable_flags",
srcs: ["bar.cc"],
- bazel_module: { bp2build_available: false },
}
cc_aconfig_library {
name: "foo",
@@ -131,7 +130,8 @@
},
)}
RunBp2BuildTestCase(t, registerAconfigModuleTypes, Bp2buildTestCase{
- Blueprint: bp,
- ExpectedBazelTargets: expectedBazelTargets,
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ StubbedBuildDefinitions: []string{"server_configurable_flags"},
})
}
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
index 8ec4b35..afe6dcd 100644
--- a/bp2build/android_app_conversion_test.go
+++ b/bp2build/android_app_conversion_test.go
@@ -478,3 +478,41 @@
}),
}})
}
+
+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 b724f57..3e00453 100644
--- a/bp2build/bp2build_product_config.go
+++ b/bp2build/bp2build_product_config.go
@@ -6,6 +6,7 @@
"os"
"path/filepath"
"reflect"
+ "sort"
"strings"
"android/soong/android"
@@ -28,6 +29,22 @@
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 @@
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 @@
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 @@
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 @@
}
}
- 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 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 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 @@
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 @@
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 ce2a955..f53588d 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -783,13 +783,13 @@
} 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/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index c2b65a1..3cce430 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -5161,7 +5161,6 @@
Blueprint: `
cc_library {
name: "libfoo",
- bazel_module: { bp2build_available: false },
}
ndk_library {
name: "libfoo",
@@ -5169,6 +5168,7 @@
symbol_file: "libfoo.map.txt",
}
`,
+ StubbedBuildDefinitions: []string{"libfoo"},
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_stub_suite", "libfoo.ndk_stub_libs", AttrNameToString{
"api_surface": `"publicapi"`,
diff --git a/bp2build/java_test_host_conversion_test.go b/bp2build/java_test_host_conversion_test.go
index 95c239d..87f35f6 100644
--- a/bp2build/java_test_host_conversion_test.go
+++ b/bp2build/java_test_host_conversion_test.go
@@ -97,14 +97,13 @@
java_library {
name: "lib_a",
- bazel_module: { bp2build_available: false },
}
java_library {
name: "static_libs_a",
- bazel_module: { bp2build_available: false },
}
`,
+ StubbedBuildDefinitions: []string{"lib_a", "static_libs_a"},
ExpectedBazelTargets: []string{
MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{
"runtime_deps": `[
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index b3bb2da..56c57b9 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -386,9 +386,11 @@
// 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 @@
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 9ceb1c8..6329e97 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -1113,12 +1113,15 @@
// 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 49117a0..31e668e 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "reflect"
"runtime"
"strings"
"testing"
@@ -1273,3 +1274,122 @@
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 7531f6d..71d986b 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -35,6 +35,7 @@
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 fc56dd5..3364f50 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -119,6 +119,9 @@
}
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 6f3d915..44496dc 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -1223,6 +1223,7 @@
type bazelAapt struct {
Manifest bazel.Label
Resource_files bazel.LabelListAttribute
+ Resource_zips bazel.LabelListAttribute
Assets_dir bazel.StringAttribute
Assets bazel.LabelListAttribute
}
@@ -1267,9 +1268,20 @@
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
@@ -1344,10 +1356,12 @@
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 ed1c107..166c22d 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1683,6 +1683,13 @@
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
@@ -1784,11 +1791,18 @@
// 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 fb7b95a..db237da 100644
--- a/java/base.go
+++ b/java/base.go
@@ -432,6 +432,9 @@
srcJarArgs []string
srcJarDeps android.Paths
+ // the source files of this module and all its static dependencies
+ transitiveSrcFiles *android.DepSet[android.Path]
+
// jar file containing implementation classes and resources including static library
// dependencies
implementationAndResourcesJar android.Path
@@ -1694,6 +1697,8 @@
j.linter.lint(ctx)
}
+ j.collectTransitiveSrcFiles(ctx, srcFiles)
+
ctx.CheckbuildFile(outputFile)
j.collectTransitiveAconfigFiles(ctx)
@@ -1708,6 +1713,7 @@
AidlIncludeDirs: j.exportAidlIncludeDirs,
SrcJarArgs: j.srcJarArgs,
SrcJarDeps: j.srcJarDeps,
+ TransitiveSrcFiles: j.transitiveSrcFiles,
ExportedPlugins: j.exportedPluginJars,
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
@@ -2032,6 +2038,21 @@
return j.jacocoReportClassesFile
}
+func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) {
+ var fromDeps []*android.DepSet[android.Path]
+ ctx.VisitDirectDeps(func(module android.Module) {
+ tag := ctx.OtherModuleDependencyTag(module)
+ if tag == staticLibTag {
+ depInfo := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ if depInfo.TransitiveSrcFiles != nil {
+ fromDeps = append(fromDeps, depInfo.TransitiveSrcFiles)
+ }
+ }
+ })
+
+ j.transitiveSrcFiles = android.NewDepSet(android.POSTORDER, mine, fromDeps)
+}
+
func (j *Module) IsInstallable() bool {
return Bool(j.properties.Installable)
}
diff --git a/java/java.go b/java/java.go
index bf692be..cac49a2 100644
--- a/java/java.go
+++ b/java/java.go
@@ -278,6 +278,9 @@
// SrcJarDeps is a list of paths to depend on when packaging the sources of this module.
SrcJarDeps android.Paths
+ // The source files of this module and all its transitive static dependencies.
+ TransitiveSrcFiles *android.DepSet[android.Path]
+
// ExportedPlugins is a list of paths that should be used as annotation processors for any
// module that depends on this module.
ExportedPlugins android.Paths
diff --git a/java/java_test.go b/java/java_test.go
index b555a95..d51604a 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -2263,6 +2263,28 @@
android.AssertStringDoesContain(t, "Command expected to contain full_api_surface_stub output jar", manifestCommand, "lib1.jar")
}
+func TestTransitiveSrcFiles(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "a",
+ srcs: ["a.java"],
+ }
+ java_library {
+ name: "b",
+ srcs: ["b.java"],
+ }
+ java_library {
+ name: "c",
+ srcs: ["c.java"],
+ libs: ["a"],
+ static_libs: ["b"],
+ }
+ `)
+ c := ctx.ModuleForTests("c", "android_common").Module()
+ transitiveSrcFiles := android.Paths(ctx.ModuleProvider(c, JavaInfoProvider).(JavaInfo).TransitiveSrcFiles.ToList())
+ android.AssertArrayString(t, "unexpected jar deps", []string{"b.java", "c.java"}, transitiveSrcFiles.Strings())
+}
+
func TestTradefedOptions(t *testing.T) {
result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
java_test_host {
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index ade7395..02a2298 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -57,6 +57,9 @@
// Path to the monolithic hiddenapi-unsupported.csv file.
hiddenAPIMetadataCSV android.OutputPath
+
+ // Path to a srcjar containing all the transitive sources of the bootclasspath.
+ srcjar android.OutputPath
}
type platformBootclasspathProperties struct {
@@ -95,6 +98,8 @@
return android.Paths{b.hiddenAPIIndexCSV}, nil
case "hiddenapi-metadata.csv":
return android.Paths{b.hiddenAPIMetadataCSV}, nil
+ case ".srcjar":
+ return android.Paths{b.srcjar}, nil
}
return nil, fmt.Errorf("unknown tag %s", tag)
@@ -173,6 +178,18 @@
allModules = append(allModules, apexModules...)
b.configuredModules = allModules
+ var transitiveSrcFiles android.Paths
+ for _, module := range allModules {
+ depInfo := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ if depInfo.TransitiveSrcFiles != nil {
+ transitiveSrcFiles = append(transitiveSrcFiles, depInfo.TransitiveSrcFiles.ToList()...)
+ }
+ }
+ jarArgs := resourcePathsToJarArgs(transitiveSrcFiles)
+ jarArgs = append(jarArgs, "-srcjar") // Move srcfiles to the right package
+ b.srcjar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-transitive.srcjar").OutputPath
+ TransformResourcesToJar(ctx, b.srcjar, jarArgs, transitiveSrcFiles)
+
// Gather all the fragments dependencies.
b.fragments = gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index ff2da4b..37ff639 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -81,6 +81,15 @@
RunTest(t)
})
+ fooSourceSrc := "source/a.java"
+ barSrc := "a.java"
+
+ checkSrcJarInputs := func(t *testing.T, result *android.TestResult, name string, expected []string) {
+ t.Helper()
+ srcjar := result.ModuleForTests(name, "android_common").Output(name + "-transitive.srcjar")
+ android.AssertStringDoesContain(t, "srcjar arg", srcjar.Args["jarArgs"], "-srcjar")
+ android.AssertArrayString(t, "srcjar inputs", expected, srcjar.Implicits.Strings())
+ }
t.Run("source", func(t *testing.T) {
result := android.GroupFixturePreparers(
preparer,
@@ -91,6 +100,10 @@
"platform:foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ fooSourceSrc,
+ barSrc,
+ })
})
t.Run("prebuilt", func(t *testing.T) {
@@ -103,6 +116,10 @@
"platform:prebuilt_foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ // TODO(b/151360309): This should also have the srcs for prebuilt_foo
+ barSrc,
+ })
})
t.Run("source+prebuilt - source preferred", func(t *testing.T) {
@@ -116,6 +133,10 @@
"platform:foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ fooSourceSrc,
+ barSrc,
+ })
})
t.Run("source+prebuilt - prebuilt preferred", func(t *testing.T) {
@@ -129,6 +150,10 @@
"platform:prebuilt_foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ // TODO(b/151360309): This should also have the srcs for prebuilt_foo
+ barSrc,
+ })
})
t.Run("dex import", func(t *testing.T) {
@@ -146,6 +171,10 @@
"platform:prebuilt_foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ // TODO(b/151360309): This should also have the srcs for prebuilt_foo
+ barSrc,
+ })
})
}
diff --git a/rust/binary.go b/rust/binary.go
index 1408ff1..aee4da6 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -138,9 +138,14 @@
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 @@
}
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 e6a7a93..d6c52e8 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -73,6 +73,15 @@
// 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 @@
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 c976617..f397ce9 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -81,13 +81,7 @@
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 @@
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 0357086..f4a2b54 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -489,7 +489,7 @@
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 @@
// 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 @@
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 @@
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 c3aa8dc..2982efd 100644
--- a/rust/protobuf.go
+++ b/rust/protobuf.go
@@ -20,6 +20,7 @@
"android/soong/android"
"android/soong/bazel"
+ "android/soong/cc"
"github.com/google/blueprint/proptools"
)
@@ -59,14 +60,18 @@
// 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 @@
// 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 @@
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 b723f3f..9dca029 100644
--- a/rust/protobuf_test.go
+++ b/rust/protobuf_test.go
@@ -118,6 +118,58 @@
}
}
+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 250e398..49a7ff3 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -267,6 +267,15 @@
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 @@
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 @@
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 @@
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 @@
}
// 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})
-
- 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.
+ 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(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 326d529..054104c 100644
--- a/rust/toolchain_library.go
+++ b/rust/toolchain_library.go
@@ -18,9 +18,12 @@
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 @@
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 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 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
+}