wa-lang.org/wazero@v1.0.2/Makefile (about)

     1  
     2  # Make functions strip spaces and use commas to separate parameters. The below variables escape these characters.
     3  comma := ,
     4  space :=
     5  space +=
     6  
     7  gofumpt := mvdan.cc/gofumpt@v0.4.0
     8  gosimports := github.com/rinchsan/gosimports/cmd/gosimports@v0.3.4
     9  golangci_lint := github.com/golangci/golangci-lint/cmd/golangci-lint@v1.50.1
    10  # sync this with netlify.toml!
    11  hugo          := github.com/gohugoio/hugo@v0.105.0
    12  
    13  # Make 3.81 doesn't support '**' globbing: Set explicitly instead of recursion.
    14  all_sources   := $(wildcard *.go */*.go */*/*.go */*/*/*.go */*/*/*.go */*/*/*/*.go)
    15  all_testdata  := $(wildcard testdata/* */testdata/* */*/testdata/* */*/testdata/*/* */*/*/testdata/*)
    16  all_testing   := $(wildcard internal/testing/* internal/testing/*/* internal/testing/*/*/*)
    17  all_examples  := $(wildcard examples/* examples/*/* examples/*/*/* */*/example/* */*/example/*/* */*/example/*/*/*)
    18  all_it        := $(wildcard internal/integration_test/* internal/integration_test/*/* internal/integration_test/*/*/*)
    19  # main_sources exclude any test or example related code
    20  main_sources  := $(wildcard $(filter-out %_test.go $(all_testdata) $(all_testing) $(all_examples) $(all_it), $(all_sources)))
    21  # main_packages collect the unique main source directories (sort will dedupe).
    22  # Paths need to all start with ./, so we do that manually vs foreach which strips it.
    23  main_packages := $(sort $(foreach f,$(dir $(main_sources)),$(if $(findstring ./,$(f)),./,./$(f))))
    24  
    25  ensureCompilerFastest := -ldflags '-X github.com/tetratelabs/wazero/internal/integration_test/vs.ensureCompilerFastest=true'
    26  .PHONY: bench
    27  bench:
    28  	@go test -run=NONE -benchmem -bench=. ./internal/integration_test/bench/...
    29  	@go test -benchmem -bench=. ./internal/integration_test/vs/... $(ensureCompilerFastest)
    30  
    31  .PHONY: bench.check
    32  bench.check:
    33  	@go build ./internal/integration_test/bench/...
    34  	@# Don't use -test.benchmem as it isn't accurate when comparing against CGO libs
    35  	@for d in vs/time vs/wasmedge vs/wasmer vs/wasmtime ; do \
    36  		cd ./internal/integration_test/$$d ; \
    37  		go test -bench=. . -tags='wasmedge' $(ensureCompilerFastest) ; \
    38  		cd - ;\
    39  	done
    40  
    41  bench_testdata_dir := internal/integration_test/bench/testdata
    42  .PHONY: build.bench
    43  build.bench:
    44  	@tinygo build -o $(bench_testdata_dir)/case.wasm -scheduler=none --no-debug -target=wasi $(bench_testdata_dir)/case.go
    45  
    46  .PHONY: test.examples
    47  test.examples:
    48  	@go test ./examples/... ./imports/assemblyscript/example/... ./imports/emscripten/... ./imports/go/example/... ./imports/wasi_snapshot_preview1/example/...
    49  
    50  .PHONY: build.examples.as
    51  build.examples.as:
    52  	@cd ./imports/assemblyscript/example/testdata && npm install && npm run build
    53  
    54  # Use -fstage1 to avoid bugs in the new compiler
    55  # https://github.com/ziglang/zig/wiki/Self-Hosted-Compiler-Upgrade-Guide#is-it-time-to-upgrade
    56  %.wasm: %.zig
    57  	@(cd $(@D); zig build -fstage1 -Drelease-small=true)
    58  	@mv $(@D)/zig-out/*/$(@F) $(@D)
    59  
    60  .PHONY: build.examples.zig
    61  build.examples.zig: examples/allocation/zig/testdata/greet.wasm imports/wasi_snapshot_preview1/example/testdata/zig/cat.wasm
    62  
    63  tinygo_sources := examples/basic/testdata/add.go examples/allocation/tinygo/testdata/greet.go examples/cli/testdata/cli.go imports/wasi_snapshot_preview1/example/testdata/tinygo/cat.go
    64  .PHONY: build.examples.tinygo
    65  build.examples.tinygo: $(tinygo_sources)
    66  	@for f in $^; do \
    67  	    tinygo build -o $$(echo $$f | sed -e 's/\.go/\.wasm/') -scheduler=none --no-debug --target=wasi $$f; \
    68  	done
    69  
    70  # We use zig to build C as it is easy to install and embeds a copy of zig-cc.
    71  c_sources := imports/wasi_snapshot_preview1/example/testdata/zig-cc/cat.c imports/wasi_snapshot_preview1/testdata/zig-cc/ls.c
    72  .PHONY: build.examples.zig-cc
    73  build.examples.zig-cc: $(c_sources)
    74  	@for f in $^; do \
    75  	    zig cc --target=wasm32-wasi -Oz -o $$(echo $$f | sed -e 's/\.c/\.wasm/') $$f; \
    76  	done
    77  
    78  # Here are the emcc args we use:
    79  #
    80  # * `-Oz` - most optimization for code size.
    81  # * `--profiling` - adds the name section.
    82  # * `-s STANDALONE_WASM` - ensures wasm is built for a non-js runtime.
    83  # * `-s EXPORTED_FUNCTIONS=_malloc,_free` - export allocation functions so that
    84  #   they can be used externally as "malloc" and "free".
    85  # * `-s WARN_ON_UNDEFINED_SYMBOLS=0` - imports not defined in JavaScript error
    86  #   otherwise. See https://github.com/emscripten-core/emscripten/issues/13641
    87  # * `-s TOTAL_STACK=8KB -s TOTAL_MEMORY=64KB` - reduce memory default from 16MB
    88  #   to one page (64KB). To do this, we have to reduce the stack size.
    89  # * `-s ALLOW_MEMORY_GROWTH` - allows "memory.grow" instructions to succeed, but
    90  #   requires a function import "emscripten_notify_memory_growth".
    91  emscripten_sources := $(wildcard imports/emscripten/testdata/*.cc)
    92  .PHONY: build.examples.emscripten
    93  build.examples.emscripten: $(emscripten_sources)
    94  	@for f in $^; do \
    95  		em++ -Oz --profiling \
    96  		-s STANDALONE_WASM \
    97  		-s EXPORTED_FUNCTIONS=_malloc,_free \
    98  		-s WARN_ON_UNDEFINED_SYMBOLS=0 \
    99  		-s TOTAL_STACK=8KB -s TOTAL_MEMORY=64KB \
   100  		-s ALLOW_MEMORY_GROWTH \
   101  		--std=c++17 -o $$(echo $$f | sed -e 's/\.cc/\.wasm/') $$f; \
   102  	done
   103  
   104  %/greet.wasm : cargo_target := wasm32-unknown-unknown
   105  %/cat.wasm : cargo_target := wasm32-wasi
   106  %/ls.wasm : cargo_target := wasm32-wasi
   107  
   108  .PHONY: build.examples.rust
   109  build.examples.rust: examples/allocation/rust/testdata/greet.wasm imports/wasi_snapshot_preview1/example/testdata/cargo-wasi/cat.wasm imports/wasi_snapshot_preview1/testdata/cargo-wasi/ls.wasm
   110  
   111  # Builds rust using cargo normally, or cargo-wasi.
   112  %.wasm: %.rs
   113  	@(cd $(@D); cargo $(if $(findstring wasi,$(cargo_target)),wasi build,build --target $(cargo_target)) --release)
   114  	@mv $(@D)/target/$(cargo_target)/release/$(@F) $(@D)
   115  
   116  spectest_base_dir := internal/integration_test/spectest
   117  spectest_v1_dir := $(spectest_base_dir)/v1
   118  spectest_v1_testdata_dir := $(spectest_v1_dir)/testdata
   119  spec_version_v1 := wg-1.0
   120  spectest_v2_dir := $(spectest_base_dir)/v2
   121  spectest_v2_testdata_dir := $(spectest_v2_dir)/testdata
   122  # Latest draft state as of Nov 9, 2022.
   123  spec_version_v2 := f9b461a312426a60f2f81dcb19b39b66b90a5447
   124  
   125  .PHONY: build.spectest
   126  build.spectest:
   127  	@$(MAKE) build.spectest.v1
   128  	@$(MAKE) build.spectest.v2
   129  
   130  .PHONY: build.spectest.v1
   131  build.spectest.v1: # Note: wabt by default uses >1.0 features, so wast2json flags might drift as they include more. See WebAssembly/wabt#1878
   132  	@rm -rf $(spectest_v1_testdata_dir)
   133  	@mkdir -p $(spectest_v1_testdata_dir)
   134  	@cd $(spectest_v1_testdata_dir) \
   135  		&& curl -sSL 'https://api.github.com/repos/WebAssembly/spec/contents/test/core?ref=$(spec_version_v1)' | jq -r '.[]| .download_url' | grep -E ".wast" | xargs -Iurl curl -sJL url -O
   136  	@cd $(spectest_v1_testdata_dir) && for f in `find . -name '*.wast'`; do \
   137  		perl -pi -e 's/\(assert_return_canonical_nan\s(\(invoke\s"f32.demote_f64"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\))\)/\(assert_return $$1 \(f32.const nan:canonical\)\)/g' $$f; \
   138  		perl -pi -e 's/\(assert_return_arithmetic_nan\s(\(invoke\s"f32.demote_f64"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\))\)/\(assert_return $$1 \(f32.const nan:arithmetic\)\)/g' $$f; \
   139  		perl -pi -e 's/\(assert_return_canonical_nan\s(\(invoke\s"f64\.promote_f32"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\))\)/\(assert_return $$1 \(f64.const nan:canonical\)\)/g' $$f; \
   140  		perl -pi -e 's/\(assert_return_arithmetic_nan\s(\(invoke\s"f64\.promote_f32"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\))\)/\(assert_return $$1 \(f64.const nan:arithmetic\)\)/g' $$f; \
   141  		perl -pi -e 's/\(assert_return_canonical_nan\s(\(invoke\s"[a-z._0-9]+"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\))\)/\(assert_return $$1 \($$2.const nan:canonical\)\)/g' $$f; \
   142  		perl -pi -e 's/\(assert_return_arithmetic_nan\s(\(invoke\s"[a-z._0-9]+"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\))\)/\(assert_return $$1 \($$2.const nan:arithmetic\)\)/g' $$f; \
   143  		perl -pi -e 's/\(assert_return_canonical_nan\s(\(invoke\s"[a-z._0-9]+"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\s\([a-z0-9.\s+-:]+\)\))\)/\(assert_return $$1 \($$2.const nan:canonical\)\)/g' $$f; \
   144  		perl -pi -e 's/\(assert_return_arithmetic_nan\s(\(invoke\s"[a-z._0-9]+"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\s\([a-z0-9.\s+-:]+\)\))\)/\(assert_return $$1 \($$2.const nan:arithmetic\)\)/g' $$f; \
   145  		perl -pi -e 's/\(assert_return_canonical_nan\s(\(invoke\s"[a-z._0-9]+"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\))\)/\(assert_return $$1 \($$2.const nan:canonical\)\)/g' $$f; \
   146  		perl -pi -e 's/\(assert_return_arithmetic_nan\s(\(invoke\s"[a-z._0-9]+"\s\((f[0-9]{2})\.const\s[a-z0-9.+:-]+\)\))\)/\(assert_return $$1 \($$2.const nan:arithmetic\)\)/g' $$f; \
   147  		wast2json \
   148  			--disable-saturating-float-to-int \
   149  			--disable-sign-extension \
   150  			--disable-simd \
   151  			--disable-multi-value \
   152  			--disable-bulk-memory \
   153  			--disable-reference-types \
   154  			--debug-names $$f; \
   155  	done
   156  
   157  .PHONY: build.spectest.v2
   158  build.spectest.v2: # Note: SIMD cases are placed in the "simd" subdirectory.
   159  	@mkdir -p $(spectest_v2_testdata_dir)
   160  	@cd $(spectest_v2_testdata_dir) \
   161  		&& curl -sSL 'https://api.github.com/repos/WebAssembly/spec/contents/test/core?ref=$(spec_version_v2)' | jq -r '.[]| .download_url' | grep -E ".wast" | xargs -Iurl curl -sJL url -O
   162  	@cd $(spectest_v2_testdata_dir) \
   163  		&& curl -sSL 'https://api.github.com/repos/WebAssembly/spec/contents/test/core/simd?ref=$(spec_version_v2)' | jq -r '.[]| .download_url' | grep -E ".wast" | xargs -Iurl curl -sJL url -O
   164  	@cd $(spectest_v2_testdata_dir) && for f in `find . -name '*.wast'`; do \
   165  		wast2json --debug-names $$f; \
   166  	done
   167  
   168  .PHONY: test
   169  test:
   170  	@go test $$(go list ./... | grep -vE '$(spectest_v1_dir)|$(spectest_v2_dir)') -timeout 120s
   171  	@cd internal/version/testdata && go test ./... -timeout 120s
   172  
   173  .PHONY: coverage
   174  coverpkg = $(subst $(space),$(comma),$(main_packages))
   175  coverage: ## Generate test coverage
   176  	@go test -coverprofile=coverage.txt -covermode=atomic --coverpkg=$(coverpkg) $(main_packages)
   177  	@go tool cover -func coverage.txt
   178  
   179  .PHONY: spectest
   180  spectest:
   181  	@$(MAKE) spectest.v1
   182  	@$(MAKE) spectest.v2
   183  
   184  spectest.v1:
   185  	@go test $$(go list ./... | grep $(spectest_v1_dir)) -timeout 120s
   186  
   187  spectest.v2:
   188  	@go test $$(go list ./... | grep $(spectest_v2_dir)) -timeout 120s
   189  
   190  golangci_lint_path := $(shell go env GOPATH)/bin/golangci-lint
   191  
   192  $(golangci_lint_path):
   193  	@go install $(golangci_lint)
   194  
   195  golangci_lint_goarch ?= $(shell go env GOARCH)
   196  
   197  .PHONY: lint
   198  lint: $(golangci_lint_path)
   199  	@GOARCH=$(golangci_lint_goarch) CGO_ENABLED=0 $(golangci_lint_path) run --timeout 5m
   200  
   201  .PHONY: format
   202  format:
   203  	@go run $(gofumpt) -l -w .
   204  	@go run $(gosimports) -local github.com/tetratelabs/ -w $(shell find . -name '*.go' -type f)
   205  
   206  .PHONY: check
   207  check:
   208  	@GOARCH=amd64 GOOS=dragonfly go build ./... # Check if the internal/platform can be built on compiler-unsupported platforms
   209  	@$(MAKE) lint golangci_lint_goarch=arm64
   210  	@$(MAKE) lint golangci_lint_goarch=amd64
   211  	@$(MAKE) format
   212  	@go mod tidy
   213  	@if [ ! -z "`git status -s`" ]; then \
   214  		echo "The following differences will fail CI until committed:"; \
   215  		git diff --exit-code; \
   216  	fi
   217  
   218  .PHONY: site
   219  site: ## Serve website content
   220  	@git submodule update --init
   221  	@cd site && go run $(hugo) server --minify --disableFastRender --baseURL localhost:1313 --cleanDestinationDir -D
   222  
   223  .PHONY: clean
   224  clean: ## Ensure a clean build
   225  	@rm -rf dist build coverage.txt
   226  	@go clean -testcache
   227  
   228  fuzz_timeout_seconds ?= 10
   229  .PHONY: fuzz
   230  fuzz:
   231  	@cd internal/integration_test/fuzz && cargo fuzz run basic -- -max_total_time=$(fuzz_timeout_seconds)