GithubHelp home page GithubHelp logo

tinygo-gccgo's Introduction

TinyGo GCC (abandoned)

This project is abandoned. See Current status below.

What is this?

A runtime for the Go programming language that is very small in size and doesn't rely as much on an OS.

Note: This project is unrelated to the now-dead Tiny runtime of the Go language, see below.

Why was it created?

I wanted to be able to run Go on a microcontroller. While this goal hasn't been reached yet, the resulting binary can be very small.

Inside src/hello/hello.go:

// Simple program with the bare minimum of Go.
package main

func main() {
        println("hello, world!")
}

Running on an ARM machine (Raspberry Pi 3):

$ tinygo build -lto -o hello ./src/hello/

$ strip hello

$ ./hello
hello, world!

$ /bin/ls -lh hello
-rwxrwxr-x 1 ayke ayke 5,5K mrt  9 23:43 build/hello

$ size hello
   text    data     bss     dec     hex filename
   1961     316      20    2297     8f9 build/hello

As you can see, this produces a file that's just 5.5kB in size and contains about 2kB of machine code. The same source compiled by the official Go compiler (1.7.4) produces an executable that is about 564kB in size after stripping, most of which is also .text.

Of course, this is a bit cheating. The small 'hello' program does not include most of the runtime, that's all stripped away by the linker. A somewhat more realistic example is the channel example, which produces an executable of 18kB. That runtime contains the scheduler, memory allocator (no GC yet) and channel send/receive primitives.

Limitations

There are many.

  • Works with gccgo 6.3 (Debian stretch) and 5.2 (xtensa-esp32-elf), no other compiler versions have been tested.
  • recover() has bugs (but seems to work somewhat).
  • No function names or line numbers in the panic() output, and no backtraces on anything except ARM. I would like to fix this at some time, but it will increase the binary size if it must work after stripping. It currently outputs the function addresses, which you can look up with nm (e.g. nm -S ./build/example | egrep ' [tT] main\.').
  • No garbage collector, yet. Allocated memory is never freed.
  • Many types might not be implemented, but support will probably be pretty easy to add by including the correct files from gcc/libgo/runtime.
  • The scheduler is pretty dumb right now. Passing messages between two goroutines is fast (on the Raspberry Pi 3 slightly faster than the standard Go compiler!) but any extra goroutine that is started will slow down any blocking operation.
  • No support for running multiple goroutines on different threads. I don't really have an intention to implement this as it will complicate the scheduler and I don't want a complicated scheduler.
  • Most of the standard library doesn't build yet, in particular the fmt package (which depends on a whole slew of other packages).
  • ... probably many more.

Current status

At the moment I'm no longer working on this project. The main reason is that it turns out that the code gccgo produces is relatively bloated and is written specifically for the regular Go runtime, which is optimized for speed and not RAM/flash usage. I'm now working on a new implementation based on LLVM just like llgo.

This was mostly a proof of concept and I don't expect to be working on it in the future, but I'm happy that it works (to some degree).

Also, it depends on gccgo and gccgo seems to be moving to a runtime written in Go, so I might need to adjust to that in the future.

Building

Dependencies:

  • Installed gcc and gccgo, tested version 6.3.
  • Installed go tool.

Build steps:

  • Fetch GCC sources (needed to build the runtime). Do this by running:

    $ git submodule update --init
    
  • Build the runtime. For example, for the unix target:

    $ cd ports/unix
    $ make -j8
    
  • Add the tinygo script to your $PATH, for example by adding this project directory to your $PATH.

Now you can use tinygo just like you're used from the go tool, except that it is still very limited in which packages it can build.

License

The license is the same BSD 3-clause license as the one used for Go. See the LICENSE file for details.

Some code has a different (but compatible) license. In particular, this project contains some code from the MicroPython project which is licensed under the MIT license.

Bare metal support

ESP32

There is initial (very limited) support for the ESP32. A blinky example:

package main

import (
    "machine"
    "time"
)

func main() {
    led := machine.LED_BUILTIN
    led.Configure(machine.GPIOConfig{Mode: machine.GPIO_OUTPUT})
    high := false
    for {
        high = !high
        led.Set(high)
        time.Sleep(200 * time.Millisecond)
    }
}

Implemented so far:

  • GPIO peripheral (only pin 2 and 4, others can be added easily)
  • Goroutines
  • Channels
  • Sleep
  • Stack overflow checking

Other (similar) projects

  • libmigo: implements a bare-bones libgo for an x86 kernel.
  • gopher-os appears to be still alive. Also see the Golang UK Conference about it.
  • There is another (now dead) project called 'tinygo' over here and here that tried to run a very old variant of the runtime bare-metal. I only discovered it the moment I wanted to push this project to GitHub.
  • gofy is yet another kernel. Appears to be dead.

Note that most of these are meant for kernel development. Kernel development, although nice, is not the goal of TinyGo. Instead, the runtime should be kept as small as possible to eventually make it work on microcontrollers with much more limited resources.

tinygo-gccgo's People

Contributors

aykevl avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.