main: test other architectures by specifying a different GOARCH
... instead of setting a special -target= value. This is more robust and makes sure that the test actually tests different arcitectures as they would be compiled by TinyGo. As an example, the bug of the bugfix in the previous commit ("arm: use armv7 instead of thumbv7") would have been caught if this change was applied earlier. I've decided to put GOOS/GOARCH in compileopts.Options, as it makes sense to me to treat them the same way as command line parameters.
Этот коммит содержится в:
родитель
36f1517e8d
коммит
0a80da46b1
8 изменённых файлов: 72 добавлений и 47 удалений
|
@ -13,7 +13,7 @@ import (
|
|||
// uses the currently active GOPATH (from the goenv package) to determine the Go
|
||||
// version to use.
|
||||
func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
|
||||
spec, err := compileopts.LoadTarget(options.Target)
|
||||
spec, err := compileopts.LoadTarget(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -16,8 +16,11 @@ var (
|
|||
)
|
||||
|
||||
// Options contains extra options to give to the compiler. These options are
|
||||
// usually passed from the command line.
|
||||
// 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
|
||||
Target string
|
||||
Opt string
|
||||
GC string
|
||||
|
|
|
@ -161,36 +161,34 @@ func (spec *TargetSpec) resolveInherits() error {
|
|||
}
|
||||
|
||||
// Load a target specification.
|
||||
func LoadTarget(target string) (*TargetSpec, error) {
|
||||
if target == "" {
|
||||
func LoadTarget(options *Options) (*TargetSpec, error) {
|
||||
if options.Target == "" {
|
||||
// Configure based on GOOS/GOARCH environment variables (falling back to
|
||||
// runtime.GOOS/runtime.GOARCH), and generate a LLVM target based on it.
|
||||
goos := goenv.Get("GOOS")
|
||||
goarch := goenv.Get("GOARCH")
|
||||
llvmos := goos
|
||||
llvmos := options.GOOS
|
||||
llvmarch := map[string]string{
|
||||
"386": "i386",
|
||||
"amd64": "x86_64",
|
||||
"arm64": "aarch64",
|
||||
"arm": "armv7",
|
||||
}[goarch]
|
||||
}[options.GOARCH]
|
||||
if llvmarch == "" {
|
||||
llvmarch = goarch
|
||||
llvmarch = options.GOARCH
|
||||
}
|
||||
// Target triples (which actually have four components, but are called
|
||||
// triples for historical reasons) have the form:
|
||||
// arch-vendor-os-environment
|
||||
target = llvmarch + "-unknown-" + llvmos
|
||||
if goarch == "arm" {
|
||||
target := llvmarch + "-unknown-" + llvmos
|
||||
if options.GOARCH == "arm" {
|
||||
target += "-gnueabihf"
|
||||
}
|
||||
return defaultTarget(goos, goarch, target)
|
||||
return defaultTarget(options.GOOS, options.GOARCH, target)
|
||||
}
|
||||
|
||||
// See whether there is a target specification for this target (e.g.
|
||||
// Arduino).
|
||||
spec := &TargetSpec{}
|
||||
err := spec.loadFromGivenStr(target)
|
||||
err := spec.loadFromGivenStr(options.Target)
|
||||
if err == nil {
|
||||
// Successfully loaded this target from a built-in .json file. Make sure
|
||||
// it includes all parents as specified in the "inherits" key.
|
||||
|
@ -206,7 +204,7 @@ func LoadTarget(target string) (*TargetSpec, error) {
|
|||
} else {
|
||||
// Load target from given triple, ignore GOOS/GOARCH environment
|
||||
// variables.
|
||||
tripleSplit := strings.Split(target, "-")
|
||||
tripleSplit := strings.Split(options.Target, "-")
|
||||
if len(tripleSplit) < 3 {
|
||||
return nil, errors.New("expected a full LLVM target or a custom target in -target flag")
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ import (
|
|||
)
|
||||
|
||||
func TestLoadTarget(t *testing.T) {
|
||||
_, err := LoadTarget("arduino")
|
||||
_, err := LoadTarget(&Options{Target: "arduino"})
|
||||
if err != nil {
|
||||
t.Error("LoadTarget test failed:", err)
|
||||
}
|
||||
|
||||
_, err = LoadTarget("notexist")
|
||||
_, err = LoadTarget(&Options{Target: "notexist"})
|
||||
if err == nil {
|
||||
t.Error("LoadTarget should have failed with non existing target")
|
||||
}
|
||||
|
|
|
@ -73,12 +73,15 @@ func TestCompiler(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
target, err := compileopts.LoadTarget(targetString)
|
||||
options := &compileopts.Options{
|
||||
Target: targetString,
|
||||
}
|
||||
target, err := compileopts.LoadTarget(options)
|
||||
if err != nil {
|
||||
t.Fatal("failed to load target:", err)
|
||||
}
|
||||
config := &compileopts.Config{
|
||||
Options: &compileopts.Options{},
|
||||
Options: options,
|
||||
Target: target,
|
||||
}
|
||||
compilerConfig := &Config{
|
||||
|
|
4
main.go
4
main.go
|
@ -1147,6 +1147,8 @@ func main() {
|
|||
}
|
||||
|
||||
options := &compileopts.Options{
|
||||
GOOS: goenv.Get("GOOS"),
|
||||
GOARCH: goenv.Get("GOARCH"),
|
||||
Target: *target,
|
||||
Opt: *opt,
|
||||
GC: *gc,
|
||||
|
@ -1309,7 +1311,7 @@ func main() {
|
|||
continue
|
||||
}
|
||||
path := filepath.Join(dir, entry.Name())
|
||||
spec, err := compileopts.LoadTarget(path)
|
||||
spec, err := compileopts.LoadTarget(&compileopts.Options{Target: path})
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "could not list target:", err)
|
||||
os.Exit(1)
|
||||
|
|
73
main_test.go
73
main_test.go
|
@ -67,13 +67,13 @@ func TestCompiler(t *testing.T) {
|
|||
// This makes it possible to run one specific test (instead of all),
|
||||
// which is especially useful to quickly check whether some changes
|
||||
// affect a particular target architecture.
|
||||
runPlatTests(*testTarget, tests, t)
|
||||
runPlatTests(optionsFromTarget(*testTarget), tests, t)
|
||||
return
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
t.Run("Host", func(t *testing.T) {
|
||||
runPlatTests("", tests, t)
|
||||
runPlatTests(optionsFromTarget(""), tests, t)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -82,32 +82,32 @@ func TestCompiler(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("EmulatedCortexM3", func(t *testing.T) {
|
||||
runPlatTests("cortex-m-qemu", tests, t)
|
||||
runPlatTests(optionsFromTarget("cortex-m-qemu"), tests, t)
|
||||
})
|
||||
|
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||
// Note: running only on Windows and macOS because Linux (as of 2020)
|
||||
// usually has an outdated QEMU version that doesn't support RISC-V yet.
|
||||
t.Run("EmulatedRISCV", func(t *testing.T) {
|
||||
runPlatTests("riscv-qemu", tests, t)
|
||||
runPlatTests(optionsFromTarget("riscv-qemu"), tests, t)
|
||||
})
|
||||
}
|
||||
|
||||
if runtime.GOOS == "linux" {
|
||||
t.Run("X86Linux", func(t *testing.T) {
|
||||
runPlatTests("i386-unknown-linux", tests, t)
|
||||
runPlatTests(optionsFromOSARCH("linux", "386"), tests, t)
|
||||
})
|
||||
t.Run("ARMLinux", func(t *testing.T) {
|
||||
runPlatTests("armv7-unknown-linux-gnueabihf", tests, t)
|
||||
runPlatTests(optionsFromOSARCH("linux", "arm"), tests, t)
|
||||
})
|
||||
t.Run("ARM64Linux", func(t *testing.T) {
|
||||
runPlatTests("aarch64-unknown-linux", tests, t)
|
||||
runPlatTests(optionsFromOSARCH("linux", "arm64"), tests, t)
|
||||
})
|
||||
t.Run("WebAssembly", func(t *testing.T) {
|
||||
runPlatTests("wasm", tests, t)
|
||||
runPlatTests(optionsFromTarget("wasm"), tests, t)
|
||||
})
|
||||
t.Run("WASI", func(t *testing.T) {
|
||||
runPlatTests("wasi", tests, t)
|
||||
runPlatTests(optionsFromTarget("wasi"), tests, t)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -122,8 +122,10 @@ func TestCompiler(t *testing.T) {
|
|||
// Test with few optimizations enabled (no inlining, etc).
|
||||
t.Run("opt=1", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runTestWithConfig("stdlib.go", "", t, compileopts.Options{
|
||||
Opt: "1",
|
||||
runTestWithConfig("stdlib.go", t, compileopts.Options{
|
||||
GOOS: goenv.Get("GOOS"),
|
||||
GOARCH: goenv.Get("GOARCH"),
|
||||
Opt: "1",
|
||||
}, nil, nil)
|
||||
})
|
||||
|
||||
|
@ -131,14 +133,18 @@ func TestCompiler(t *testing.T) {
|
|||
// TODO: fix this for stdlib.go, which currently fails.
|
||||
t.Run("opt=0", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runTestWithConfig("print.go", "", t, compileopts.Options{
|
||||
Opt: "0",
|
||||
runTestWithConfig("print.go", t, compileopts.Options{
|
||||
GOOS: goenv.Get("GOOS"),
|
||||
GOARCH: goenv.Get("GOARCH"),
|
||||
Opt: "0",
|
||||
}, nil, nil)
|
||||
})
|
||||
|
||||
t.Run("ldflags", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runTestWithConfig("ldflags.go", "", t, compileopts.Options{
|
||||
runTestWithConfig("ldflags.go", t, compileopts.Options{
|
||||
GOOS: goenv.Get("GOOS"),
|
||||
GOARCH: goenv.Get("GOARCH"),
|
||||
GlobalValues: map[string]map[string]string{
|
||||
"main": {
|
||||
"someGlobal": "foobar",
|
||||
|
@ -149,30 +155,30 @@ func TestCompiler(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func runPlatTests(target string, tests []string, t *testing.T) {
|
||||
func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, name := range tests {
|
||||
name := name // redefine to avoid race condition
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runTest(name, target, t, nil, nil)
|
||||
runTest(name, options, t, nil, nil)
|
||||
})
|
||||
}
|
||||
t.Run("env.go", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runTest("env.go", target, t, []string{"first", "second"}, []string{"ENV1=VALUE1", "ENV2=VALUE2"})
|
||||
runTest("env.go", options, t, []string{"first", "second"}, []string{"ENV1=VALUE1", "ENV2=VALUE2"})
|
||||
})
|
||||
if target == "" || target == "wasi" {
|
||||
if options.Target == "" || options.Target == "wasi" {
|
||||
t.Run("filesystem.go", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runTest("filesystem.go", target, t, nil, nil)
|
||||
runTest("filesystem.go", options, t, nil, nil)
|
||||
})
|
||||
}
|
||||
if target == "" || target == "wasi" || target == "wasm" {
|
||||
if options.Target == "" || options.Target == "wasi" || options.Target == "wasm" {
|
||||
t.Run("rand.go", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runTest("rand.go", target, t, nil, nil)
|
||||
runTest("rand.go", options, t, nil, nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -189,14 +195,27 @@ func runBuild(src, out string, opts *compileopts.Options) error {
|
|||
return Build(src, out, opts)
|
||||
}
|
||||
|
||||
func runTest(name, target string, t *testing.T, cmdArgs, environmentVars []string) {
|
||||
options := compileopts.Options{
|
||||
func optionsFromTarget(target string) compileopts.Options {
|
||||
return compileopts.Options{
|
||||
// GOOS/GOARCH are only used if target == ""
|
||||
GOOS: goenv.Get("GOOS"),
|
||||
GOARCH: goenv.Get("GOARCH"),
|
||||
Target: target,
|
||||
}
|
||||
runTestWithConfig(name, target, t, options, cmdArgs, environmentVars)
|
||||
}
|
||||
|
||||
func runTestWithConfig(name, target string, t *testing.T, options compileopts.Options, cmdArgs, environmentVars []string) {
|
||||
func optionsFromOSARCH(goos, goarch string) compileopts.Options {
|
||||
return compileopts.Options{
|
||||
GOOS: goos,
|
||||
GOARCH: goarch,
|
||||
}
|
||||
}
|
||||
|
||||
func runTest(name string, options compileopts.Options, t *testing.T, cmdArgs, environmentVars []string) {
|
||||
runTestWithConfig(name, t, options, cmdArgs, environmentVars)
|
||||
}
|
||||
|
||||
func runTestWithConfig(name string, t *testing.T, options compileopts.Options, cmdArgs, environmentVars []string) {
|
||||
// Set default config.
|
||||
options.Debug = true
|
||||
options.VerifyIR = true
|
||||
|
@ -227,7 +246,7 @@ func runTestWithConfig(name, target string, t *testing.T, options compileopts.Op
|
|||
// we need to pass command line arguments and environment variables through
|
||||
// global variables (built into the binary directly) instead of the
|
||||
// conventional way.
|
||||
spec, err := compileopts.LoadTarget(target)
|
||||
spec, err := compileopts.LoadTarget(&options)
|
||||
if err != nil {
|
||||
t.Fatal("failed to load target spec:", err)
|
||||
}
|
||||
|
@ -314,7 +333,7 @@ func runTestWithConfig(name, target string, t *testing.T, options compileopts.Op
|
|||
}
|
||||
}()
|
||||
err = cmd.Wait()
|
||||
if _, ok := err.(*exec.ExitError); ok && target != "" {
|
||||
if _, ok := err.(*exec.ExitError); ok && options.Target != "" {
|
||||
err = nil // workaround for QEMU
|
||||
}
|
||||
close(runComplete)
|
||||
|
|
|
@ -140,7 +140,7 @@ func filterIrrelevantIRLines(lines []string) []string {
|
|||
// run.
|
||||
// If there are any errors, they are reported via the *testing.T instance.
|
||||
func compileGoFileForTesting(t *testing.T, filename string) llvm.Module {
|
||||
target, err := compileopts.LoadTarget("i686--linux")
|
||||
target, err := compileopts.LoadTarget(&compileopts.Options{GOOS: "linux", GOARCH: "386"})
|
||||
if err != nil {
|
||||
t.Fatal("failed to load target:", err)
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче