diff --git a/.editorconfig b/.editorconfig
index 050d49d94..3a6e9e472 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -11,6 +11,10 @@ insert_final_newline = true
indent_style = space
indent_size = 4
+[*.py]
+indent_style = space
+indent_size = 4
+
[{Makefile,*.go}]
indent_style = tab
indent_size = 4
diff --git a/.gitignore b/.gitignore
index b90ce48f2..c9c09715c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
-target/
+# Please also see libwasmvm/.gitignore for the Rust-specific ignored files.
+
**/*.rs.bk
*.iml
.idea
@@ -7,7 +8,6 @@ target/
lib*.a
# artifacts from compile tests
-artifacts/
/demo
tmp
a.out
diff --git a/Makefile b/Makefile
index f6f3a1778..3a0d64746 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,9 @@
.PHONY: all build build-rust build-go test
# Builds the Rust library libwasmvm
-BUILDERS_PREFIX := cosmwasm/go-ext-builder:0008
+BUILDERS_PREFIX := cosmwasm/go-ext-builder:0009
# Contains a full Go dev environment in order to run Go tests on the built library
-ALPINE_TESTER := cosmwasm/go-ext-builder:0008-alpine
+ALPINE_TESTER := cosmwasm/go-ext-builder:0009-alpine
USER_ID := $(shell id -u)
USER_GROUP = $(shell id -g)
@@ -73,10 +73,10 @@ release-build-linux:
# Creates a release build in a containerized build environment of the shared library for macOS (.dylib)
release-build-macos:
- rm -rf libwasmvm/target/release
- docker run --rm -u $(USER_ID):$(USER_GROUP) -v $(shell pwd)/libwasmvm:/code $(BUILDERS_PREFIX)-cross
- cp libwasmvm/target/x86_64-apple-darwin/release/deps/libwasmvm.dylib api
- cp libwasmvm/bindings.h api
+ rm -rf libwasmvm/target/x86_64-apple-darwin/release
+ rm -rf libwasmvm/target/aarch64-apple-darwin/release
+ docker run --rm -u $(USER_ID):$(USER_GROUP) -v $(shell pwd)/libwasmvm:/code $(BUILDERS_PREFIX)-cross build_macos.sh
+ cp libwasmvm/artifacts/libwasmvm.dylib api
make update-bindings
update-bindings:
diff --git a/README.md b/README.md
index 0c85ba1a7..6f7309a9a 100644
--- a/README.md
+++ b/README.md
@@ -14,39 +14,45 @@ link with, and Go developers should just be able to import this directly.
## Supported Platforms
-Requires Rust 1.51+, Requires Go 1.17+
-
-Since this package includes a rust prebuilt dll, you cannot just import the go code,
-but need to be on a system that works with an existing dll. Currently this is Linux
-(tested on Ubuntu, Debian, and CentOS7) and MacOS. We have a build system for Windows,
-but it is [not supported][wasmer_support] by the Wasmer Singlepass backend which we rely upon.
-
-[wasmer_support]: https://docs.wasmer.io/ecosystem/wasmer/wasmer-features
-
-### Overview
-
-| | [x86] | [x86_64] | [ARM32] | [ARM64] |
-| ------------- | ------------------- | ------------------- | -------------------- | -------------------- |
-| Linux (glibc) | ❌ | ✅ | ❌ [#53] | ❌ [#53] |
-| Linux (muslc) | ❌ | ✅ | ❌ [#53] | ❌ [#53] |
-| macOS | ❌ | ✅ | ❌ [#53] | ❌ [#53] |
-| Windows | ❌ [#28] | ❌ [#28] | ❌ [#28] | ❌ [#28] |
-
-[x86]: https://en.wikipedia.org/wiki/X86
-[x86_64]: https://en.wikipedia.org/wiki/X86-64
-[arm32]: https://en.wikipedia.org/wiki/AArch32
-[arm64]: https://en.wikipedia.org/wiki/AArch64
-[#28]: https://github.com/CosmWasm/wasmvm/issues/28
-[#53]: https://github.com/CosmWasm/wasmvm/issues/53
-
-✅ Supported and activly maintained.
-
-❌ Blocked by external dependency.
-
-🤷 Not supported because nobody cares so far. Feel free to look into it.
-
-This is all blocked on [wasmer support for singlepass backend](https://docs.wasmer.io/ecosystem/wasmer/wasmer-features#compiler-support-by-chipset).
-We can only move on these wasmvm issues when the upstream has support.
+Requires Rust 1.55+ and Go 1.17+.
+
+The Rust implementation of the VM is compiled to a library called libwasmvm. This is
+then linked to the Go code when the final binary is built. For that reason not all
+systems supported by Go are supported by this project.
+
+Linux (tested on Ubuntu, Debian, and CentOS7, Alpine) and macOS is supported.
+We are working on Windows (#288).
+
+[#288]: https://github.com/CosmWasm/wasmvm/pull/288
+
+### Builds of libwasmvm
+
+Our system currently supports the following builds. In general we can only support targets
+that are [supported by Wasmer's singlepass backend](https://docs.wasmer.io/ecosystem/wasmer/wasmer-features#compiler-support-by-chipset),
+which for example excludes all 32 bit systems.
+
+
+
+| OS family | Arch | Linking | Supported | Wasmer 2.2+ | Note |
+| --------------- | ------- | ------- | -------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
+| Linux (glibc) | x86_64 | shared | ✅libwasmvm.so | ✅libwasmvm.so | |
+| Linux (glibc) | x86_64 | static | 🚫 | 🚫 | Would link libwasmvm statically but glibc dynamically as static glibc linking is not recommended. Potentially interesting for Osmosis. |
+| Linux (glibc) | aarch64 | shared | 🚫 | ✅libwasmvm.aarch64.so | |
+| Linux (glibc) | aarch64 | static | 🚫 | 🚫 | |
+| Linux (musl) | x86_64 | shared | 🚫 | 🚫 | Possible but not needed |
+| Linux (musl) | x86_64 | static | ✅libwasmvm_muslc.a | ✅libwasmvm_muslc.a | |
+| Linux (musl) | aarch64 | shared | 🚫 | 🚫 | Possible but not needed |
+| Linux (musl) | aarch64 | static | 🚫 | ✅libwasmvm_muslc.aarch64.a | |
+| macOS | x86_64 | shared | ✅libwasmvm.dylib | ✅libwasmvm.dylib | Fat/universal library with multiple archs (#294) |
+| macOS | x86_64 | static | 🚫 | 🚫 | |
+| macOS | aarch64 | shared | 🚫 | ✅libwasmvm.dylib | Fat/universal library with multiple archs (#294) |
+| macOS | aarch64 | static | 🚫 | 🚫 | |
+| Windows (mingw) | x86_64 | shared | 🏗wasmvm.dll | 🏗wasmvm.dll | See #288 |
+| Windows (mingw) | x86_64 | static | 🚫 | 🚫 | |
+| Windows (mingw) | aarch64 | shared | 🚫 | 🚫 | |
+| Windows (mingw) | aarch64 | static | 🚫 | 🚫 | |
+
+
## Docs
diff --git a/builders/Dockerfile.alpine b/builders/Dockerfile.alpine
index bac7fb831..4ce6fa137 100644
--- a/builders/Dockerfile.alpine
+++ b/builders/Dockerfile.alpine
@@ -2,7 +2,7 @@
# 1. Build the static Rust library
# 2. Execute Go tests that use and test this library
# For 2. we define the Go image here. For 1. we install Rust below.
-FROM golang:1.17.5-alpine
+FROM golang:1.17.7-alpine
ENV RUSTUP_HOME=/usr/local/rustup \
CARGO_HOME=/usr/local/cargo \
diff --git a/builders/Dockerfile.centos7 b/builders/Dockerfile.centos7
index 5ddbe8a1d..fa582e27a 100644
--- a/builders/Dockerfile.centos7
+++ b/builders/Dockerfile.centos7
@@ -1,23 +1,21 @@
FROM centos:centos7
-RUN yum -y update
-RUN yum -y install clang gcc gcc-c++ make wget
+RUN yum -y update \
+ && yum -y install clang gcc gcc-c++ make wget
# GET FROM https://github.com/rust-lang/docker-rust-nightly
ENV RUSTUP_HOME=/usr/local/rustup \
CARGO_HOME=/usr/local/cargo \
PATH=/usr/local/cargo/bin:$PATH
-
-RUN url="https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init"; \
- wget "$url"; \
- chmod +x rustup-init; \
- ./rustup-init -y --no-modify-path --default-toolchain 1.55.0; \
- rm rustup-init; \
- chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
- rustup --version; \
- cargo --version; \
- rustc --version;
+RUN wget "https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init" \
+ && chmod +x rustup-init \
+ && ./rustup-init -y --no-modify-path --default-toolchain 1.55.0 \
+ && rm rustup-init \
+ && chmod -R a+w $RUSTUP_HOME $CARGO_HOME \
+ && rustup --version \
+ && cargo --version \
+ && rustc --version
# allow non-root user to download more deps later
RUN chmod -R 777 /usr/local/cargo
diff --git a/builders/Dockerfile.cross b/builders/Dockerfile.cross
index 766ece467..35f741188 100644
--- a/builders/Dockerfile.cross
+++ b/builders/Dockerfile.cross
@@ -1,33 +1,40 @@
-FROM rust:1.55.0-buster
+FROM rust:1.55.0-bullseye
# Install build dependencies
-RUN apt-get update
-RUN apt install -y clang gcc g++ zlib1g-dev libmpc-dev libmpfr-dev libgmp-dev
-RUN apt install -y build-essential cmake
-
-# add some llvm configs for later - how to cross-compile this in wasmer-llvm-backend???
-RUN echo deb http://deb.debian.org/debian buster-backports main >> /etc/apt/sources.list
-RUN apt-get update
-RUN apt install -y libllvm8 llvm-8 llvm-8-dev llvm-8-runtime
-ENV LLVM_SYS_80_PREFIX=/usr/lib/llvm-8
+RUN apt-get update \
+ && apt install -y clang gcc g++ zlib1g-dev libmpc-dev libmpfr-dev libgmp-dev build-essential cmake
## ADD MACOS SUPPORT
WORKDIR /opt
-# Add macOS Rust target
-RUN rustup target add x86_64-apple-darwin
+# Add macOS Rust targets
+RUN rustup target add x86_64-apple-darwin aarch64-apple-darwin
# Build osxcross
-RUN git clone https://github.com/tpoechtrager/osxcross
-RUN cd osxcross && \
- wget -nc https://s3.dockerproject.org/darwin/v2/MacOSX10.10.sdk.tar.xz && \
- mv MacOSX10.10.sdk.tar.xz tarballs/ && \
- UNATTENDED=yes OSX_VERSION_MIN=10.10 ./build.sh
+# See https://github.com/tpoechtrager/osxcross/blob/master/build.sh#L31-L49 for SDK overview.
+#
+# SDK availability is tricky. There is 10.10 and 10.11. at
+# - https://s3.dockerproject.org/darwin/v2/MacOSX10.10.sdk.tar.xz
+# - https://s3.dockerproject.org/darwin/v2/MacOSX10.11.sdk.tar.xz
+# and we have https://github.com/phracker/MacOSX-SDKs/releases.
+# At some point we might want to use our own package.
+RUN git clone https://github.com/tpoechtrager/osxcross \
+ && cd osxcross \
+ # Don't change file name when downloading because osxcross auto-detects the version from the name
+ && wget -nc https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX11.3.sdk.tar.xz \
+ && mv MacOSX11.3.sdk.tar.xz tarballs/ \
+ && UNATTENDED=yes OSX_VERSION_MIN=10.10 ./build.sh \
+ # Cleanups before Docker layer is finalized
+ && rm -r tarballs/
RUN chmod +rx /opt/osxcross
RUN chmod +rx /opt/osxcross/target
RUN chmod -R +rx /opt/osxcross/target/bin
+# RUN ls -l /opt/osxcross/target/bin
+RUN /opt/osxcross/target/bin/x86_64-apple-darwin20.4-clang --version
+RUN /opt/osxcross/target/bin/aarch64-apple-darwin20.4-clang --version
+
# allow non-root user to download more deps later
RUN chmod -R 777 /usr/local/cargo
@@ -35,11 +42,11 @@ RUN chmod -R 777 /usr/local/cargo
WORKDIR /code
-COPY guest/*.sh /opt/
-RUN chmod +x /opt/*.sh
+COPY guest/*.sh /usr/local/bin/
+RUN chmod +x /usr/local/bin/*.sh
RUN mkdir /.cargo
RUN chmod +rx /.cargo
COPY guest/cargo-config /.cargo/config
-CMD ["/opt/build_macos.sh"]
+CMD ["bash", "-c", "echo 'Argument missing. Pass one build script (e.g. build_macos.sh) to docker run' && exit 1"]
diff --git a/builders/Makefile b/builders/Makefile
index 5702d7c0c..8355a7e9c 100644
--- a/builders/Makefile
+++ b/builders/Makefile
@@ -1,6 +1,6 @@
# Versioned by a simple counter that is not bound to a specific CosmWasm version
# See builders/README.md
-BUILDERS_PREFIX := cosmwasm/go-ext-builder:0008
+BUILDERS_PREFIX := cosmwasm/go-ext-builder:0009
.PHONY: docker-image-centos7
docker-image-centos7:
diff --git a/builders/README.md b/builders/README.md
index 772c6c59b..a6efd8dfb 100644
--- a/builders/README.md
+++ b/builders/README.md
@@ -14,6 +14,11 @@ can do the cross-compilation.
## Changelog
+**Version 0009:**
+
+- Let macOS build dylib files with both aarch64 and x86_64 code.
+- Update Go (for testing only) to 1.17.7.
+
**Version 0008:**
- Update Rust to 1.55.0 and Go (for testing only) to 1.17.5.
diff --git a/builders/guest/build_linux.sh b/builders/guest/build_linux.sh
index 750196992..889841da2 100755
--- a/builders/guest/build_linux.sh
+++ b/builders/guest/build_linux.sh
@@ -1,4 +1,5 @@
#!/bin/bash
+set -o errexit -o nounset -o pipefail
# See https://github.com/CosmWasm/wasmvm/issues/222#issuecomment-880616953 for two approaches to
# enable stripping through cargo (if that is desired).
diff --git a/builders/guest/build_macos.sh b/builders/guest/build_macos.sh
index ae6d5967e..c4de4584c 100755
--- a/builders/guest/build_macos.sh
+++ b/builders/guest/build_macos.sh
@@ -1,12 +1,24 @@
#!/bin/bash
+set -o errexit -o nounset -o pipefail
# ref: https://wapl.es/rust/2019/02/17/rust-cross-compile-linux-to-macos.html
export PATH="/opt/osxcross/target/bin:$PATH"
export LIBZ_SYS_STATIC=1
-export CC=o64-clang
-export CXX=o64-clang++
# See https://github.com/CosmWasm/wasmvm/issues/222#issuecomment-880616953 for two approaches to
# enable stripping through cargo (if that is desired).
+echo "Starting aarch64-apple-darwin build"
+export CC=aarch64-apple-darwin20.4-clang
+export CXX=aarch64-apple-darwin20.4-clang++
+cargo build --release --target aarch64-apple-darwin
+
+echo "Starting x86_64-apple-darwin build"
+export CC=o64-clang
+export CXX=o64-clang++
cargo build --release --target x86_64-apple-darwin
+
+# Create a universal library with both archs
+lipo -output artifacts/libwasmvm.dylib -create \
+ target/x86_64-apple-darwin/release/deps/libwasmvm.dylib \
+ target/aarch64-apple-darwin/release/deps/libwasmvm.dylib
diff --git a/builders/guest/cargo-config b/builders/guest/cargo-config
index 4727075fd..4391721da 100644
--- a/builders/guest/cargo-config
+++ b/builders/guest/cargo-config
@@ -1,3 +1,7 @@
[target.x86_64-apple-darwin]
-linker = "x86_64-apple-darwin14-clang"
-ar = "x86_64-apple-darwin14-ar"
\ No newline at end of file
+linker = "x86_64-apple-darwin20.4-clang"
+ar = "x86_64-apple-darwin20.4-ar"
+
+[target.aarch64-apple-darwin]
+linker = "aarch64-apple-darwin20.4-clang"
+ar = "aarch64-apple-darwin20.4-ar"
diff --git a/docs/libwasmvm_builds.py b/docs/libwasmvm_builds.py
new file mode 100644
index 000000000..1e68fc059
--- /dev/null
+++ b/docs/libwasmvm_builds.py
@@ -0,0 +1,92 @@
+
+
+oss = ["Linux (glibc)", "Linux (musl)", "macOS", "Windows (mingw)"]
+cpus = ["x86_64", "aarch64"]
+build_types = ["shared", "static"]
+# libc = ["glibc", "musl"]
+
+ZERO_WIDTH_SPACE = "\u200B"
+SUPPORTED = "✅" + ZERO_WIDTH_SPACE
+UNSUPPORTED = "🚫" + ZERO_WIDTH_SPACE
+UNKNOWN = "🤷" + ZERO_WIDTH_SPACE
+UNDER_CONSTRUCTION = "🏗" + ZERO_WIDTH_SPACE
+
+def is_supported(os, cpu, build_type):
+ if cpu == "aarch64":
+ return UNSUPPORTED
+ if os == "Windows (mingw)":
+ if cpu == "x86_64" and build_type == "shared":
+ return UNDER_CONSTRUCTION + "wasmvm.dll"
+ else:
+ return UNSUPPORTED
+ if os == "macOS" and build_type == "static":
+ return UNSUPPORTED
+ if os == "macOS" and build_type == "shared":
+ return SUPPORTED + "libwasmvm.dylib"
+ if os == "Linux (musl)":
+ if build_type == "static":
+ return SUPPORTED + "libwasmvm_muslc.a"
+ if build_type == "shared":
+ return UNSUPPORTED
+ if os == "Linux (glibc)":
+ if build_type == "static":
+ return UNSUPPORTED
+ if build_type == "shared":
+ return SUPPORTED + "libwasmvm.so"
+ return UNKNOWN
+
+def wasmer22_supported(os, cpu, build_type):
+ if os == "Windows (mingw)":
+ if cpu == "x86_64" and build_type == "shared":
+ return UNDER_CONSTRUCTION + "wasmvm.dll"
+ else:
+ return UNSUPPORTED
+ if os == "macOS" and build_type == "static":
+ return UNSUPPORTED
+ if os == "macOS" and build_type == "shared":
+ return SUPPORTED + "libwasmvm.dylib"
+ if os == "Linux (musl)":
+ if build_type == "static":
+ if cpu == "x86_64":
+ return SUPPORTED + "libwasmvm_muslc.a"
+ elif cpu == "aarch64":
+ return SUPPORTED + "libwasmvm_muslc.aarch64.a"
+ if build_type == "shared":
+ return UNSUPPORTED
+ if os == "Linux (glibc)":
+ if build_type == "static":
+ return UNSUPPORTED
+ if build_type == "shared":
+ if cpu == "x86_64":
+ return SUPPORTED + "libwasmvm.so"
+ elif cpu == "aarch64":
+ return SUPPORTED + "libwasmvm.aarch64.so"
+ return UNKNOWN
+
+def get_note(os, cpu, build_type):
+ if os == "Windows (mingw)" and cpu == "x86_64" and build_type == "shared":
+ return "See #288"
+ if os == "Linux (glibc)" and cpu == "x86_64" and build_type == "static":
+ return "Would link libwasmvm statically but glibc dynamically as static glibc linking is not recommended. Potentially interesting for Osmosis."
+ if os == "Linux (musl)" and build_type == "shared":
+ return "Possible but not needed"
+ if os == "macOS" and build_type == "shared":
+ return "Fat/universal library with multiple archs (#294)"
+ return ""
+
+print("")
+print("| OS family | Arch | Linking | Supported | Wasmer 2.2+ | Note |")
+print("| --------------- | ------- | ------- | ------------------- | ----------------------------- | ------- |")
+
+for os in oss:
+ for cpu in cpus:
+ for build_type in build_types:
+ s1 = is_supported(os, cpu, build_type)
+ s2 = wasmer22_supported(os, cpu, build_type)
+ note = get_note(os, cpu, build_type)
+ print(
+ "| {:<15} | {:<7} | {:<7} | {:<19} | {:<29} | {} |".format(
+ os, cpu, build_type, s1, s2, note
+ )
+ )
+print("")
diff --git a/libwasmvm/.gitignore b/libwasmvm/.gitignore
new file mode 100644
index 000000000..1f2eb5641
--- /dev/null
+++ b/libwasmvm/.gitignore
@@ -0,0 +1,3 @@
+# Build results
+target/
+artifacts/
diff --git a/libwasmvm/artifacts/.gitkeep b/libwasmvm/artifacts/.gitkeep
new file mode 100644
index 000000000..e69de29bb