Browse Source

wasm: include wasi-libc

This allows CGo code to call some libc functions. Additionally, by
putting memset/memmove/memcpy in an archive they're not included anymore
when not necessary, reducing code size for small programs.
pull/870/head
Ayke van Laethem 5 years ago
committed by Ron Evans
parent
commit
e2aa3789c3
  1. 32
      .circleci/config.yml
  2. 3
      .gitmodules
  3. 18
      Makefile
  4. 10
      azure-pipelines.yml
  5. 1
      lib/wasi-libc
  6. 26
      src/runtime/runtime_wasm.go
  7. 10
      targets/wasm.json

32
.circleci/config.yml

@ -49,6 +49,18 @@ commands:
key: llvm-source-9-v0
paths:
- llvm-project
build-wasi-libc:
steps:
- restore_cache:
keys:
- wasi-libc-sysroot-v0
- run:
name: "Build wasi-libc"
command: make wasi-libc CLANG=$PWD/llvm-build/bin/clang LLVM_AR=$PWD/llvm-build/bin/llvm-ar LLVM_NM=$PWD/llvm-build/bin/llvm-nm
- save_cache:
key: wasi-libc-sysroot-v0
paths:
- lib/wasi-libc/sysroot
test-linux:
steps:
- checkout
@ -62,6 +74,14 @@ commands:
- go-cache-v2-{{ checksum "go.mod" }}
- llvm-source-linux
- run: go install .
- restore_cache:
keys:
- wasi-libc-sysroot-systemclang-v0
- run: make wasi-libc
- save_cache:
key: wasi-libc-sysroot-systemclang-v0
paths:
- lib/wasi-libc/sysroot
- run: go test -v ./cgo ./compileopts ./interp ./transform .
- run: make gen-device -j4
- run: make smoketest
@ -119,6 +139,7 @@ commands:
paths:
llvm-build
- run: make ASSERT=1
- build-wasi-libc
- run:
name: "Test TinyGo"
command: make ASSERT=1 test
@ -176,6 +197,7 @@ commands:
key: llvm-build-9-linux-v0
paths:
llvm-build
- build-wasi-libc
- run:
name: "Test TinyGo"
command: make test
@ -242,6 +264,16 @@ commands:
key: llvm-build-9-macos-v0
paths:
llvm-build
- restore_cache:
keys:
- wasi-libc-sysroot-macos-v0
- run:
name: "Build wasi-libc"
command: make wasi-libc CLANG=$PWD/llvm-build/bin/clang LLVM_AR=$PWD/llvm-build/bin/llvm-ar LLVM_NM=$PWD/llvm-build/bin/llvm-nm
- save_cache:
key: wasi-libc-sysroot-macos-v0
paths:
- lib/wasi-libc/sysroot
- run:
name: "Test TinyGo"
command: make test

3
.gitmodules

@ -14,3 +14,6 @@
path = lib/compiler-rt
url = https://github.com/llvm-mirror/compiler-rt.git
branch = release_80
[submodule "lib/wasi-libc"]
path = lib/wasi-libc
url = https://github.com/CraneStation/wasi-libc

18
Makefile

