Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acd75d2b authored by Andrew Walbran's avatar Andrew Walbran
Browse files

Generate wrapper lib.rs with one module per sysprop file.

This required moving to a SourceProvider for the Rust library. With the
previous approach only the first input file was being used.

Bug: 270547306
Test: Built libplatformproperties_rust, looked at output
Change-Id: I1070655abc071e099a42bc4be61cc080902e31c1
parent d3f500da
Loading
Loading
Loading
Loading
+50 −36
Original line number Diff line number Diff line
@@ -54,15 +54,13 @@ type syspropJavaGenRule struct {
}

type syspropRustGenRule struct {
	android.ModuleBase

	properties syspropGenProperties
	*rust.BaseSourceProvider

	genSrcs android.Paths
	properties rustLibraryProperties
}

var _ android.OutputFileProducer = (*syspropJavaGenRule)(nil)
var _ android.OutputFileProducer = (*syspropRustGenRule)(nil)
var _ rust.SourceProvider = (*syspropRustGenRule)(nil)

var (
	syspropJava = pctx.AndroidStaticRule("syspropJava",
@@ -144,7 +142,7 @@ func syspropJavaGenFactory() android.Module {

// syspropRustGenRule module generates rust source files containing generated rust APIs.
// It also depends on check api rule, so api check has to pass to use sysprop_library.
func (g *syspropRustGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
func (g *syspropRustGenRule) GenerateSource(ctx rust.ModuleContext, deps rust.PathDeps) android.Path {
	var checkApiFileTimeStamp android.WritablePath

	ctx.VisitDirectDeps(func(dep android.Module) {
@@ -153,25 +151,47 @@ func (g *syspropRustGenRule) GenerateAndroidBuildActions(ctx android.ModuleConte
		}
	})

	for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Srcs) {
		syspropDir := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcrust")
		outputDir := syspropDir.Join(ctx, "src")
		libPath := syspropDir.Join(ctx, "src", "lib.rs")
	outputDir := android.PathForModuleOut(ctx, "src")
	libFile := outputDir.Join(ctx, "lib.rs")
	g.BaseSourceProvider.OutputFiles = append(g.BaseSourceProvider.OutputFiles, libFile)
	libFileLines := []string{"//! Autogenerated system property accessors."}

	for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Sysprop_srcs) {
		moduleName := syspropPathToRustModule(syspropFile)
		moduleDir := outputDir.Join(ctx, moduleName)
		modulePath := moduleDir.Join(ctx, "mod.rs")

		ctx.Build(pctx, android.BuildParams{
			Rule:        syspropRust,
			Description: "sysprop_rust " + syspropFile.Rel(),
			Outputs:     android.WritablePaths{libPath},
			Output:      modulePath,
			Input:       syspropFile,
			Implicit:    checkApiFileTimeStamp,
			Args: map[string]string{
				"scope":   g.properties.Scope,
				"out_dir": outputDir.String(),
				"out_dir": moduleDir.String(),
			},
		})

		g.genSrcs = append(g.genSrcs, libPath)
		g.BaseSourceProvider.OutputFiles = append(g.BaseSourceProvider.OutputFiles, modulePath)
		libFileLines = append(libFileLines, fmt.Sprintf("pub mod %s;", moduleName))
	}

	libFileSource := strings.Join(libFileLines, "\n")
	android.WriteFileRule(ctx, libFile, libFileSource)

	return libFile
}

func (g *syspropRustGenRule) SourceProviderProps() []interface{} {
	return append(g.BaseSourceProvider.SourceProviderProps(), &g.Properties)
}

// syspropPathToRustModule takes a path to a .sysprop file and returns the name to use for the
// corresponding Rust module.
func syspropPathToRustModule(syspropFilename android.Path) string {
	filenameBase := strings.TrimSuffix(syspropFilename.Base(), ".sysprop")
	return strings.ToLower(filenameBase)
}

func (g *syspropRustGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -180,15 +200,13 @@ func (g *syspropRustGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
	ctx.AddFarVariationDependencies(nil, nil, proptools.String(g.properties.Check_api))
}

func (g *syspropRustGenRule) OutputFiles(_ string) (android.Paths, error) {
	return g.genSrcs, nil
}

func syspropRustGenFactory() android.Module {
	g := &syspropRustGenRule{}
	g.AddProperties(&g.properties)
	android.InitAndroidModule(g)
	return g
	g := &syspropRustGenRule{
		BaseSourceProvider: rust.NewSourceProvider(),
	}
	sourceProvider := rust.NewSourceProviderModule(android.DeviceSupported, g, false, false)
	sourceProvider.AddProperties(&g.properties)
	return sourceProvider.Init()
}

type syspropLibrary struct {
@@ -308,10 +326,6 @@ func (m *syspropLibrary) javaGenPublicStubName() string {
	return m.BaseModuleName() + "_java_gen_public"
}

func (m *syspropLibrary) rustGenModuleName() string {
	return m.rustCrateName() + "_rust_gen"
}

func (m *syspropLibrary) rustGenStubName() string {
	return "lib" + m.rustCrateName() + "_rust"
}
@@ -528,6 +542,9 @@ type javaLibraryProperties struct {

type rustLibraryProperties struct {
	Name              *string
	Sysprop_srcs      []string `android:"path"`
	Scope             string
	Check_api         *string
	Srcs              []string
	Installable       *bool
	Crate_name        string
@@ -667,18 +684,15 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) {
	}

	// Generate a Rust implementation library.
	ctx.CreateModule(syspropRustGenFactory, &syspropGenProperties{
		Srcs:      m.properties.Srcs,
		Scope:     scope,
		Name:      proptools.StringPtr(m.rustGenModuleName()),
		Check_api: proptools.StringPtr(ctx.ModuleName()),
	})
	rustProps := rustLibraryProperties{
		Name:         proptools.StringPtr(m.rustGenStubName()),
		Srcs:        []string{":" + m.rustGenModuleName()},
		Sysprop_srcs: m.properties.Srcs,
		Scope:        scope,
		Check_api:    proptools.StringPtr(ctx.ModuleName()),
		Installable:  proptools.BoolPtr(false),
		Crate_name:   m.rustCrateName(),
		Rustlibs: []string{
			"liblog_rust",
			"librustutils",
		},
		Vendor_available:  m.properties.Vendor_available,
@@ -686,7 +700,7 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) {
		Apex_available:    m.ApexProperties.Apex_available,
		Min_sdk_version:   proptools.StringPtr("29"),
	}
	ctx.CreateModule(rust.RustLibraryFactory, &rustProps)
	ctx.CreateModule(syspropRustGenFactory, &rustProps)

	// syspropLibraries will be used by property_contexts to check types.
	// Record absolute paths of sysprop_library to prevent soong_namespace problem.
+10 −0
Original line number Diff line number Diff line
@@ -72,6 +72,15 @@ func test(t *testing.T, bp string) *android.TestResult {
			vendor_available: true,
			min_sdk_version: "29",
		}

		rust_library {
			name: "liblog_rust",
			crate_name: "log",
			srcs: ["log/src/lib.rs"],
			product_available: true,
			vendor_available: true,
			min_sdk_version: "29",
		}
	`

	mockFS := android.MockFS{
@@ -115,6 +124,7 @@ func test(t *testing.T, bp string) *android.TestResult {
		"com/android2/OdmProperties.sysprop":         nil,

		"librustutils/lib.rs": nil,
		"log/src/lib.rs":      nil,
	}

	result := android.GroupFixturePreparers(