Skip to content
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9450ee8
initial
hectorchu Apr 14, 2026
02e150a
fix esp32
hectorchu Apr 14, 2026
0491538
fix ar exec
hectorchu Apr 15, 2026
98e3f5b
use builtin ar
hectorchu Apr 15, 2026
f9d09ee
xtensa: write each function to its own section
hectorchu Apr 15, 2026
21dce58
fix multiple definitions
hectorchu Apr 15, 2026
cc16c7d
link obj files together
hectorchu Apr 15, 2026
f4fb346
only link for xtensa
hectorchu Apr 15, 2026
ab5ef7e
remove call_start_cpu0
hectorchu Apr 15, 2026
f87b75d
allow c side to set gc vars
hectorchu Apr 16, 2026
6f33edd
Merge remote-tracking branch 'origin/dev' into c-archive
hectorchu Apr 16, 2026
ead5efa
fix error
hectorchu Apr 16, 2026
1728ce0
remove malloc and friends
hectorchu Apr 17, 2026
ccb331e
remove unnecessary line
hectorchu Apr 17, 2026
575886c
simplify
hectorchu Apr 17, 2026
0ec59df
simplify
hectorchu Apr 17, 2026
27e364f
revert unneeded macos change
hectorchu Apr 17, 2026
da24005
Merge branch 'dev' into c-archive
hectorchu Apr 17, 2026
fb26e5d
apply fixup to riscv as well
hectorchu Apr 17, 2026
bfa8cd7
remove nonnull attribute from malloc
hectorchu Apr 18, 2026
ad2cb23
add buildmode to tags
hectorchu Apr 19, 2026
f012bdf
Merge branch 'dev' into c-archive
hectorchu Apr 19, 2026
73291c8
doesn't seem necessary anymore
hectorchu Apr 19, 2026
4126133
better c-archive separation
hectorchu Apr 19, 2026
3c2feba
complete overhaul
hectorchu Apr 19, 2026
88f2911
for consistency
hectorchu Apr 19, 2026
cafc515
add CGO_CFLAGS
hectorchu Apr 19, 2026
85c4b74
slightly tidier
hectorchu Apr 19, 2026
604a482
simply rename the clashing symbols
hectorchu Apr 20, 2026
0bb44a8
interrupt handling done by OS
hectorchu Apr 20, 2026
6d0d99f
restrict to esp32c3
hectorchu Apr 20, 2026
b4a7075
tinygo.riscv not esp32c3
hectorchu Apr 20, 2026
823e602
place tinygo_scanCurrentStack in same section as tinygo_scanstack to …
hectorchu Apr 20, 2026
9927d6d
Merge branch 'dev' into c-archive
hectorchu Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 81 additions & 1 deletion builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,9 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
}

// Add libc dependencies, if they exist.
linkerDependencies = append(linkerDependencies, libcDependencies...)
if config.BuildMode() != "c-archive" {
linkerDependencies = append(linkerDependencies, libcDependencies...)
}

// Add embedded files.
linkerDependencies = append(linkerDependencies, embedFileObjects...)
Expand Down Expand Up @@ -828,6 +830,84 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
}
ldflags = append(ldflags, dependency.result)
}

if config.BuildMode() == "c-archive" {
ctx := llvm.NewContext()
mod = ctx.NewModule("main")
for _, dependency := range job.dependencies {
if strings.HasSuffix(dependency.description, ".S") ||
Comment thread
hectorchu marked this conversation as resolved.
Outdated
strings.HasSuffix(dependency.result, ".a") {
continue
}
depMod, err := ctx.ParseBitcodeFile(dependency.result)
if err != nil {
return err
}
err = llvm.LinkModules(mod, depMod)
if err != nil {
return err
}
}
for _, name := range []string{"main", "malloc", "calloc", "free"} {
if fn := mod.NamedFunction(name); !fn.IsNil() {
fn2 := llvm.AddFunction(mod, name, fn.Type())
fn.ReplaceAllUsesWith(fn2)
fn.EraseFromParentAsFunction()
fn2.SetName(name)
}
}
if config.Triple() == "xtensa" {
Comment thread
hectorchu marked this conversation as resolved.
Outdated
for fn := mod.FirstFunction(); !fn.IsNil(); fn = llvm.NextFunction(fn) {
if strings.HasPrefix(fn.Name(), "__atomic_") ||
Comment thread
hectorchu marked this conversation as resolved.
Outdated
strings.HasPrefix(fn.Name(), "__sync_") {
fn.SetLinkage(llvm.InternalLinkage)
}
fn.SetSection(".text." + fn.Name())
if fn.Name() == "tinygo_scanstack" {
fn.SetSection(".text.tinygo_scanCurrentStack")
}
}
}
buf, err := machine.EmitToMemoryBuffer(mod, llvm.ObjectFile)
if err != nil {
return err
}
defer buf.Dispose()
err = os.WriteFile(result.Executable, buf.Bytes(), 0666)
if err != nil {
return err
}
objs := []string{result.Executable}
for _, dependency := range job.dependencies {
if strings.HasSuffix(dependency.description, ".S") {
objs = append(objs, dependency.result)
}
}
if config.Triple() == "xtensa" {
obj := result.Executable + ".o"
err = link(config.Target.Linker, append(objs, "-r", "-o", obj)...)
if err != nil {
return err
}
objs = []string{obj}
name, err := LookupCommand("llvm-objcopy")
if err != nil {
return err
}
err = exec.Command(name, "--strip-symbol", "call_start_cpu0", obj).Run()
if err != nil {
return err
}
}
result.Binary = result.Executable + ".a"
f, err := os.Create(result.Binary)
if err != nil {
return err
}
defer f.Close()
return makeArchive(f, objs)
}

