Add --dumpvar[s]-mode to replace config.mk uses

build/soong/soong_ui.bash --dumpvars-mode \
    --vars="..." \
    --abs-vars="..." \
    --var-prefix="..." \
    --abs-var-prefix="..."

is similar to the previous:

  CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
  make -f build/core/config.mk dump-many-vars \
    DUMP_MANY_VARS="..." \
    DUMP_MANY_ABS_VARS="..." \
    DUMP_VAR_PREFIX="..." \
    DUMP_ABS_VAR_PREFIX="..."

and

  build/soong/soong_ui.bash --dumpvar-mode [--abs] VAR

is similar to the previous:

  CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
  make -f build/core/config.mk dumpvar-[abs-]-VAR

But uses soong_ui and ckati, so that we use a consistent make parser and
sandboxing configurations.

One major output difference between the pure make implementation and
this one is that report_config in Go is implemented using embedded
newlines in single quotes, while the make implementation uses `` with
embedded echo commands. This seems to work fine for both bash and zsh,
and report_config isn't meant to be machine-parsed anyways.

Test: build/soong/soong_ui.bash --dumpvar-mode report_config
Test: build/soong/soong_ui.bash --dumpvar-mode TARGET_DEVICE
Test: build/soong/soong_ui.bash --dumpvar-mode --abs PRODUCT_OUT
Test: build/soong/soong_ui.bash --dumpvar-mode --abs ALL_PRODUCTS
Test: build/soong/soong_ui.bash --dumpvars-mode --vars="report_config TARGET_DEVICE" --abs-vars="ALL_PRODUCTS"
Test: build/soong/soong_ui.bash --dumpvars-mode --vars=TARGET_DEVICE --abs-vars=PRODUCT_OUT --var-prefix=v_ --abs-var-prefix=a_
Change-Id: I0fbd0732bbf6fcfcd24084cf3c830a91a4b6bfc2
This commit is contained in:
Dan Willemsen 2017-07-14 11:29:29 -07:00
parent 0e8afed83a
commit 051133ba54
2 changed files with 183 additions and 40 deletions

View File

