Merge changes from topics "revert-2629131-sandbox-rust-inputs-JRFPQTIPEY", "revert-2758566-WBNIADIEXA" into main

* changes:
  Revert^3 "add rust_toolchain_rustc_prebuilt module type"
  Revert^3 "add crate_root property to rust modules"
  Revert^3 "allow Ninja variables in RuleBuilder API"
  Revert "conditionally escape rule builder command"
  Revert "support sandboxed rust rules"
  Revert "fix failing rust_aconfig_library test"
  Revert "rustSetToolchainSource to use linux-x86 srcs"
  Revert "remove rust deps on clang prebuilts"
This commit is contained in:
Colin Cross
2023-09-23 05:19:13 +00:00
committed by Gerrit Code Review
33 changed files with 425 additions and 1608 deletions

View File

@@ -50,11 +50,11 @@ func TestRustAconfigLibrary(t *testing.T) {
} }
for _, variant := range variants { for _, variant := range variants {
android.AssertStringListContains( android.AssertStringEquals(
t, t,
"dylib variant builds from generated rust code", "dylib variant builds from generated rust code",
variant.Rule("rustc").Implicits.RelativeToTop().Strings(),
"out/soong/.intermediates/libmy_rust_aconfig_library/android_arm64_armv8-a_source/gen/src/lib.rs", "out/soong/.intermediates/libmy_rust_aconfig_library/android_arm64_armv8-a_source/gen/src/lib.rs",
variant.Rule("rustc").Inputs[0].RelativeToTop().String(),
) )
} }
} }

View File

@@ -95,12 +95,6 @@ func NewDepSet[T depSettableType](order DepSetOrder, direct []T, transitive []*D
} }
} }
// AddDirectToDepSet returns a new DepSet with additional elements added to its direct set.
// The transitive sets remain untouched.
func AddDirectToDepSet[T depSettableType](d *DepSet[T], direct ...T) *DepSet[T] {
return NewDepSet[T](d.order, Concat(d.direct, direct), d.transitive)
}
// DepSetBuilder is used to create an immutable DepSet. // DepSetBuilder is used to create an immutable DepSet.
type DepSetBuilder[T depSettableType] struct { type DepSetBuilder[T depSettableType] struct {
order DepSetOrder order DepSetOrder
@@ -194,14 +188,3 @@ func (d *DepSet[T]) ToList() []T {
} }
return list return list
} }
// ToListDirect returns the direct elements of a DepSet flattened to a list.
func (d *DepSet[T]) ToListDirect() []T {
if d == nil {
return nil
}
list := make([]T, len(d.direct))
copy(list, d.direct)
list = firstUniqueInPlace(list)
return list
}

View File

@@ -171,9 +171,6 @@ type Path interface {
// Base returns the last element of the path // Base returns the last element of the path
Base() string Base() string
// Dir returns a path pointing the directory containing the path
Dir() Path
// Rel returns the portion of the path relative to the directory it was created from. For // Rel returns the portion of the path relative to the directory it was created from. For
// example, Rel on a PathsForModuleSrc would return the path relative to the module source // example, Rel on a PathsForModuleSrc would return the path relative to the module source
// directory, and OutputPath.Join("foo").Rel() would return "foo". // directory, and OutputPath.Join("foo").Rel() would return "foo".
@@ -1015,12 +1012,6 @@ func (p basePath) Base() string {
return filepath.Base(p.path) return filepath.Base(p.path)
} }
func (p basePath) Dir() Path {
p.path = filepath.Dir(p.path)
p.rel = filepath.Dir(p.rel)
return p
}
func (p basePath) Rel() string { func (p basePath) Rel() string {
if p.rel != "" { if p.rel != "" {
return p.rel return p.rel
@@ -1055,11 +1046,6 @@ func (p SourcePath) withRel(rel string) SourcePath {
return p return p
} }
func (p SourcePath) Dir() Path {
p.basePath = p.basePath.Dir().(basePath)
return p
}
// safePathForSource is for paths that we expect are safe -- only for use by go // safePathForSource is for paths that we expect are safe -- only for use by go
// code that is embedding ninja variables in paths // code that is embedding ninja variables in paths
func safePathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) { func safePathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
@@ -1262,12 +1248,6 @@ func (p OutputPath) withRel(rel string) OutputPath {
return p return p
} }
func (p OutputPath) Dir() Path {
p.basePath = p.basePath.Dir().(basePath)
p.fullPath = filepath.Dir(p.fullPath)
return p
}
func (p OutputPath) WithoutRel() OutputPath { func (p OutputPath) WithoutRel() OutputPath {
p.basePath.rel = filepath.Base(p.basePath.path) p.basePath.rel = filepath.Base(p.basePath.path)
return p return p
@@ -1300,11 +1280,6 @@ type toolDepPath struct {
basePath basePath
} }
func (p toolDepPath) Dir() Path {
p.basePath = p.basePath.Dir().(basePath)
return p
}
func (t toolDepPath) RelativeToTop() Path { func (t toolDepPath) RelativeToTop() Path {
ensureTestOnly() ensureTestOnly()
return t return t
@@ -1488,11 +1463,6 @@ type ModuleOutPath struct {
OutputPath OutputPath
} }
func (p ModuleOutPath) Dir() Path {
p.OutputPath = p.OutputPath.Dir().(OutputPath)
return p
}
func (p ModuleOutPath) RelativeToTop() Path { func (p ModuleOutPath) RelativeToTop() Path {
p.OutputPath = p.outputPathRelativeToTop() p.OutputPath = p.outputPathRelativeToTop()
return p return p
@@ -1537,11 +1507,6 @@ type ModuleGenPath struct {
ModuleOutPath ModuleOutPath
} }
func (p ModuleGenPath) Dir() Path {
p.ModuleOutPath = p.ModuleOutPath.Dir().(ModuleOutPath)
return p
}
func (p ModuleGenPath) RelativeToTop() Path { func (p ModuleGenPath) RelativeToTop() Path {
p.OutputPath = p.outputPathRelativeToTop() p.OutputPath = p.outputPathRelativeToTop()
return p return p
@@ -1581,11 +1546,6 @@ type ModuleObjPath struct {
ModuleOutPath ModuleOutPath
} }
func (p ModuleObjPath) Dir() Path {
p.ModuleOutPath = p.ModuleOutPath.Dir().(ModuleOutPath)
return p
}
func (p ModuleObjPath) RelativeToTop() Path { func (p ModuleObjPath) RelativeToTop() Path {
p.OutputPath = p.outputPathRelativeToTop() p.OutputPath = p.outputPathRelativeToTop()
return p return p
@@ -1610,11 +1570,6 @@ type ModuleResPath struct {
ModuleOutPath ModuleOutPath
} }
func (p ModuleResPath) Dir() Path {
p.ModuleOutPath = p.ModuleOutPath.Dir().(ModuleOutPath)
return p
}
func (p ModuleResPath) RelativeToTop() Path { func (p ModuleResPath) RelativeToTop() Path {
p.OutputPath = p.outputPathRelativeToTop() p.OutputPath = p.outputPathRelativeToTop()
return p return p
@@ -1651,11 +1606,6 @@ type InstallPath struct {
makePath bool makePath bool
} }
func (p InstallPath) Dir() Path {
p.basePath = p.basePath.Dir().(basePath)
return p
}
// Will panic if called from outside a test environment. // Will panic if called from outside a test environment.
func ensureTestOnly() { func ensureTestOnly() {
if PrefixInList(os.Args, "-test.") { if PrefixInList(os.Args, "-test.") {
@@ -1972,11 +1922,6 @@ type PhonyPath struct {
basePath basePath
} }
func (p PhonyPath) Dir() Path {
p.basePath = p.basePath.Dir().(basePath)
return p
}
func (p PhonyPath) writablePath() {} func (p PhonyPath) writablePath() {}
func (p PhonyPath) getSoongOutDir() string { func (p PhonyPath) getSoongOutDir() string {
@@ -2002,11 +1947,6 @@ type testPath struct {
basePath basePath
} }
func (p testPath) Dir() Path {
p.basePath = p.basePath.Dir().(basePath)
return p
}
func (p testPath) RelativeToTop() Path { func (p testPath) RelativeToTop() Path {
ensureTestOnly() ensureTestOnly()
return p return p

View File

@@ -14,14 +14,10 @@
package android package android
import ( import "path/filepath"
"path/filepath"
"github.com/google/blueprint"
)
func init() { func init() {
RegisterModuleType("prebuilt_build_tool", NewPrebuiltBuildTool) RegisterModuleType("prebuilt_build_tool", prebuiltBuildToolFactory)
} }
type prebuiltBuildToolProperties struct { type prebuiltBuildToolProperties struct {
@@ -59,13 +55,6 @@ func (t *prebuiltBuildTool) DepsMutator(ctx BottomUpMutatorContext) {
} }
} }
type PrebuiltBuildToolInfo struct {
Src Path
Deps Paths
}
var PrebuiltBuildToolInfoProvider = blueprint.NewProvider(PrebuiltBuildToolInfo{})
func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) { func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) {
sourcePath := t.prebuilt.SingleSourcePath(ctx) sourcePath := t.prebuilt.SingleSourcePath(ctx)
installedPath := PathForModuleOut(ctx, t.BaseModuleName()) installedPath := PathForModuleOut(ctx, t.BaseModuleName())
@@ -93,11 +82,6 @@ func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) {
} }
t.toolPath = OptionalPathForPath(installedPath) t.toolPath = OptionalPathForPath(installedPath)
ctx.SetProvider(PrebuiltBuildToolInfoProvider, PrebuiltBuildToolInfo{
Src: sourcePath,
Deps: deps,
})
} }
func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) { func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) {
@@ -117,6 +101,10 @@ var _ HostToolProvider = &prebuiltBuildTool{}
// prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use // prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use
// in genrules with the "tools" property. // in genrules with the "tools" property.
func prebuiltBuildToolFactory() Module {
return NewPrebuiltBuildTool()
}
func NewPrebuiltBuildTool() Module { func NewPrebuiltBuildTool() Module {
module := &prebuiltBuildTool{} module := &prebuiltBuildTool{}
module.AddProperties(&module.properties) module.AddProperties(&module.properties)

View File

@@ -474,23 +474,13 @@ func (r *RuleBuilder) depFileMergerCmd(depFiles WritablePaths) *RuleBuilderComma
Inputs(depFiles.Paths()) 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 // Build adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for
// Outputs. // Outputs.
func (r *RuleBuilder) Build(name string, desc string) { 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) name = ninjaNameEscape(name)
if len(r.missingDeps) > 0 { if len(r.missingDeps) > 0 {
r.ctx.Build(r.pctx, BuildParams{ r.ctx.Build(pctx, BuildParams{
Rule: ErrorRule, Rule: ErrorRule,
Outputs: r.Outputs(), Outputs: r.Outputs(),
Description: desc, Description: desc,
@@ -629,35 +619,12 @@ func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString b
name, r.sboxManifestPath.String(), r.outDir.String()) name, r.sboxManifestPath.String(), r.outDir.String())
} }
// Create a rule to write the manifest as textproto. // Create a rule to write the manifest as a the textproto.
pbText, err := prototext.Marshal(&manifest) pbText, err := prototext.Marshal(&manifest)
if err != nil { if err != nil {
ReportPathErrorf(r.ctx, "sbox manifest failed to marshal: %q", err) ReportPathErrorf(r.ctx, "sbox manifest failed to marshal: %q", err)
} }
if ninjaEscapeCommandString {
WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText)) 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 // 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 // a RuleBuilderCommand as a convenience method of building the command line, then
@@ -756,13 +723,9 @@ func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString b
pool = localPool pool = localPool
} }
if ninjaEscapeCommandString {
commandString = proptools.NinjaEscape(commandString)
}
r.ctx.Build(r.pctx, BuildParams{ r.ctx.Build(r.pctx, BuildParams{
Rule: r.ctx.Rule(r.pctx, name, blueprint.RuleParams{ Rule: r.ctx.Rule(pctx, name, blueprint.RuleParams{
Command: commandString, Command: proptools.NinjaEscape(commandString),
CommandDeps: proptools.NinjaEscapeList(tools.Strings()), CommandDeps: proptools.NinjaEscapeList(tools.Strings()),
Restat: r.restat, Restat: r.restat,
Rspfile: proptools.NinjaEscape(rspFile), Rspfile: proptools.NinjaEscape(rspFile),

View File

@@ -28,17 +28,6 @@ import (
"android/soong/shared" "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 { func builderContext() BuilderContext {
return BuilderContextForTesting(TestConfig("out", nil, "", map[string][]byte{ return BuilderContextForTesting(TestConfig("out", nil, "", map[string][]byte{
"ld": nil, "ld": nil,
@@ -508,12 +497,10 @@ type testRuleBuilderModule struct {
ModuleBase ModuleBase
properties struct { properties struct {
Srcs []string Srcs []string
Flags []string
Restat bool Restat bool
Sbox bool Sbox bool
Sbox_inputs bool Sbox_inputs bool
Unescape_ninja_vars bool
} }
} }
@@ -531,9 +518,8 @@ func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"})
manifestPath := PathForModuleOut(ctx, "sbox.textproto") manifestPath := PathForModuleOut(ctx, "sbox.textproto")
testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, t.properties.Flags, testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir,
out, outDep, outDir, manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs,
manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs, t.properties.Unescape_ninja_vars,
rspFile, rspFileContents, rspFile2, rspFileContents2) rspFile, rspFileContents, rspFile2, rspFileContents2)
} }
@@ -557,18 +543,17 @@ func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) {
rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"})
manifestPath := PathForOutput(ctx, "singleton/sbox.textproto") manifestPath := PathForOutput(ctx, "singleton/sbox.textproto")
testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, nil, out, outDep, outDir, testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir,
manifestPath, true, false, false, false, manifestPath, true, false, false,
rspFile, rspFileContents, rspFile2, rspFileContents2) rspFile, rspFileContents, rspFile2, rspFileContents2)
} }
func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path, func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path,
flags []string,
out, outDep, outDir, manifestPath WritablePath, out, outDep, outDir, manifestPath WritablePath,
restat, sbox, sboxInputs, unescapeNinjaVars bool, restat, sbox, sboxInputs bool,
rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) { rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) {
rule := NewRuleBuilder(pctx_ruleBuilderTest, ctx) rule := NewRuleBuilder(pctx, ctx)
if sbox { if sbox {
rule.Sbox(outDir, manifestPath) rule.Sbox(outDir, manifestPath)
@@ -579,7 +564,6 @@ func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, va
rule.Command(). rule.Command().
Tool(PathForSource(ctx, "cp")). Tool(PathForSource(ctx, "cp")).
Flags(flags).
Inputs(in). Inputs(in).
Implicit(implicit). Implicit(implicit).
OrderOnly(orderOnly). OrderOnly(orderOnly).
@@ -593,12 +577,8 @@ func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, va
rule.Restat() rule.Restat()
} }
if unescapeNinjaVars {
rule.BuildWithUnescapedNinjaVars("rule", "desc")
} else {
rule.Build("rule", "desc") rule.Build("rule", "desc")
} }
}
var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) { var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterModuleType("rule_builder_test", testRuleBuilderFactory) ctx.RegisterModuleType("rule_builder_test", testRuleBuilderFactory)
@@ -812,47 +792,3 @@ 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}",
)
}

View File

@@ -33,17 +33,12 @@ func CopyOf[T any](s []T) []T {
return append([]T{}, s...) return append([]T{}, s...)
} }
// Concat returns a new slice concatenated from the input slices. It does not change the input // Concat returns a new slice concatenated from the two input slices. It does not change the input
// slices. // slices.
func Concat[T any](slices ...[]T) []T { func Concat[T any](s1, s2 []T) []T {
newLength := 0 res := make([]T, 0, len(s1)+len(s2))
for _, s := range slices { res = append(res, s1...)
newLength += len(s) res = append(res, s2...)
}
res := make([]T, 0, newLength)
for _, s := range slices {
res = append(res, s...)
}
return res return res
} }

View File

@@ -948,7 +948,7 @@ func TestApexWithStubs(t *testing.T) {
// Ensure that stub dependency from a rust module is not included // Ensure that stub dependency from a rust module is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so") ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
// The rust module is linked to the stub cc library // The rust module is linked to the stub cc library
rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").RuleParams.Command rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"]
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so") ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so") ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
@@ -1024,7 +1024,7 @@ func TestApexCanUsePrivateApis(t *testing.T) {
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so") ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").RuleParams.Command rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"]
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so") ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so") ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
} }

View File

@@ -35,7 +35,6 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
multitree.RegisterApiImportsModule(ctx) multitree.RegisterApiImportsModule(ctx)
ctx.RegisterModuleType("prebuilt_build_tool", android.NewPrebuiltBuildTool)
ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory) ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory)
ctx.RegisterModuleType("cc_object", ObjectFactory) ctx.RegisterModuleType("cc_object", ObjectFactory)
ctx.RegisterModuleType("cc_genrule", GenRuleFactory) ctx.RegisterModuleType("cc_genrule", GenRuleFactory)
@@ -68,26 +67,6 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
func commonDefaultModules() string { func commonDefaultModules() string {
return ` return `
prebuilt_build_tool {
name: "clang++",
src: "bin/clang++",
}
prebuilt_build_tool {
name: "clang++.real",
src: "bin/clang++.real",
}
prebuilt_build_tool {
name: "lld",
src: "bin/lld",
}
prebuilt_build_tool {
name: "ld.lld",
src: "bin/ld.lld",
}
prebuilt_build_tool {
name: "llvm-ar",
src: "bin/llvm-ar",
}
cc_defaults { cc_defaults {
name: "toolchain_libs_defaults", name: "toolchain_libs_defaults",
host_supported: true, host_supported: true,
@@ -589,12 +568,6 @@ var PrepareForTestWithCcDefaultModules = android.GroupFixturePreparers(
// Additional files needed in tests that disallow non-existent source. // Additional files needed in tests that disallow non-existent source.
android.MockFS{ android.MockFS{
"defaults/cc/common/bin/clang++": nil,
"defaults/cc/common/bin/clang++.real": nil,
"defaults/cc/common/bin/lld": nil,
"defaults/cc/common/bin/ld.lld": nil,
"defaults/cc/common/bin/llvm-ar": nil,
"defaults/cc/common/libc.map.txt": nil, "defaults/cc/common/libc.map.txt": nil,
"defaults/cc/common/libdl.map.txt": nil, "defaults/cc/common/libdl.map.txt": nil,
"defaults/cc/common/libm.map.txt": nil, "defaults/cc/common/libm.map.txt": nil,

View File

@@ -119,9 +119,6 @@ func run() error {
} }
manifest, err := readManifest(manifestFile) manifest, err := readManifest(manifestFile)
if err != nil {
return err
}
if len(manifest.Commands) == 0 { if len(manifest.Commands) == 0 {
return fmt.Errorf("at least one commands entry is required in %q", manifestFile) return fmt.Errorf("at least one commands entry is required in %q", manifestFile)

View File

@@ -54,8 +54,8 @@ func TestAfdoEnabled(t *testing.T) {
expectedCFlag := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo.afdo") expectedCFlag := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo.afdo")
if !strings.Contains(foo.RuleParams.Command, expectedCFlag) { if !strings.Contains(foo.Args["rustcFlags"], expectedCFlag) {
t.Errorf("Expected 'foo' to enable afdo, but did not find %q in command %q", expectedCFlag, foo.RuleParams.Command) t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", expectedCFlag, foo.Args["rustcFlags"])
} }
} }
@@ -96,17 +96,17 @@ func TestAfdoEnabledWithMultiArchs(t *testing.T) {
rustMockedFiles.AddToFixture(), rustMockedFiles.AddToFixture(),
).RunTestWithBp(t, bp) ).RunTestWithBp(t, bp)
fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon").Description("rustc") fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon").Rule("rustc")
fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a").Description("rustc") fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
expectedCFlagArm := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo_arm.afdo") expectedCFlagArm := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo_arm.afdo")
expectedCFlagArm64 := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo_arm64.afdo") expectedCFlagArm64 := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo_arm64.afdo")
if !strings.Contains(fooArm.RuleParams.Command, expectedCFlagArm) { if !strings.Contains(fooArm.Args["rustcFlags"], expectedCFlagArm) {
t.Errorf("Expected 'fooArm' to enable afdo, but did not find %q in command %q", expectedCFlagArm, fooArm.RuleParams.Command) t.Errorf("Expected 'fooArm' to enable afdo, but did not find %q in cflags %q", expectedCFlagArm, fooArm.Args["rustcFlags"])
} }
if !strings.Contains(fooArm64.RuleParams.Command, expectedCFlagArm64) { if !strings.Contains(fooArm64.Args["rustcFlags"], expectedCFlagArm64) {
t.Errorf("Expected 'fooArm64' to enable afdo, but did not find %q in command %q", expectedCFlagArm64, fooArm.RuleParams.Command) t.Errorf("Expected 'fooArm64' to enable afdo, but did not find %q in cflags %q", expectedCFlagArm64, fooArm64.Args["rustcFlags"])
} }
} }

View File

@@ -138,17 +138,13 @@ func (binary *binaryDecorator) preferRlib() bool {
func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix() fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
outputFile := android.PathForModuleOut(ctx, fileName) outputFile := android.PathForModuleOut(ctx, fileName)
ret := buildOutput{outputFile: outputFile} 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.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
if binary.stripper.NeedsStrip(ctx) { if binary.stripper.NeedsStrip(ctx) {
strippedOutputFile := outputFile strippedOutputFile := outputFile
@@ -159,7 +155,7 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path
} }
binary.baseCompiler.unstrippedOutputFile = outputFile binary.baseCompiler.unstrippedOutputFile = outputFile
ret.kytheFile = TransformSrcToBinary(ctx, binary, crateRootPath, deps, flags, outputFile).kytheFile ret.kytheFile = TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile).kytheFile
return ret return ret
} }

View File

@@ -135,7 +135,7 @@ func TestBinaryFlags(t *testing.T) {
fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc") fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc")
flags := fizzBuzz.RuleParams.Command flags := fizzBuzz.Args["rustcFlags"]
if strings.Contains(flags, "--test") { if strings.Contains(flags, "--test") {
t.Errorf("extra --test flag, rustcFlags: %#v", flags) t.Errorf("extra --test flag, rustcFlags: %#v", flags)
} }
@@ -150,11 +150,11 @@ func TestBootstrap(t *testing.T) {
bootstrap: true, bootstrap: true,
}`) }`)
foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc") foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustLink")
flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64" flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64"
if !strings.Contains(foo.RuleParams.Command, flag) { if !strings.Contains(foo.Args["linkFlags"], flag) {
t.Errorf("missing link flag to use bootstrap linker, expecting %#v, command: %#v", flag, foo.RuleParams.Command) t.Errorf("missing link flag to use bootstrap linker, expecting %#v, linkFlags: %#v", flag, foo.Args["linkFlags"])
} }
} }
@@ -167,17 +167,19 @@ func TestStaticBinaryFlags(t *testing.T) {
}`) }`)
fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc") fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc")
fizzOutLink := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustLink")
fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module) fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
flags := fizzOut.RuleParams.Command flags := fizzOut.Args["rustcFlags"]
linkFlags := fizzOutLink.Args["linkFlags"]
if !strings.Contains(flags, "-C relocation-model=static") { if !strings.Contains(flags, "-C relocation-model=static") {
t.Errorf("static binary missing '-C relocation-model=static' in command, found: %#v", flags) t.Errorf("static binary missing '-C relocation-model=static' in rustcFlags, found: %#v", flags)
} }
if !strings.Contains(flags, "-C panic=abort") { if !strings.Contains(flags, "-C panic=abort") {
t.Errorf("static binary missing '-C panic=abort' in command, found: %#v", flags) t.Errorf("static binary missing '-C panic=abort' in rustcFlags, found: %#v", flags)
} }
if !strings.Contains(flags, "-static") { if !strings.Contains(linkFlags, "-static") {
t.Errorf("static binary missing '-static' in command, found: %#v", flags) t.Errorf("static binary missing '-static' in linkFlags, found: %#v", flags)
} }
if !android.InList("libc", fizzMod.Properties.AndroidMkStaticLibs) { if !android.InList("libc", fizzMod.Properties.AndroidMkStaticLibs) {
@@ -199,9 +201,10 @@ func TestLinkObjects(t *testing.T) {
name: "libfoo", name: "libfoo",
}`) }`)
fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustc") fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustLink")
if !strings.Contains(fizzBuzz.RuleParams.Command, "/libfoo.so") { linkFlags := fizzBuzz.Args["linkFlags"]
t.Errorf("missing shared dependency 'libfoo.so' in command: %#v", fizzBuzz.RuleParams.Command) if !strings.Contains(linkFlags, "/libfoo.so") {
t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags)
} }
} }

