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

Commit acd5a0c0 authored by Usta Shrestha's avatar Usta Shrestha
Browse files

paths in depfiles are relative to $OUT_DIR

Test: USE_BAZEL_ANALYSIS=1 m libc droid
Bug: b/232250671
Change-Id: I7a570894371bd31339ab0cf3c619c30b3cf8cd73
parent 2ff57f9d
Loading
Loading
Loading
Loading
+55 −41
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import (
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"
@@ -870,16 +871,29 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
		})
	}

	// Register bazel-owned build statements (obtained from the aquery invocation).
	executionRoot := path.Join(ctx.Config().BazelContext.OutputBase(), "execroot", "__main__")
	bazelOutDir := path.Join(executionRoot, "bazel-out")
	for index, buildStatement := range ctx.Config().BazelContext.BuildStatementsToRegister() {
		if len(buildStatement.Command) < 1 {
			panic(fmt.Sprintf("unhandled build statement: %v", buildStatement))
		}
		rule := NewRuleBuilder(pctx, ctx)
		cmd := rule.Command()
		createCommand(rule.Command(), buildStatement, executionRoot, bazelOutDir, ctx)
		// This is required to silence warnings pertaining to unexpected timestamps. Particularly,
		// some Bazel builtins (such as files in the bazel_tools directory) have far-future
		// timestamps. Without restat, Ninja would emit warnings that the input files of a
		// build statement have later timestamps than the outputs.
		rule.Restat()

		desc := fmt.Sprintf("%s: %s", buildStatement.Mnemonic, buildStatement.OutputPaths)
		rule.Build(fmt.Sprintf("bazel %d", index), desc)
	}
}

		// cd into Bazel's execution root, which is the action cwd.
		cmd.Text(fmt.Sprintf("cd %s/execroot/__main__ &&", ctx.Config().BazelContext.OutputBase()))
// Register bazel-owned build statements (obtained from the aquery invocation).
func createCommand(cmd *RuleBuilderCommand, buildStatement bazel.BuildStatement, executionRoot string, bazelOutDir string, ctx PathContext) {
	// executionRoot is the action cwd.
	cmd.Text(fmt.Sprintf("cd '%s' &&", executionRoot))

	// Remove old outputs, as some actions might not rerun if the outputs are detected.
	if len(buildStatement.OutputPaths) > 0 {
@@ -910,22 +924,22 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
	}

	if depfile := buildStatement.Depfile; depfile != nil {
		// The paths in depfile are relative to `executionRoot`.
		// Hence, they need to be corrected by replacing "bazel-out"
		// with the full `bazelOutDir`.
		// Otherwise, implicit outputs and implicit inputs under "bazel-out/"
		// would be deemed missing.
		// (Note: The regexp uses a capture group because the version of sed
		//  does not support a look-behind pattern.)
		replacement := fmt.Sprintf(`&& sed -i'' -E 's@(^|\s|")bazel-out/@\1%s/@g' '%s'`,
			bazelOutDir, *depfile)
		cmd.Text(replacement)
		cmd.ImplicitDepFile(PathForBazelOut(ctx, *depfile))
	}

	for _, symlinkPath := range buildStatement.SymlinkPaths {
		cmd.ImplicitSymlinkOutput(PathForBazelOut(ctx, symlinkPath))
	}

		// This is required to silence warnings pertaining to unexpected timestamps. Particularly,
		// some Bazel builtins (such as files in the bazel_tools directory) have far-future
		// timestamps. Without restat, Ninja would emit warnings that the input files of a
		// build statement have later timestamps than the outputs.
		rule.Restat()

		desc := fmt.Sprintf("%s: %s", buildStatement.Mnemonic, buildStatement.OutputPaths)
		rule.Build(fmt.Sprintf("bazel %d", index), desc)
	}
}

func getCqueryId(key cqueryKey) string {
+59 −9
Original line number Diff line number Diff line
@@ -57,8 +57,13 @@ func TestInvokeBazelWritesBazelFiles(t *testing.T) {
}

func TestInvokeBazelPopulatesBuildStatements(t *testing.T) {
	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
		bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: `
	type testCase struct {
		input   string
		command string
	}

	var testCases = []testCase{
		{`
{
  "artifacts": [{
    "id": 1,
@@ -88,7 +93,45 @@ func TestInvokeBazelPopulatesBuildStatements(t *testing.T) {
    "label": "two"
  }]
}`,
	})
			"cd 'er' && rm -f one && touch foo",
		}, {`
{
  "artifacts": [{
    "id": 1,
    "pathFragmentId": 10
  }, {
    "id": 2,
    "pathFragmentId": 20
  }],
  "actions": [{
    "targetId": 100,
    "actionKey": "x",
    "mnemonic": "x",
    "arguments": ["bogus", "command"],
    "outputIds": [1, 2],
    "primaryOutputId": 1
  }],
  "pathFragments": [{
    "id": 10,
    "label": "one",
    "parentId": 30
  }, {
    "id": 20,
    "label": "one.d",
    "parentId": 30
  }, {
    "id": 30,
    "label": "parent"
  }]
}`,
			`cd 'er' && rm -f parent/one && bogus command && sed -i'' -E 's@(^|\s|")bazel-out/@\1bo/@g' 'parent/one.d'`,
		},
	}

	for _, testCase := range testCases {
		bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
			bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: testCase.input})

		err := bazelContext.InvokeBazel(testConfig)
		if err != nil {
			t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
@@ -96,7 +139,14 @@ func TestInvokeBazelPopulatesBuildStatements(t *testing.T) {

		got := bazelContext.BuildStatementsToRegister()
		if want := 1; len(got) != want {
		t.Errorf("Expected %d registered build statements, got %#v", want, got)
			t.Errorf("expected %d registered build statements, but got %#v", want, got)
		}

		cmd := RuleBuilderCommand{}
		createCommand(&cmd, got[0], "er", "bo", PathContextForTesting(TestConfig("out", nil, "", nil)))
		if actual := cmd.buf.String(); testCase.command != actual {
			t.Errorf("expected: [%s], actual: [%s]", testCase.command, actual)
		}
	}
}