122 lines
3.9 KiB
Go
122 lines
3.9 KiB
Go
// Copyright 2022 Google LLC
|
|
//
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
package exporter
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
|
|
"go.skia.org/infra/go/skerr"
|
|
"go.skia.org/skia/bazel/exporter/interfaces"
|
|
)
|
|
|
|
// BazelQueryCommand implements the QueryCommand interface. It will
|
|
// execute the bazel executable to return all rules defined in
|
|
// a protocol buffer.
|
|
type BazelQueryCommand struct {
|
|
ruleNames []string
|
|
workspace string
|
|
queryType string // "query" or "cquery"
|
|
}
|
|
|
|
// A list of all Skia Bazel build flags which enable the building and/or
|
|
// exposure of all source files.
|
|
var allSkiaFlags = []string{
|
|
"--ck_enable_canvas_polyfill",
|
|
"--ck_enable_embedded_font",
|
|
"--ck_enable_fonts",
|
|
"--ck_enable_matrix_js",
|
|
"--ck_enable_runtime_effect",
|
|
"--ck_enable_skottie",
|
|
"--ck_enable_skp_serialization",
|
|
"--enable_effect_serialization",
|
|
"--enable_gpu_test_utils",
|
|
"--enable_pdf_backend",
|
|
"--enable_sksl_tracing",
|
|
"--enable_sksl",
|
|
// "--enable_skslc", // external dependency on spirv-tools/libspirv.hpp
|
|
"--enable_svg_canvas",
|
|
"--enable_tracing",
|
|
"--enable_vma",
|
|
// "--fontmgr_factory=custom_embedded_fontmgr_factory", // external dependency on ft2build.h
|
|
"--gpu_backend=gl_backend",
|
|
// "--include_decoder=*", // All decoders have external dependencies.
|
|
// "--include_encoder", // All encoders have external dependencies.
|
|
// "--include_fontmgr=custom_embedded_fontmgr", // external dependency on ft2build.h
|
|
}
|
|
|
|
// NewBazelQueryCommand will create a new BazelQueryCommand instance which will,
|
|
// when Read() is called, invoke the bazel executable to execute a cquery
|
|
// command in the provided workspace for the supplied rules.
|
|
func NewBazelCMakeQueryCommand(ruleNames []string, workspace string) *BazelQueryCommand {
|
|
return &BazelQueryCommand{ruleNames: ruleNames, workspace: workspace, queryType: "cquery"}
|
|
}
|
|
|
|
// NewBazelQueryCommand will create a new BazelQueryCommand instance which will,
|
|
// when Read() is called, invoke the bazel executable to execute a query
|
|
// command in the provided workspace for the supplied rules.
|
|
func NewBazelGNIQueryCommand(ruleNames []string, workspace string) *BazelQueryCommand {
|
|
return &BazelQueryCommand{ruleNames: ruleNames, workspace: workspace, queryType: "query"}
|
|
}
|
|
|
|
// Stop the Bazel server if running.
|
|
func shutdownBazelServer() error {
|
|
cmd := exec.Command("bazelisk", "shutdown")
|
|
_, err := cmd.Output()
|
|
return err
|
|
}
|
|
|
|
// Read will execute the Bazel query/cquery command, supplied to NewBazel*QueryCommand(),
|
|
// and return the binary protobuf results.
|
|
func (c *BazelQueryCommand) Read() ([]byte, error) {
|
|
if len(c.ruleNames) == 0 {
|
|
return nil, skerr.Fmt("no query rules")
|
|
}
|
|
|
|
pwd, err := os.Getwd()
|
|
if err != nil {
|
|
return nil, skerr.Wrapf(err, `can't get working directory`)
|
|
}
|
|
err = os.Chdir(c.workspace)
|
|
if err != nil {
|
|
return nil, skerr.Wrapf(err, `can't set working directory to %q`, c.workspace)
|
|
}
|
|
if c.queryType == "cquery" {
|
|
// Shutdown the Bazel server to workaround a known issue with cquery:
|
|
// See "Non-deterministic output" in https://bazel.build/docs/cquery#known-issues
|
|
err = shutdownBazelServer()
|
|
if err != nil {
|
|
return nil, skerr.Wrap(err)
|
|
}
|
|
}
|
|
ruleArg := `kind("rule", `
|
|
for i, r := range c.ruleNames {
|
|
if i > 0 {
|
|
ruleArg = ruleArg + " + "
|
|
}
|
|
ruleArg = ruleArg + fmt.Sprintf("deps(%s)", r)
|
|
}
|
|
ruleArg = ruleArg + ")"
|
|
args := []string{c.queryType, "--noimplicit_deps", ruleArg, "--output", "proto"}
|
|
if c.queryType == "cquery" {
|
|
args = append(args, allSkiaFlags...)
|
|
}
|
|
cmd := exec.Command("bazelisk", args...)
|
|
_ = os.Chdir(pwd)
|
|
data, err := cmd.Output()
|
|
if err != nil {
|
|
if exiterr, ok := err.(*exec.ExitError); ok {
|
|
fmt.Printf("Stderr: %s\n", exiterr.Stderr)
|
|
}
|
|
return nil, skerr.Wrapf(err, `error running %v`, cmd)
|
|
}
|
|
return data, nil
|
|
}
|
|
|
|
// Make sure BazelQueryCommand fulfills the QueryCommand interface.
|
|
var _ interfaces.QueryCommand = (*BazelQueryCommand)(nil)
|