mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-15 16:33:40 +00:00
compileopts: refactor defaultTarget function
Move triple calculation into defaultTarget. It was separate for historic reasons that no longer apply. Merging the code makes future changes easier (in particular, softfloat support). The new code is actually shorter than the old code even though it has more comments.
This commit is contained in:
committed by
Ron Evans
parent
d6e73b4c68
commit
6efc6d2bb6
@@ -64,7 +64,6 @@ func TestClangAttributes(t *testing.T) {
|
|||||||
{GOOS: "windows", GOARCH: "amd64"},
|
{GOOS: "windows", GOARCH: "amd64"},
|
||||||
{GOOS: "windows", GOARCH: "arm64"},
|
{GOOS: "windows", GOARCH: "arm64"},
|
||||||
{GOOS: "wasip1", GOARCH: "wasm"},
|
{GOOS: "wasip1", GOARCH: "wasm"},
|
||||||
{GOOS: "wasip2", GOARCH: "wasm"},
|
|
||||||
} {
|
} {
|
||||||
name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH
|
name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH
|
||||||
if options.GOARCH == "arm" {
|
if options.GOARCH == "arm" {
|
||||||
|
|||||||
+83
-91
@@ -172,63 +172,7 @@ func (spec *TargetSpec) resolveInherits() error {
|
|||||||
// Load a target specification.
|
// Load a target specification.
|
||||||
func LoadTarget(options *Options) (*TargetSpec, error) {
|
func LoadTarget(options *Options) (*TargetSpec, error) {
|
||||||
if options.Target == "" {
|
if options.Target == "" {
|
||||||
// Configure based on GOOS/GOARCH environment variables (falling back to
|
return defaultTarget(options)
|
||||||
// runtime.GOOS/runtime.GOARCH), and generate a LLVM target based on it.
|
|
||||||
var llvmarch string
|
|
||||||
switch options.GOARCH {
|
|
||||||
case "386":
|
|
||||||
llvmarch = "i386"
|
|
||||||
case "amd64":
|
|
||||||
llvmarch = "x86_64"
|
|
||||||
case "arm64":
|
|
||||||
llvmarch = "aarch64"
|
|
||||||
case "arm":
|
|
||||||
switch options.GOARM {
|
|
||||||
case "5":
|
|
||||||
llvmarch = "armv5"
|
|
||||||
case "6":
|
|
||||||
llvmarch = "armv6"
|
|
||||||
case "7":
|
|
||||||
llvmarch = "armv7"
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid GOARM=%s, must be 5, 6, or 7", options.GOARM)
|
|
||||||
}
|
|
||||||
case "mips":
|
|
||||||
llvmarch = "mips"
|
|
||||||
case "mipsle":
|
|
||||||
llvmarch = "mipsel"
|
|
||||||
case "wasm":
|
|
||||||
llvmarch = "wasm32"
|
|
||||||
default:
|
|
||||||
llvmarch = options.GOARCH
|
|
||||||
}
|
|
||||||
llvmvendor := "unknown"
|
|
||||||
llvmos := options.GOOS
|
|
||||||
switch llvmos {
|
|
||||||
case "darwin":
|
|
||||||
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer
|
|
||||||
// to iOS!
|
|
||||||
llvmos = "macosx10.12.0"
|
|
||||||
if llvmarch == "aarch64" {
|
|
||||||
// Looks like Apple prefers to call this architecture ARM64
|
|
||||||
// instead of AArch64.
|
|
||||||
llvmarch = "arm64"
|
|
||||||
llvmos = "macosx11.0.0"
|
|
||||||
}
|
|
||||||
llvmvendor = "apple"
|
|
||||||
case "wasip1":
|
|
||||||
llvmos = "wasi"
|
|
||||||
}
|
|
||||||
// Target triples (which actually have four components, but are called
|
|
||||||
// triples for historical reasons) have the form:
|
|
||||||
// arch-vendor-os-environment
|
|
||||||
target := llvmarch + "-" + llvmvendor + "-" + llvmos
|
|
||||||
if options.GOOS == "windows" {
|
|
||||||
target += "-gnu"
|
|
||||||
} else if options.GOARCH == "arm" {
|
|
||||||
target += "-gnueabihf"
|
|
||||||
}
|
|
||||||
return defaultTarget(options.GOOS, options.GOARCH, target)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// See whether there is a target specification for this target (e.g.
|
// See whether there is a target specification for this target (e.g.
|
||||||
@@ -289,14 +233,13 @@ func GetTargetSpecs() (map[string]*TargetSpec, error) {
|
|||||||
return maps, nil
|
return maps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
// Load a target from environment variables (which default to
|
||||||
// No target spec available. Use the default one, useful on most systems
|
// runtime.GOOS/runtime.GOARCH).
|
||||||
// with a regular OS.
|
func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||||
spec := TargetSpec{
|
spec := TargetSpec{
|
||||||
Triple: triple,
|
GOOS: options.GOOS,
|
||||||
GOOS: goos,
|
GOARCH: options.GOARCH,
|
||||||
GOARCH: goarch,
|
BuildTags: []string{options.GOOS, options.GOARCH},
|
||||||
BuildTags: []string{goos, goarch},
|
|
||||||
GC: "precise",
|
GC: "precise",
|
||||||
Scheduler: "tasks",
|
Scheduler: "tasks",
|
||||||
Linker: "cc",
|
Linker: "cc",
|
||||||
@@ -304,29 +247,43 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||||||
GDB: []string{"gdb"},
|
GDB: []string{"gdb"},
|
||||||
PortReset: "false",
|
PortReset: "false",
|
||||||
}
|
}
|
||||||
switch goarch {
|
|
||||||
|
// Configure target based on GOARCH.
|
||||||
|
var llvmarch string
|
||||||
|
switch options.GOARCH {
|
||||||
case "386":
|
case "386":
|
||||||
|
llvmarch = "i386"
|
||||||
spec.CPU = "pentium4"
|
spec.CPU = "pentium4"
|
||||||
spec.Features = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
|
spec.Features = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
|
||||||
case "amd64":
|
case "amd64":
|
||||||
|
llvmarch = "x86_64"
|
||||||
spec.CPU = "x86-64"
|
spec.CPU = "x86-64"
|
||||||
spec.Features = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
|
spec.Features = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
|
||||||
case "arm":
|
case "arm":
|
||||||
spec.CPU = "generic"
|
spec.CPU = "generic"
|
||||||
spec.CFlags = append(spec.CFlags, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
spec.CFlags = append(spec.CFlags, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
|
||||||
switch strings.Split(triple, "-")[0] {
|
switch options.GOARM {
|
||||||
case "armv5":
|
case "5":
|
||||||
|
llvmarch = "armv5"
|
||||||
spec.Features = "+armv5t,+strict-align,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
spec.Features = "+armv5t,+strict-align,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
case "armv6":
|
case "6":
|
||||||
|
llvmarch = "armv6"
|
||||||
spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-aes,-d32,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-neon,-sha2,-thumb-mode,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-aes,-d32,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-neon,-sha2,-thumb-mode,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
case "armv7":
|
case "7":
|
||||||
|
llvmarch = "armv7"
|
||||||
spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-aes,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-sha2,-thumb-mode,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-aes,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-sha2,-thumb-mode,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp"
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid GOARM=%s, must be 5, 6, or 7", options.GOARM)
|
||||||
}
|
}
|
||||||
case "arm64":
|
case "arm64":
|
||||||
spec.CPU = "generic"
|
spec.CPU = "generic"
|
||||||
if goos == "darwin" {
|
llvmarch = "aarch64"
|
||||||
|
if options.GOOS == "darwin" {
|
||||||
spec.Features = "+fp-armv8,+neon"
|
spec.Features = "+fp-armv8,+neon"
|
||||||
} else if goos == "windows" {
|
// Looks like Apple prefers to call this architecture ARM64
|
||||||
|
// instead of AArch64.
|
||||||
|
llvmarch = "arm64"
|
||||||
|
} else if options.GOOS == "windows" {
|
||||||
spec.Features = "+fp-armv8,+neon,-fmv"
|
spec.Features = "+fp-armv8,+neon,-fmv"
|
||||||
} else { // linux
|
} else { // linux
|
||||||
spec.Features = "+fp-armv8,+neon,-fmv,-outline-atomics"
|
spec.Features = "+fp-armv8,+neon,-fmv,-outline-atomics"
|
||||||
@@ -335,7 +292,13 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||||||
spec.CPU = "mips32r2"
|
spec.CPU = "mips32r2"
|
||||||
spec.Features = "+fpxx,+mips32r2,+nooddspreg,-noabicalls"
|
spec.Features = "+fpxx,+mips32r2,+nooddspreg,-noabicalls"
|
||||||
spec.CFlags = append(spec.CFlags, "-fno-pic")
|
spec.CFlags = append(spec.CFlags, "-fno-pic")
|
||||||
|
if options.GOOS == "mips" {
|
||||||
|
llvmarch = "mips" // big endian
|
||||||
|
} else {
|
||||||
|
llvmarch = "mipsel" // little endian
|
||||||
|
}
|
||||||
case "wasm":
|
case "wasm":
|
||||||
|
llvmarch = "wasm32"
|
||||||
spec.CPU = "generic"
|
spec.CPU = "generic"
|
||||||
spec.Features = "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext"
|
spec.Features = "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext"
|
||||||
spec.BuildTags = append(spec.BuildTags, "tinygo.wasm")
|
spec.BuildTags = append(spec.BuildTags, "tinygo.wasm")
|
||||||
@@ -344,24 +307,37 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||||||
"-mnontrapping-fptoint",
|
"-mnontrapping-fptoint",
|
||||||
"-msign-ext",
|
"-msign-ext",
|
||||||
)
|
)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown GOARCH=%s", options.GOARCH)
|
||||||
}
|
}
|
||||||
if goos == "darwin" {
|
|
||||||
|
// Configure target based on GOOS.
|
||||||
|
llvmos := options.GOOS
|
||||||
|
llvmvendor := "unknown"
|
||||||
|
switch options.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
platformVersion := "10.12.0"
|
||||||
|
if options.GOARCH == "arm64" {
|
||||||
|
platformVersion = "11.0.0" // first macosx platform with arm64 support
|
||||||
|
}
|
||||||
|
llvmvendor = "apple"
|
||||||
spec.Linker = "ld.lld"
|
spec.Linker = "ld.lld"
|
||||||
spec.Libc = "darwin-libSystem"
|
spec.Libc = "darwin-libSystem"
|
||||||
arch := strings.Split(triple, "-")[0]
|
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer to
|
||||||
platformVersion := strings.TrimPrefix(strings.Split(triple, "-")[2], "macosx")
|
// iOS!
|
||||||
|
llvmos = "macosx" + platformVersion
|
||||||
spec.LDFlags = append(spec.LDFlags,
|
spec.LDFlags = append(spec.LDFlags,
|
||||||
"-flavor", "darwin",
|
"-flavor", "darwin",
|
||||||
"-dead_strip",
|
"-dead_strip",
|
||||||
"-arch", arch,
|
"-arch", llvmarch,
|
||||||
"-platform_version", "macos", platformVersion, platformVersion,
|
"-platform_version", "macos", platformVersion, platformVersion,
|
||||||
)
|
)
|
||||||
} else if goos == "linux" {
|
case "linux":
|
||||||
spec.Linker = "ld.lld"
|
spec.Linker = "ld.lld"
|
||||||
spec.RTLib = "compiler-rt"
|
spec.RTLib = "compiler-rt"
|
||||||
spec.Libc = "musl"
|
spec.Libc = "musl"
|
||||||
spec.LDFlags = append(spec.LDFlags, "--gc-sections")
|
spec.LDFlags = append(spec.LDFlags, "--gc-sections")
|
||||||
if goarch == "arm64" {
|
if options.GOARCH == "arm64" {
|
||||||
// Disable outline atomics. For details, see:
|
// Disable outline atomics. For details, see:
|
||||||
// https://cpufun.substack.com/p/atomics-in-aarch64
|
// https://cpufun.substack.com/p/atomics-in-aarch64
|
||||||
// A better way would be to fully support outline atomics, which
|
// A better way would be to fully support outline atomics, which
|
||||||
@@ -375,7 +351,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||||||
// proper threading.
|
// proper threading.
|
||||||
spec.CFlags = append(spec.CFlags, "-mno-outline-atomics")
|
spec.CFlags = append(spec.CFlags, "-mno-outline-atomics")
|
||||||
}
|
}
|
||||||
} else if goos == "windows" {
|
case "windows":
|
||||||
spec.Linker = "ld.lld"
|
spec.Linker = "ld.lld"
|
||||||
spec.Libc = "mingw-w64"
|
spec.Libc = "mingw-w64"
|
||||||
// Note: using a medium code model, low image base and no ASLR
|
// Note: using a medium code model, low image base and no ASLR
|
||||||
@@ -384,7 +360,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||||||
// normally present in Go (without explicitly opting in).
|
// normally present in Go (without explicitly opting in).
|
||||||
// For more discussion:
|
// For more discussion:
|
||||||
// https://groups.google.com/g/Golang-nuts/c/Jd9tlNc6jUE/m/Zo-7zIP_m3MJ?pli=1
|
// https://groups.google.com/g/Golang-nuts/c/Jd9tlNc6jUE/m/Zo-7zIP_m3MJ?pli=1
|
||||||
switch goarch {
|
switch options.GOARCH {
|
||||||
case "amd64":
|
case "amd64":
|
||||||
spec.LDFlags = append(spec.LDFlags,
|
spec.LDFlags = append(spec.LDFlags,
|
||||||
"-m", "i386pep",
|
"-m", "i386pep",
|
||||||
@@ -401,7 +377,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||||||
"--no-insert-timestamp",
|
"--no-insert-timestamp",
|
||||||
"--no-dynamicbase",
|
"--no-dynamicbase",
|
||||||
)
|
)
|
||||||
} else if goos == "wasip1" {
|
case "wasip1":
|
||||||
spec.GC = "" // use default GC
|
spec.GC = "" // use default GC
|
||||||
spec.Scheduler = "asyncify"
|
spec.Scheduler = "asyncify"
|
||||||
spec.Linker = "wasm-ld"
|
spec.Linker = "wasm-ld"
|
||||||
@@ -417,28 +393,43 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||||||
"src/runtime/asm_tinygowasm.S",
|
"src/runtime/asm_tinygowasm.S",
|
||||||
"src/internal/task/task_asyncify_wasm.S",
|
"src/internal/task/task_asyncify_wasm.S",
|
||||||
)
|
)
|
||||||
} else {
|
llvmos = "wasi"
|
||||||
spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown GOOS=%s", options.GOOS)
|
||||||
}
|
}
|
||||||
if goarch != "wasm" {
|
|
||||||
|
// Target triples (which actually have four components, but are called
|
||||||
|
// triples for historical reasons) have the form:
|
||||||
|
// arch-vendor-os-environment
|
||||||
|
spec.Triple = llvmarch + "-" + llvmvendor + "-" + llvmos
|
||||||
|
if options.GOOS == "windows" {
|
||||||
|
spec.Triple += "-gnu"
|
||||||
|
} else if options.GOARCH == "arm" {
|
||||||
|
spec.Triple += "-gnueabihf"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add extra assembly files (needed for the scheduler etc).
|
||||||
|
if options.GOARCH != "wasm" {
|
||||||
suffix := ""
|
suffix := ""
|
||||||
if goos == "windows" && goarch == "amd64" {
|
if options.GOOS == "windows" && options.GOARCH == "amd64" {
|
||||||
// Windows uses a different calling convention on amd64 from other
|
// Windows uses a different calling convention on amd64 from other
|
||||||
// operating systems so we need separate assembly files.
|
// operating systems so we need separate assembly files.
|
||||||
suffix = "_windows"
|
suffix = "_windows"
|
||||||
}
|
}
|
||||||
asmGoarch := goarch
|
asmGoarch := options.GOARCH
|
||||||
if goarch == "mips" || goarch == "mipsle" {
|
if options.GOARCH == "mips" || options.GOARCH == "mipsle" {
|
||||||
asmGoarch = "mipsx"
|
asmGoarch = "mipsx"
|
||||||
}
|
}
|
||||||
spec.ExtraFiles = append(spec.ExtraFiles, "src/runtime/asm_"+asmGoarch+suffix+".S")
|
spec.ExtraFiles = append(spec.ExtraFiles, "src/runtime/asm_"+asmGoarch+suffix+".S")
|
||||||
spec.ExtraFiles = append(spec.ExtraFiles, "src/internal/task/task_stack_"+asmGoarch+suffix+".S")
|
spec.ExtraFiles = append(spec.ExtraFiles, "src/internal/task/task_stack_"+asmGoarch+suffix+".S")
|
||||||
}
|
}
|
||||||
if goarch != runtime.GOARCH {
|
|
||||||
|
// Configure the emulator.
|
||||||
|
if options.GOARCH != runtime.GOARCH {
|
||||||
// Some educated guesses as to how to invoke helper programs.
|
// Some educated guesses as to how to invoke helper programs.
|
||||||
spec.GDB = []string{"gdb-multiarch"}
|
spec.GDB = []string{"gdb-multiarch"}
|
||||||
if goos == "linux" {
|
if options.GOOS == "linux" {
|
||||||
switch goarch {
|
switch options.GOARCH {
|
||||||
case "386":
|
case "386":
|
||||||
// amd64 can _usually_ run 32-bit programs, so skip the emulator in that case.
|
// amd64 can _usually_ run 32-bit programs, so skip the emulator in that case.
|
||||||
if runtime.GOARCH != "amd64" {
|
if runtime.GOARCH != "amd64" {
|
||||||
@@ -457,11 +448,12 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if goos != runtime.GOOS {
|
if options.GOOS != runtime.GOOS {
|
||||||
if goos == "windows" {
|
if options.GOOS == "windows" {
|
||||||
spec.Emulator = "wine {}"
|
spec.Emulator = "wine {}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &spec, nil
|
return &spec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user