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

Commit d6cd813a authored by Lukacs T. Berki's avatar Lukacs T. Berki
Browse files

Call mixed mode Bazel in the symlink forest.

Test: Presubmits + manual execution.
Change-Id: Idef2d821222ccbf9385d0ea3fc92178b3206df0a
parent 3784448c
Loading
Loading
Loading
Loading
+38 −64
Original line number Diff line number Diff line
@@ -321,9 +321,8 @@ type builtinBazelRunner struct{}
// the invocation returned an error code.
func (r *builtinBazelRunner) issueBazelCommand(paths *bazelPaths, runName bazel.RunName, command bazelCommand,
	extraFlags ...string) (string, string, error) {
	cmdFlags := []string{"--output_base=" + paths.outputBase, command.command}
	cmdFlags := []string{"--output_base=" + absolutePath(paths.outputBase), command.command}
	cmdFlags = append(cmdFlags, command.expression)
	cmdFlags = append(cmdFlags, "--package_path=%workspace%/"+paths.intermediatesDir())
	cmdFlags = append(cmdFlags, "--profile="+shared.BazelMetricsFilename(paths, runName))

	// Set default platforms to canonicalized values for mixed builds requests.
@@ -334,20 +333,20 @@ func (r *builtinBazelRunner) issueBazelCommand(paths *bazelPaths, runName bazel.
	// The actual platform values here may be overridden by configuration
	// transitions from the buildroot.
	cmdFlags = append(cmdFlags,
		fmt.Sprintf("--platforms=%s", canonicalizeLabel("//build/bazel/platforms:android_x86_64")))
		fmt.Sprintf("--platforms=%s", "//build/bazel/platforms:android_x86_64"))
	cmdFlags = append(cmdFlags,
		fmt.Sprintf("--extra_toolchains=%s", canonicalizeLabel("//prebuilts/clang/host/linux-x86:all")))
		fmt.Sprintf("--extra_toolchains=%s", "//prebuilts/clang/host/linux-x86:all"))
	// This should be parameterized on the host OS, but let's restrict to linux
	// to keep things simple for now.
	cmdFlags = append(cmdFlags,
		fmt.Sprintf("--host_platform=%s", canonicalizeLabel("//build/bazel/platforms:linux_x86_64")))
		fmt.Sprintf("--host_platform=%s", "//build/bazel/platforms:linux_x86_64"))

	// Explicitly disable downloading rules (such as canonical C++ and Java rules) from the network.
	cmdFlags = append(cmdFlags, "--experimental_repository_disable_download")
	cmdFlags = append(cmdFlags, extraFlags...)

	bazelCmd := exec.Command(paths.bazelPath, cmdFlags...)
	bazelCmd.Dir = paths.workspaceDir
	bazelCmd.Dir = absolutePath(paths.syntheticWorkspaceDir())
	bazelCmd.Env = append(os.Environ(), "HOME="+paths.homeDir, pwdPrefix(),
		// Disables local host detection of gcc; toolchain information is defined
		// explicitly in BUILD files.
@@ -363,31 +362,6 @@ func (r *builtinBazelRunner) issueBazelCommand(paths *bazelPaths, runName bazel.
	}
}

// Returns the string contents of a workspace file that should be output
// adjacent to the main bzl file and build file.
// This workspace file allows, via local_repository rule, sourcetree-level
// BUILD targets to be referenced via @sourceroot.
func (context *bazelContext) workspaceFileContents() []byte {
	formatString := `
# This file is generated by soong_build. Do not edit.
local_repository(
    name = "sourceroot",
    path = "%[1]s",
)

local_repository(
    name = "rules_cc",
    path = "%[1]s/build/bazel/rules_cc",
)

local_repository(
    name = "bazel_skylib",
    path = "%[1]s/build/bazel/bazel_skylib",
)
`
	return []byte(fmt.Sprintf(formatString, context.paths.workspaceDir))
}

