mirror of https://github.com/tinygo-org/tinygo.git
wasmstm32webassemblymicrocontrollerarmavrspiwasiadafruitarduinocircuitplayground-expressgpioi2cllvmmicrobitnrf51nrf52nrf52840samd21tinygo
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.3 KiB
87 lines
2.3 KiB
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
// Target specification for a given target. Used for bare metal targets.
|
|
//
|
|
// The target specification is mostly inspired by Rust:
|
|
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/struct.TargetOptions.html
|
|
// https://github.com/shepmaster/rust-arduino-blink-led-no-core-with-cargo/blob/master/blink/arduino.json
|
|
type TargetSpec struct {
|
|
Triple string `json:"llvm-target"`
|
|
BuildTags []string `json:"build-tags"`
|
|
Linker string `json:"linker"`
|
|
PreLinkArgs []string `json:"pre-link-args"`
|
|
Objcopy string `json:"objcopy"`
|
|
Flasher string `json:"flash"`
|
|
OCDDaemon []string `json:"ocd-daemon"`
|
|
GDB string `json:"gdb"`
|
|
GDBCmds []string `json:"gdb-initial-cmds"`
|
|
}
|
|
|
|
// Load a target specification
|
|
func LoadTarget(target string) (*TargetSpec, error) {
|
|
spec := &TargetSpec{
|
|
Triple: target,
|
|
BuildTags: []string{runtime.GOOS, runtime.GOARCH},
|
|
Linker: "cc",
|
|
PreLinkArgs: []string{"-no-pie"}, // WARNING: clang < 5.0 requires -nopie
|
|
Objcopy: "objcopy",
|
|
GDB: "gdb",
|
|
GDBCmds: []string{"run"},
|
|
}
|
|
|
|
// See whether there is a target specification for this target (e.g.
|
|
// Arduino).
|
|
path := filepath.Join(sourceDir(), "targets", strings.ToLower(target)+".json")
|
|
if fp, err := os.Open(path); err == nil {
|
|
defer fp.Close()
|
|
*spec = TargetSpec{} // reset all fields
|
|
err := json.NewDecoder(fp).Decode(spec)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else if !os.IsNotExist(err) {
|
|
// Expected a 'file not found' error, got something else.
|
|
return nil, err
|
|
} else {
|
|
// No target spec available. This is fine.
|
|
}
|
|
|
|
return spec, nil
|
|
}
|
|
|
|
// Return the source directory of this package, or "." when it cannot be
|
|
// recovered.
|
|
func sourceDir() string {
|
|
// https://stackoverflow.com/a/32163888/559350
|
|
_, path, _, _ := runtime.Caller(0)
|
|
return filepath.Dir(path)
|
|
}
|
|
|
|
func getGopath() string {
|
|
gopath := os.Getenv("GOPATH")
|
|
if gopath != "" {
|
|
return gopath
|
|
}
|
|
|
|
// fallback
|
|
var home string
|
|
if runtime.GOOS == "windows" {
|
|
home = os.Getenv("USERPROFILE")
|
|
} else {
|
|
home = os.Getenv("HOME")
|
|
}
|
|
if home == "" {
|
|
// This is very unlikely, so panic here.
|
|
// Not the nicest solution, however.
|
|
panic("no $HOME or %USERPROFILE% found")
|
|
}
|
|
return filepath.Join(home, "go")
|
|
}
|
|
|