ldflags = append(ldflags, "-mllvm", "-mcpu="+config.CPU())
ldflags = append(ldflags, "-mllvm", "-mattr="+config.Features()) // needed for MIPS softfloat
if config.GOOS() == "windows" {
Expand Down
2 changes: 2 additions & 0 deletions builder/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func init() {
commands["ld.lld"] = []string{"ld.lld-" + llvmMajor, "ld.lld"}
commands["wasm-ld"] = []string{"wasm-ld-" + llvmMajor, "wasm-ld"}
commands["lldb"] = []string{"lldb-" + llvmMajor, "lldb"}
commands["llvm-objcopy"] = []string{"llvm-objcopy-" + llvmMajor, "llvm-objcopy"}
// Add the path to a Homebrew-installed LLVM for ease of use (no need to
// manually set $PATH).
if runtime.GOOS == "darwin" {
Expand All @@ -39,6 +40,7 @@ func init() {
commands["ld.lld"] = append(commands["ld.lld"], prefix+"ld.lld")
commands["wasm-ld"] = append(commands["wasm-ld"], prefix+"wasm-ld")
commands["lldb"] = append(commands["lldb"], prefix+"lldb")
commands["llvm-objcopy"] = append(commands["llvm-objcopy"], prefix+"llvm-objcopy")
}
// Add the path for when LLVM was installed with the installer from
// llvm.org, which by default doesn't add LLVM to the $PATH environment
Expand Down
3 changes: 3 additions & 0 deletions compileopts/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ func (c *Config) DefaultBinaryExtension() string {
// I think it's a good tradition, so let's keep it.
return ".elf"
}
if c.BuildMode() == "c-archive" {
return ".a"
}
// Linux, MacOS, etc, don't use a file extension. Use it as a fallback.
return ""
}
Expand Down
2 changes: 1 addition & 1 deletion compileopts/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

var (
validBuildModeOptions = []string{"default", "c-shared", "wasi-legacy"}
validBuildModeOptions = []string{"default", "c-archive", "c-shared", "wasi-legacy"}
validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise", "boehm"}
validSchedulerOptions = []string{"none", "tasks", "asyncify", "threads", "cores"}
validSerialOptions = []string{"none", "uart", "usb", "rtt"}
Expand Down
9 changes: 7 additions & 2 deletions compileopts/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,9 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
llvmvendor := "unknown"
switch options.GOOS {
case "darwin":
spec.GC = "boehm"
if options.GC == "boehm" {
Comment thread
hectorchu marked this conversation as resolved.
Outdated
spec.GC = "boehm"
}
platformVersion := "10.12.0"
if options.GOARCH == "arm64" {
platformVersion = "11.0.0" // first macosx platform with arm64 support
Expand All @@ -418,10 +420,13 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
)
spec.ExtraFiles = append(spec.ExtraFiles,
"src/internal/futex/futex_darwin.c",
"src/internal/task/task_threads.c",
"src/runtime/os_darwin.c",
"src/runtime/runtime_unix.c",
"src/runtime/signal.c")
if options.Scheduler == "threads" {
spec.ExtraFiles = append(spec.ExtraFiles,
"src/internal/task/task_threads.c")
}
case "linux":
spec.GC = "boehm"
spec.Scheduler = "threads"
Expand Down
10 changes: 10 additions & 0 deletions src/runtime/baremetal.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ var (
stackTop = uintptr(unsafe.Pointer(&stackTopSymbol))
)

//export tinygo_init
func tinygo_init(p, n, bss, bssEnd, sp uintptr) {
Comment thread
hectorchu marked this conversation as resolved.
Outdated
heapStart, heapEnd = p, p+n
globalsStart, globalsEnd = bss, bssEnd
stackTop = sp
initRand()
initHeap()
initAll()
}

// growHeap tries to grow the heap size. It returns true if it succeeds, false
// otherwise.
func growHeap() bool {
Expand Down