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 (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
|
@ -17,6 +18,7 @@ import (
|
|||
// 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 {
|
||||
Inherits []string `json:"inherits"`
|
||||
Triple string `json:"llvm-target"`
|
||||
BuildTags []string `json:"build-tags"`
|
||||
Linker string `json:"linker"`
|
||||
|
@ -30,13 +32,117 @@ type TargetSpec struct {
|
|||
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) {
|
||||
if target == "" {
|
||||
target = llvm.DefaultTargetTriple()
|
||||
}
|
||||
|
||||
spec := &TargetSpec{
|
||||
// See whether there is a target specification for this target (e.g.
|
||||
// Arduino).
|
||||
spec := &TargetSpec{}
|
||||
err := spec.loadFromName(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.
|
||||
err = spec.resolveInherits()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return spec, nil
|
||||
} else if !os.IsNotExist(err) {
|
||||
// Expected a 'file not found' error, got something else. Report it as
|
||||
// an error.
|
||||
return nil, err
|
||||
} else {
|
||||
// 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",
|
||||
|
@ -45,25 +151,8 @@ func LoadTarget(target string) (*TargetSpec, error) {
|
|||
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. Use the default one.
|
||||
}
|
||||
|
||||
return spec, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Return the source directory of this package, or "." when it cannot be
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv7m-none-eabi",
|
||||
"build-tags": ["bluepill", "stm32f103xx", "stm32", "tinygo.arm", "js", "wasm"],
|
||||
"linker": "arm-none-eabi-gcc",
|
||||
"rtlib": "compiler-rt",
|
||||
"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"],
|
||||
"objcopy": "arm-none-eabi-objcopy",
|
||||
"build-tags": ["bluepill", "stm32f103xx", "stm32"],
|
||||
"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"
|
||||
],
|
||||
"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",
|
||||
"build-tags": ["microbit", "nrf51822", "nrf51", "nrf", "tinygo.arm", "js", "wasm"],
|
||||
"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",
|
||||
"inherits": ["nrf51"],
|
||||
"build-tags": ["microbit"],
|
||||
"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"],
|
||||
"gdb": "arm-none-eabi-gdb",
|
||||
"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",
|
||||
"build-tags": ["nrf52840_mdk", "nrf52840", "nrf", "tinygo.arm", "js", "wasm"],
|
||||
"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",
|
||||
"inherits": ["nrf52840"],
|
||||
"build-tags": ["nrf52840_mdk"],
|
||||
"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"],
|
||||
"gdb": "arm-none-eabi-gdb",
|
||||
"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",
|
||||
"build-tags": ["pca10040", "nrf52832", "nrf52", "nrf", "tinygo.arm", "js", "wasm"],
|
||||
"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",
|
||||
"inherits": ["nrf52"],
|
||||
"build-tags": ["pca10040"],
|
||||
"flash": "nrfjprog -f nrf52 --sectorerase --program {hex} --reset",
|
||||
"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"]
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
{
|
||||
"inherits": ["cortex-m"],
|
||||
"llvm-target": "armv7m-none-eabi",
|
||||
"build-tags": ["qemu", "lm3s6965", "tinygo.arm", "js", "wasm"],
|
||||
"linker": "arm-none-eabi-gcc",
|
||||
"rtlib": "compiler-rt",
|
||||
"build-tags": ["qemu", "lm3s6965"],
|
||||
"pre-link-args": [
|
||||
"-nostdlib",
|
||||
"-nostartfiles",
|
||||
|
@ -15,6 +14,5 @@
|
|||
"-Os",
|
||||
"targets/cortex-m.s"
|
||||
],
|
||||
"objcopy": "arm-none-eabi-objcopy",
|
||||
"emulator": ["qemu-system-arm", "-machine", "lm3s6965evb", "-semihosting", "-nographic", "-kernel"]
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче