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

Commit b4bb20f5 authored by Vinh Tran's avatar Vinh Tran
Browse files

Implement bp2build converter for rust_proc_macro

Test: WIP
Bug: 297356482
Change-Id: I17d1a0a95d4a67ccbc9b2d74e49bcacd6ff4d26b
parent 3570ce3f
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
package bp2build

import (
	"android/soong/android"
	"android/soong/rust"
	"testing"
)

func rustRustProcMacroTestCase(t *testing.T, tc Bp2buildTestCase) {
	t.Helper()
	RunBp2BuildTestCase(t, registerRustProcMacroModuleTypes, tc)
}

func registerRustProcMacroModuleTypes(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("rust_library_host", rust.RustLibraryHostFactory)
	ctx.RegisterModuleType("rust_proc_macro", rust.ProcMacroFactory)
}

func TestRustProcMacroLibrary(t *testing.T) {
	runRustLibraryTestCase(t, Bp2buildTestCase{
		Dir:       "external/rust/crates/foo",
		Blueprint: "",
		Filesystem: map[string]string{
			"external/rust/crates/foo/src/lib.rs":    "",
			"external/rust/crates/foo/src/helper.rs": "",
			"external/rust/crates/foo/Android.bp": `
rust_proc_macro {
	name: "libfoo",
	crate_name: "foo",
	srcs: ["src/lib.rs"],
	edition: "2021",
	features: ["bah-enabled"],
	cfgs: ["baz"],
	rustlibs: ["libbar"],
    bazel_module: { bp2build_available: true },
}
`,
			"external/rust/crates/bar/src/lib.rs": "",
			"external/rust/crates/bar/Android.bp": `
rust_library_host {
    name: "libbar",
    crate_name: "bar",
    srcs: ["src/lib.rs"],
    bazel_module: { bp2build_available: true },
}`,
		},
		ExpectedBazelTargets: []string{
			makeBazelTargetHostOrDevice("rust_proc_macro", "libfoo", AttrNameToString{
				"crate_name": `"foo"`,
				"srcs": `[
        "src/helper.rs",
        "src/lib.rs",
    ]`,
				"crate_features": `["bah-enabled"]`,
				"edition":        `"2021"`,
				"rustc_flags":    `["--cfg=baz"]`,
				"deps":           `["//external/rust/crates/bar:libbar"]`,
			}, android.HostSupported),
		},
	},
	)
}
+17 −34
Original line number Diff line number Diff line
@@ -807,43 +807,23 @@ type rustLibraryAttributes struct {
	Crate_features  bazel.StringListAttribute
	Deps            bazel.LabelListAttribute
	Rustc_flags     bazel.StringListAttribute
	Proc_macro_deps bazel.LabelListAttribute
}