@ -16,6 +16,8 @@ package main
import (
"context"
"flag"
"fmt"
"os"
"path/filepath"
"strconv"
@ -45,7 +47,10 @@ func main() {
log := logger.New(os.Stderr)
defer log.Cleanup()
if len(os.Args) < 2 || !inList("--make-mode", os.Args) {
if len(os.Args) < 2 || !(inList("--make-mode", os.Args) ||
os.Args[1] == "--dumpvars-mode" ||
os.Args[1] == "--dumpvar-mode") {
log.Fatalln("The `soong` native UI is not yet available.")
}
@ -66,7 +71,12 @@ func main() {
Tracer: trace,
StdioInterface: build.StdioImpl{},
}}
config := build.NewConfig(buildCtx, os.Args[1:]...)
var config build.Config
if os.Args[1] == "--dumpvars-mode" || os.Args[1] == "--dumpvar-mode" {
config = build.NewConfig(buildCtx)
} else {
config = build.NewConfig(buildCtx, os.Args[1:]...)
}
log.SetVerbose(config.IsVerbose())
build.SetupOutDir(buildCtx, config)
@ -99,5 +109,129 @@ func main() {
defer f.Shutdown()
build.FindSources(buildCtx, config, f)
build.Build(buildCtx, config, build.BuildAll)
if os.Args[1] == "--dumpvar-mode" {
dumpVar(buildCtx, config, os.Args[2:])
} else if os.Args[1] == "--dumpvars-mode" {
dumpVars(buildCtx, config, os.Args[2:])
} else {
build.Build(buildCtx, config, build.BuildAll)
}
}
func dumpVar(ctx build.Context, config build.Config, args []string) {
flags := flag.NewFlagSet("dumpvar", flag.ExitOnError)
flags.Usage = func() {
fmt.Fprintf(os.Stderr, "usage: %s --dumpvar-mode [--abs] <VAR>\n\n", os.Args[0])
fmt.Fprintln(os.Stderr, "In dumpvar mode, print the value of the legacy make variable VAR to stdout")
fmt.Fprintln(os.Stderr, "")
fmt.Fprintln(os.Stderr, "'report_config' is a special case that prints the human-readable config banner")
fmt.Fprintln(os.Stderr, "from the beginning of the build.")
fmt.Fprintln(os.Stderr, "")
flags.PrintDefaults()
}
abs := flags.Bool("abs", false, "Print the absolute path of the value")
flags.Parse(args)
if flags.NArg() != 1 {
flags.Usage()
os.Exit(1)
}
varName := flags.Arg(0)
if varName == "report_config" {
varData, err := build.DumpMakeVars(ctx, config, nil, build.BannerVars)
if err != nil {
ctx.Fatal(err)
}
fmt.Println(build.Banner(varData))
} else {
varData, err := build.DumpMakeVars(ctx, config, nil, []string{varName})
if err != nil {
ctx.Fatal(err)
}
if *abs {
var res []string
for _, path := range strings.Fields(varData[varName]) {
if abs, err := filepath.Abs(path); err == nil {
res = append(res, abs)
} else {
ctx.Fatalln("Failed to get absolute path of", path, err)
}
}
fmt.Println(strings.Join(res, " "))
} else {
fmt.Println(varData[varName])
}
}
}
func dumpVars(ctx build.Context, config build.Config, args []string) {
flags := flag.NewFlagSet("dumpvars", flag.ExitOnError)
flags.Usage = func() {
fmt.Fprintf(os.Stderr, "usage: %s --dumpvars-mode [--vars=\"VAR VAR ...\"]\n\n", os.Args[0])
fmt.Fprintln(os.Stderr, "In dumpvars mode, dump the values of one or more legacy make variables, in")
fmt.Fprintln(os.Stderr, "shell syntax. The resulting output may be sourced directly into a shell to")
fmt.Fprintln(os.Stderr, "set corresponding shell variables.")
fmt.Fprintln(os.Stderr, "")
fmt.Fprintln(os.Stderr, "'report_config' is a special case that dumps a variable containing the")
fmt.Fprintln(os.Stderr, "human-readable config banner from the beginning of the build.")
fmt.Fprintln(os.Stderr, "")
flags.PrintDefaults()
}
varsStr := flags.String("vars", "", "Space-separated list of variables to dump")
absVarsStr := flags.String("abs-vars", "", "Space-separated list of variables to dump (using absolute paths)")
varPrefix := flags.String("var-prefix", "", "String to prepend to all variable names when dumping")
absVarPrefix := flags.String("abs-var-prefix", "", "String to prepent to all absolute path variable names when dumping")
flags.Parse(args)
if flags.NArg() != 0 {
flags.Usage()
os.Exit(1)
}
vars := strings.Fields(*varsStr)
absVars := strings.Fields(*absVarsStr)
allVars := append([]string{}, vars...)
allVars = append(allVars, absVars...)
if i := indexList("report_config", allVars); i != -1 {
allVars = append(allVars[:i], allVars[i+1:]...)
allVars = append(allVars, build.BannerVars...)
}
if len(allVars) == 0 {
return
}
varData, err := build.DumpMakeVars(ctx, config, nil, allVars)
if err != nil {
ctx.Fatal(err)
}
for _, name := range vars {
if name == "report_config" {
fmt.Printf("%sreport_config='%s'\n", *varPrefix, build.Banner(varData))
} else {
fmt.Printf("%s%s='%s'\n", *varPrefix, name, varData[name])
}
}
for _, name := range absVars {
var res []string
for _, path := range strings.Fields(varData[name]) {
abs, err := filepath.Abs(path)
if err != nil {
ctx.Fatalln("Failed to get absolute path of", path, err)
}
res = append(res, abs)
}
fmt.Printf("%s%s='%s'\n", *absVarPrefix, name, strings.Join(res, " "))
}
}

View File

@ -15,6 +15,7 @@
package build
import (
"bytes"
"fmt"
"strings"
)
@ -78,6 +79,49 @@ func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_
return ret, nil
}
// Variables to print out in the top banner
var BannerVars = []string{
"PLATFORM_VERSION_CODENAME",
"PLATFORM_VERSION",
"TARGET_PRODUCT",
"TARGET_BUILD_VARIANT",
"TARGET_BUILD_TYPE",
"TARGET_BUILD_APPS",
"TARGET_ARCH",
"TARGET_ARCH_VARIANT",
"TARGET_CPU_VARIANT",
"TARGET_2ND_ARCH",
"TARGET_2ND_ARCH_VARIANT",
"TARGET_2ND_CPU_VARIANT",
"HOST_ARCH",
"HOST_2ND_ARCH",
"HOST_OS",
"HOST_OS_EXTRA",
"HOST_CROSS_OS",
"HOST_CROSS_ARCH",
"HOST_CROSS_2ND_ARCH",
"HOST_BUILD_TYPE",
"BUILD_ID",
"OUT_DIR",
"AUX_OS_VARIANT_LIST",
"TARGET_BUILD_PDK",
"PDK_FUSION_PLATFORM_ZIP",
}
func Banner(make_vars map[string]string) string {
b := &bytes.Buffer{}
fmt.Fprintln(b, "============================================")
for _, name := range BannerVars {
if make_vars[name] != "" {
fmt.Fprintf(b, "%s=%s\n", name, make_vars[name])
}
}
fmt.Fprint(b, "============================================")
return b.String()
}
func runMakeProductConfig(ctx Context, config Config) {
// Variables to export into the environment of Kati/Ninja
exportEnvVars := []string{
@ -99,35 +143,6 @@ func runMakeProductConfig(ctx Context, config Config) {
"CCACHE_CPP2",
}
// Variables to print out in the top banner
bannerVars := []string{
"PLATFORM_VERSION_CODENAME",
"PLATFORM_VERSION",
"TARGET_PRODUCT",
"TARGET_BUILD_VARIANT",
"TARGET_BUILD_TYPE",
"TARGET_BUILD_APPS",
"TARGET_ARCH",
"TARGET_ARCH_VARIANT",
"TARGET_CPU_VARIANT",
"TARGET_2ND_ARCH",
"TARGET_2ND_ARCH_VARIANT",
"TARGET_2ND_CPU_VARIANT",
"HOST_ARCH",
"HOST_2ND_ARCH",
"HOST_OS",
"HOST_OS_EXTRA",
"HOST_CROSS_OS",
"HOST_CROSS_ARCH",
"HOST_CROSS_2ND_ARCH",
"HOST_BUILD_TYPE",
"BUILD_ID",
"OUT_DIR",
"AUX_OS_VARIANT_LIST",
"TARGET_BUILD_PDK",
"PDK_FUSION_PLATFORM_ZIP",
}
allVars := append(append([]string{
// Used to execute Kati and Ninja
"NINJA_GOALS",
@ -135,7 +150,7 @@ func runMakeProductConfig(ctx Context, config Config) {
// To find target/product/<DEVICE>
"TARGET_DEVICE",
}, exportEnvVars...), bannerVars...)
}, exportEnvVars...), BannerVars...)
make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true)
if err != nil {
@ -143,13 +158,7 @@ func runMakeProductConfig(ctx Context, config Config) {
}
// Print the banner like make does
fmt.Fprintln(ctx.Stdout(), "============================================")
for _, name := range bannerVars {
if make_vars[name] != "" {
fmt.Fprintf(ctx.Stdout(), "%s=%s\n", name, make_vars[name])
}
}
fmt.Fprintln(ctx.Stdout(), "============================================")
fmt.Fprintln(ctx.Stdout(), Banner(make_vars))
// Populate the environment
env := config.Environment()