View File

@@ -15,18 +15,64 @@
package rust package rust
import ( import (
"fmt"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/google/blueprint" "github.com/google/blueprint"
"android/soong/android" "android/soong/android"
cc_config "android/soong/cc/config"
"android/soong/rust/config" "android/soong/rust/config"
) )
var ( var (
_ = pctx.SourcePathVariable("rustcCmd", "${config.RustBin}/rustc")
_ = pctx.SourcePathVariable("mkcraterspCmd", "build/soong/scripts/mkcratersp.py")
rustc = pctx.AndroidStaticRule("rustc",
blueprint.RuleParams{
Command: "$envVars $rustcCmd " +
"-C linker=$mkcraterspCmd " +
"--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" +
" && grep \"^$out:\" $out.d.raw > $out.d",
CommandDeps: []string{"$rustcCmd", "$mkcraterspCmd"},
// Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633
// Rustc emits unneeded dependency lines for the .d and input .rs files.
// Those extra lines cause ninja warning:
// "warning: depfile has multiple output paths"
// For ninja, we keep/grep only the dependency rule for the rust $out file.
Deps: blueprint.DepsGCC,
Depfile: "$out.d",
},
"rustcFlags", "libFlags", "envVars")
rustLink = pctx.AndroidStaticRule("rustLink",
blueprint.RuleParams{
Command: "${config.RustLinker} -o $out ${crtBegin} ${earlyLinkFlags} @$in ${linkFlags} ${crtEnd}",
},
"earlyLinkFlags", "linkFlags", "crtBegin", "crtEnd")
_ = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc")
rustdoc = pctx.AndroidStaticRule("rustdoc",
blueprint.RuleParams{
Command: "$envVars $rustdocCmd $rustdocFlags $in -o $outDir && " +
"touch $out",
CommandDeps: []string{"$rustdocCmd"},
},
"rustdocFlags", "outDir", "envVars")
_ = pctx.SourcePathVariable("clippyCmd", "${config.RustBin}/clippy-driver")
clippyDriver = pctx.AndroidStaticRule("clippy",
blueprint.RuleParams{
Command: "$envVars $clippyCmd " +
// Because clippy-driver uses rustc as backend, we need to have some output even during the linting.
// Use the metadata output as it has the smallest footprint.
"--emit metadata -o $out --emit dep-info=$out.d.raw $in ${libFlags} " +
"$rustcFlags $clippyFlags" +
" && grep \"^$out:\" $out.d.raw > $out.d",
CommandDeps: []string{"$clippyCmd"},
Deps: blueprint.DepsGCC,
Depfile: "$out.d",
},
"rustcFlags", "libFlags", "clippyFlags", "envVars")
zip = pctx.AndroidStaticRule("zip", zip = pctx.AndroidStaticRule("zip",
blueprint.RuleParams{ blueprint.RuleParams{
Command: "cat $out.rsp | tr ' ' '\\n' | tr -d \\' | sort -u > ${out}.tmp && ${SoongZipCmd} -o ${out} -C $$OUT_DIR -l ${out}.tmp", Command: "cat $out.rsp | tr ' ' '\\n' | tr -d \\' | sort -u > ${out}.tmp && ${SoongZipCmd} -o ${out} -C $$OUT_DIR -l ${out}.tmp",
@@ -35,7 +81,7 @@ var (
RspfileContent: "$in", RspfileContent: "$in",
}) })
cpDir = pctx.AndroidStaticRule("cpDir", cp = pctx.AndroidStaticRule("cp",
blueprint.RuleParams{ blueprint.RuleParams{
Command: "cp `cat $outDir.rsp` $outDir", Command: "cp `cat $outDir.rsp` $outDir",
Rspfile: "${outDir}.rsp", Rspfile: "${outDir}.rsp",
@@ -43,12 +89,6 @@ var (
}, },
"outDir") "outDir")
cp = pctx.AndroidStaticRule("cp",
blueprint.RuleParams{
Command: "rm -f $out && cp $in $out",
Description: "cp $out",
})
// Cross-referencing: // Cross-referencing:
_ = pctx.SourcePathVariable("rustExtractor", _ = pctx.SourcePathVariable("rustExtractor",
"prebuilts/build-tools/${config.HostPrebuiltTag}/bin/rust_extractor") "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/rust_extractor")
@@ -56,6 +96,23 @@ var (
func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() }) func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
_ = pctx.VariableFunc("kytheCuEncoding", _ = pctx.VariableFunc("kytheCuEncoding",
func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() }) func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
_ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
kytheExtract = pctx.AndroidStaticRule("kythe",
blueprint.RuleParams{
Command: `KYTHE_CORPUS=${kytheCorpus} ` +
`KYTHE_OUTPUT_FILE=$out ` +
`KYTHE_VNAMES=$kytheVnames ` +
`KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
`KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative ` +
`$rustExtractor $envVars ` +
`$rustcCmd ` +
`-C linker=true ` +
`$in ${libFlags} $rustcFlags`,
CommandDeps: []string{"$rustExtractor", "$kytheVnames"},
Rspfile: "${out}.rsp",
RspfileContent: "$in",
},
"rustcFlags", "libFlags", "envVars")
) )
type buildOutput struct { type buildOutput struct {
@@ -67,40 +124,40 @@ func init() {
pctx.HostBinToolVariable("SoongZipCmd", "soong_zip") pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
} }
func TransformSrcToBinary(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags, func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput { outputFile android.WritablePath) buildOutput {
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin") flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "bin") return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "bin")
} }
func TransformSrctoRlib(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags, func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput { outputFile android.WritablePath) buildOutput {
return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "rlib") return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "rlib")
} }
func TransformSrctoDylib(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags, func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput { outputFile android.WritablePath) buildOutput {
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin") flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "dylib") return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "dylib")
} }
func TransformSrctoStatic(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags, func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput { outputFile android.WritablePath) buildOutput {
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin") flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "staticlib") return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "staticlib")
} }
func TransformSrctoShared(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags, func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput { outputFile android.WritablePath) buildOutput {
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin") flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "cdylib") return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "cdylib")
} }
func TransformSrctoProcMacro(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, func TransformSrctoProcMacro(ctx ModuleContext, mainSrc android.Path, deps PathDeps,
flags Flags, outputFile android.WritablePath) buildOutput { flags Flags, outputFile android.WritablePath) buildOutput {
return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "proc-macro") return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "proc-macro")
} }
func rustLibsToPaths(libs RustLibraries) android.Paths { func rustLibsToPaths(libs RustLibraries) android.Paths {
@@ -111,46 +168,28 @@ func rustLibsToPaths(libs RustLibraries) android.Paths {
return paths return paths
} }
func makeLibFlags(deps PathDeps, ruleCmd *android.RuleBuilderCommand) []string { func makeLibFlags(deps PathDeps) []string {
var libFlags []string var libFlags []string
// Collect library/crate flags // Collect library/crate flags
for _, lib := range deps.Rlibs.ToListDirect() { for _, lib := range deps.RLibs {
libPath := ruleCmd.PathForInput(lib.Path) libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
libFlags = append(libFlags, "--extern "+lib.CrateName+"="+libPath)
} }
for _, lib := range deps.Dylibs.ToListDirect() { for _, lib := range deps.DyLibs {
libPath := ruleCmd.PathForInput(lib.Path) libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
libFlags = append(libFlags, "--extern "+lib.CrateName+"="+libPath)
} }
for _, procMacro := range deps.ProcMacros.ToListDirect() { for _, proc_macro := range deps.ProcMacros {
procMacroPath := ruleCmd.PathForInput(procMacro.Path) libFlags = append(libFlags, "--extern "+proc_macro.CrateName+"="+proc_macro.Path.String())
libFlags = append(libFlags, "--extern "+procMacro.CrateName+"="+procMacroPath)
} }
for _, path := range deps.linkDirs { for _, path := range deps.linkDirs {
libFlags = append(libFlags, "-L "+ruleCmd.PathForInput(path)) libFlags = append(libFlags, "-L "+path)
} }
return libFlags return libFlags
} }
func collectImplicits(deps PathDeps) android.Paths { func rustEnvVars(ctx ModuleContext, deps PathDeps) []string {
depPaths := android.Paths{}
depPaths = append(depPaths, rustLibsToPaths(deps.Rlibs.ToList())...)
depPaths = append(depPaths, rustLibsToPaths(deps.Dylibs.ToList())...)
depPaths = append(depPaths, rustLibsToPaths(deps.ProcMacros.ToList())...)
depPaths = append(depPaths, deps.AfdoProfiles...)
depPaths = append(depPaths, deps.WholeStaticLibs...)
depPaths = append(depPaths, deps.SrcDeps...)
depPaths = append(depPaths, deps.srcProviderFiles...)
depPaths = append(depPaths, deps.LibDeps...)
depPaths = append(depPaths, deps.linkObjects...)
depPaths = append(depPaths, deps.BuildToolSrcDeps...)
return depPaths
}
func rustEnvVars(ctx ModuleContext, deps PathDeps, cmd *android.RuleBuilderCommand) []string {
var envVars []string var envVars []string
// libstd requires a specific environment variable to be set. This is // libstd requires a specific environment variable to be set. This is
@@ -164,17 +203,15 @@ func rustEnvVars(ctx ModuleContext, deps PathDeps, cmd *android.RuleBuilderComma
moduleGenDir := ctx.RustModule().compiler.CargoOutDir() moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
// We must calculate an absolute path for OUT_DIR since Rust's include! macro (which normally consumes this) // We must calculate an absolute path for OUT_DIR since Rust's include! macro (which normally consumes this)
// assumes that paths are relative to the source file. // assumes that paths are relative to the source file.
var outDir string var outDirPrefix string
if filepath.IsAbs(moduleGenDir.String()) { if !filepath.IsAbs(moduleGenDir.String()) {
// If OUT_DIR is absolute, then moduleGenDir will be an absolute path, so we don't need to set this to anything.
outDir = moduleGenDir.String()
} else if moduleGenDir.Valid() {
// If OUT_DIR is not absolute, we use $$PWD to generate an absolute path (os.Getwd() returns '/') // If OUT_DIR is not absolute, we use $$PWD to generate an absolute path (os.Getwd() returns '/')
outDir = filepath.Join("$$PWD/", cmd.PathForInput(moduleGenDir.Path())) outDirPrefix = "$$PWD/"
} else { } else {
outDir = "$$PWD/" // If OUT_DIR is absolute, then moduleGenDir will be an absolute path, so we don't need to set this to anything.
outDirPrefix = ""
} }
envVars = append(envVars, "OUT_DIR="+outDir) envVars = append(envVars, "OUT_DIR="+filepath.Join(outDirPrefix, moduleGenDir.String()))
} else { } else {
// TODO(pcc): Change this to "OUT_DIR=" after fixing crates to not rely on this value. // TODO(pcc): Change this to "OUT_DIR=" after fixing crates to not rely on this value.
envVars = append(envVars, "OUT_DIR=out") envVars = append(envVars, "OUT_DIR=out")
@@ -205,9 +242,7 @@ func rustEnvVars(ctx ModuleContext, deps PathDeps, cmd *android.RuleBuilderComma
} }
} }
envVars = append(envVars, "AR="+cmd.PathForInput( envVars = append(envVars, "AR=${cc_config.ClangBin}/llvm-ar")
cc_config.ClangPath(ctx, "bin/llvm-ar")),
)
if ctx.Darwin() { if ctx.Darwin() {
envVars = append(envVars, "ANDROID_RUST_DARWIN=true") envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
@@ -216,18 +251,21 @@ func rustEnvVars(ctx ModuleContext, deps PathDeps, cmd *android.RuleBuilderComma
return envVars return envVars
} }
func transformSrctoCrate(ctx ModuleContext, comp compiler, main android.Path, deps PathDeps, flags Flags, func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath, crateType string) buildOutput { outputFile android.WritablePath, crateType string) buildOutput {
var inputs android.Paths var inputs android.Paths
var implicits, linkImplicits, linkOrderOnly android.Paths
var output buildOutput var output buildOutput
var rustcFlags, linkFlags []string var rustcFlags, linkFlags []string
var earlyLinkFlags []string var earlyLinkFlags string
output.outputFile = outputFile output.outputFile = outputFile
crateName := ctx.RustModule().CrateName() crateName := ctx.RustModule().CrateName()
targetTriple := ctx.toolchain().RustTriple() targetTriple := ctx.toolchain().RustTriple()
envVars := rustEnvVars(ctx, deps)
inputs = append(inputs, main) inputs = append(inputs, main)
// Collect rustc flags // Collect rustc flags
@@ -248,6 +286,7 @@ func transformSrctoCrate(ctx ModuleContext, comp compiler, main android.Path, de
// Enable incremental compilation if requested by user // Enable incremental compilation if requested by user
if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") { if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
incrementalPath := android.PathForOutput(ctx, "rustc").String() incrementalPath := android.PathForOutput(ctx, "rustc").String()
rustcFlags = append(rustcFlags, "-Cincremental="+incrementalPath) rustcFlags = append(rustcFlags, "-Cincremental="+incrementalPath)
} }
@@ -259,16 +298,36 @@ func transformSrctoCrate(ctx ModuleContext, comp compiler, main android.Path, de
// Collect linker flags // Collect linker flags
if !ctx.Darwin() { if !ctx.Darwin() {
earlyLinkFlags = append(earlyLinkFlags, "-Wl,--as-needed") earlyLinkFlags = "-Wl,--as-needed"
} }
linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
linkFlags = append(linkFlags, flags.LinkFlags...)
// Check if this module needs to use the bootstrap linker
if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() {
dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
if ctx.toolchain().Is64Bit() {
dynamicLinker += "64"
}
linkFlags = append(linkFlags, dynamicLinker)
}
libFlags := makeLibFlags(deps)
// Collect dependencies // Collect dependencies
var linkImplicits android.Paths implicits = append(implicits, rustLibsToPaths(deps.RLibs)...)
implicits := collectImplicits(deps) implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...)
toolImplicits := android.Concat(deps.BuildToolDeps) implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
implicits = append(implicits, deps.AfdoProfiles...)
implicits = append(implicits, deps.srcProviderFiles...)
implicits = append(implicits, deps.WholeStaticLibs...)
linkImplicits = append(linkImplicits, deps.LibDeps...)
linkImplicits = append(linkImplicits, deps.CrtBegin...) linkImplicits = append(linkImplicits, deps.CrtBegin...)
linkImplicits = append(linkImplicits, deps.CrtEnd...) linkImplicits = append(linkImplicits, deps.CrtEnd...)
implicits = append(implicits, comp.compilationSourcesAndData(ctx)...)
linkOrderOnly = append(linkOrderOnly, deps.linkObjects...)
if len(deps.SrcDeps) > 0 { if len(deps.SrcDeps) > 0 {
moduleGenDir := ctx.RustModule().compiler.CargoOutDir() moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
@@ -283,7 +342,7 @@ func transformSrctoCrate(ctx ModuleContext, comp compiler, main android.Path, de
} }
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: cpDir, Rule: cp,
Description: "cp " + moduleGenDir.Path().Rel(), Description: "cp " + moduleGenDir.Path().Rel(),
Outputs: outputs, Outputs: outputs,
Inputs: deps.SrcDeps, Inputs: deps.SrcDeps,
@@ -295,183 +354,81 @@ func transformSrctoCrate(ctx ModuleContext, comp compiler, main android.Path, de
} }
if flags.Clippy { if flags.Clippy {
clippyRule := getRuleBuilder(ctx, pctx, false, "clippy")
clippyCmd := clippyRule.Command()
clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy") clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
clippyDepInfoFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy.d.raw") ctx.Build(pctx, android.BuildParams{
clippyDepFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy.d") Rule: clippyDriver,
Description: "clippy " + main.Rel(),
clippyCmd. Output: clippyFile,
Flags(rustEnvVars(ctx, deps, clippyCmd)). Inputs: inputs,
Tool(config.RustPath(ctx, "bin/clippy-driver")). Implicits: implicits,
Flag("--emit metadata"). Args: map[string]string{
FlagWithOutput("-o ", clippyFile). "rustcFlags": strings.Join(rustcFlags, " "),
FlagWithOutput("--emit dep-info=", clippyDepInfoFile). "libFlags": strings.Join(libFlags, " "),
Inputs(inputs). "clippyFlags": strings.Join(flags.ClippyFlags, " "),
Flags(makeLibFlags(deps, clippyCmd)). "envVars": strings.Join(envVars, " "),
Flags(rustcFlags). },
Flags(flags.ClippyFlags). })
ImplicitTools(toolImplicits).
Implicits(implicits)
depfileCreationCmd := clippyRule.Command()
depfileCreationCmd.
Flag(fmt.Sprintf(
`grep "^%s:" %s >`,
depfileCreationCmd.PathForOutput(clippyFile),
depfileCreationCmd.PathForOutput(clippyDepInfoFile),
)).
DepFile(clippyDepFile)
clippyRule.BuildWithUnescapedNinjaVars("clippy", "clippy "+main.Rel())
// Declare the clippy build as an implicit dependency of the original crate. // Declare the clippy build as an implicit dependency of the original crate.
implicits = append(implicits, clippyFile) implicits = append(implicits, clippyFile)
} }
sboxDirectory := "rustc" rustcOutputFile := outputFile
rustSboxOutputFile := android.PathForModuleOut(ctx, sboxDirectory, outputFile.Base())
depFile := android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".d")
depInfoFile := android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".d.raw")
var rustcImplicitOutputs android.WritablePaths
sandboxedCompilation := comp.crateRoot(ctx) != nil
rustcRule := getRuleBuilder(ctx, pctx, sandboxedCompilation, sboxDirectory)
rustcCmd := rustcRule.Command()
linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
linkFlags = append(linkFlags, flags.LinkFlags...)
linkFlags = append(linkFlags, rustcCmd.PathsForInputs(deps.linkObjects)...)
// Check if this module needs to use the bootstrap linker
if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() {
dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
if ctx.toolchain().Is64Bit() {
dynamicLinker += "64"
}
linkFlags = append(linkFlags, dynamicLinker)
}
libFlags := makeLibFlags(deps, rustcCmd)
usesLinker := crateType == "bin" || crateType == "dylib" || crateType == "cdylib" || crateType == "proc-macro" usesLinker := crateType == "bin" || crateType == "dylib" || crateType == "cdylib" || crateType == "proc-macro"
if usesLinker { if usesLinker {
rustSboxOutputFile = android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".rsp") rustcOutputFile = android.PathForModuleOut(ctx, outputFile.Base()+".rsp")
rustcImplicitOutputs = android.WritablePaths{
android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".whole.a"),
android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".a"),
}
} }
clangTools := android.Paths{
cc_config.ClangPath(ctx, "bin/llvm-ar"),
}
if ctx.Config().BuildOS != android.Darwin {
clangTools = append(clangTools,
cc_config.ClangPath(ctx, "lib/libc++.so"),
)
}
rustcCmd.
Flags(rustEnvVars(ctx, deps, rustcCmd)).
Tool(config.RustPath(ctx, "bin/rustc")).
FlagWithInput("-C linker=", android.PathForSource(ctx, "build", "soong", "scripts", "mkcratersp.py")).
Flag("--emit link").
Flag("-o").
Output(rustSboxOutputFile).
FlagWithOutput("--emit dep-info=", depInfoFile).
Inputs(inputs).
Flags(libFlags).
Implicits(clangTools).
ImplicitTools(toolImplicits).
Implicits(implicits).
Flags(rustcFlags).
ImplicitOutputs(rustcImplicitOutputs)
depfileCreationCmd := rustcRule.Command()
depfileCreationCmd.
Flag(fmt.Sprintf(
`grep "^%s:" %s >`,
depfileCreationCmd.PathForOutput(rustSboxOutputFile),
depfileCreationCmd.PathForOutput(depInfoFile),
)).
DepFile(depFile)
if !usesLinker {
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: cp, Rule: rustc,
Input: rustSboxOutputFile, Description: "rustc " + main.Rel(),
Output: outputFile, Output: rustcOutputFile,
Inputs: inputs,
Implicits: implicits,
Args: map[string]string{
"rustcFlags": strings.Join(rustcFlags, " "),
"libFlags": strings.Join(libFlags, " "),
"envVars": strings.Join(envVars, " "),
},
}) })
} else {
// TODO: delmerico - separate rustLink into its own rule if usesLinker {
// mkcratersp.py hardcodes paths to files within the sandbox, so
// those need to be renamed/symlinked to something in the rustLink sandbox
// if we want to separate the rules
linkerSboxOutputFile := android.PathForModuleOut(ctx, sboxDirectory, outputFile.Base())
clangTools := android.Paths{
cc_config.ClangPath(ctx, "bin/clang++"),
cc_config.ClangPath(ctx, "bin/lld"),
cc_config.ClangPath(ctx, "bin/ld.lld"),
}
if ctx.Config().BuildOS != android.Darwin {
clangTools = append(clangTools,
cc_config.ClangPath(ctx, "bin/clang++.real"),
cc_config.ClangPath(ctx, "lib/libc++.so"),
)
}
rustLinkCmd := rustcRule.Command()
rustLinkCmd.
Tool(cc_config.ClangPath(ctx, "bin/clang++")).
Flag("-o").
Output(linkerSboxOutputFile).
Inputs(deps.CrtBegin).
Flags(earlyLinkFlags).
FlagWithInput("@", rustSboxOutputFile).
Flags(linkFlags).
Inputs(deps.CrtEnd).
ImplicitTools(clangTools).
ImplicitTools(toolImplicits).
Implicits(rustcImplicitOutputs.Paths()).
Implicits(implicits).
Implicits(linkImplicits)
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: cp, Rule: rustLink,
Input: linkerSboxOutputFile, Description: "rustLink " + main.Rel(),
Output: outputFile, Output: outputFile,
Inputs: android.Paths{rustcOutputFile},
Implicits: linkImplicits,
OrderOnly: linkOrderOnly,
Args: map[string]string{
"earlyLinkFlags": earlyLinkFlags,
"linkFlags": strings.Join(linkFlags, " "),
"crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
"crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
},
}) })
} }
rustcRule.BuildWithUnescapedNinjaVars("rustc", "rustc "+main.Rel())
if flags.EmitXrefs { if flags.EmitXrefs {
kytheRule := getRuleBuilder(ctx, pctx, false, "kythe")
kytheCmd := kytheRule.Command()
kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip") kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip")
kytheCmd. ctx.Build(pctx, android.BuildParams{
Flag("KYTHE_CORPUS=${kytheCorpus}"). Rule: kytheExtract,
FlagWithOutput("KYTHE_OUTPUT_FILE=", kytheFile). Description: "Xref Rust extractor " + main.Rel(),
FlagWithInput("KYTHE_VNAMES=", android.PathForSource(ctx, "build", "soong", "vnames.json")). Output: kytheFile,
Flag("KYTHE_KZIP_ENCODING=${kytheCuEncoding}"). Inputs: inputs,
Flag("KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative"). Implicits: implicits,
Tool(ctx.Config().PrebuiltBuildTool(ctx, "rust_extractor")). Args: map[string]string{
Flags(rustEnvVars(ctx, deps, kytheCmd)). "rustcFlags": strings.Join(rustcFlags, " "),
Tool(config.RustPath(ctx, "bin/rustc")). "libFlags": strings.Join(libFlags, " "),
Flag("-C linker=true"). "envVars": strings.Join(envVars, " "),
Inputs(inputs). },
Flags(makeLibFlags(deps, kytheCmd)). })
Flags(rustcFlags).
ImplicitTools(toolImplicits).
Implicits(implicits)
kytheRule.BuildWithUnescapedNinjaVars("kythe", "Xref Rust extractor "+main.Rel())
output.kytheFile = kytheFile output.kytheFile = kytheFile
} }
return output return output
} }
func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags) android.ModuleOutPath { func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps,
rustdocRule := getRuleBuilder(ctx, pctx, false, "rustdoc") flags Flags) android.ModuleOutPath {
rustdocCmd := rustdocRule.Command()
rustdocFlags := append([]string{}, flags.RustdocFlags...) rustdocFlags := append([]string{}, flags.RustdocFlags...)
rustdocFlags = append(rustdocFlags, "--sysroot=/dev/null") rustdocFlags = append(rustdocFlags, "--sysroot=/dev/null")
@@ -490,7 +447,7 @@ func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags) a
crateName := ctx.RustModule().CrateName() crateName := ctx.RustModule().CrateName()
rustdocFlags = append(rustdocFlags, "--crate-name "+crateName) rustdocFlags = append(rustdocFlags, "--crate-name "+crateName)
rustdocFlags = append(rustdocFlags, makeLibFlags(deps, rustdocCmd)...) rustdocFlags = append(rustdocFlags, makeLibFlags(deps)...)
docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp") docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp")
// Silence warnings about renamed lints for third-party crates // Silence warnings about renamed lints for third-party crates
@@ -506,26 +463,18 @@ func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags) a
// https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render/write_shared.rs#L144-L146 // https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render/write_shared.rs#L144-L146
docDir := android.PathForOutput(ctx, "rustdoc") docDir := android.PathForOutput(ctx, "rustdoc")
rustdocCmd. ctx.Build(pctx, android.BuildParams{
Flags(rustEnvVars(ctx, deps, rustdocCmd)). Rule: rustdoc,
Tool(config.RustPath(ctx, "bin/rustdoc")). Description: "rustdoc " + main.Rel(),
Flags(rustdocFlags). Output: docTimestampFile,
Input(main). Input: main,
Flag("-o "+docDir.String()). Implicit: ctx.RustModule().UnstrippedOutputFile(),
FlagWithOutput("&& touch ", docTimestampFile). Args: map[string]string{
Implicit(ctx.RustModule().UnstrippedOutputFile()) "rustdocFlags": strings.Join(rustdocFlags, " "),
"outDir": docDir.String(),
"envVars": strings.Join(rustEnvVars(ctx, deps), " "),
},
})
rustdocRule.BuildWithUnescapedNinjaVars("rustdoc", "rustdoc "+main.Rel())
return docTimestampFile return docTimestampFile
} }
func getRuleBuilder(ctx android.ModuleContext, pctx android.PackageContext, sbox bool, sboxDirectory string) *android.RuleBuilder {
r := android.NewRuleBuilder(pctx, ctx)
if sbox {
r = r.Sbox(
android.PathForModuleOut(ctx, sboxDirectory),
android.PathForModuleOut(ctx, sboxDirectory+".sbox.textproto"),
).SandboxInputs()
}
return r
}

View File

@@ -63,14 +63,14 @@ func TestClippy(t *testing.T) {
).RunTest(t) ).RunTest(t)
r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("clippy") r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
android.AssertStringDoesContain(t, "libfoo flags", r.RuleParams.Command, tc.fooFlags) android.AssertStringEquals(t, "libfoo flags", tc.fooFlags, r.Args["clippyFlags"])
r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("clippy") r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
android.AssertStringDoesContain(t, "libbar flags", r.RuleParams.Command, "${config.ClippyDefaultLints}") android.AssertStringEquals(t, "libbar flags", "${config.ClippyDefaultLints}", r.Args["clippyFlags"])
r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("clippy") r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
if r.Rule != nil { if r.Rule != nil {
t.Errorf("libfoobar is setup to use clippy when explicitly disabled: command=%q", r.RuleParams.Command) t.Errorf("libfoobar is setup to use clippy when explicitly disabled: clippyFlags=%q", r.Args["clippyFlags"])
} }
}) })
} }

View File

@@ -73,18 +73,6 @@ type BaseCompilerProperties struct {
// If no source file is defined, a single generated source module can be defined to be used as the main source. // 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"` 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"`
// Additional data files that are used during compilation only. These are not accessible at runtime.
Compile_data []string `android:"path,arch_variant"`
// name of the lint set that should be used to validate this module. // name of the lint set that should be used to validate this module.
// //
// Possible values are "default" (for using a sensible set of lints // Possible values are "default" (for using a sensible set of lints
@@ -346,23 +334,6 @@ func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathD
panic(fmt.Errorf("baseCrater doesn't know how to crate things!")) panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
} }
func (compile *baseCompiler) crateRoot(ctx ModuleContext) android.Path {
if compile.Properties.Crate_root != nil {
return android.PathForModuleSrc(ctx, *compile.Properties.Crate_root)
}
return nil
}
// compilationSourcesAndData returns a list of files necessary to complete the compilation.
// This includes the rust source files as well as any other data files that
// are referenced during the build.
func (compile *baseCompiler) compilationSourcesAndData(ctx ModuleContext) android.Paths {
return android.PathsForModuleSrc(ctx, android.Concat(
compile.Properties.Srcs,
compile.Properties.Compile_data,
))
}
func (compiler *baseCompiler) rustdoc(ctx ModuleContext, flags Flags, func (compiler *baseCompiler) rustdoc(ctx ModuleContext, flags Flags,
deps PathDeps) android.OptionalPath { deps PathDeps) android.OptionalPath {
@@ -540,8 +511,6 @@ 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.") 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) paths := android.PathsForModuleSrc(ctx, srcs)
return paths[srcIndex], paths[1:] return paths[srcIndex], paths[1:]
} }

View File

@@ -36,9 +36,9 @@ func TestFeaturesToFlags(t *testing.T) {
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
if !strings.Contains(libfooDylib.RuleParams.Command, "cfg 'feature=\"fizz\"'") || if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"fizz\"'") ||
!strings.Contains(libfooDylib.RuleParams.Command, "cfg 'feature=\"buzz\"'") { !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"buzz\"'") {
t.Fatalf("missing fizz and buzz feature flags for libfoo dylib, command: %#v", libfooDylib.RuleParams.Command) t.Fatalf("missing fizz and buzz feature flags for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
} }
} }
@@ -57,9 +57,9 @@ func TestCfgsToFlags(t *testing.T) {
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
if !strings.Contains(libfooDylib.RuleParams.Command, "cfg 'std'") || if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'std'") ||
!strings.Contains(libfooDylib.RuleParams.Command, "cfg 'cfg1=\"one\"'") { !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'cfg1=\"one\"'") {
t.Fatalf("missing std and cfg1 flags for libfoo dylib, rustcFlags: %#v", libfooDylib.RuleParams.Command) t.Fatalf("missing std and cfg1 flags for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
} }
} }
@@ -146,14 +146,14 @@ func TestCargoCompat(t *testing.T) {
fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc") fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc")
if !strings.Contains(fizz.RuleParams.Command, "CARGO_BIN_NAME=fizz") { if !strings.Contains(fizz.Args["envVars"], "CARGO_BIN_NAME=fizz") {
t.Fatalf("expected 'CARGO_BIN_NAME=fizz' in envVars, actual command: %#v", fizz.RuleParams.Command) t.Fatalf("expected 'CARGO_BIN_NAME=fizz' in envVars, actual envVars: %#v", fizz.Args["envVars"])
} }
if !strings.Contains(fizz.RuleParams.Command, "CARGO_CRATE_NAME=foo") { if !strings.Contains(fizz.Args["envVars"], "CARGO_CRATE_NAME=foo") {
t.Fatalf("expected 'CARGO_CRATE_NAME=foo' in envVars, actual command: %#v", fizz.RuleParams.Command) t.Fatalf("expected 'CARGO_CRATE_NAME=foo' in envVars, actual envVars: %#v", fizz.Args["envVars"])
} }
if !strings.Contains(fizz.RuleParams.Command, "CARGO_PKG_VERSION=1.0.0") { if !strings.Contains(fizz.Args["envVars"], "CARGO_PKG_VERSION=1.0.0") {
t.Fatalf("expected 'CARGO_PKG_VERSION=1.0.0' in envVars, actual command: %#v", fizz.RuleParams.Command) t.Fatalf("expected 'CARGO_PKG_VERSION=1.0.0' in envVars, actual envVars: %#v", fizz.Args["envVars"])
} }
} }
@@ -230,13 +230,13 @@ func TestLints(t *testing.T) {
).RunTest(t) ).RunTest(t)
r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc") r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
android.AssertStringDoesContain(t, "libfoo flags", r.RuleParams.Command, tc.fooFlags) android.AssertStringDoesContain(t, "libfoo flags", r.Args["rustcFlags"], tc.fooFlags)
r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc") r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
android.AssertStringDoesContain(t, "libbar flags", r.RuleParams.Command, "${config.RustDefaultLints}") android.AssertStringDoesContain(t, "libbar flags", r.Args["rustcFlags"], "${config.RustDefaultLints}")
r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc") r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
android.AssertStringDoesContain(t, "libfoobar flags", r.RuleParams.Command, "${config.RustAllowAllLints}") android.AssertStringDoesContain(t, "libfoobar flags", r.Args["rustcFlags"], "${config.RustAllowAllLints}")
}) })
} }
} }

