targets: let specific targets inherit more general targets
This avoids a ton of duplication and makes it easier to change a generic target (for example, the "cortex-m" target) for all boards that use it. Also, by making it possible to inherit properties from a parent target specification, it is easier to support out-of-tree boards that don't have to be updated so often. A target specification for a special-purpose board can simply inherit the specification of a supported chip and override the properites it needs to override (like the programming interface).
Этот коммит содержится в:
родитель
f02766265c
коммит
760bc5d0a4
10 изменённых файлов: 198 добавлений и 91 удалений
129
target.go
129
target.go
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -17,6 +18,7 @@ import (
|
||||||
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/struct.TargetOptions.html
|
// 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
|
// https://github.com/shepmaster/rust-arduino-blink-led-no-core-with-cargo/blob/master/blink/arduino.json
|
||||||
type TargetSpec struct {
|
type TargetSpec struct {
|
||||||
|
Inherits []string `json:"inherits"`
|
||||||
Triple string `json:"llvm-target"`
|
Triple string `json:"llvm-target"`
|
||||||
BuildTags []string `json:"build-tags"`
|
BuildTags []string `json:"build-tags"`
|
||||||
Linker string `json:"linker"`
|
Linker string `json:"linker"`
|
||||||
|
@ -30,40 +32,127 @@ type TargetSpec struct {
|
||||||
GDBCmds []string `json:"gdb-initial-cmds"`
|
GDBCmds []string `json:"gdb-initial-cmds"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load a target specification
|
// copyProperties copies all properties that are set in spec2 into itself.
|
||||||
|
func (spec *TargetSpec) copyProperties(spec2 *TargetSpec) {
|
||||||
|
// TODO: simplify this using reflection? Inherits and BuildTags are special
|
||||||
|
// cases, but the rest can simply be copied if set.
|
||||||
|
spec.Inherits = append(spec.Inherits, spec2.Inherits...)
|
||||||
|
if spec2.Triple != "" {
|
||||||
|
spec.Triple = spec2.Triple
|
||||||
|
}
|
||||||
|
spec.BuildTags = append(spec.BuildTags, spec2.BuildTags...)
|
||||||
|
if spec2.Linker != "" {
|
||||||
|
spec.Linker = spec2.Linker
|
||||||
|
}
|
||||||
|
if spec2.RTLib != "" {
|
||||||
|
spec.RTLib = spec2.RTLib
|
||||||
|
}
|
||||||
|
if len(spec2.PreLinkArgs) != 0 {
|
||||||
|
spec.PreLinkArgs = spec2.PreLinkArgs
|
||||||
|
}
|
||||||
|
if spec2.Objcopy != "" {
|
||||||
|
spec.Objcopy = spec2.Objcopy
|
||||||
|
}
|
||||||
|
if len(spec2.Emulator) != 0 {
|
||||||
|
spec.Emulator = spec2.Emulator
|
||||||
|
}
|
||||||
|
if spec2.Flasher != "" {
|
||||||
|
spec.Flasher = spec2.Flasher
|
||||||
|
}
|
||||||
|
if len(spec2.OCDDaemon) != 0 {
|
||||||
|
spec.OCDDaemon = spec2.OCDDaemon
|
||||||
|
}
|
||||||
|
if spec2.GDB != "" {
|
||||||
|
spec.GDB = spec2.GDB
|
||||||
|
}
|
||||||
|
if len(spec2.GDBCmds) != 0 {
|
||||||
|
spec.GDBCmds = spec2.GDBCmds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load reads a target specification from the JSON in the given io.Reader. It
|
||||||
|
// may load more targets specified using the "inherits" property.
|
||||||
|
func (spec *TargetSpec) load(r io.Reader) error {
|
||||||
|
err := json.NewDecoder(r).Decode(spec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadFromName loads the given target from the targets/ directory inside the
|
||||||
|
// compiler sources.
|
||||||
|
func (spec *TargetSpec) loadFromName(name string) error {
|
||||||
|
path := filepath.Join(sourceDir(), "targets", strings.ToLower(name)+".json")
|
||||||
|
fp, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fp.Close()
|
||||||
|
return spec.load(fp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolveInherits loads inherited targets, recursively.
|
||||||
|
func (spec *TargetSpec) resolveInherits() error {
|
||||||
|
// First create a new spec with all the inherited properties.
|
||||||
|
newSpec := &TargetSpec{}
|
||||||
|
for _, name := range spec.Inherits {
|
||||||
|
subtarget := &TargetSpec{}
|
||||||
|
err := subtarget.loadFromName(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = subtarget.resolveInherits()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newSpec.copyProperties(subtarget)
|
||||||
|
}
|
||||||
|
|
||||||
|
// When all properties are loaded, make sure they are properly inherited.
|
||||||
|
newSpec.copyProperties(spec)
|
||||||
|
*spec = *newSpec
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load a target specification.
|
||||||
func LoadTarget(target string) (*TargetSpec, error) {
|
func LoadTarget(target string) (*TargetSpec, error) {
|
||||||
if target == "" {
|
if target == "" {
|
||||||
target = llvm.DefaultTargetTriple()
|
target = llvm.DefaultTargetTriple()
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
// See whether there is a target specification for this target (e.g.
|
||||||
// Arduino).
|
// Arduino).
|
||||||
path := filepath.Join(sourceDir(), "targets", strings.ToLower(target)+".json")
|
spec := &TargetSpec{}
|
||||||
if fp, err := os.Open(path); err == nil {
|
err := spec.loadFromName(target)
|
||||||
defer fp.Close()
|
if err == nil {
|
||||||
*spec = TargetSpec{} // reset all fields
|
// Successfully loaded this target from a built-in .json file. Make sure
|
||||||
err := json.NewDecoder(fp).Decode(spec)
|
// it includes all parents as specified in the "inherits" key.
|
||||||
|
err = spec.resolveInherits()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return spec, nil
|
||||||
} else if !os.IsNotExist(err) {
|
} else if !os.IsNotExist(err) {
|
||||||
// Expected a 'file not found' error, got something else.
|
// Expected a 'file not found' error, got something else. Report it as
|
||||||
|
// an error.
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
// No target spec available. Use the default one.
|
// No target spec available. Use the default one, useful on most systems
|
||||||
|
// with a regular OS.
|
||||||
|
*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"},
|
||||||
|
}
|
||||||
|
return spec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the source directory of this package, or "." when it cannot be
|
// Return the source directory of this package, or "." when it cannot be
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
{
|
{
|
||||||
|
"inherits": ["cortex-m"],
|
||||||
"llvm-target": "armv7m-none-eabi",
|
"llvm-target": "armv7m-none-eabi",
|
||||||
"build-tags": ["bluepill", "stm32f103xx", "stm32", "tinygo.arm", "js", "wasm"],
|
"build-tags": ["bluepill", "stm32f103xx", "stm32"],
|
||||||
"linker": "arm-none-eabi-gcc",
|
"pre-link-args": [
|
||||||
"rtlib": "compiler-rt",
|
"-nostdlib",
|
||||||
"pre-link-args": ["-nostdlib", "-nostartfiles", "-mcpu=cortex-m3", "-mthumb", "-T", "targets/stm32.ld", "-Wl,--gc-sections", "-fno-exceptions", "-fno-unwind-tables", "-ffunction-sections", "-fdata-sections", "-Os", "src/device/stm32/stm32f103xx.s"],
|
"-nostartfiles",
|
||||||
"objcopy": "arm-none-eabi-objcopy",
|
"-mcpu=cortex-m3",
|
||||||
|
"-mthumb",
|
||||||
|
"-T", "targets/stm32.ld",
|
||||||
|
"-Wl,--gc-sections",
|
||||||
|
"-fno-exceptions", "-fno-unwind-tables",
|
||||||
|
"-ffunction-sections", "-fdata-sections",
|
||||||
|
"-Os",
|
||||||
|
"src/device/stm32/stm32f103xx.s"
|
||||||
|
],
|
||||||
"flash": "openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c 'program {hex} reset exit'"
|
"flash": "openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c 'program {hex} reset exit'"
|
||||||
}
|
}
|
||||||
|
|
7
targets/cortex-m.json
Обычный файл
7
targets/cortex-m.json
Обычный файл
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"build-tags": ["tinygo.arm", "js", "wasm"],
|
||||||
|
"linker": "arm-none-eabi-gcc",
|
||||||
|
"rtlib": "compiler-rt",
|
||||||
|
"objcopy": "arm-none-eabi-objcopy",
|
||||||
|
"gdb": "arm-none-eabi-gdb"
|
||||||
|
}
|
|
@ -1,26 +1,7 @@
|
||||||
{
|
{
|
||||||
"llvm-target": "armv6m-none-eabi",
|
"inherits": ["nrf51"],
|
||||||
"build-tags": ["microbit", "nrf51822", "nrf51", "nrf", "tinygo.arm", "js", "wasm"],
|
"build-tags": ["microbit"],
|
||||||
"linker": "arm-none-eabi-gcc",
|
|
||||||
"rtlib": "compiler-rt",
|
|
||||||
"pre-link-args": [
|
|
||||||
"-nostdlib",
|
|
||||||
"-nostartfiles",
|
|
||||||
"-mcpu=cortex-m0",
|
|
||||||
"-mthumb",
|
|
||||||
"-T", "targets/nrf51.ld",
|
|
||||||
"-Wl,--gc-sections",
|
|
||||||
"-fno-exceptions", "-fno-unwind-tables",
|
|
||||||
"-ffunction-sections", "-fdata-sections",
|
|
||||||
"-Os",
|
|
||||||
"-DNRF51",
|
|
||||||
"-Ilib/CMSIS/CMSIS/Include",
|
|
||||||
"lib/nrfx/mdk/system_nrf51.c",
|
|
||||||
"src/device/nrf/nrf51.s"
|
|
||||||
],
|
|
||||||
"objcopy": "arm-none-eabi-objcopy",
|
|
||||||
"flash": "openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg -c 'program {hex} reset exit'",
|
"flash": "openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg -c 'program {hex} reset exit'",
|
||||||
"ocd-daemon": ["openocd", "-f", "interface/cmsis-dap.cfg", "-f", "target/nrf51.cfg"],
|
"ocd-daemon": ["openocd", "-f", "interface/cmsis-dap.cfg", "-f", "target/nrf51.cfg"],
|
||||||
"gdb": "arm-none-eabi-gdb",
|
|
||||||
"gdb-initial-cmds": ["target remote :3333", "monitor halt", "load", "monitor reset", "c"]
|
"gdb-initial-cmds": ["target remote :3333", "monitor halt", "load", "monitor reset", "c"]
|
||||||
}
|
}
|
||||||
|
|
20
targets/nrf51.json
Обычный файл
20
targets/nrf51.json
Обычный файл
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"inherits": ["cortex-m"],
|
||||||
|
"llvm-target": "armv6m-none-eabi",
|
||||||
|
"build-tags": ["nrf51822", "nrf51", "nrf"],
|
||||||
|
"pre-link-args": [
|
||||||
|
"-nostdlib",
|
||||||
|
"-nostartfiles",
|
||||||
|
"-mcpu=cortex-m0",
|
||||||
|
"-mthumb",
|
||||||
|
"-T", "targets/nrf51.ld",
|
||||||
|
"-Wl,--gc-sections",
|
||||||
|
"-fno-exceptions", "-fno-unwind-tables",
|
||||||
|
"-ffunction-sections", "-fdata-sections",
|
||||||
|
"-Os",
|
||||||
|
"-DNRF51",
|
||||||
|
"-Ilib/CMSIS/CMSIS/Include",
|
||||||
|
"lib/nrfx/mdk/system_nrf51.c",
|
||||||
|
"src/device/nrf/nrf51.s"
|
||||||
|
]
|
||||||
|
}
|
20
targets/nrf52.json
Обычный файл
20
targets/nrf52.json
Обычный файл
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"inherits": ["cortex-m"],
|
||||||
|
"llvm-target": "armv7em-none-eabi",
|
||||||
|
"build-tags": ["nrf52", "nrf"],
|
||||||
|
"pre-link-args": [
|
||||||
|
"-nostdlib",
|
||||||
|
"-nostartfiles",
|
||||||
|
"-mcpu=cortex-m4",
|
||||||
|
"-mthumb",
|
||||||
|
"-T", "targets/nrf52.ld",
|
||||||
|
"-Wl,--gc-sections",
|
||||||
|
"-fno-exceptions", "-fno-unwind-tables",
|
||||||
|
"-ffunction-sections", "-fdata-sections",
|
||||||
|
"-Os",
|
||||||
|
"-DNRF52832_XXAA",
|
||||||
|
"-Ilib/CMSIS/CMSIS/Include",
|
||||||
|
"lib/nrfx/mdk/system_nrf52.c",
|
||||||
|
"src/device/nrf/nrf52.s"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,25 +1,7 @@
|
||||||
{
|
{
|
||||||
"llvm-target": "armv7em-none-eabi",
|
"inherits": ["nrf52840"],
|
||||||
"build-tags": ["nrf52840_mdk", "nrf52840", "nrf", "tinygo.arm", "js", "wasm"],
|
"build-tags": ["nrf52840_mdk"],
|
||||||
"linker": "arm-none-eabi-gcc",
|
|
||||||
"pre-link-args": [
|
|
||||||
"-nostdlib",
|
|
||||||
"-nostartfiles",
|
|
||||||
"-mcpu=cortex-m4",
|
|
||||||
"-mthumb",
|
|
||||||
"-T", "targets/nrf52840.ld",
|
|
||||||
"-Wl,--gc-sections",
|
|
||||||
"-fno-exceptions", "-fno-unwind-tables",
|
|
||||||
"-ffunction-sections", "-fdata-sections",
|
|
||||||
"-Os",
|
|
||||||
"-DNRF52840_XXAA",
|
|
||||||
"-Ilib/CMSIS/CMSIS/Include",
|
|
||||||
"lib/nrfx/mdk/system_nrf52840.c",
|
|
||||||
"src/device/nrf/nrf52840.s"
|
|
||||||
],
|
|
||||||
"objcopy": "arm-none-eabi-objcopy",
|
|
||||||
"flash": "openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg -c 'program {hex} reset exit'",
|
"flash": "openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg -c 'program {hex} reset exit'",
|
||||||
"ocd-daemon": ["openocd", "-f", "interface/cmsis-dap.cfg", "-f", "target/nrf51.cfg"],
|
"ocd-daemon": ["openocd", "-f", "interface/cmsis-dap.cfg", "-f", "target/nrf51.cfg"],
|
||||||
"gdb": "arm-none-eabi-gdb",
|
|
||||||
"gdb-initial-cmds": ["target remote :3333", "monitor halt", "load", "monitor reset", "c"]
|
"gdb-initial-cmds": ["target remote :3333", "monitor halt", "load", "monitor reset", "c"]
|
||||||
}
|
}
|
||||||
|
|
20
targets/nrf52840.json
Обычный файл
20
targets/nrf52840.json
Обычный файл
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"inherits": ["cortex-m"],
|
||||||
|
"llvm-target": "armv7em-none-eabi",
|
||||||
|
"build-tags": ["nrf52840", "nrf"],
|
||||||
|
"pre-link-args": [
|
||||||
|
"-nostdlib",
|
||||||
|
"-nostartfiles",
|
||||||
|
"-mcpu=cortex-m4",
|
||||||
|
"-mthumb",
|
||||||
|
"-T", "targets/nrf52840.ld",
|
||||||
|
"-Wl,--gc-sections",
|
||||||
|
"-fno-exceptions", "-fno-unwind-tables",
|
||||||
|
"-ffunction-sections", "-fdata-sections",
|
||||||
|
"-Os",
|
||||||
|
"-DNRF52840_XXAA",
|
||||||
|
"-Ilib/CMSIS/CMSIS/Include",
|
||||||
|
"lib/nrfx/mdk/system_nrf52840.c",
|
||||||
|
"src/device/nrf/nrf52840.s"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,26 +1,7 @@
|
||||||
{
|
{
|
||||||
"llvm-target": "armv7em-none-eabi",
|
"inherits": ["nrf52"],
|
||||||
"build-tags": ["pca10040", "nrf52832", "nrf52", "nrf", "tinygo.arm", "js", "wasm"],
|
"build-tags": ["pca10040"],
|
||||||
"linker": "arm-none-eabi-gcc",
|
|
||||||
"rtlib": "compiler-rt",
|
|
||||||
"pre-link-args": [
|
|
||||||
"-nostdlib",
|
|
||||||
"-nostartfiles",
|
|
||||||
"-mcpu=cortex-m4",
|
|
||||||
"-mthumb",
|
|
||||||
"-T", "targets/nrf52.ld",
|
|
||||||
"-Wl,--gc-sections",
|
|
||||||
"-fno-exceptions", "-fno-unwind-tables",
|
|
||||||
"-ffunction-sections", "-fdata-sections",
|
|
||||||
"-Os",
|
|
||||||
"-DNRF52832_XXAA",
|
|
||||||
"-Ilib/CMSIS/CMSIS/Include",
|
|
||||||
"lib/nrfx/mdk/system_nrf52.c",
|
|
||||||
"src/device/nrf/nrf52.s"
|
|
||||||
],
|
|
||||||
"objcopy": "arm-none-eabi-objcopy",
|
|
||||||
"flash": "nrfjprog -f nrf52 --sectorerase --program {hex} --reset",
|
"flash": "nrfjprog -f nrf52 --sectorerase --program {hex} --reset",
|
||||||
"ocd-daemon": ["openocd", "-f", "interface/jlink.cfg", "-c", "transport select swd", "-f", "target/nrf51.cfg"],
|
"ocd-daemon": ["openocd", "-f", "interface/jlink.cfg", "-c", "transport select swd", "-f", "target/nrf51.cfg"],
|
||||||
"gdb": "arm-none-eabi-gdb",
|
|
||||||
"gdb-initial-cmds": ["target remote :3333", "monitor halt", "load", "monitor reset", "c"]
|
"gdb-initial-cmds": ["target remote :3333", "monitor halt", "load", "monitor reset", "c"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
{
|
{
|
||||||
|
"inherits": ["cortex-m"],
|
||||||
"llvm-target": "armv7m-none-eabi",
|
"llvm-target": "armv7m-none-eabi",
|
||||||
"build-tags": ["qemu", "lm3s6965", "tinygo.arm", "js", "wasm"],
|
"build-tags": ["qemu", "lm3s6965"],
|
||||||
"linker": "arm-none-eabi-gcc",
|
|
||||||
"rtlib": "compiler-rt",
|
|
||||||
"pre-link-args": [
|
"pre-link-args": [
|
||||||
"-nostdlib",
|
"-nostdlib",
|
||||||
"-nostartfiles",
|
"-nostartfiles",
|
||||||
|
@ -15,6 +14,5 @@
|
||||||
"-Os",
|
"-Os",
|
||||||
"targets/cortex-m.s"
|
"targets/cortex-m.s"
|
||||||
],
|
],
|
||||||
"objcopy": "arm-none-eabi-objcopy",
|
|
||||||
"emulator": ["qemu-system-arm", "-machine", "lm3s6965evb", "-semihosting", "-nographic", "-kernel"]
|
"emulator": ["qemu-system-arm", "-machine", "lm3s6965evb", "-semihosting", "-nographic", "-kernel"]
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче