diff --git a/main.go b/main.go index 40518f07..dbdf3995 100644 --- a/main.go +++ b/main.go @@ -12,21 +12,9 @@ import ( // Helper function for Compiler object. func Compile(pkgName, runtimePath, outpath, target string, printIR, dumpSSA bool) error { - var buildTags []string - // TODO: put this somewhere else - if target == "pca10040" { - // Pretend to be a WASM target, not ARM (for standard library support). - buildTags = append(buildTags, "nrf", "nrf52", "nrf52832", "js", "wasm") - target = "armv7m-none-eabi" - } else if target == "arduino" { - // Pretend to be a WASM target, not AVR (for standard library support). - buildTags = append(buildTags, "avr", "avr8", "atmega", "atmega328p", "js", "wasm") - target = "avr--" - } else { - buildTags = append(buildTags, runtime.GOOS, runtime.GOARCH) - } + spec, err := LoadTarget(target) - c, err := NewCompiler(pkgName, target, dumpSSA) + c, err := NewCompiler(pkgName, spec.Triple, dumpSSA) if err != nil { return err } @@ -52,7 +40,7 @@ func Compile(pkgName, runtimePath, outpath, target string, printIR, dumpSSA bool fmt.Println(c.IR()) }() } - return c.Parse(pkgName, buildTags) + return c.Parse(pkgName, spec.BuildTags) }() if parseErr != nil { return parseErr diff --git a/target.go b/target.go new file mode 100644 index 00000000..476cc8f0 --- /dev/null +++ b/target.go @@ -0,0 +1,45 @@ +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"` +} + +// Load a target specification +func LoadTarget(target string) (*TargetSpec, error) { + spec := &TargetSpec{ + Triple: target, + BuildTags: []string{runtime.GOOS, runtime.GOARCH}, + } + + // See whether there is a target specification for this target (e.g. + // Arduino). + path := filepath.Join("targets", strings.ToLower(target)+".json") + if fp, err := os.Open(path); err == nil { + defer fp.Close() + 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 +} diff --git a/targets/arduino.json b/targets/arduino.json new file mode 100644 index 00000000..5ba6d38f --- /dev/null +++ b/targets/arduino.json @@ -0,0 +1,4 @@ +{ + "llvm-target": "avr-atmel-none", + "build-tags": ["avr", "avr8", "atmega", "atmega328p", "js", "wasm"] +} diff --git a/targets/pca10040.json b/targets/pca10040.json new file mode 100644 index 00000000..55f9f258 --- /dev/null +++ b/targets/pca10040.json @@ -0,0 +1,4 @@ +{ + "llvm-target": "armv7m-none-eabi", + "build-tags": ["nrf", "nrf52", "nrf52832", "js", "wasm"] +}