View File

@@ -81,7 +81,13 @@ var (
func init() { func init() {
pctx.SourcePathVariable("RustDefaultBase", RustDefaultBase) pctx.SourcePathVariable("RustDefaultBase", RustDefaultBase)
pctx.VariableConfigMethod("HostPrebuiltTag", HostPrebuiltTag) pctx.VariableConfigMethod("HostPrebuiltTag", func(config android.Config) string {
if config.UseHostMusl() {
return "linux-musl-x86"
} else {
return config.PrebuiltOS()
}
})
pctx.VariableFunc("RustBase", func(ctx android.PackageVarContext) string { pctx.VariableFunc("RustBase", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("RUST_PREBUILTS_BASE"); override != "" { if override := ctx.Config().Getenv("RUST_PREBUILTS_BASE"); override != "" {
@@ -103,14 +109,6 @@ func init() {
exportedVars.ExportStringStaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion) 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 { func getRustVersionPctx(ctx android.PackageVarContext) string {
return GetRustVersion(ctx) return GetRustVersion(ctx)
} }
@@ -126,27 +124,3 @@ func GetRustVersion(ctx android.PathContext) string {
func BazelRustToolchainVars(config android.Config) string { func BazelRustToolchainVars(config android.Config) string {
return android.BazelToolchainVars(config, exportedVars) return android.BazelToolchainVars(config, exportedVars)
} }
func RustPath(ctx android.PathContext, file string) android.SourcePath {
type rustToolKey string
key := android.NewCustomOnceKey(rustToolKey(file))
return ctx.Config().OnceSourcePath(key, func() android.SourcePath {
return rustPath(ctx).Join(ctx, file)
})
}
var rustPathKey = android.NewOnceKey("clangPath")
func rustPath(ctx android.PathContext) android.SourcePath {
return ctx.Config().OnceSourcePath(rustPathKey, func() android.SourcePath {
rustBase := RustDefaultBase
if override := ctx.Config().Getenv("RUST_PREBUILTS_BASE"); override != "" {
rustBase = override
}
rustVersion := RustDefaultVersion
if override := ctx.Config().Getenv("RUST_DEFAULT_VERSION"); override != "" {
rustVersion = override
}
return android.PathForSource(ctx, rustBase, HostPrebuiltTag(ctx.Config()), rustVersion)
})
}

View File

@@ -17,7 +17,6 @@ package rust
import ( import (
"github.com/google/blueprint" "github.com/google/blueprint"
"android/soong/android"
"android/soong/cc" "android/soong/cc"
) )
@@ -71,10 +70,7 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags
// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency. // no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() { if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() {
profiler_builtins := ctx.GetDirectDepWithTag(ProfilerBuiltins, rlibDepTag).(*Module) profiler_builtins := ctx.GetDirectDepWithTag(ProfilerBuiltins, rlibDepTag).(*Module)
deps.Rlibs = android.AddDirectToDepSet[RustLibrary](deps.Rlibs, RustLibrary{ deps.RLibs = append(deps.RLibs, RustLibrary{Path: profiler_builtins.OutputFile().Path(), CrateName: profiler_builtins.CrateName()})
Path: profiler_builtins.OutputFile().Path(),
CrateName: profiler_builtins.CrateName(),
})
} }
if cc.EnableContinuousCoverage(ctx) { if cc.EnableContinuousCoverage(ctx) {

View File

@@ -55,27 +55,27 @@ func TestCoverageFlags(t *testing.T) {
libbarNoCov := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc") libbarNoCov := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc")
fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc") fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc") buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
libfooCovLink := ctx.ModuleForTests("libfoo_cov", "android_arm64_armv8-a_dylib_cov").Rule("rustc") libfooCovLink := ctx.ModuleForTests("libfoo_cov", "android_arm64_armv8-a_dylib_cov").Rule("rustLink")
libbarNoCovLink := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc") libbarNoCovLink := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustLink")
fizzCovLink := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc") fizzCovLink := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustLink")
buzzNoCovLink := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc") buzzNoCovLink := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustLink")
rustcCoverageFlags := []string{"-C instrument-coverage", " -g "} rustcCoverageFlags := []string{"-C instrument-coverage", " -g "}
for _, flag := range rustcCoverageFlags { for _, flag := range rustcCoverageFlags {
missingErrorStr := "missing rustc flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v" missingErrorStr := "missing rustc flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
containsErrorStr := "contains rustc flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v" containsErrorStr := "contains rustc flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
if !strings.Contains(fizzCov.RuleParams.Command, flag) { if !strings.Contains(fizzCov.Args["rustcFlags"], flag) {
t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCov.RuleParams.Command) t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCov.Args["rustcFlags"])
} }
if !strings.Contains(libfooCov.RuleParams.Command, flag) { if !strings.Contains(libfooCov.Args["rustcFlags"], flag) {
t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCov.RuleParams.Command) t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCov.Args["rustcFlags"])
} }
if strings.Contains(buzzNoCov.RuleParams.Command, flag) { if strings.Contains(buzzNoCov.Args["rustcFlags"], flag) {
t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCov.RuleParams.Command) t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCov.Args["rustcFlags"])
} }
if strings.Contains(libbarNoCov.RuleParams.Command, flag) { if strings.Contains(libbarNoCov.Args["rustcFlags"], flag) {
t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCov.RuleParams.Command) t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCov.Args["rustcFlags"])
} }
} }
@@ -84,17 +84,17 @@ func TestCoverageFlags(t *testing.T) {
missingErrorStr := "missing rust linker flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v" missingErrorStr := "missing rust linker flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
containsErrorStr := "contains rust linker flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v" containsErrorStr := "contains rust linker flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
if !strings.Contains(fizzCovLink.RuleParams.Command, flag) { if !strings.Contains(fizzCovLink.Args["linkFlags"], flag) {
t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCovLink.RuleParams.Command) t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCovLink.Args["linkFlags"])
} }
if !strings.Contains(libfooCovLink.RuleParams.Command, flag) { if !strings.Contains(libfooCovLink.Args["linkFlags"], flag) {
t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCovLink.RuleParams.Command) t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCovLink.Args["linkFlags"])
} }
if strings.Contains(buzzNoCovLink.RuleParams.Command, flag) { if strings.Contains(buzzNoCovLink.Args["linkFlags"], flag) {
t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCovLink.RuleParams.Command) t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCovLink.Args["linkFlags"])
} }
if strings.Contains(libbarNoCovLink.RuleParams.Command, flag) { if strings.Contains(libbarNoCovLink.Args["linkFlags"], flag) {
t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCovLink.RuleParams.Command) t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCovLink.Args["linkFlags"])
} }
} }
@@ -107,8 +107,8 @@ func TestCoverageDeps(t *testing.T) {
srcs: ["foo.rs"], srcs: ["foo.rs"],
}`) }`)
fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustc") fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustLink")
if !strings.Contains(fizz.RuleParams.Command, "libprofile-clang-extras.a") { if !strings.Contains(fizz.Args["linkFlags"], "libprofile-clang-extras.a") {
t.Fatalf("missing expected coverage 'libprofile-clang-extras' dependency in linkFlags: %#v", fizz.RuleParams.Command) t.Fatalf("missing expected coverage 'libprofile-clang-extras' dependency in linkFlags: %#v", fizz.Args["linkFlags"])
} }
} }

View File

@@ -51,23 +51,23 @@ func TestRustFuzz(t *testing.T) {
// Check that compiler flags are set appropriately . // Check that compiler flags are set appropriately .
fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc") fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc")
if !strings.Contains(fuzz_libtest.RuleParams.Command, "-C passes='sancov-module'") || if !strings.Contains(fuzz_libtest.Args["rustcFlags"], "-C passes='sancov-module'") ||
!strings.Contains(fuzz_libtest.RuleParams.Command, "--cfg fuzzing") { !strings.Contains(fuzz_libtest.Args["rustcFlags"], "--cfg fuzzing") {
t.Errorf("rust_fuzz module does not contain the expected flags (sancov-module, cfg fuzzing).") t.Errorf("rust_fuzz module does not contain the expected flags (sancov-module, cfg fuzzing).")
} }
// Check that host modules support fuzzing. // Check that host modules support fuzzing.
host_fuzzer := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc") host_fuzzer := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc")
if !strings.Contains(host_fuzzer.RuleParams.Command, "-C passes='sancov-module'") || if !strings.Contains(host_fuzzer.Args["rustcFlags"], "-C passes='sancov-module'") ||
!strings.Contains(host_fuzzer.RuleParams.Command, "--cfg fuzzing") { !strings.Contains(host_fuzzer.Args["rustcFlags"], "--cfg fuzzing") {
t.Errorf("rust_fuzz_host module does not contain the expected flags (sancov-module, cfg fuzzing).") t.Errorf("rust_fuzz_host module does not contain the expected flags (sancov-module, cfg fuzzing).")
} }
// Check that dependencies have 'fuzzer' variants produced for them as well. // Check that dependencies have 'fuzzer' variants produced for them as well.
libtest_fuzzer := ctx.ModuleForTests("libtest_fuzzing", "android_arm64_armv8-a_rlib_rlib-std_fuzzer").Rule("rustc") libtest_fuzzer := ctx.ModuleForTests("libtest_fuzzing", "android_arm64_armv8-a_rlib_rlib-std_fuzzer").Output("libtest_fuzzing.rlib")
if !strings.Contains(libtest_fuzzer.RuleParams.Command, "-C passes='sancov-module'") || if !strings.Contains(libtest_fuzzer.Args["rustcFlags"], "-C passes='sancov-module'") ||
!strings.Contains(libtest_fuzzer.RuleParams.Command, "--cfg fuzzing") { !strings.Contains(libtest_fuzzer.Args["rustcFlags"], "--cfg fuzzing") {
t.Errorf("rust_fuzz dependent library does not contain the expected flags (sancov-module, cfg fuzzing). command: %q", libtest_fuzzer.RuleParams.Command) t.Errorf("rust_fuzz dependent library does not contain the expected flags (sancov-module, cfg fuzzing).")
} }
} }

