Call mixed mode Bazel in the symlink forest.
Test: Presubmits + manual execution. Change-Id: Idef2d821222ccbf9385d0ea3fc92178b3206df0a
This commit is contained in:
@@ -321,9 +321,8 @@ type builtinBazelRunner struct{}
|
|||||||
// the invocation returned an error code.
|
// the invocation returned an error code.
|
||||||
func (r *builtinBazelRunner) issueBazelCommand(paths *bazelPaths, runName bazel.RunName, command bazelCommand,
|
func (r *builtinBazelRunner) issueBazelCommand(paths *bazelPaths, runName bazel.RunName, command bazelCommand,
|
||||||
extraFlags ...string) (string, string, error) {
|
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, command.expression)
|
||||||
cmdFlags = append(cmdFlags, "--package_path=%workspace%/"+paths.intermediatesDir())
|
|
||||||
cmdFlags = append(cmdFlags, "--profile="+shared.BazelMetricsFilename(paths, runName))
|
cmdFlags = append(cmdFlags, "--profile="+shared.BazelMetricsFilename(paths, runName))
|
||||||
|
|
||||||
// Set default platforms to canonicalized values for mixed builds requests.
|
// 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
|
// The actual platform values here may be overridden by configuration
|
||||||
// transitions from the buildroot.
|
// transitions from the buildroot.
|
||||||
cmdFlags = append(cmdFlags,
|
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,
|
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
|
// This should be parameterized on the host OS, but let's restrict to linux
|
||||||
// to keep things simple for now.
|
// to keep things simple for now.
|
||||||
cmdFlags = append(cmdFlags,
|
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.
|
// Explicitly disable downloading rules (such as canonical C++ and Java rules) from the network.
|
||||||
cmdFlags = append(cmdFlags, "--experimental_repository_disable_download")
|
cmdFlags = append(cmdFlags, "--experimental_repository_disable_download")
|
||||||
cmdFlags = append(cmdFlags, extraFlags...)
|
cmdFlags = append(cmdFlags, extraFlags...)
|
||||||
|
|
||||||
bazelCmd := exec.Command(paths.bazelPath, cmdFlags...)
|
bazelCmd := exec.Command(paths.bazelPath, cmdFlags...)
|
||||||
bazelCmd.Dir = paths.workspaceDir
|
bazelCmd.Dir = absolutePath(paths.syntheticWorkspaceDir())
|
||||||
bazelCmd.Env = append(os.Environ(), "HOME="+paths.homeDir, pwdPrefix(),
|
bazelCmd.Env = append(os.Environ(), "HOME="+paths.homeDir, pwdPrefix(),
|
||||||
// Disables local host detection of gcc; toolchain information is defined
|
// Disables local host detection of gcc; toolchain information is defined
|
||||||
// explicitly in BUILD files.
|
// 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 {
|
func (context *bazelContext) mainBzlFileContents() []byte {
|
||||||
// TODO(cparsons): Define configuration transitions programmatically based
|
// TODO(cparsons): Define configuration transitions programmatically based
|
||||||
// on available archs.
|
// on available archs.
|
||||||
@@ -398,7 +372,7 @@ func (context *bazelContext) mainBzlFileContents() []byte {
|
|||||||
|
|
||||||
def _config_node_transition_impl(settings, attr):
|
def _config_node_transition_impl(settings, attr):
|
||||||
return {
|
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(
|
_config_node_transition = transition(
|
||||||
@@ -447,18 +421,6 @@ phony_root = rule(
|
|||||||
return []byte(contents)
|
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 {
|
func (context *bazelContext) mainBuildFileContents() []byte {
|
||||||
// TODO(cparsons): Map label to attribute programmatically; don't use hard-coded
|
// TODO(cparsons): Map label to attribute programmatically; don't use hard-coded
|
||||||
// architecture mapping.
|
// architecture mapping.
|
||||||
@@ -487,7 +449,7 @@ config_node(name = "%s",
|
|||||||
|
|
||||||
labelsByArch := map[string][]string{}
|
labelsByArch := map[string][]string{}
|
||||||
for val, _ := range context.requests {
|
for val, _ := range context.requests {
|
||||||
labelString := fmt.Sprintf("\"%s\"", canonicalizeLabel(val.label))
|
labelString := fmt.Sprintf("\"@%s\"", val.label)
|
||||||
archString := getArchString(val)
|
archString := getArchString(val)
|
||||||
labelsByArch[archString] = append(labelsByArch[archString], labelString)
|
labelsByArch[archString] = append(labelsByArch[archString], labelString)
|
||||||
}
|
}
|
||||||
@@ -593,12 +555,24 @@ def format(target):
|
|||||||
mainSwitchSection))
|
mainSwitchSection))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a workspace-relative path containing build-related metadata required
|
// Returns a path containing build-related metadata required for interfacing
|
||||||
// for interfacing with Bazel. Example: out/soong/bazel.
|
// with Bazel. Example: out/soong/bazel.
|
||||||
func (p *bazelPaths) intermediatesDir() string {
|
func (p *bazelPaths) intermediatesDir() string {
|
||||||
return filepath.Join(p.buildDir, "bazel")
|
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
|
// Issues commands to Bazel to receive results for all cquery requests
|
||||||
// queued in the BazelContext.
|
// queued in the BazelContext.
|
||||||
func (context *bazelContext) InvokeBazel() error {
|
func (context *bazelContext) InvokeBazel() error {
|
||||||
@@ -608,47 +582,47 @@ func (context *bazelContext) InvokeBazel() error {
|
|||||||
var cqueryErr string
|
var cqueryErr string
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
intermediatesDirPath := absolutePath(context.paths.intermediatesDir())
|
soongInjectionPath := absolutePath(context.paths.injectedFilesDir())
|
||||||
if _, err := os.Stat(intermediatesDirPath); os.IsNotExist(err) {
|
if _, err := os.Stat(soongInjectionPath); os.IsNotExist(err) {
|
||||||
err = os.Mkdir(intermediatesDirPath, 0777)
|
err = os.Mkdir(soongInjectionPath, 0777)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "WORKSPACE.bazel"), []byte{}, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err = ioutil.WriteFile(
|
err = ioutil.WriteFile(
|
||||||
filepath.Join(intermediatesDirPath, "main.bzl"),
|
filepath.Join(soongInjectionPath, "main.bzl"),
|
||||||
context.mainBzlFileContents(), 0666)
|
context.mainBzlFileContents(), 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ioutil.WriteFile(
|
err = ioutil.WriteFile(
|
||||||
filepath.Join(intermediatesDirPath, "BUILD.bazel"),
|
filepath.Join(soongInjectionPath, "BUILD.bazel"),
|
||||||
context.mainBuildFileContents(), 0666)
|
context.mainBuildFileContents(), 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cqueryFileRelpath := filepath.Join(context.paths.intermediatesDir(), "buildroot.cquery")
|
cqueryFileRelpath := filepath.Join(context.paths.injectedFilesDir(), "buildroot.cquery")
|
||||||
err = ioutil.WriteFile(
|
err = ioutil.WriteFile(
|
||||||
absolutePath(cqueryFileRelpath),
|
absolutePath(cqueryFileRelpath),
|
||||||
context.cqueryStarlarkFileContents(), 0666)
|
context.cqueryStarlarkFileContents(), 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = ioutil.WriteFile(
|
buildrootLabel := "@soong_injection//:buildroot"
|
||||||
filepath.Join(intermediatesDirPath, "WORKSPACE.bazel"),
|
|
||||||
context.workspaceFileContents(), 0666)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
buildrootLabel := "//:buildroot"
|
|
||||||
cqueryOutput, cqueryErr, err = context.issueBazelCommand(
|
cqueryOutput, cqueryErr, err = context.issueBazelCommand(
|
||||||
context.paths,
|
context.paths,
|
||||||
bazel.CqueryBuildRootRunName,
|
bazel.CqueryBuildRootRunName,
|
||||||
bazelCommand{"cquery", fmt.Sprintf("kind(rule, deps(%s))", buildrootLabel)},
|
bazelCommand{"cquery", fmt.Sprintf("kind(rule, deps(%s))", buildrootLabel)},
|
||||||
"--output=starlark",
|
"--output=starlark",
|
||||||
"--starlark:file="+cqueryFileRelpath)
|
"--starlark:file="+absolutePath(cqueryFileRelpath))
|
||||||
err = ioutil.WriteFile(filepath.Join(intermediatesDirPath, "cquery.out"),
|
err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"),
|
||||||
[]byte(cqueryOutput), 0666)
|
[]byte(cqueryOutput), 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -702,7 +676,7 @@ func (context *bazelContext) InvokeBazel() error {
|
|||||||
_, _, err = context.issueBazelCommand(
|
_, _, err = context.issueBazelCommand(
|
||||||
context.paths,
|
context.paths,
|
||||||
bazel.BazelBuildPhonyRootRunName,
|
bazel.BazelBuildPhonyRootRunName,
|
||||||
bazelCommand{"build", "//:phonyroot"})
|
bazelCommand{"build", "@soong_injection//:phonyroot"})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -781,7 +755,7 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getCqueryId(key cqueryKey) string {
|
func getCqueryId(key cqueryKey) string {
|
||||||
return canonicalizeLabel(key.label) + "|" + getArchString(key)
|
return key.label + "|" + getArchString(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getArchString(key cqueryKey) string {
|
func getArchString(key cqueryKey) string {
|
||||||
|
Reference in New Issue
Block a user