func (context *bazelContext) mainBzlFileContents() []byte {
	// TODO(cparsons): Define configuration transitions programmatically based
	// on available archs.
@@ -398,7 +372,7 @@ func (context *bazelContext) mainBzlFileContents() []byte {

def _config_node_transition_impl(settings, attr):
    return {
        "//command_line_option:platforms": "@sourceroot//build/bazel/platforms:android_%s" % attr.arch,
        "//command_line_option:platforms": "@//build/bazel/platforms:android_%s" % attr.arch,
    }

_config_node_transition = transition(
@@ -447,18 +421,6 @@ phony_root = rule(
	return []byte(contents)
}

// Returns a "canonicalized" corresponding to the given sourcetree-level label.
// This abstraction is required because a sourcetree label such as //foo/bar:baz
// must be referenced via the local repository prefix, such as
// @sourceroot//foo/bar:baz.
func canonicalizeLabel(label string) string {
	if strings.HasPrefix(label, "//") {
		return "@sourceroot" + label
	} else {
		return "@sourceroot//" + label
	}
}

func (context *bazelContext) mainBuildFileContents() []byte {
	// TODO(cparsons): Map label to attribute programmatically; don't use hard-coded
	// architecture mapping.
@@ -487,7 +449,7 @@ config_node(name = "%s",

	labelsByArch := map[string][]string{}
	for val, _ := range context.requests {
		labelString := fmt.Sprintf("\"%s\"", canonicalizeLabel(val.label))
		labelString := fmt.Sprintf("\"@%s\"", val.label)
		archString := getArchString(val)
		labelsByArch[archString] = append(labelsByArch[archString], labelString)
	}
@@ -593,12 +555,24 @@ def format(target):
		mainSwitchSection))
}

// Returns a workspace-relative path containing build-related metadata required
// for interfacing with Bazel. Example: out/soong/bazel.
// Returns a path containing build-related metadata required for interfacing
// with Bazel. Example: out/soong/bazel.
func (p *bazelPaths) intermediatesDir() string {
	return filepath.Join(p.buildDir, "bazel")
}

// Returns the path where the contents of the @soong_injection repository live.
// It is used by Soong to tell Bazel things it cannot over the command line.
func (p *bazelPaths) injectedFilesDir() string {
	return filepath.Join(p.buildDir, "soong_injection")
}

// Returns the path of the synthetic Bazel workspace that contains a symlink
// forest composed the whole source tree and BUILD files generated by bp2build.
func (p *bazelPaths) syntheticWorkspaceDir() string {
	return filepath.Join(p.buildDir, "workspace")
}

// Issues commands to Bazel to receive results for all cquery requests
// queued in the BazelContext.
func (context *bazelContext) InvokeBazel() error {
@@ -608,47 +582,47 @@ func (context *bazelContext) InvokeBazel() error {
	var cqueryErr string
	var err error

	intermediatesDirPath := absolutePath(context.paths.intermediatesDir())
	if _, err := os.Stat(intermediatesDirPath); os.IsNotExist(err) {
		err = os.Mkdir(intermediatesDirPath, 0777)
	soongInjectionPath := absolutePath(context.paths.injectedFilesDir())
	if _, err := os.Stat(soongInjectionPath); os.IsNotExist(err) {
		err = os.Mkdir(soongInjectionPath, 0777)
	}
	if err != nil {
		return err
	}

	err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "WORKSPACE.bazel"), []byte{}, 0666)
	if err != nil {
		return err
	}

	err = ioutil.WriteFile(
		filepath.Join(intermediatesDirPath, "main.bzl"),
		filepath.Join(soongInjectionPath, "main.bzl"),
		context.mainBzlFileContents(), 0666)
	if err != nil {
		return err
	}

	err = ioutil.WriteFile(
		filepath.Join(intermediatesDirPath, "BUILD.bazel"),
		filepath.Join(soongInjectionPath, "BUILD.bazel"),
		context.mainBuildFileContents(), 0666)
	if err != nil {
		return err
	}
	cqueryFileRelpath := filepath.Join(context.paths.intermediatesDir(), "buildroot.cquery")
	cqueryFileRelpath := filepath.Join(context.paths.injectedFilesDir(), "buildroot.cquery")
	err = ioutil.WriteFile(
		absolutePath(cqueryFileRelpath),
		context.cqueryStarlarkFileContents(), 0666)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(
		filepath.Join(intermediatesDirPath, "WORKSPACE.bazel"),
		context.workspaceFileContents(), 0666)
	if err != nil {
		return err
	}
	buildrootLabel := "//:buildroot"
	buildrootLabel := "@soong_injection//:buildroot"
	cqueryOutput, cqueryErr, err = context.issueBazelCommand(
		context.paths,
		bazel.CqueryBuildRootRunName,
		bazelCommand{"cquery", fmt.Sprintf("kind(rule, deps(%s))", buildrootLabel)},
		"--output=starlark",
		"--starlark:file="+cqueryFileRelpath)
	err = ioutil.WriteFile(filepath.Join(intermediatesDirPath, "cquery.out"),
		"--starlark:file="+absolutePath(cqueryFileRelpath))
	err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"),
		[]byte(cqueryOutput), 0666)
	if err != nil {
		return err
@@ -702,7 +676,7 @@ func (context *bazelContext) InvokeBazel() error {
	_, _, err = context.issueBazelCommand(
		context.paths,
		bazel.BazelBuildPhonyRootRunName,
		bazelCommand{"build", "//:phonyroot"})
		bazelCommand{"build", "@soong_injection//:phonyroot"})

	if err != nil {
		return err
@@ -781,7 +755,7 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
}

func getCqueryId(key cqueryKey) string {
	return canonicalizeLabel(key.label) + "|" + getArchString(key)
	return key.label + "|" + getArchString(key)
}

func getArchString(key cqueryKey) string {