@ -7,6 +7,11 @@ LLVM_BUILDDIR ?= llvm-build
CLANG_SRC ?= llvm-project/clang
LLD_SRC ?= llvm-project/lld
# Default tool selection.
CLANG ?= clang-9
LLVM_AR ?= llvm-ar-9
LLVM_NM ?= llvm-nm-9
# Go binary and GOROOT to select
GO ?= go
export GOROOT = $(shell $(GO) env GOROOT)
@ -139,12 +144,19 @@ $(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja
cd $(LLVM_BUILDDIR); ninja
# Build wasi-libc sysroot
.PHONY: wasi-libc
wasi-libc: lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a
lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a:
cd lib/wasi-libc && make -j4 WASM_CC=$(CLANG) WASM_AR=$(LLVM_AR) WASM_NM=$(LLVM_NM)
# Build the Go compiler.
tinygo:
@if [ ! -f "$(LLVM_BUILDDIR)/bin/llvm-config" ]; then echo "Fetch and build LLVM first by running:"; echo " make llvm-source"; echo " make $(LLVM_BUILDDIR)"; exit 1; fi
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -o build/tinygo$(EXE) -tags byollvm .
test:
test: wasi-libc
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test -v -tags byollvm ./cgo ./compileopts ./interp ./transform .
tinygo-test:
@ -261,12 +273,13 @@ endif
$(TINYGO) build -o wasm.wasm -target=wasm examples/wasm/export
$(TINYGO) build -o wasm.wasm -target=wasm examples/wasm/main
release: tinygo gen-device
release: tinygo gen-device wasi-libc
@mkdir -p build/release/tinygo/bin
@mkdir -p build/release/tinygo/lib/clang/include
@mkdir -p build/release/tinygo/lib/CMSIS/CMSIS
@mkdir -p build/release/tinygo/lib/compiler-rt/lib
@mkdir -p build/release/tinygo/lib/nrfx
@mkdir -p build/release/tinygo/lib/wasi-libc
@mkdir -p build/release/tinygo/pkg/armv6m-none-eabi
@mkdir -p build/release/tinygo/pkg/armv7m-none-eabi
@mkdir -p build/release/tinygo/pkg/armv7em-none-eabi
@ -279,6 +292,7 @@ release: tinygo gen-device
@cp -rp lib/compiler-rt/LICENSE.TXT build/release/tinygo/lib/compiler-rt
@cp -rp lib/compiler-rt/README.txt build/release/tinygo/lib/compiler-rt
@cp -rp lib/nrfx/* build/release/tinygo/lib/nrfx
@cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
@cp -rp src build/release/tinygo/src
@cp -rp targets build/release/tinygo/targets
./build/tinygo build-builtins -target=armv6m-none-eabi -o build/release/tinygo/pkg/armv6m-none-eabi/compiler-rt.a

10
azure-pipelines.yml

@ -45,6 +45,16 @@ jobs:
inputs:
targetType: inline
script: choco install qemu
- task: CacheBeta@0
displayName: Cache wasi-libc sysroot
inputs:
key: wasi-libc-sysroot-v0
path: lib/wasi-libc/sysroot
- task: Bash@3
displayName: Build wasi-libc
inputs:
targetType: inline
script: make wasi-libc CLANG=$PWD/llvm-build/bin/clang LLVM_AR=$PWD/llvm-build/bin/llvm-ar LLVM_NM=$PWD/llvm-build/bin/llvm-nm
- task: Bash@3
displayName: Test TinyGo
inputs:

1
lib/wasi-libc

@ -0,0 +1 @@
Subproject commit a280fead2ae71b9a230d3b48c1f95867431888e4

26
src/runtime/runtime_wasm.go

@ -2,10 +2,6 @@
package runtime
import (
"unsafe"
)
type timeUnit float64 // time in milliseconds, just like Date.now() in JavaScript
const tickMicros = 1000000
@ -68,25 +64,3 @@ func ticks() timeUnit
func abort() {
trap()
}
//go:export memset
func memset(ptr unsafe.Pointer, c byte, size uintptr) unsafe.Pointer {
for i := uintptr(0); i < size; i++ {
*(*byte)(unsafe.Pointer(uintptr(ptr) + i)) = c
}
return ptr
}
// Implement memmove for LLVM and compiler-rt.
//go:export memmove
func libc_memmove(dst, src unsafe.Pointer, size uintptr) unsafe.Pointer {
memmove(dst, src, size)
return dst
}
// Implement memcpy for LLVM and compiler-rt.
//go:export memcpy
func libc_memcpy(dst, src unsafe.Pointer, size uintptr) unsafe.Pointer {
memcpy(dst, src, size)
return dst
}

10
targets/wasm.json

@ -1,21 +1,21 @@
{
"llvm-target": "wasm32-unknown-unknown-wasm",
"llvm-target": "wasm32--wasi",
"build-tags": ["js", "wasm"],
"goos": "js",
"goarch": "wasm",
"compiler": "clang",
"linker": "wasm-ld",
"cflags": [
"--target=wasm32",
"-nostdlibinc",
"-Wno-macro-redefined",
"--target=wasm32--wasi",
"--sysroot={root}/lib/wasi-libc/sysroot",
"-Oz"
],
"ldflags": [
"--allow-undefined",
"--no-threads",
"--stack-first",
"--export-all"
"--export-all",
"{root}/lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a"
],
"emulator": ["node", "targets/wasm_exec.js"]
}

Loading…
Cancel
Save