aboutsummaryrefslogtreecommitdiffhomepage
path: root/compileopts/options.go
blob: 980097200d335ca31d721a8fe0e706d704cd1273 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package compileopts

import (
	"fmt"
	"regexp"
	"strings"
	"time"
)

var (
	validGCOptions            = []string{"none", "leaking", "conservative", "custom", "precise"}
	validSchedulerOptions     = []string{"none", "tasks", "asyncify"}
	validSerialOptions        = []string{"none", "uart", "usb", "rtt"}
	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, but can also be passed in environment
// variables for example.
type Options struct {
	GOOS            string // environment variable
	GOARCH          string // environment variable
	GOARM           string // environment variable (only used with GOARCH=arm)
	GOMIPS          string // environment variable (only used with GOARCH=mips and GOARCH=mipsle)
	Directory       string // working dir, leave it unset to use the current working dir
	Target          string
	Opt             string
	GC              string
	PanicStrategy   string
	Scheduler       string
	StackSize       uint64 // goroutine stack size (if none could be automatically determined)
	Serial          string
	Work            bool // -work flag to print temporary build directory
	InterpTimeout   time.Duration
	PrintIR         bool
	DumpSSA         bool
	VerifyIR        bool
	SkipDWARF       bool
	PrintCommands   func(cmd string, args ...string) `json:"-"`
	Semaphore       chan struct{}                    `json:"-"` // -p flag controls cap
	Debug           bool
	PrintSizes      string
	PrintAllocs     *regexp.Regexp // regexp string
	PrintStacks     bool
	Tags            []string
	GlobalValues    map[string]map[string]string // map[pkgpath]map[varname]value
	TestConfig      TestConfig
	Programmer      string
	OpenOCDCommands []string
	LLVMFeatures    string
	PrintJSON       bool
	Monitor         bool
	BaudRate        int
	Timeout         time.Duration
	WITPackage      string // pass through to wasm-tools component embed invocation
	WITWorld        string // pass through to wasm-tools component embed -w option
	ExtLDFlags      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.Serial != "" {
		valid := isInArray(validSerialOptions, o.Serial)
		if !valid {
			return fmt.Errorf(`invalid serial option '%s': valid values are %s`,
				o.Serial,
				strings.Join(validSerialOptions, ", "))
		}
	}

	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
}