
This commit implements replacing some global variables with a different value, if the global variable has no initializer. For example, if you have: package main var version string you can replace the value with -ldflags="-X main.version=0.2". Right now it only works for uninitialized globals. The Go tooling also supports initialized globals (var version = "<undefined>") but that is a bit hard to combine with how initialized globals are currently implemented. The current implementation still allows caching package IR files while making sure the values don't end up in the build cache. This means compiling a program multiple times with different values will use the cached package each time, inserting the string value only late in the build process. Fixes #1045
92 строки
2,3 КиБ
Go
92 строки
2,3 КиБ
Go
package compileopts
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
validGCOptions = []string{"none", "leaking", "extalloc", "conservative"}
|
|
validSchedulerOptions = []string{"none", "tasks", "coroutines"}
|
|
validPrintSizeOptions = []string{"none", "short", "full"}
|
|
validPanicStrategyOptions = []string{"print", "trap"}
|
|
validOptOptions = []string{"none", "0", "1", "2", "s", "z"}
|
|
)
|
|
|
|
// Options contains extra options to give to the compiler. These options are
|
|
// usually passed from the command line.
|
|
type Options struct {
|
|
Target string
|
|
Opt string
|
|
GC string
|
|
PanicStrategy string
|
|
Scheduler string
|
|
PrintIR bool
|
|
DumpSSA bool
|
|
VerifyIR bool
|
|
PrintCommands bool
|
|
Debug bool
|
|
PrintSizes string
|
|
PrintStacks bool
|
|
Tags string
|
|
WasmAbi string
|
|
GlobalValues map[string]map[string]string // map[pkgpath]map[varname]value
|
|
TestConfig TestConfig
|
|
Programmer string
|
|
}
|
|
|
|
// Verify performs a validation on the given options, raising an error if options are not valid.
|
|
func (o *Options) Verify() error {
|
|
if o.GC != "" {
|
|
valid := isInArray(validGCOptions, o.GC)
|
|
if !valid {
|
|
return fmt.Errorf(`invalid gc option '%s': valid values are %s`,
|
|
o.GC,
|
|
strings.Join(validGCOptions, ", "))
|
|
}
|
|
}
|
|
|
|
if o.Scheduler != "" {
|
|
valid := isInArray(validSchedulerOptions, o.Scheduler)
|
|
if !valid {
|
|
return fmt.Errorf(`invalid scheduler option '%s': valid values are %s`,
|
|
o.Scheduler,
|
|
strings.Join(validSchedulerOptions, ", "))
|
|
}
|
|
}
|
|
|
|
if o.PrintSizes != "" {
|
|
valid := isInArray(validPrintSizeOptions, o.PrintSizes)
|
|
if !valid {
|
|
return fmt.Errorf(`invalid size option '%s': valid values are %s`,
|
|
o.PrintSizes,
|
|
strings.Join(validPrintSizeOptions, ", "))
|
|
}
|
|
}
|
|
|
|
if o.PanicStrategy != "" {
|
|
valid := isInArray(validPanicStrategyOptions, o.PanicStrategy)
|
|
if !valid {
|
|
return fmt.Errorf(`invalid panic option '%s': valid values are %s`,
|
|
o.PanicStrategy,
|
|
strings.Join(validPanicStrategyOptions, ", "))
|
|
}
|
|
}
|
|
|
|
if o.Opt != "" {
|
|
if !isInArray(validOptOptions, o.Opt) {
|
|
return fmt.Errorf("invalid -opt=%s: valid values are %s", o.Opt, strings.Join(validOptOptions, ", "))
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func isInArray(arr []string, item string) bool {
|
|
for _, i := range arr {
|
|
if i == item {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|