func libraryBp2build(ctx android.TopDownMutatorContext, m *Module) {
	lib := m.compiler.(*libraryDecorator)
	srcs, compileData := srcsAndCompileDataAttrs(ctx, *lib.baseCompiler)
	deps := android.BazelLabelForModuleDeps(ctx, append(
		lib.baseCompiler.Properties.Rustlibs,
		lib.baseCompiler.Properties.Rlibs...,
	))
	procMacroDeps := android.BazelLabelForModuleDeps(ctx, lib.baseCompiler.Properties.Proc_macros)

	var srcs bazel.LabelList
	var compileData bazel.LabelList
	var rustcFLags []string

	// This is a workaround by assuming the conventions that rust crate repos are structured
	//  while waiting for the sandboxing work to complete.
	// TODO: When crate_root prop is set which enforces inputs sandboxing,
	// always use `srcs` and `compile_data` props to generate `srcs` and `compile_data` attributes
	// instead of using globs.
	if lib.baseCompiler.Properties.Srcs[0] == "src/lib.rs" {
		srcs = android.BazelLabelForModuleSrc(ctx, []string{"src/**/*.rs"})
		compileData = android.BazelLabelForModuleSrc(
			ctx,
			[]string{
				"src/**/*.proto",
				"examples/**/*.rs",
				"**/*.md",
			},
		)
	} else {
		srcs = android.BazelLabelForModuleSrc(ctx, lib.baseCompiler.Properties.Srcs)
	}

	for _, cfg := range lib.baseCompiler.Properties.Cfgs {
		rustcFLags = append(rustcFLags, fmt.Sprintf("--cfg=%s", cfg))
	}

	deps := android.BazelLabelForModuleDeps(ctx, append(
		lib.baseCompiler.Properties.Rustlibs,
		lib.baseCompiler.Properties.Rlibs...,
	))

	attrs := &rustLibraryAttributes{
		Srcs: bazel.MakeLabelListAttribute(
			srcs,
@@ -863,6 +843,9 @@ func libraryBp2build(ctx android.TopDownMutatorContext, m *Module) {
		Deps: bazel.MakeLabelListAttribute(
			deps,
		),
		Proc_macro_deps: bazel.MakeLabelListAttribute(
			procMacroDeps,
		),
		Rustc_flags: bazel.StringListAttribute{
			Value: append(
				rustcFLags,
+66 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ package rust

import (
	"android/soong/android"
	"android/soong/bazel"
	"fmt"
)

func init() {
@@ -47,6 +49,8 @@ func ProcMacroFactory() android.Module {
func NewProcMacro(hod android.HostOrDeviceSupported) (*Module, *procMacroDecorator) {
	module := newModule(hod, android.MultilibFirst)

	android.InitBazelModule(module)

	procMacro := &procMacroDecorator{
		baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
		flagExporter: NewFlagExporter(),
@@ -99,3 +103,65 @@ func (procMacro *procMacroDecorator) everInstallable() bool {
	// Proc_macros are never installed
	return false
}

type procMacroAttributes struct {
	Srcs           bazel.LabelListAttribute
	Compile_data   bazel.LabelListAttribute
	Crate_name     bazel.StringAttribute
	Edition        bazel.StringAttribute
	Crate_features bazel.StringListAttribute
	Deps           bazel.LabelListAttribute
	Rustc_flags    bazel.StringListAttribute
}

func procMacroBp2build(ctx android.TopDownMutatorContext, m *Module) {
	procMacro := m.compiler.(*procMacroDecorator)
	srcs, compileData := srcsAndCompileDataAttrs(ctx, *procMacro.baseCompiler)
	deps := android.BazelLabelForModuleDeps(ctx, append(
		procMacro.baseCompiler.Properties.Rustlibs,
		procMacro.baseCompiler.Properties.Rlibs...,
	))

	var rustcFLags []string
	for _, cfg := range procMacro.baseCompiler.Properties.Cfgs {
		rustcFLags = append(rustcFLags, fmt.Sprintf("--cfg=%s", cfg))
	}

	attrs := &procMacroAttributes{
		Srcs: bazel.MakeLabelListAttribute(
			srcs,
		),
		Compile_data: bazel.MakeLabelListAttribute(
			compileData,
		),
		Crate_name: bazel.StringAttribute{
			Value: &procMacro.baseCompiler.Properties.Crate_name,
		},
		Edition: bazel.StringAttribute{
			Value: procMacro.baseCompiler.Properties.Edition,
		},
		Crate_features: bazel.StringListAttribute{
			Value: procMacro.baseCompiler.Properties.Features,
		},
		Deps: bazel.MakeLabelListAttribute(
			deps,
		),
		Rustc_flags: bazel.StringListAttribute{
			Value: append(
				rustcFLags,
				procMacro.baseCompiler.Properties.Flags...,
			),
		},
	}
	// m.IsConvertedByBp2build()
	ctx.CreateBazelTargetModule(
		bazel.BazelTargetModuleProperties{
			Rule_class:        "rust_proc_macro",
			Bzl_load_location: "@rules_rust//rust:defs.bzl",
		},
		android.CommonAttributes{
			Name: m.Name(),
		},
		attrs,
	)
}
+31 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package rust

import (
	"android/soong/bazel"
	"android/soong/bloaty"
	"android/soong/ui/metrics/bp2build_metrics_proto"
	"fmt"
@@ -1847,11 +1848,41 @@ func (c *Module) Partition() string {
func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
	if ctx.ModuleType() == "rust_library_host" || ctx.ModuleType() == "rust_library" {
		libraryBp2build(ctx, m)
	} else if ctx.ModuleType() == "rust_proc_macro" {
		procMacroBp2build(ctx, m)
	} else {
		ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
	}
}

// This is a workaround by assuming the conventions that rust crate repos are structured
//
//	while waiting for the sandboxing work to complete.
//
// TODO(b/297344471): When crate_root prop is set which enforces inputs sandboxing,
// always use `srcs` and `compile_data` props to generate `srcs` and `compile_data` attributes
// instead of using globs.
func srcsAndCompileDataAttrs(ctx android.TopDownMutatorContext, c baseCompiler) (bazel.LabelList, bazel.LabelList) {
	var srcs bazel.LabelList
	var compileData bazel.LabelList

	if c.Properties.Srcs[0] == "src/lib.rs" {
		srcs = android.BazelLabelForModuleSrc(ctx, []string{"src/**/*.rs"})
		compileData = android.BazelLabelForModuleSrc(
			ctx,
			[]string{
				"src/**/*.proto",
				"examples/**/*.rs",
				"**/*.md",
			},
		)
	} else {
		srcs = android.BazelLabelForModuleSrc(ctx, c.Properties.Srcs)
	}

	return srcs, compileData
}

var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String