Call mixed mode Bazel in the symlink forest.
Test: Presubmits + manual execution.
Change-Id: Idef2d821222ccbf9385d0ea3fc92178b3206df0a
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 8d561d2..4598995 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -321,9 +321,8 @@
// 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 @@
// 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 @@
}
}
-// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
_, _, 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 getCqueryId(key cqueryKey) string {
- return canonicalizeLabel(key.label) + "|" + getArchString(key)
+ return key.label + "|" + getArchString(key)
}
func getArchString(key cqueryKey) string {