View File

@@ -59,36 +59,36 @@ func TestImageVndkCfgFlag(t *testing.T) {
vendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_static").Rule("rustc") vendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_static").Rule("rustc")
if !strings.Contains(vendor.RuleParams.Command, "--cfg 'android_vndk'") { if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") {
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.RuleParams.Command) t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
} }
if !strings.Contains(vendor.RuleParams.Command, "--cfg 'android_vendor'") { if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vendor'") {
t.Errorf("missing \"--cfg 'android_vendor'\" for libfoo vendor variant, rustcFlags: %#v", vendor.RuleParams.Command) t.Errorf("missing \"--cfg 'android_vendor'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
} }
if strings.Contains(vendor.RuleParams.Command, "--cfg 'android_product'") { if strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_product'") {
t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.RuleParams.Command) t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
} }
product := ctx.ModuleForTests("libfoo", "android_product.29_arm64_armv8-a_static").Rule("rustc") product := ctx.ModuleForTests("libfoo", "android_product.29_arm64_armv8-a_static").Rule("rustc")
if !strings.Contains(product.RuleParams.Command, "--cfg 'android_vndk'") { if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") {
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.RuleParams.Command) t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
} }
if strings.Contains(product.RuleParams.Command, "--cfg 'android_vendor'") { if strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vendor'") {
t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo product variant, rustcFlags: %#v", product.RuleParams.Command) t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
} }
if !strings.Contains(product.RuleParams.Command, "--cfg 'android_product'") { if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_product'") {
t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.RuleParams.Command) t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
} }
system := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Rule("rustc") system := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Rule("rustc")
if strings.Contains(system.RuleParams.Command, "--cfg 'android_vndk'") { if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vndk'") {
t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.RuleParams.Command) t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"])
} }
if strings.Contains(system.RuleParams.Command, "--cfg 'android_vendor'") { if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vendor'") {
t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo system variant, rustcFlags: %#v", system.RuleParams.Command) t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"])
} }
if strings.Contains(system.RuleParams.Command, "--cfg 'android_product'") { if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_product'") {
t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo system variant, rustcFlags: %#v", product.RuleParams.Command) t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo system variant, rustcFlags: %#v", product.Args["rustcFlags"])
} }
} }

View File

@@ -485,28 +485,11 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) F
return flags return flags
} }
func (library *libraryDecorator) compilationSourcesAndData(ctx ModuleContext) android.Paths {
var extraSrcs android.Paths
if library.rlib() {
extraSrcs = android.PathsForModuleSrc(ctx, library.Properties.Rlib.Srcs)
} else if library.dylib() {
extraSrcs = android.PathsForModuleSrc(ctx, library.Properties.Dylib.Srcs)
} else if library.static() {
extraSrcs = android.PathsForModuleSrc(ctx, library.Properties.Static.Srcs)
} else if library.shared() {
extraSrcs = android.PathsForModuleSrc(ctx, library.Properties.Shared.Srcs)
}
return android.Concat(
library.baseCompiler.compilationSourcesAndData(ctx),
extraSrcs,
)
}
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
var outputFile android.ModuleOutPath var outputFile android.ModuleOutPath
var ret buildOutput var ret buildOutput
var fileName string var fileName string
crateRootPath := library.crateRootPath(ctx, deps) srcPath := library.srcPath(ctx, deps)
if library.sourceProvider != nil { if library.sourceProvider != nil {
deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...) deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
@@ -542,6 +525,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
if library.dylib() { if library.dylib() {
// We need prefer-dynamic for now to avoid linking in the static stdlib. See: // We need prefer-dynamic for now to avoid linking in the static stdlib. See:
@@ -552,13 +536,13 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
// Call the appropriate builder for this library type // Call the appropriate builder for this library type
if library.rlib() { if library.rlib() {
ret.kytheFile = TransformSrctoRlib(ctx, library, crateRootPath, deps, flags, outputFile).kytheFile ret.kytheFile = TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile).kytheFile
} else if library.dylib() { } else if library.dylib() {
ret.kytheFile = TransformSrctoDylib(ctx, library, crateRootPath, deps, flags, outputFile).kytheFile ret.kytheFile = TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile).kytheFile
} else if library.static() { } else if library.static() {
ret.kytheFile = TransformSrctoStatic(ctx, library, crateRootPath, deps, flags, outputFile).kytheFile ret.kytheFile = TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile).kytheFile
} else if library.shared() { } else if library.shared() {
ret.kytheFile = TransformSrctoShared(ctx, library, crateRootPath, deps, flags, outputFile).kytheFile ret.kytheFile = TransformSrctoShared(ctx, srcPath, deps, flags, outputFile).kytheFile
} }
if library.rlib() || library.dylib() { if library.rlib() || library.dylib() {
@@ -601,15 +585,13 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
return ret return ret
} }
func (library *libraryDecorator) crateRootPath(ctx ModuleContext, _ PathDeps) android.Path { func (library *libraryDecorator) srcPath(ctx ModuleContext, _ PathDeps) android.Path {
if library.sourceProvider != nil { if library.sourceProvider != nil {
// Assume the first source from the source provider is the library entry point. // Assume the first source from the source provider is the library entry point.
return library.sourceProvider.Srcs()[0] return library.sourceProvider.Srcs()[0]
} else if library.baseCompiler.Properties.Crate_root == nil { } else {
path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs) path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
return path return path
} else {
return android.PathForModuleSrc(ctx, *library.baseCompiler.Properties.Crate_root)
} }
} }
@@ -624,7 +606,7 @@ func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
return android.OptionalPath{} return android.OptionalPath{}
} }
return android.OptionalPathForPath(Rustdoc(ctx, library.crateRootPath(ctx, deps), return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps),
deps, flags)) deps, flags))
} }

View File

@@ -48,23 +48,23 @@ func TestLibraryVariants(t *testing.T) {
staticCrateType := "staticlib" staticCrateType := "staticlib"
// Test crate type for rlib is correct. // Test crate type for rlib is correct.
if !strings.Contains(libfooRlib.RuleParams.Command, "crate-type="+rlibCrateType) { if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooRlib.RuleParams.Command) t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooRlib.Args["rustcFlags"])
} }
// Test crate type for dylib is correct. // Test crate type for dylib is correct.
if !strings.Contains(libfooDylib.RuleParams.Command, "crate-type="+dylibCrateType) { if !strings.Contains(libfooDylib.Args["rustcFlags"], "crate-type="+dylibCrateType) {
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", dylibCrateType, libfooDylib.RuleParams.Command) t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", dylibCrateType, libfooDylib.Args["rustcFlags"])
} }
// Test crate type for C static libraries is correct. // Test crate type for C static libraries is correct.
if !strings.Contains(libfooStatic.RuleParams.Command, "crate-type="+staticCrateType) { if !strings.Contains(libfooStatic.Args["rustcFlags"], "crate-type="+staticCrateType) {
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", staticCrateType, libfooStatic.RuleParams.Command) t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", staticCrateType, libfooStatic.Args["rustcFlags"])
} }
// Test crate type for C shared libraries is correct. // Test crate type for C shared libraries is correct.
if !strings.Contains(libfooShared.RuleParams.Command, "crate-type="+sharedCrateType) { if !strings.Contains(libfooShared.Args["rustcFlags"], "crate-type="+sharedCrateType) {
t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.RuleParams.Command) t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.Args["rustcFlags"])
} }
} }
@@ -78,10 +78,10 @@ func TestDylibPreferDynamic(t *testing.T) {
crate_name: "foo", crate_name: "foo",
}`) }`)
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Description("rustc") libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
if !strings.Contains(libfooDylib.RuleParams.Command, "prefer-dynamic") { if !strings.Contains(libfooDylib.Args["rustcFlags"], "prefer-dynamic") {
t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.RuleParams.Command) t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
} }
} }
@@ -94,10 +94,10 @@ func TestAndroidDylib(t *testing.T) {
crate_name: "foo", crate_name: "foo",
}`) }`)
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Description("rustc") libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
if !strings.Contains(libfooDylib.RuleParams.Command, "--cfg 'android_dylib'") { if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") {
t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.RuleParams.Command) t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
} }
} }
@@ -148,10 +148,10 @@ func TestSharedLibrary(t *testing.T) {
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared") libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared")
libfooOutput := libfoo.Rule("rustc") libfooOutput := libfoo.Rule("rustLink")
if !strings.Contains(libfooOutput.RuleParams.Command, "-Wl,-soname=libfoo.so") { if !strings.Contains(libfooOutput.Args["linkFlags"], "-Wl,-soname=libfoo.so") {
t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v", t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v",
libfooOutput.RuleParams.Command) libfooOutput.Args["linkFlags"])
} }
if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkDylibs) { if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkDylibs) {
@@ -237,21 +237,19 @@ func TestNativeDependencyOfRlib(t *testing.T) {
// The build system assumes the cc deps will be at the final linkage (either a shared library or binary) // The build system assumes the cc deps will be at the final linkage (either a shared library or binary)
// Hence, these flags are no-op // Hence, these flags are no-op
// TODO: We could consider removing these flags // TODO: We could consider removing these flags
expectedSharedFlag := "-L out/soong/.intermediates/shared_cc_dep/android_arm64_armv8-a_shared"
expectedStaticFlag := "-L out/soong/.intermediates/static_cc_dep/android_arm64_armv8-a_static"
for _, module := range modules { for _, module := range modules {
if !strings.Contains(module.Rule("rustc").RuleParams.Command, expectedSharedFlag) { if !strings.Contains(module.Rule("rustc").Args["libFlags"],
"-L out/soong/.intermediates/shared_cc_dep/android_arm64_armv8-a_shared/") {
t.Errorf( t.Errorf(
"expected to find shared library linkdir flag %q, rustcFlags: %#v", "missing -L flag for shared_cc_dep, rustcFlags: %#v",
expectedSharedFlag, rustRlibRlibStd.Rule("rustc").Args["libFlags"],
rustRlibRlibStd.Rule("rustc").RuleParams.Command,
) )
} }
if !strings.Contains(module.Rule("rustc").RuleParams.Command, expectedStaticFlag) { if !strings.Contains(module.Rule("rustc").Args["libFlags"],
"-L out/soong/.intermediates/static_cc_dep/android_arm64_armv8-a_static/") {
t.Errorf( t.Errorf(
"expected to find static library linkdir flag %q, rustcFlags: %#v", "missing -L flag for static_cc_dep, rustcFlags: %#v",
expectedStaticFlag, rustRlibRlibStd.Rule("rustc").Args["libFlags"],
rustRlibRlibStd.Rule("rustc").RuleParams.Command,
) )
} }
} }

View File

@@ -146,10 +146,7 @@ func (prebuilt *prebuiltLibraryDecorator) compilerProps() []interface{} {
} }
func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
deps.linkDirs = append(deps.linkDirs, android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs)...) prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
prebuilt.flagExporter.exportLinkDirs(deps.linkDirs...)
prebuilt.flagExporter.exportLinkObjects(deps.linkObjects...)
prebuilt.flagExporter.exportLibDeps(deps.LibDeps...)
prebuilt.flagExporter.setProvider(ctx) prebuilt.flagExporter.setProvider(ctx)
srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs()) srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())
@@ -206,7 +203,7 @@ func (prebuilt *prebuiltProcMacroDecorator) compilerProps() []interface{} {
} }
func (prebuilt *prebuiltProcMacroDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { func (prebuilt *prebuiltProcMacroDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs)...) prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
prebuilt.flagExporter.setProvider(ctx) prebuilt.flagExporter.setProvider(ctx)
srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs()) srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())

View File

@@ -80,7 +80,7 @@ func (procMacro *procMacroDecorator) compile(ctx ModuleContext, flags Flags, dep
outputFile := android.PathForModuleOut(ctx, fileName) outputFile := android.PathForModuleOut(ctx, fileName)
srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs) srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
ret := TransformSrctoProcMacro(ctx, procMacro, srcPath, deps, flags, outputFile) ret := TransformSrctoProcMacro(ctx, srcPath, deps, flags, outputFile)
procMacro.baseCompiler.unstrippedOutputFile = outputFile procMacro.baseCompiler.unstrippedOutputFile = outputFile
return ret return ret
} }

View File

@@ -30,7 +30,7 @@ func TestRustProcMacro(t *testing.T) {
libprocmacro := ctx.ModuleForTests("libprocmacro", "linux_glibc_x86_64").Rule("rustc") libprocmacro := ctx.ModuleForTests("libprocmacro", "linux_glibc_x86_64").Rule("rustc")
if !strings.Contains(libprocmacro.RuleParams.Command, "--extern proc_macro") { if !strings.Contains(libprocmacro.Args["rustcFlags"], "--extern proc_macro") {
t.Errorf("--extern proc_macro flag not being passed to rustc for proc macro %#v", libprocmacro.RuleParams.Command) t.Errorf("--extern proc_macro flag not being passed to rustc for proc macro %#v", libprocmacro.Args["rustcFlags"])
} }
} }

View File

@@ -438,18 +438,12 @@ type Deps struct {
} }
type PathDeps struct { type PathDeps struct {
Dylibs *android.DepSet[RustLibrary] DyLibs RustLibraries
Rlibs *android.DepSet[RustLibrary] RLibs RustLibraries
ProcMacros *android.DepSet[RustLibrary]
LibDeps android.Paths LibDeps android.Paths
WholeStaticLibs android.Paths WholeStaticLibs android.Paths
ProcMacros RustLibraries
AfdoProfiles android.Paths AfdoProfiles android.Paths
// These paths are files needed to run the build tools and will be located under
// __SBOX_SANDBOX_DIR__/tools/...
BuildToolDeps android.Paths
// These paths are files needed to run the build tools and will be located under
// __SBOX_SANDBOX_DIR__/...
BuildToolSrcDeps android.Paths
// depFlags and depLinkFlags are rustc and linker (clang) flags. // depFlags and depLinkFlags are rustc and linker (clang) flags.
depFlags []string depFlags []string
@@ -457,7 +451,7 @@ type PathDeps struct {
// linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker. // linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker.
// Both of these are exported and propagate to dependencies. // Both of these are exported and propagate to dependencies.
linkDirs android.Paths linkDirs []string
linkObjects android.Paths linkObjects android.Paths
// Used by bindgen modules which call clang // Used by bindgen modules which call clang
@@ -491,8 +485,6 @@ type compiler interface {
compilerDeps(ctx DepsContext, deps Deps) Deps compilerDeps(ctx DepsContext, deps Deps) Deps
crateName() string crateName() string
rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath
crateRoot(ctx ModuleContext) android.Path
compilationSourcesAndData(ctx ModuleContext) android.Paths
// Output directory in which source-generated code from dependencies is // Output directory in which source-generated code from dependencies is
// copied. This is equivalent to Cargo's OUT_DIR variable. // copied. This is equivalent to Cargo's OUT_DIR variable.
@@ -522,7 +514,7 @@ type compiler interface {
} }
type exportedFlagsProducer interface { type exportedFlagsProducer interface {
exportLinkDirs(...android.Path) exportLinkDirs(...string)
exportLinkObjects(...android.Path) exportLinkObjects(...android.Path)
} }
@@ -531,13 +523,13 @@ type xref interface {
} }
type flagExporter struct { type flagExporter struct {
linkDirs android.Paths linkDirs []string
linkObjects android.Paths linkObjects android.Paths
libDeps android.Paths libDeps android.Paths
} }
func (flagExporter *flagExporter) exportLinkDirs(dirs ...android.Path) { func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
flagExporter.linkDirs = android.FirstUniquePaths(append(flagExporter.linkDirs, dirs...)) flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
} }
func (flagExporter *flagExporter) exportLinkObjects(flags ...android.Path) { func (flagExporter *flagExporter) exportLinkObjects(flags ...android.Path) {
@@ -564,7 +556,7 @@ func NewFlagExporter() *flagExporter {
type FlagExporterInfo struct { type FlagExporterInfo struct {
Flags []string Flags []string
LinkDirs android.Paths LinkDirs []string // TODO: this should be android.Paths
LinkObjects android.Paths LinkObjects android.Paths
LibDeps android.Paths LibDeps android.Paths
} }
@@ -934,14 +926,6 @@ func (mod *Module) ccToolchain(ctx android.BaseModuleContext) cc_config.Toolchai
func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
} }
type RustInfo struct {
TransitiveRlibs *android.DepSet[RustLibrary]
TransitiveDylibs *android.DepSet[RustLibrary]
TransitiveProcMacros *android.DepSet[RustLibrary]
}
var RustInfoProvider = blueprint.NewProvider(RustInfo{})
func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
ctx := &moduleContext{ ctx := &moduleContext{
ModuleContext: actx, ModuleContext: actx,
@@ -1051,12 +1035,6 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
ctx.Phony("rust", ctx.RustModule().OutputFile().Path()) ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
} }
ctx.SetProvider(RustInfoProvider, RustInfo{
TransitiveRlibs: deps.Rlibs,
TransitiveDylibs: deps.Dylibs,
TransitiveProcMacros: deps.ProcMacros,
})
} }
func (mod *Module) deps(ctx DepsContext) Deps { func (mod *Module) deps(ctx DepsContext) Deps {
@@ -1115,7 +1093,6 @@ func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
var _ android.LicenseAnnotationsDependencyTag = dependencyTag{} var _ android.LicenseAnnotationsDependencyTag = dependencyTag{}
var ( var (
buildToolDepTag = dependencyTag{name: "buildToolTag"}
customBindgenDepTag = dependencyTag{name: "customBindgenTag"} customBindgenDepTag = dependencyTag{name: "customBindgenTag"}
rlibDepTag = dependencyTag{name: "rlibTag", library: true} rlibDepTag = dependencyTag{name: "rlibTag", library: true}
dylibDepTag = dependencyTag{name: "dylib", library: true, dynamic: true} dylibDepTag = dependencyTag{name: "dylib", library: true, dynamic: true}
@@ -1249,9 +1226,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var transitiveAndroidMkSharedLibs []*android.DepSet[string] var transitiveAndroidMkSharedLibs []*android.DepSet[string]
var directAndroidMkSharedLibs []string var directAndroidMkSharedLibs []string
transitiveRlibs := android.NewDepSetBuilder[RustLibrary](android.PREORDER)
transitiveDylibs := android.NewDepSetBuilder[RustLibrary](android.PREORDER)
transitiveProcMacros := android.NewDepSetBuilder[RustLibrary](android.PREORDER)
ctx.VisitDirectDeps(func(dep android.Module) { ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep) depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep) depTag := ctx.OtherModuleDependencyTag(dep)
@@ -1264,17 +1239,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
return return
} }
rustInfo := ctx.OtherModuleProvider(dep, RustInfoProvider).(RustInfo)
if rustInfo.TransitiveDylibs != nil {
transitiveDylibs.Transitive(rustInfo.TransitiveDylibs)
}
if rustInfo.TransitiveRlibs != nil {
transitiveRlibs.Transitive(rustInfo.TransitiveRlibs)
}
if rustInfo.TransitiveProcMacros != nil {
transitiveProcMacros.Transitive(rustInfo.TransitiveProcMacros)
}
if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() { if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() {
//Handle Rust Modules //Handle Rust Modules
makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName) makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName)
@@ -1289,12 +1253,9 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
directDylibDeps = append(directDylibDeps, rustDep) directDylibDeps = append(directDylibDeps, rustDep)
mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName) mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName)
mod.Properties.SnapshotDylibs = append(mod.Properties.SnapshotDylibs, cc.BaseLibName(depName)) mod.Properties.SnapshotDylibs = append(mod.Properties.SnapshotDylibs, cc.BaseLibName(depName))
transitiveDylibs.Direct(RustLibrary{
Path: rustDep.UnstrippedOutputFile(),
CrateName: rustDep.CrateName(),
})
case rlibDepTag: case rlibDepTag:
rlib, ok := rustDep.compiler.(libraryInterface) rlib, ok := rustDep.compiler.(libraryInterface)
if !ok || !rlib.rlib() { if !ok || !rlib.rlib() {
ctx.ModuleErrorf("mod %q not an rlib library", makeLibName) ctx.ModuleErrorf("mod %q not an rlib library", makeLibName)
@@ -1303,18 +1264,10 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
directRlibDeps = append(directRlibDeps, rustDep) directRlibDeps = append(directRlibDeps, rustDep)
mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName) mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName)
mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName)) mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName))
transitiveRlibs.Direct(RustLibrary{
Path: rustDep.UnstrippedOutputFile(),
CrateName: rustDep.CrateName(),
})
case procMacroDepTag: case procMacroDepTag:
directProcMacroDeps = append(directProcMacroDeps, rustDep) directProcMacroDeps = append(directProcMacroDeps, rustDep)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName) mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
transitiveProcMacros.Direct(RustLibrary{
Path: rustDep.UnstrippedOutputFile(),
CrateName: rustDep.CrateName(),
})
} }
transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs) transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs)
@@ -1350,8 +1303,9 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
linkFile := rustDep.UnstrippedOutputFile() linkFile := rustDep.UnstrippedOutputFile()
linkDir := linkPathFromFilePath(linkFile)
if lib, ok := mod.compiler.(exportedFlagsProducer); ok { if lib, ok := mod.compiler.(exportedFlagsProducer); ok {
lib.exportLinkDirs(linkFile.Dir()) lib.exportLinkDirs(linkDir)
} }
} }
@@ -1378,7 +1332,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
return return
} }
linkPath := linkObject.Path().Dir() linkPath := linkPathFromFilePath(linkObject.Path())
exportDep := false exportDep := false
switch { switch {
@@ -1432,7 +1386,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
} }
return return
} }
linkPath = linkObject.Path().Dir() linkPath = linkPathFromFilePath(linkObject.Path())
depPaths.linkDirs = append(depPaths.linkDirs, linkPath) depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...) depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...)
@@ -1467,16 +1421,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
} }
} else { } else {
switch { switch {
case depTag == buildToolDepTag:
buildTool := ctx.OtherModuleProvider(dep, android.PrebuiltBuildToolInfoProvider).(android.PrebuiltBuildToolInfo)
depPaths.BuildToolDeps = append(depPaths.BuildToolDeps, buildTool.Src)
depPaths.BuildToolDeps = append(depPaths.BuildToolDeps, buildTool.Deps...)
switch android.RemoveOptionalPrebuiltPrefix(dep.Name()) {
case "rustc":
// rustc expects the standard cc toolchain libraries (libdl, libm, libc, etc.)
// not to be under the __SBOX_SANDBOX_DIR__/ directory
depPaths.BuildToolSrcDeps = append(depPaths.BuildToolSrcDeps, buildTool.Deps...)
}
case depTag == cc.CrtBeginDepTag: case depTag == cc.CrtBeginDepTag:
depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, "")) depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, ""))
case depTag == cc.CrtEndDepTag: case depTag == cc.CrtEndDepTag:
@@ -1492,6 +1436,21 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
} }
}) })
mod.transitiveAndroidMkSharedLibs = android.NewDepSet[string](android.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs)
var rlibDepFiles RustLibraries
for _, dep := range directRlibDeps {
rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
}
var dylibDepFiles RustLibraries
for _, dep := range directDylibDeps {
dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
}
var procMacroDepFiles RustLibraries
for _, dep := range directProcMacroDeps {
procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
}
var libDepFiles android.Paths var libDepFiles android.Paths
for _, dep := range directStaticLibDeps { for _, dep := range directStaticLibDeps {
libDepFiles = append(libDepFiles, dep.OutputFile().Path()) libDepFiles = append(libDepFiles, dep.OutputFile().Path())
@@ -1515,22 +1474,20 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
srcProviderDepFiles = append(srcProviderDepFiles, srcs...) srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
} }
depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
depPaths.LibDeps = append(depPaths.LibDeps, libDepFiles...) depPaths.LibDeps = append(depPaths.LibDeps, libDepFiles...)
depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...)
depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...) depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...)
// Dedup exported flags from dependencies // Dedup exported flags from dependencies
depPaths.linkDirs = android.FirstUniquePaths(depPaths.linkDirs) depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
depPaths.linkObjects = android.FirstUniquePaths(depPaths.linkObjects) depPaths.linkObjects = android.FirstUniquePaths(depPaths.linkObjects)
depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags) depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags) depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths) depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths) depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths)
depPaths.Rlibs = transitiveRlibs.Build()
depPaths.Dylibs = transitiveDylibs.Build()
depPaths.ProcMacros = transitiveProcMacros.Build()
mod.transitiveAndroidMkSharedLibs = android.NewDepSet[string](android.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs)
return depPaths return depPaths
} }
@@ -1553,6 +1510,10 @@ func (mod *Module) InstallInRecovery() bool {
return mod.InRecovery() return mod.InRecovery()
} }
func linkPathFromFilePath(filepath android.Path) string {
return strings.Split(filepath.String(), filepath.Base())[0]
}
// usePublicApi returns true if the rust variant should link against NDK (publicapi) // usePublicApi returns true if the rust variant should link against NDK (publicapi)
func (r *Module) usePublicApi() bool { func (r *Module) usePublicApi() bool {
return r.Device() && r.UseSdk() return r.Device() && r.UseSdk()
@@ -1595,8 +1556,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage}) blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage})
} }
ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "rustc")
// rlibs // rlibs
rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation}) rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation})
for _, lib := range deps.Rlibs { for _, lib := range deps.Rlibs {

View File

@@ -15,17 +15,14 @@
package rust package rust
import ( import (
"fmt"
"os" "os"
"runtime" "runtime"
"strings" "strings"
"testing" "testing"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
"google.golang.org/protobuf/encoding/prototext"
"android/soong/android" "android/soong/android"
"android/soong/cmd/sbox/sbox_proto"
"android/soong/genrule" "android/soong/genrule"
) )
@@ -67,14 +64,11 @@ var rustMockedFiles = android.MockFS{
// testRust returns a TestContext in which a basic environment has been setup. // testRust returns a TestContext in which a basic environment has been setup.
// This environment contains a few mocked files. See rustMockedFiles for the list of these files. // This environment contains a few mocked files. See rustMockedFiles for the list of these files.
func testRust(t *testing.T, bp string, preparers ...android.FixturePreparer) *android.TestContext { func testRust(t *testing.T, bp string) *android.TestContext {
skipTestIfOsNotSupported(t) skipTestIfOsNotSupported(t)
result := android.GroupFixturePreparers( result := android.GroupFixturePreparers(
prepareForRustTest, prepareForRustTest,
rustMockedFiles.AddToFixture(), rustMockedFiles.AddToFixture(),
android.GroupFixturePreparers(
preparers...,
),
). ).
RunTestWithBp(t, bp) RunTestWithBp(t, bp)
return result.TestContext return result.TestContext
@@ -208,11 +202,11 @@ func skipTestIfOsNotSupported(t *testing.T) {
// Test that we can extract the link path from a lib path. // Test that we can extract the link path from a lib path.
func TestLinkPathFromFilePath(t *testing.T) { func TestLinkPathFromFilePath(t *testing.T) {
barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so") barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
libName := barPath.Dir() libName := linkPathFromFilePath(barPath)
expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared" expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/"
if libName.String() != expectedResult { if libName != expectedResult {
t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName.String()) t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName)
} }
} }
@@ -262,7 +256,7 @@ func TestDepsTracking(t *testing.T) {
`) `)
module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module) module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
rustc := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc") rustc := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
rustLink := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc") rustLink := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustLink")
// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up. // Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
if !android.InList("librlib.rlib-std", module.Properties.AndroidMkRlibs) { if !android.InList("librlib.rlib-std", module.Properties.AndroidMkRlibs) {
@@ -281,16 +275,16 @@ func TestDepsTracking(t *testing.T) {
t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)") t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)")
} }
if !strings.Contains(rustc.RuleParams.Command, "-lstatic=wholestatic") { if !strings.Contains(rustc.Args["rustcFlags"], "-lstatic=wholestatic") {
t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.RuleParams.Command) t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.Args["rustcFlags"])
} }
if !strings.Contains(rustLink.RuleParams.Command, "cc_stubs_dep.so") { if !strings.Contains(rustLink.Args["linkFlags"], "cc_stubs_dep.so") {
t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustLink.RuleParams.Command) t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustLink.Args["linkFlags"])
} }
if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so") { if !android.SuffixInList(rustLink.OrderOnly.Strings(), "cc_stubs_dep.so") {
t.Errorf("shared cc dep not being passed as implicit to rustc %#v", rustLink.OrderOnly.Strings()) t.Errorf("shared cc dep not being passed as order-only to rustc %#v", rustLink.OrderOnly.Strings())
} }
if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so.toc") { if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so.toc") {
@@ -433,7 +427,7 @@ func TestProcMacroDeviceDeps(t *testing.T) {
`) `)
rustc := ctx.ModuleForTests("libpm", "linux_glibc_x86_64").Rule("rustc") rustc := ctx.ModuleForTests("libpm", "linux_glibc_x86_64").Rule("rustc")
if !strings.Contains(rustc.RuleParams.Command, "libbar/linux_glibc_x86_64") { if !strings.Contains(rustc.Args["libFlags"], "libbar/linux_glibc_x86_64") {
t.Errorf("Proc_macro is not using host variant of dependent modules.") t.Errorf("Proc_macro is not using host variant of dependent modules.")
} }
} }
@@ -486,396 +480,3 @@ func assertString(t *testing.T, got, expected string) {
t.Errorf("expected %q got %q", expected, got) t.Errorf("expected %q got %q", expected, got)
} }
} }
var (
sboxCompilationFiles = []string{
"out/soong/.intermediates/defaults/rust/libaddr2line/android_arm64_armv8-a_rlib/libaddr2line.rlib",
"out/soong/.intermediates/defaults/rust/libadler/android_arm64_armv8-a_rlib/libadler.rlib",
"out/soong/.intermediates/defaults/rust/liballoc/android_arm64_armv8-a_rlib/liballoc.rlib",
"out/soong/.intermediates/defaults/rust/libcfg_if/android_arm64_armv8-a_rlib/libcfg_if.rlib",
"out/soong/.intermediates/defaults/rust/libcompiler_builtins/android_arm64_armv8-a_rlib/libcompiler_builtins.rlib",
"out/soong/.intermediates/defaults/rust/libcore/android_arm64_armv8-a_rlib/libcore.rlib",
"out/soong/.intermediates/defaults/rust/libgimli/android_arm64_armv8-a_rlib/libgimli.rlib",
"out/soong/.intermediates/defaults/rust/libhashbrown/android_arm64_armv8-a_rlib/libhashbrown.rlib",
"out/soong/.intermediates/defaults/rust/liblibc/android_arm64_armv8-a_rlib/liblibc.rlib",
"out/soong/.intermediates/defaults/rust/libmemchr/android_arm64_armv8-a_rlib/libmemchr.rlib",
"out/soong/.intermediates/defaults/rust/libminiz_oxide/android_arm64_armv8-a_rlib/libminiz_oxide.rlib",
"out/soong/.intermediates/defaults/rust/libobject/android_arm64_armv8-a_rlib/libobject.rlib",
"out/soong/.intermediates/defaults/rust/libpanic_unwind/android_arm64_armv8-a_rlib/libpanic_unwind.rlib",
"out/soong/.intermediates/defaults/rust/librustc_demangle/android_arm64_armv8-a_rlib/librustc_demangle.rlib",
"out/soong/.intermediates/defaults/rust/librustc_std_workspace_alloc/android_arm64_armv8-a_rlib/librustc_std_workspace_alloc.rlib",
"out/soong/.intermediates/defaults/rust/librustc_std_workspace_core/android_arm64_armv8-a_rlib/librustc_std_workspace_core.rlib",
"out/soong/.intermediates/defaults/rust/libstd_detect/android_arm64_armv8-a_rlib/libstd_detect.rlib",
"build/soong/scripts/mkcratersp.py",
"defaults/rust/linux-x86/1.69.0/bin/rustc",
"defaults/rust/linux-x86/1.69.0/lib/libstd.so",
"defaults/rust/linux-x86/1.69.0/lib64/libc++.so.1",
}
sboxCompilationFilesWithCc = []string{
"defaults/cc/common",
"out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so",
"out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so.toc",
"out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so",
"out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so.toc",
"out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so",
"out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so.toc",
"out/soong/.intermediates/defaults/rust/liblog/android_arm64_armv8-a_shared/liblog.so",
"out/soong/.intermediates/defaults/rust/liblog/android_arm64_armv8-a_shared/liblog.so.toc",
}
)
func TestSandboxCompilation(t *testing.T) {
ctx := testRust(t, `
filegroup {
name: "libsrcs1",
srcs: ["src_filegroup1.rs"],
}
filegroup {
name: "libsrcs2",
srcs: ["src_filegroup2.rs"],
}
rust_library {
name: "libfizz_buzz",
crate_name:"fizz_buzz",
crate_root: "foo.rs",
srcs: [
"src_lib*.rs",
":libsrcs1",
":libsrcs2",
],
compile_data: [
"compile_data1.txt",
"compile_data2.txt",
],
dylib: {
srcs: ["dylib_only.rs"],
},
rlib: {
srcs: ["rlib_only.rs"],
},
}
rust_binary {
name: "fizz_buzz",
crate_name:"fizz_buzz",
crate_root: "foo.rs",
srcs: [
"src_lib*.rs",
":libsrcs1",
":libsrcs2",
],
}
rust_ffi {
name: "librust_ffi",
crate_name: "rust_ffi",
crate_root: "foo.rs",
static: {
srcs: ["static_only.rs"],
},
shared: {
srcs: ["shared_only.rs"],
},
srcs: ["src1.rs"],
}
cc_library_static {
name: "cc_dep_static",
}
cc_library_shared {
name: "cc_dep_shared",
}
rust_library {
name: "libfizz_buzz_cc_deps",
crate_name:"fizz_buzz",
crate_root: "foo.rs",
srcs: ["src*.rs"],
shared_libs: ["cc_dep_shared"],
static_libs: ["cc_dep_static"],
}
rust_library {
name: "libfizz_buzz_intermediate_cc_deps",
crate_name:"fizz_buzz",
crate_root: "foo.rs",
srcs: ["src*.rs"],
rustlibs: ["libfizz_buzz_cc_deps"],
}
rust_library {
name: "libfizz_buzz_transitive_cc_deps",
crate_name:"fizz_buzz",
crate_root: "foo.rs",
srcs: ["src*.rs"],
rustlibs: ["libfizz_buzz_intermediate_cc_deps"],
}
`,
android.FixtureMergeMockFs(android.MockFS{
"src_lib1.rs": nil,
"src_lib2.rs": nil,
"src_lib3.rs": nil,
"src_lib4.rs": nil,
"src_filegroup1.rs": nil,
"src_filegroup2.rs": nil,
"static_only.rs": nil,
"shared_only.rs": nil,
}),
)
testcases := []struct {
name string
moduleName string
variant string
rustcExpectedFilesToCopy []string
expectedFlags []string
}{
{
name: "rust_library (dylib)",
moduleName: "libfizz_buzz",
variant: "android_arm64_armv8-a_dylib",
rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, sboxCompilationFilesWithCc, []string{
"foo.rs",
"src_lib1.rs",
"src_lib2.rs",
"src_lib3.rs",
"src_lib4.rs",
"src_filegroup1.rs",
"src_filegroup2.rs",
"compile_data1.txt",
"compile_data2.txt",
"dylib_only.rs",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/out/src_filegroup1.rs",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/out/src_filegroup2.rs",
"out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so",
"out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so.toc",
"out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so",
"out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so.toc",
"out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so",
"out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so.toc",
"out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so",
"out/soong/.intermediates/defaults/cc/common/crtbegin_so/android_arm64_armv8-a/crtbegin_so.o",
"out/soong/.intermediates/defaults/cc/common/crtend_so/android_arm64_armv8-a/crtend_so.o",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so.clippy",
}),
expectedFlags: []string{
"-C linker=build/soong/scripts/mkcratersp.py",
"--emit link",
"-o __SBOX_SANDBOX_DIR__/out/libfizz_buzz.dylib.so.rsp",
"--emit dep-info=__SBOX_SANDBOX_DIR__/out/libfizz_buzz.dylib.so.d.raw",
"foo.rs", // this is the entry point
},
},
{
name: "rust_library (rlib dylib-std)",
moduleName: "libfizz_buzz",
variant: "android_arm64_armv8-a_rlib_dylib-std",
rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, []string{
"foo.rs",
"src_lib1.rs",
"src_lib2.rs",
"src_lib3.rs",
"src_lib4.rs",
"src_filegroup1.rs",
"src_filegroup2.rs",
"rlib_only.rs",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_dylib-std/out/src_filegroup1.rs",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_dylib-std/out/src_filegroup2.rs",
"out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so",
}),
expectedFlags: []string{
"--emit link",
"-o __SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib",
"--emit dep-info=__SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib.d.raw",
"foo.rs", // this is the entry point
},
},
{
name: "rust_library (rlib rlib-std)",
moduleName: "libfizz_buzz",
variant: "android_arm64_armv8-a_rlib_rlib-std",
rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, []string{
"foo.rs",
"src_lib1.rs",
"src_lib2.rs",
"src_lib3.rs",
"src_lib4.rs",
"src_filegroup1.rs",
"src_filegroup2.rs",
"rlib_only.rs",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/out/src_filegroup1.rs",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/out/src_filegroup2.rs",
"out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/libfizz_buzz.rlib.clippy",
"out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_rlib/libstd.rlib",
}),
expectedFlags: []string{
"--emit link",
"-o __SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib",
"--emit dep-info=__SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib.d.raw",
"foo.rs", // this is the entry point
},
},
{
name: "rust_binary",
moduleName: "fizz_buzz",
variant: "android_arm64_armv8-a",
rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, sboxCompilationFilesWithCc, []string{
"foo.rs",
"src_lib1.rs",
"src_lib2.rs",
"src_lib3.rs",
"src_lib4.rs",
"src_filegroup1.rs",
"src_filegroup2.rs",
"out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/out/src_filegroup1.rs",
"out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/out/src_filegroup2.rs",
"out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so",
"out/soong/.intermediates/defaults/cc/common/crtbegin_dynamic/android_arm64_armv8-a/crtbegin_dynamic.o",
"out/soong/.intermediates/defaults/cc/common/crtend_android/android_arm64_armv8-a/crtend_android.o",
"out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz.clippy",
}),
expectedFlags: []string{
"--emit link",
"-o __SBOX_SANDBOX_DIR__/out/fizz_buzz",
"--emit dep-info=__SBOX_SANDBOX_DIR__/out/fizz_buzz.d.raw",
"foo.rs", // this is the entry point
},
},
{
name: "rust_ffi static lib variant",
moduleName: "librust_ffi",
variant: "android_arm64_armv8-a_static",
rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, []string{
"foo.rs",
"src1.rs",
"static_only.rs",
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/librust_ffi.a.clippy",
"out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_rlib/libstd.rlib",
}),
expectedFlags: []string{
"--emit link",
"-o __SBOX_SANDBOX_DIR__/out/librust_ffi.a",
"--emit dep-info=__SBOX_SANDBOX_DIR__/out/librust_ffi.a.d.raw",
"foo.rs", // this is the entry point
},
},
{
name: "rust_ffi shared lib variant",
moduleName: "librust_ffi",
variant: "android_arm64_armv8-a_shared",
rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, sboxCompilationFilesWithCc, []string{
"foo.rs",
"src1.rs",
"shared_only.rs",
"out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so",
"out/soong/.intermediates/defaults/cc/common/crtbegin_so/android_arm64_armv8-a/crtbegin_so.o",
"out/soong/.intermediates/defaults/cc/common/crtend_so/android_arm64_armv8-a/crtend_so.o",
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so.clippy",
}),
expectedFlags: []string{
"--emit link",
"-o __SBOX_SANDBOX_DIR__/out/librust_ffi.so",
"--emit dep-info=__SBOX_SANDBOX_DIR__/out/librust_ffi.so.d.raw",
"foo.rs", // this is the entry point
},
},
{
name: "rust_library with cc deps (dylib)",
moduleName: "libfizz_buzz_cc_deps",
variant: "android_arm64_armv8-a_dylib",
rustcExpectedFilesToCopy: []string{
"out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
},
},
{
name: "rust_library with cc deps (rlib rlib-std)",
moduleName: "libfizz_buzz_cc_deps",
variant: "android_arm64_armv8-a_rlib_rlib-std",
rustcExpectedFilesToCopy: []string{
"out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
},
},
{
name: "rust_library with cc deps (rlib dylib-std)",
moduleName: "libfizz_buzz_cc_deps",
variant: "android_arm64_armv8-a_rlib_dylib-std",
rustcExpectedFilesToCopy: []string{
"out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
},
},
{
name: "rust_library with transitive cc deps (dylib)",
moduleName: "libfizz_buzz_transitive_cc_deps",
variant: "android_arm64_armv8-a_dylib",
rustcExpectedFilesToCopy: []string{
"out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
},
},
{
name: "rust_library with transitive cc deps (rlib rlib-std)",
moduleName: "libfizz_buzz_transitive_cc_deps",
variant: "android_arm64_armv8-a_rlib_rlib-std",
rustcExpectedFilesToCopy: []string{
"out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
},
},
{
name: "rust_library with transitive cc deps (rlib dylib-std)",
moduleName: "libfizz_buzz_transitive_cc_deps",
variant: "android_arm64_armv8-a_rlib_dylib-std",
rustcExpectedFilesToCopy: []string{
"out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
"out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
},
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
writeFile := ctx.ModuleForTests(tc.moduleName, tc.variant).Rule("unescapedWriteFile")
contents := writeFile.BuildParams.Args["content"]
manifestProto := sbox_proto.Manifest{}
err := prototext.Unmarshal([]byte(contents), &manifestProto)
if err != nil {
t.Errorf("expected no errors unmarshaling manifest proto; got %v", err)
}
if len(manifestProto.Commands) != 1 {
t.Errorf("expected 1 command; got %v", len(manifestProto.Commands))
}
// check that sandbox contains correct files
rustc := manifestProto.Commands[0]
actualFilesToCopy := []string{}
for _, copy := range rustc.CopyBefore {
actualFilesToCopy = append(actualFilesToCopy, copy.GetFrom())
}
_, expectedFilesNotCopied, _ := android.ListSetDifference(tc.rustcExpectedFilesToCopy, actualFilesToCopy)
if len(expectedFilesNotCopied) > 0 {
t.Errorf("did not copy expected files to sbox: %v;\n files copied: %v", expectedFilesNotCopied, actualFilesToCopy)
}
rustcCmd := proptools.String(rustc.Command)
for _, flag := range tc.expectedFlags {
android.AssertStringDoesContain(
t,
fmt.Sprintf(
"missing flag in rustc invocation; expected to find substring %q; got %q",
flag,
rustcCmd,
),
rustcCmd,
flag,
)
}
})
}
}

