diff --git a/.circleci/config.yml b/.circleci/config.yml index 8b3915d0..fcb30b20 100644 --- a/.circleci/config.yml +++ b/.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 diff --git a/.gitmodules b/.gitmodules index 36288c43..4d539c85 100644 --- a/.gitmodules +++ b/.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 diff --git a/Makefile b/Makefile index ecc6d22f..2d4f2580 100644 --- a/Makefile +++ b/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 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5b6a5c04..ba5ff50e 100644 --- a/azure-pipelines.yml +++ b/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: diff --git a/lib/wasi-libc b/lib/wasi-libc new file mode 160000 index 00000000..a280fead --- /dev/null +++ b/lib/wasi-libc @@ -0,0 +1 @@ +Subproject commit a280fead2ae71b9a230d3b48c1f95867431888e4 diff --git a/src/runtime/runtime_wasm.go b/src/runtime/runtime_wasm.go index 4264ea19..154739b8 100644 --- a/src/runtime/runtime_wasm.go +++ b/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 -} diff --git a/targets/wasm.json b/targets/wasm.json index e8cdb5e1..47c20825 100644 --- a/targets/wasm.json +++ b/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"] }