diff --git a/builtins.go b/builtins.go
index 2d43a8ed..8d665457 100644
--- a/builtins.go
+++ b/builtins.go
@@ -195,7 +195,7 @@ func loadBuiltins(target string) (path string, err error) {
objpath := filepath.Join(dir, objname+".o")
objs = append(objs, objpath)
srcpath := filepath.Join(builtinsDir, name)
- cmd := exec.Command(commands["clang"], "-c", "-Oz", "-g", "-Werror", "-Wall", "-std=c11", "-fshort-enums", "-nostdlibinc", "--target="+target, "-o", objpath, srcpath)
+ cmd := exec.Command(commands["clang"], "-c", "-Oz", "-g", "-Werror", "-Wall", "-std=c11", "-fshort-enums", "-nostdlibinc", "-ffunction-sections", "-fdata-sections", "--target="+target, "-o", objpath, srcpath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = dir
diff --git a/docs/installation.rst b/docs/installation.rst
index f1719a94..af50ceca 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -24,11 +24,10 @@ ARM LLVM backend (which is even used in the propietary C compiler from ARM).
Compiling to object code should be supported out of the box, but compiling the
final binary and flashing it needs some extra tools.
- * binutils (``arm-none-eabi-objcopy``) for producing .hex files for
- flashing.
- * GCC (``arm-none-eabi-gcc``) for linking object files.
- * Clang 7 (``clang-7``) for building the `compiler runtime library
- `_.
+ * binutils (``arm-none-eabi-ld``, ``arm-none-eabi-objcopy``) for linking and
+ for producing .hex files for flashing.
+ * Clang 7 (``clang-7``) for building assembly files and the `compiler
+ runtime library `_ .
* The flashing tool for the particular chip, like ``openocd`` or
``nrfjprog``.
diff --git a/main.go b/main.go
index e87636d6..d371e466 100644
--- a/main.go
+++ b/main.go
@@ -10,6 +10,7 @@ import (
"os/exec"
"os/signal"
"path/filepath"
+ "strconv"
"strings"
"syscall"
@@ -161,14 +162,30 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
cachePath, _ = filepath.Split(librt)
}
- // Link the object file with the system compiler.
+ // Prepare link command.
executable := filepath.Join(dir, "main")
tmppath := executable // final file
- args := append(spec.PreLinkArgs, "-o", executable, objfile)
+ ldflags := append(spec.LDFlags, "-o", executable, objfile)
if spec.RTLib == "compiler-rt" {
- args = append(args, "-L", cachePath, "-lrt-"+spec.Triple)
+ ldflags = append(ldflags, "-L", cachePath, "-lrt-"+spec.Triple)
}
- cmd := exec.Command(spec.Linker, args...)
+
+ // Compile extra files.
+ for i, path := range spec.ExtraFiles {
+ outpath := filepath.Join(dir, "extra-"+strconv.Itoa(i)+"-"+filepath.Base(path)+".o")
+ cmd := exec.Command(spec.Compiler, append(spec.CFlags, "-c", "-o", outpath, path)...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ cmd.Dir = sourceDir()
+ err := cmd.Run()
+ if err != nil {
+ return err
+ }
+ ldflags = append(ldflags, outpath)
+ }
+
+ // Link the object files together.
+ cmd := exec.Command(spec.Linker, ldflags...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = sourceDir()
diff --git a/target.go b/target.go
index 8d425595..b8f73ddf 100644
--- a/target.go
+++ b/target.go
@@ -18,18 +18,21 @@ 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"`
- RTLib string `json:"rtlib"` // compiler runtime library (libgcc, compiler-rt)
- PreLinkArgs []string `json:"pre-link-args"`
- Objcopy string `json:"objcopy"`
- Emulator []string `json:"emulator"`
- Flasher string `json:"flash"`
- OCDDaemon []string `json:"ocd-daemon"`
- GDB string `json:"gdb"`
- GDBCmds []string `json:"gdb-initial-cmds"`
+ Inherits []string `json:"inherits"`
+ Triple string `json:"llvm-target"`
+ BuildTags []string `json:"build-tags"`
+ Compiler string `json:"compiler"`
+ Linker string `json:"linker"`
+ RTLib string `json:"rtlib"` // compiler runtime library (libgcc, compiler-rt)
+ CFlags []string `json:"cflags"`
+ LDFlags []string `json:"ldflags"`
+ ExtraFiles []string `json:"extra-files"`
+ Objcopy string `json:"objcopy"`
+ Emulator []string `json:"emulator"`
+ Flasher string `json:"flash"`
+ OCDDaemon []string `json:"ocd-daemon"`
+ GDB string `json:"gdb"`
+ GDBCmds []string `json:"gdb-initial-cmds"`
}
// copyProperties copies all properties that are set in spec2 into itself.
@@ -41,15 +44,18 @@ func (spec *TargetSpec) copyProperties(spec2 *TargetSpec) {
spec.Triple = spec2.Triple
}
spec.BuildTags = append(spec.BuildTags, spec2.BuildTags...)
+ if spec2.Compiler != "" {
+ spec.Compiler = spec2.Compiler
+ }
if spec2.Linker != "" {
spec.Linker = spec2.Linker
}
if spec2.RTLib != "" {
spec.RTLib = spec2.RTLib
}
- if len(spec2.PreLinkArgs) != 0 {
- spec.PreLinkArgs = spec2.PreLinkArgs
- }
+ spec.CFlags = append(spec.CFlags, spec2.CFlags...)
+ spec.LDFlags = append(spec.LDFlags, spec2.LDFlags...)
+ spec.ExtraFiles = append(spec.ExtraFiles, spec2.ExtraFiles...)
if spec2.Objcopy != "" {
spec.Objcopy = spec2.Objcopy
}
@@ -143,13 +149,13 @@ func LoadTarget(target string) (*TargetSpec, error) {
// 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"},
+ Triple: target,
+ BuildTags: []string{runtime.GOOS, runtime.GOARCH},
+ Linker: "cc",
+ LDFlags: []string{"-no-pie"}, // WARNING: clang < 5.0 requires -nopie
+ Objcopy: "objcopy",
+ GDB: "gdb",
+ GDBCmds: []string{"run"},
}
return spec, nil
}
diff --git a/targets/arduino.json b/targets/arduino.json
index 795a9956..20e592be 100644
--- a/targets/arduino.json
+++ b/targets/arduino.json
@@ -2,14 +2,15 @@
"inherits": ["avr"],
"llvm-target": "avr-atmel-none",
"build-tags": ["arduino", "atmega328p", "atmega", "avr5"],
- "pre-link-args": [
- "-nostartfiles",
- "-mmcu=avr5",
+ "cflags": [
+ "-mmcu=atmega328p"
+ ],
+ "ldflags": [
"-Wl,--defsym=_bootloader_size=512",
"-Wl,--defsym=_stack_size=512",
- "-T", "src/device/avr/atmega328p.ld",
- "-T", "targets/avr.ld",
- "-Wl,--gc-sections",
+ "-T", "src/device/avr/atmega328p.ld"
+ ],
+ "extra-files": [
"targets/avr.S",
"src/device/avr/atmega328p.s"
],
diff --git a/targets/arm.ld b/targets/arm.ld
index 2788fddd..c964331d 100644
--- a/targets/arm.ld
+++ b/targets/arm.ld
@@ -1,4 +1,7 @@
+/* Unused, but here to silence a linker warning. */
+ENTRY(Reset_Handler)
+
/* define output sections */
SECTIONS
{
diff --git a/targets/avr.json b/targets/avr.json
index debb5478..abe486ec 100644
--- a/targets/avr.json
+++ b/targets/avr.json
@@ -1,5 +1,10 @@
{
"build-tags": ["avr", "js", "wasm"],
+ "compiler": "avr-gcc",
"linker": "avr-gcc",
- "objcopy": "avr-objcopy"
+ "objcopy": "avr-objcopy",
+ "ldflags": [
+ "-T", "targets/avr.ld",
+ "-Wl,--gc-sections"
+ ]
}
diff --git a/targets/bluepill.json b/targets/bluepill.json
index 3c086ec6..ef2c915a 100644
--- a/targets/bluepill.json
+++ b/targets/bluepill.json
@@ -2,16 +2,14 @@
"inherits": ["cortex-m"],
"llvm-target": "armv7m-none-eabi",
"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",
+ "cflags": [
+ "--target=armv7m-none-eabi",
+ "-Qunused-arguments"
+ ],
+ "ldflags": [
+ "-T", "targets/stm32.ld"
+ ],
+ "extra-files": [
"src/device/stm32/stm32f103xx.s"
],
"flash": "openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c 'program {hex} reset exit'"
diff --git a/targets/cortex-m.json b/targets/cortex-m.json
index 71d354f4..b373ef9b 100644
--- a/targets/cortex-m.json
+++ b/targets/cortex-m.json
@@ -1,7 +1,18 @@
{
"build-tags": ["tinygo.arm", "js", "wasm"],
- "linker": "arm-none-eabi-gcc",
+ "compiler": "clang-7",
+ "linker": "arm-none-eabi-ld",
"rtlib": "compiler-rt",
+ "cflags": [
+ "-Oz",
+ "-mthumb",
+ "-fshort-enums",
+ "-fno-exceptions", "-fno-unwind-tables",
+ "-ffunction-sections", "-fdata-sections"
+ ],
+ "ldflags": [
+ "--gc-sections"
+ ],
"objcopy": "arm-none-eabi-objcopy",
"gdb": "arm-none-eabi-gdb"
}
diff --git a/targets/cortex-m.s b/targets/cortex-m.s
index 62ed28ef..595ff56f 100644
--- a/targets/cortex-m.s
+++ b/targets/cortex-m.s
@@ -26,7 +26,7 @@ Default_Handler:
.set \handler, Default_Handler
.endm
-.section .isr_vector
+.section .isr_vector, "a", %progbits
.global __isr_vector
// Interrupt vector as defined by Cortex-M, starting with the stack top.
// On reset, SP is initialized with *0x0 and PC is loaded with *0x4, loading
diff --git a/targets/digispark.json b/targets/digispark.json
index 02d9b87e..6c198f4f 100644
--- a/targets/digispark.json
+++ b/targets/digispark.json
@@ -2,14 +2,15 @@
"inherits": ["avr"],
"llvm-target": "avr-atmel-none",
"build-tags": ["digispark", "attiny85", "attiny", "avr2", "avr25"],
- "pre-link-args": [
- "-nostartfiles",
- "-mmcu=attiny85",
+ "cflags": [
+ "-mmcu=attiny85"
+ ],
+ "ldflags": [
"-Wl,--defsym=_bootloader_size=2180",
"-Wl,--defsym=_stack_size=128",
- "-T", "src/device/avr/attiny85.ld",
- "-T", "targets/avr.ld",
- "-Wl,--gc-sections",
+ "-T", "src/device/avr/attiny85.ld"
+ ],
+ "extra-files": [
"targets/avr.S",
"src/device/avr/attiny85.s"
],
diff --git a/targets/nrf51.json b/targets/nrf51.json
index 68c6b14f..f37db3e9 100644
--- a/targets/nrf51.json
+++ b/targets/nrf51.json
@@ -2,18 +2,16 @@
"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",
+ "cflags": [
+ "--target=armv6m-none-eabi",
+ "-Qunused-arguments",
"-DNRF51",
- "-Ilib/CMSIS/CMSIS/Include",
+ "-Ilib/CMSIS/CMSIS/Include"
+ ],
+ "ldflags": [
+ "-T", "targets/nrf51.ld"
+ ],
+ "extra-files": [
"lib/nrfx/mdk/system_nrf51.c",
"src/device/nrf/nrf51.s"
]
diff --git a/targets/nrf52.json b/targets/nrf52.json
index 53ff2a47..6eeaf651 100644
--- a/targets/nrf52.json
+++ b/targets/nrf52.json
@@ -2,18 +2,16 @@
"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",
+ "cflags": [
+ "--target=armv7em-none-eabi",
+ "-Qunused-arguments",
"-DNRF52832_XXAA",
- "-Ilib/CMSIS/CMSIS/Include",
+ "-Ilib/CMSIS/CMSIS/Include"
+ ],
+ "ldflags": [
+ "-T", "targets/nrf52.ld"
+ ],
+ "extra-files": [
"lib/nrfx/mdk/system_nrf52.c",
"src/device/nrf/nrf52.s"
]
diff --git a/targets/nrf52840.json b/targets/nrf52840.json
index 8346735c..d49a1f0a 100644
--- a/targets/nrf52840.json
+++ b/targets/nrf52840.json
@@ -2,18 +2,16 @@
"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",
+ "cflags": [
+ "--target=armv7em-none-eabi",
+ "-Qunused-arguments",
"-DNRF52840_XXAA",
- "-Ilib/CMSIS/CMSIS/Include",
+ "-Ilib/CMSIS/CMSIS/Include"
+ ],
+ "ldflags": [
+ "-T", "targets/nrf52840.ld"
+ ],
+ "extra-files": [
"lib/nrfx/mdk/system_nrf52840.c",
"src/device/nrf/nrf52840.s"
]
diff --git a/targets/qemu.json b/targets/qemu.json
index 7cc23da8..929fb1e8 100644
--- a/targets/qemu.json
+++ b/targets/qemu.json
@@ -2,16 +2,14 @@
"inherits": ["cortex-m"],
"llvm-target": "armv7m-none-eabi",
"build-tags": ["qemu", "lm3s6965"],
- "pre-link-args": [
- "-nostdlib",
- "-nostartfiles",
- "-mcpu=cortex-m0",
- "-mthumb",
- "-T", "targets/lm3s6965.ld",
- "-Wl,--gc-sections",
- "-fno-exceptions", "-fno-unwind-tables",
- "-ffunction-sections", "-fdata-sections",
- "-Os",
+ "cflags": [
+ "--target=armv7m-none-eabi",
+ "-Qunused-arguments"
+ ],
+ "ldflags": [
+ "-T", "targets/lm3s6965.ld"
+ ],
+ "extra-files": [
"targets/cortex-m.s"
],
"emulator": ["qemu-system-arm", "-machine", "lm3s6965evb", "-semihosting", "-nographic", "-kernel"]