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

Commit f3bfd02a authored by Colin Cross's avatar Colin Cross
Browse files

Add environment variables to cc_genrule commands

Pass the architecture, mulitlib type and native bridge state to
each variant of a cc_genrule rule as environment variables.

Bug: 200872604
Test: TestCmdPrefix
Change-Id: I39c4c2d5bbd4f4cc72a4777715db1df049345b37
parent 6a779a4b
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
package cc

import (
	"fmt"

	"android/soong/android"
	"android/soong/genrule"
	"android/soong/snapshot"
@@ -36,13 +38,23 @@ type GenruleExtraProperties struct {

// cc_genrule is a genrule that can depend on other cc_* objects.
// The cmd may be run multiple times, once for each of the different arch/etc
// variations.
// variations.  The following environment variables will be set when the command
// execute:
//
//   CC_ARCH           the name of the architecture the command is being executed for
//
//   CC_MULTILIB       "lib32" if the architecture the command is being executed for is 32-bit,
//                     "lib64" if it is 64-bit.
//
//   CC_NATIVE_BRIDGE  the name of the subdirectory that native bridge libraries are stored in if
//                     the architecture has native bridge enabled, empty if it is disabled.
func GenRuleFactory() android.Module {
	module := genrule.NewGenRule()

	extra := &GenruleExtraProperties{}
	module.Extra = extra
	module.ImageInterface = extra
	module.CmdModifier = genruleCmdModifier
	module.AddProperties(module.Extra)

	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibBoth)
@@ -53,6 +65,13 @@ func GenRuleFactory() android.Module {
	return module
}

func genruleCmdModifier(ctx android.ModuleContext, cmd string) string {
	target := ctx.Target()
	arch := target.Arch.ArchType
	return fmt.Sprintf("CC_ARCH=%s CC_NATIVE_BRIDGE=%s CC_MULTILIB=%s && %s",
		arch.Name, target.NativeBridgeRelativePath, arch.Multilib, cmd)
}

var _ android.ImageInterface = (*GenruleExtraProperties)(nil)

func (g *GenruleExtraProperties) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+72 −0
Original line number Diff line number Diff line
@@ -115,3 +115,75 @@ func TestLibraryGenruleCmd(t *testing.T) {
		t.Errorf(`want inputs %v, got %v`, expected, got)
	}
}

func TestCmdPrefix(t *testing.T) {
	bp := `
		cc_genrule {
			name: "gen",
			cmd: "echo foo",
			out: ["out"],
			native_bridge_supported: true,
		}
		`

	testCases := []struct {
		name     string
		variant  string
		preparer android.FixturePreparer

		arch         string
		nativeBridge string
		multilib     string
	}{
		{
			name:     "arm",
			variant:  "android_arm_armv7-a-neon",
			arch:     "arm",
			multilib: "lib32",
		},
		{
			name:     "arm64",
			variant:  "android_arm64_armv8-a",
			arch:     "arm64",
			multilib: "lib64",
		},
		{
			name:    "nativebridge",
			variant: "android_native_bridge_arm_armv7-a-neon",
			preparer: android.FixtureModifyConfig(func(config android.Config) {
				config.Targets[android.Android] = []android.Target{
					{
						Os:           android.Android,
						Arch:         android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}},
						NativeBridge: android.NativeBridgeDisabled,
					},
					{
						Os:                       android.Android,
						Arch:                     android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}},
						NativeBridge:             android.NativeBridgeEnabled,
						NativeBridgeHostArchName: "x86",
						NativeBridgeRelativePath: "arm",
					},
				}
			}),
			arch:         "arm",
			multilib:     "lib32",
			nativeBridge: "arm",
		},
	}

	for _, tt := range testCases {
		t.Run(tt.name, func(t *testing.T) {
			result := android.GroupFixturePreparers(
				PrepareForIntegrationTestWithCc,
				android.OptionalFixturePreparer(tt.preparer),
			).RunTestWithBp(t, bp)
			gen := result.ModuleForTests("gen", tt.variant)
			sboxProto := android.RuleBuilderSboxProtoForTests(t, gen.Output("genrule.sbox.textproto"))
			cmd := *sboxProto.Commands[0].Command
			android.AssertStringDoesContain(t, "incorrect CC_ARCH", cmd, "CC_ARCH="+tt.arch+" ")
			android.AssertStringDoesContain(t, "incorrect CC_NATIVE_BRIDGE", cmd, "CC_NATIVE_BRIDGE="+tt.nativeBridge+" ")
			android.AssertStringDoesContain(t, "incorrect CC_MULTILIB", cmd, "CC_MULTILIB="+tt.multilib+" ")
		})
	}
}
+11 −1
Original line number Diff line number Diff line
@@ -156,6 +156,11 @@ type Module struct {
	// For other packages to make their own genrules with extra
	// properties
	Extra interface{}

	// CmdModifier can be set by wrappers around genrule to modify the command, for example to
	// prefix environment variables to it.
	CmdModifier func(ctx android.ModuleContext, cmd string) string

	android.ImageInterface

	properties generatorProperties
@@ -398,8 +403,13 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	var outputFiles android.WritablePaths
	var zipArgs strings.Builder

	cmd := String(g.properties.Cmd)
	if g.CmdModifier != nil {
		cmd = g.CmdModifier(ctx, cmd)
	}

	// Generate tasks, either from genrule or gensrcs.
	for _, task := range g.taskGenerator(ctx, String(g.properties.Cmd), srcFiles) {
	for _, task := range g.taskGenerator(ctx, cmd, srcFiles) {
		if len(task.out) == 0 {
			ctx.ModuleErrorf("must have at least one output file")
			return