View File

@@ -35,7 +35,7 @@ func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNo
note_sync := "note_memtag_heap_sync" note_sync := "note_memtag_heap_sync"
found := None found := None
implicits := m.Rule("rustc").Implicits implicits := m.Rule("rustLink").Implicits
for _, lib := range implicits { for _, lib := range implicits {
if strings.Contains(lib.Rel(), note_async) { if strings.Contains(lib.Rel(), note_async) {
found = Async found = Async

View File

@@ -52,22 +52,6 @@ var PrepareForTestWithRustIncludeVndk = android.GroupFixturePreparers(
func GatherRequiredDepsForTest() string { func GatherRequiredDepsForTest() string {
bp := ` bp := `
prebuilt_build_tool {
name: "rustc",
src: "linux-x86/1.69.0/bin/rustc",
deps: [
"linux-x86/1.69.0/lib/libstd.so",
"linux-x86/1.69.0/lib64/libc++.so.1",
],
}
prebuilt_build_tool {
name: "clippy-driver",
src: "linux-x86/1.69.0/bin/clippy-driver",
}
prebuilt_build_tool {
name: "rustdoc",
src: "linux-x86/1.69.0/bin/rustdoc",
}
rust_prebuilt_library { rust_prebuilt_library {
name: "libstd", name: "libstd",
crate_name: "std", crate_name: "std",
@@ -79,25 +63,6 @@ func GatherRequiredDepsForTest() string {
}, },
host_supported: true, host_supported: true,
sysroot: true, sysroot: true,
rlibs: [
"libaddr2line",
"libadler",
"liballoc",
"libcfg_if",
"libcompiler_builtins",
"libcore",
"libgimli",
"libhashbrown",
"liblibc",
"libmemchr",
"libminiz_oxide",
"libobject",
"libpanic_unwind",
"librustc_demangle",
"librustc_std_workspace_alloc",
"librustc_std_workspace_core",
"libstd_detect",
],
} }
////////////////////////////// //////////////////////////////
// Device module requirements // Device module requirements
@@ -134,278 +99,6 @@ func GatherRequiredDepsForTest() string {
nocrt: true, nocrt: true,
system_shared_libs: [], system_shared_libs: [],
} }
rust_library_rlib {
name: "libaddr2line",
crate_name: "addr2line",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libadler",
crate_name: "adler",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "liballoc",
crate_name: "alloc",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libcfg_if",
crate_name: "cfg_if",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libcompiler_builtins",
crate_name: "compiler_builtins",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libcore",
crate_name: "core",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libgimli",
crate_name: "gimli",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libhashbrown",
crate_name: "hashbrown",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "liblibc",
crate_name: "libc",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libmemchr",
crate_name: "memchr",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libminiz_oxide",
crate_name: "miniz_oxide",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libobject",
crate_name: "object",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libpanic_unwind",
crate_name: "panic_unwind",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "librustc_demangle",
crate_name: "rustc_demangle",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "librustc_std_workspace_alloc",
crate_name: "rustc_std_workspace_alloc",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "librustc_std_workspace_core",
crate_name: "rustc_std_workspace_core",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library_rlib {
name: "libstd_detect",
crate_name: "std_detect",
enabled:true,
srcs: ["foo.rs"],
no_stdlibs: true,
product_available: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
rust_library { rust_library {
name: "libstd", name: "libstd",
crate_name: "std", crate_name: "std",
@@ -420,25 +113,6 @@ func GatherRequiredDepsForTest() string {
sysroot: true, sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"], apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29", min_sdk_version: "29",
rlibs: [
"libaddr2line",
"libadler",
"liballoc",
"libcfg_if",
"libcompiler_builtins",
"libcore",
"libgimli",
"libhashbrown",
"liblibc",
"libmemchr",
"libminiz_oxide",
"libobject",
"libpanic_unwind",
"librustc_demangle",
"librustc_std_workspace_alloc",
"librustc_std_workspace_core",
"libstd_detect",
],
} }
rust_library { rust_library {
name: "libtest", name: "libtest",

View File

@@ -18,12 +18,9 @@ package rust
import ( import (
"path" "path"
"path/filepath"
"android/soong/android" "android/soong/android"
"android/soong/rust/config" "android/soong/rust/config"
"github.com/google/blueprint/proptools"
) )
// This module is used to compile the rust toolchain libraries // This module is used to compile the rust toolchain libraries
@@ -36,15 +33,11 @@ func init() {
rustToolchainLibraryRlibFactory) rustToolchainLibraryRlibFactory)
android.RegisterModuleType("rust_toolchain_library_dylib", android.RegisterModuleType("rust_toolchain_library_dylib",
rustToolchainLibraryDylibFactory) rustToolchainLibraryDylibFactory)
android.RegisterModuleType("rust_toolchain_rustc_prebuilt",
rustToolchainRustcPrebuiltFactory)
} }
type toolchainLibraryProperties struct { type toolchainLibraryProperties struct {
// path to the toolchain crate root, relative to the top of the toolchain source // path to the toolchain source, relative to the top of the toolchain source
Toolchain_crate_root *string `android:"arch_variant"` Toolchain_src *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 { type toolchainLibraryDecorator struct {
@@ -89,21 +82,16 @@ func initToolchainLibrary(module *Module, library *libraryDecorator) android.Mod
func rustSetToolchainSource(ctx android.LoadHookContext) { func rustSetToolchainSource(ctx android.LoadHookContext) {
if toolchainLib, ok := ctx.Module().(*Module).compiler.(*toolchainLibraryDecorator); ok { if toolchainLib, ok := ctx.Module().(*Module).compiler.(*toolchainLibraryDecorator); ok {
prefix := filepath.Join("linux-x86", GetRustPrebuiltVersion(ctx)) prefix := "linux-x86/" + GetRustPrebuiltVersion(ctx)
versionedCrateRoot := path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_crate_root)) newSrcs := []string{path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_src))}
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 { type props struct {
Crate_root *string
Srcs []string Srcs []string
} }
p := &props{} p := &props{}
p.Crate_root = &versionedCrateRoot p.Srcs = newSrcs
p.Srcs = versionedSrcs
ctx.AppendProperties(p) ctx.AppendProperties(p)
} else { } else {
ctx.ModuleErrorf("Called rustSetToolchainSource on a non-Rust Module.") ctx.ModuleErrorf("Called rustSetToolchainSource on a non-Rust Module.")
} }
@@ -113,47 +101,3 @@ func rustSetToolchainSource(ctx android.LoadHookContext) {
func GetRustPrebuiltVersion(ctx android.LoadHookContext) string { func GetRustPrebuiltVersion(ctx android.LoadHookContext) string {
return ctx.AConfig().GetenvWithDefault("RUST_PREBUILTS_VERSION", config.RustDefaultVersion) 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
}

View File

@@ -1051,7 +1051,7 @@ func TestVendorSnapshotUse(t *testing.T) {
ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31") ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31")
// libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot // libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot
libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustc").RuleParams.Command libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustLink").Args["linkFlags"]
for _, input := range [][]string{ for _, input := range [][]string{
[]string{sharedVariant, "libvndk.vndk.30.arm64"}, []string{sharedVariant, "libvndk.vndk.30.arm64"},
[]string{staticVariant, "libvendor.vendor_static.30.arm64"}, []string{staticVariant, "libvendor.vendor_static.30.arm64"},
@@ -1119,7 +1119,7 @@ func TestVendorSnapshotUse(t *testing.T) {
t.Errorf("Unexpected rust rlib name in AndroidMk: %q, expected: %q\n", rustVendorBinMkDylibName, expectedRustVendorSnapshotName) t.Errorf("Unexpected rust rlib name in AndroidMk: %q, expected: %q\n", rustVendorBinMkDylibName, expectedRustVendorSnapshotName)
} }
binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustc").RuleParams.Command binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustLink").Args["linkFlags"]
libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"}) libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"})
if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) { if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v", t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",