diff --git a/.github/workflows/west.yml b/.github/workflows/west.yml index db2849f..ea99ade 100644 --- a/.github/workflows/west.yml +++ b/.github/workflows/west.yml @@ -24,8 +24,8 @@ jobs: strategy: matrix: target: - - aarch64-unknown-linux-musl - aarch64-linux-android + - aarch64-unknown-linux-musl - riscv64gc-unknown-linux-gnu - x86_64-pc-windows-gnu - x86_64-unknown-linux-musl @@ -49,22 +49,24 @@ jobs: matrix: config: - os: macos-13 - lib: x86_64-darwin target: x86_64-apple-darwin + sdk: 10.12 - os: macos-14 - lib: aarch64-darwin target: aarch64-apple-darwin + sdk: 11.0 name: west-${{ matrix.config.target }} runs-on: ${{ matrix.config.os }} steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: ./.github/actions/install-nix - with: - cachixAuthToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - run: nix build -L - - run: nix run -L --inputs-from . 'nixpkgs#coreutils' -- --coreutils-prog=cp -RLv ./result artifact + - run: rustup show + - uses: Swatinem/rust-cache@v2.7.3 + - run: cargo build -p west-sys --release --target ${{ matrix.config.target }} + env: + MACOSX_DEPLOYMENT_TARGET: ${{ matrix.config.sdk }} + - run: mkdir -p artifact/lib + - run: mv target/${{ matrix.config.target }}/release/libwest_sys.a artifact/lib/libwest_sys.a - uses: actions/upload-artifact@v4 with: name: west-${{ matrix.config.target }} @@ -93,26 +95,43 @@ jobs: - os: ubuntu-latest lib: x86_64-linux target: x86_64-unknown-linux-musl + shell: bash - os: windows-latest lib: x86_64-windows target: x86_64-pc-windows-gnu + shell: msys2 - os: macos-13 lib: x86_64-darwin target: x86_64-apple-darwin + shell: bash - os: macos-14 lib: aarch64-darwin target: aarch64-apple-darwin + shell: bash - name: test-release-${{ matrix.config.target }} + name: test-release (${{ matrix.config.os }}) needs: - build-ffi - build-ffi-darwin - build-wasm runs-on: ${{ matrix.config.os }} + defaults: + run: + shell: ${{ matrix.config.shell }} {0} steps: + - uses: msys2/setup-msys2@v2 + if: matrix.config.os == 'windows-latest' + with: + update: true + install: mingw-w64-x86_64-toolchain + msystem: MINGW64 + path-type: inherit + - run: git config --global core.autocrlf input + if: matrix.config.os == 'windows-latest' + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: @@ -124,46 +143,73 @@ jobs: - run: mv lib/libwest_sys.a "lib/${{ matrix.config.lib }}/libwest.a" - uses: actions/setup-go@v5 with: - go-version-file: 'go.mod' + go-version-file: go.mod + if: matrix.config.os != 'windows-latest' - run: rustup show + if: matrix.config.os != 'windows-latest' - uses: Swatinem/rust-cache@v2.7.3 + if: matrix.config.os != 'windows-latest' - uses: cargo-bins/cargo-binstall@v1.10.5 - run: cargo binstall -y wasm-tools@1.217 - run: go generate ./tests/go/... - - run: go test ./... + - run: go test -failfast ./... env: GOGC: 1 WEST_LOG: trace - continue-on-error: ${{ matrix.config.os == 'ubuntu-latest' || matrix.config.os == 'windows-latest' }} # TODO: remove + continue-on-error: ${{ matrix.config.os == 'ubuntu-latest' }} # TODO: remove - run: git diff --exit-code test-dev: strategy: matrix: - os: - - ubuntu-latest - - windows-latest - - macos-13 - - macos-14 - - name: test-dev-${{ matrix.os }} - runs-on: ${{ matrix.os }} + config: + - os: ubuntu-latest + shell: bash + + - os: windows-latest + shell: msys2 + + - os: macos-13 + shell: bash + + - os: macos-14 + shell: bash + + runs-on: ${{ matrix.config.os }} + defaults: + run: + shell: ${{ matrix.config.shell }} {0} steps: + - uses: msys2/setup-msys2@v2 + if: matrix.config.os == 'windows-latest' + with: + update: true + install: mingw-w64-x86_64-toolchain + msystem: MINGW64 + path-type: inherit + - run: git config --global core.autocrlf input + if: matrix.config.os == 'windows-latest' + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - uses: actions/setup-go@v5 with: - go-version-file: 'go.mod' + go-version-file: go.mod + + - run: rustup set default-host x86_64-pc-windows-gnu + if: matrix.config.os == 'windows-latest' - run: rustup show + - uses: Swatinem/rust-cache@v2.7.3 - uses: cargo-bins/cargo-binstall@v1.10.5 - run: cargo binstall -y wasm-tools@1.217 - run: cargo test --workspace --all-targets + if: matrix.config.os != 'windows-latest' - run: go generate -tags=dev ./... - - run: go test -tags=dev ./... + - run: go test -failfast -tags=dev ./... env: GOGC: 1 WEST_LOG: trace - continue-on-error: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'windows-latest' }} # TODO: remove + continue-on-error: ${{ matrix.config.os == 'ubuntu-latest' }} # TODO: remove - run: git diff --exit-code gofmt: @@ -172,7 +218,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - uses: actions/setup-go@v5 with: - go-version-file: 'go.mod' + go-version-file: go.mod - run: gofmt -w -s **/*.go - run: git diff --exit-code diff --git a/.gitignore b/.gitignore index 684e484..0f5250b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /target *.wasm *.a +*.lib west_bindings_test.go /go/internal/tests/*/bindings/* diff --git a/build.go b/build.go deleted file mode 100644 index 9510afd..0000000 --- a/build.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build !dev - -//go:generate cargo build -p west-sys --release -//go:generate cargo build -p west-passthrough --target wasm32-unknown-unknown --release -//go:generate wasm-tools component new target/wasm32-unknown-unknown/release/west_passthrough.wasm -o lib/passthrough.wasm - -package west - -// #cgo LDFLAGS: -lwest -// #cgo linux LDFLAGS: -lm -// #cgo android,arm64 LDFLAGS: -L${SRCDIR}/lib/aarch64-android -// #cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/lib/x86_64-darwin -// #cgo darwin,arm64 LDFLAGS: -L${SRCDIR}/lib/aarch64-darwin -// #cgo linux,amd64 LDFLAGS: -L${SRCDIR}/lib/x86_64-linux -// #cgo linux,arm64 LDFLAGS: -L${SRCDIR}/lib/aarch64-linux -// #cgo linux,riscv64 LDFLAGS: -L${SRCDIR}/lib/riscv64-linux -// #cgo windows,amd64 LDFLAGS: -L${SRCDIR}/lib/x86_64-windows -// #cgo windows,arm64 LDFLAGS: -L${SRCDIR}/lib/aarch64-windows -import "C" diff --git a/build_dev.go b/build_dev.go deleted file mode 100644 index c71c840..0000000 --- a/build_dev.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build dev - -//go:generate cargo build -p west-sys -//go:generate cargo build -p west-passthrough --target wasm32-unknown-unknown -//go:generate wasm-tools component new target/wasm32-unknown-unknown/debug/west_passthrough.wasm -o lib/passthrough.wasm - -package west - -// #cgo LDFLAGS: -L${SRCDIR}/target/debug -lwest_sys -// #cgo linux LDFLAGS: -lm -import "C" diff --git a/gen.go b/gen.go new file mode 100644 index 0000000..9bf662c --- /dev/null +++ b/gen.go @@ -0,0 +1,5 @@ +//go:build !dev + +//go:generate go run ./internal/generate + +package west diff --git a/gen_dev.go b/gen_dev.go new file mode 100644 index 0000000..73ac83d --- /dev/null +++ b/gen_dev.go @@ -0,0 +1,5 @@ +//go:build dev + +//go:generate go run -tags=dev ./internal/generate + +package west diff --git a/internal/generate/build.go b/internal/generate/build.go new file mode 100644 index 0000000..b41eae6 --- /dev/null +++ b/internal/generate/build.go @@ -0,0 +1,22 @@ +//go:build !dev + +package main + +import ( + "path/filepath" +) + +func TargetPath(target string) string { + if target == "" { + return filepath.Join(TargetDir, "release") + } + return filepath.Join(TargetDir, target, "release") +} + +func CargoBuild(target string, args ...string) error { + base := []string{"build", "--release"} + if target != "" { + base = append(base, "--target", target) + } + return RunCargo(append(base, args...)...) +} diff --git a/internal/generate/build_dev.go b/internal/generate/build_dev.go new file mode 100644 index 0000000..87253e0 --- /dev/null +++ b/internal/generate/build_dev.go @@ -0,0 +1,22 @@ +//go:build dev + +package main + +import ( + "path/filepath" +) + +func TargetPath(target string) string { + if target == "" { + return filepath.Join(TargetDir, "debug") + } + return filepath.Join(TargetDir, target, "debug") +} + +func CargoBuild(target string, args ...string) error { + base := []string{"build"} + if target != "" { + base = append(base, "--target", target) + } + return RunCargo(append(base, args...)...) +} diff --git a/internal/generate/west.go b/internal/generate/west.go new file mode 100644 index 0000000..019980f --- /dev/null +++ b/internal/generate/west.go @@ -0,0 +1,77 @@ +package main + +import ( + "flag" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" +) + +var ( + Root = func() string { + _, f, _, _ := runtime.Caller(0) + return filepath.Join(f, "..", "..", "..") + }() + + TargetDir = filepath.Join(Root, "target") + LibDir = filepath.Join(Root, "lib") +) + +func init() { + log.SetFlags(0) + flag.Parse() +} + +func Run(cmd *exec.Cmd) error { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} + +func RunCargo(args ...string) error { + return Run(exec.Command("cargo", args...)) +} + +func main() { + if err := Run(exec.Command( + "go", + "run", + "github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go", + "generate", + "-w", + "imports", + "-o", + "bindings", + filepath.Join(Root, "wit"), + )); err != nil { + log.Fatalf("failed to generate WIT bindings: %s", err) + } + if err := CargoBuild(CARGO_TARGET, "-p", "west-sys"); err != nil { + log.Fatalf("failed to build FFI: %s", err) + } + libTarget := filepath.Join(LibTargetDir, "libwest.a") + if err := os.RemoveAll(libTarget); err != nil { + log.Fatalf("failed to remove FFI: %s", err) + } + if err := os.Link( + filepath.Join(TargetPath(CARGO_TARGET), "libwest_sys.a"), + libTarget, + ); err != nil { + log.Fatalf("failed to hard link FFI: %s", err) + } + if err := CargoBuild("wasm32-unknown-unknown", "-p", "west-passthrough"); err != nil { + log.Fatalf("failed to build passthrough component: %s", err) + } + if err := Run(exec.Command( + "wasm-tools", + "component", + "new", + filepath.Join(TargetPath("wasm32-unknown-unknown"), "west_passthrough.wasm"), + "-o", + filepath.Join(LibDir, "passthrough.wasm"), + )); err != nil { + log.Fatalf("failed to create passthrough component: %s", err) + } +} diff --git a/internal/generate/west_android_arm64.go b/internal/generate/west_android_arm64.go new file mode 100644 index 0000000..4efcd4a --- /dev/null +++ b/internal/generate/west_android_arm64.go @@ -0,0 +1,7 @@ +package main + +import "path/filepath" + +const CARGO_TARGET = "aarch64-linux-android" + +var LibTargetDir = filepath.Join(LibDir, "aarch64-android") diff --git a/internal/generate/west_darwin_amd64.go b/internal/generate/west_darwin_amd64.go new file mode 100644 index 0000000..13216fc --- /dev/null +++ b/internal/generate/west_darwin_amd64.go @@ -0,0 +1,7 @@ +package main + +import "path/filepath" + +const CARGO_TARGET = "x86_64-apple-darwin" + +var LibTargetDir = filepath.Join(LibDir, "x86_64-darwin") diff --git a/internal/generate/west_darwin_arm64.go b/internal/generate/west_darwin_arm64.go new file mode 100644 index 0000000..b59fc68 --- /dev/null +++ b/internal/generate/west_darwin_arm64.go @@ -0,0 +1,7 @@ +package main + +import "path/filepath" + +const CARGO_TARGET = "aarch64-apple-darwin" + +var LibTargetDir = filepath.Join(LibDir, "aarch64-darwin") diff --git a/internal/generate/west_linux_amd64.go b/internal/generate/west_linux_amd64.go new file mode 100644 index 0000000..944a4b1 --- /dev/null +++ b/internal/generate/west_linux_amd64.go @@ -0,0 +1,7 @@ +package main + +import "path/filepath" + +const CARGO_TARGET = "x86_64-unknown-linux-gnu" + +var LibTargetDir = filepath.Join(LibDir, "x86_64-linux") diff --git a/internal/generate/west_linux_arm64.go b/internal/generate/west_linux_arm64.go new file mode 100644 index 0000000..79fde29 --- /dev/null +++ b/internal/generate/west_linux_arm64.go @@ -0,0 +1,7 @@ +package main + +import "path/filepath" + +const CARGO_TARGET = "aarch64-unknown-linux-gnu" + +var LibTargetDir = filepath.Join(LibDir, "aarch64-linux") diff --git a/internal/generate/west_linux_riscv64.go b/internal/generate/west_linux_riscv64.go new file mode 100644 index 0000000..5cb5501 --- /dev/null +++ b/internal/generate/west_linux_riscv64.go @@ -0,0 +1,7 @@ +package main + +import "path/filepath" + +const CARGO_TARGET = "riscv64gc-unknown-linux-gnu" + +var LibTargetDir = filepath.Join(LibDir, "riscv64-linux") diff --git a/internal/generate/west_windows_amd64.go b/internal/generate/west_windows_amd64.go new file mode 100644 index 0000000..4184e50 --- /dev/null +++ b/internal/generate/west_windows_amd64.go @@ -0,0 +1,7 @@ +package main + +import "path/filepath" + +const CARGO_TARGET = "x86_64-pc-windows-gnu" + +var LibTargetDir = filepath.Join(LibDir, "x86_64-windows") diff --git a/internal/generate/west_windows_arm64.go b/internal/generate/west_windows_arm64.go new file mode 100644 index 0000000..feafa1a --- /dev/null +++ b/internal/generate/west_windows_arm64.go @@ -0,0 +1,7 @@ +package main + +import "path/filepath" + +const CARGO_TARGET = "aarch64-pc-windows-gnullvm" + +var LibTargetDir = filepath.Join(LibDir, "aarch64-windows") diff --git a/west.go b/west.go index d96a587..4923a94 100644 --- a/west.go +++ b/west.go @@ -1,7 +1,16 @@ -//go:generate go run github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go generate -w imports -o bindings ./wit - package west +// #cgo LDFLAGS: -lwest +// #cgo android,arm64 LDFLAGS: -L${SRCDIR}/lib/aarch64-android +// #cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/lib/x86_64-darwin +// #cgo darwin,arm64 LDFLAGS: -L${SRCDIR}/lib/aarch64-darwin +// #cgo linux,amd64 LDFLAGS: -L${SRCDIR}/lib/x86_64-linux +// #cgo linux,arm64 LDFLAGS: -L${SRCDIR}/lib/aarch64-linux +// #cgo linux,riscv64 LDFLAGS: -L${SRCDIR}/lib/riscv64-linux +// #cgo windows,amd64 LDFLAGS: -L${SRCDIR}/lib/x86_64-windows +// #cgo windows,arm64 LDFLAGS: -L${SRCDIR}/lib/aarch64-windows +// #cgo !windows LDFLAGS: -lm -ldl -pthread +// #cgo windows LDFLAGS: -lws2_32 -lole32 -loleaut32 -lntdll -lbcrypt -luserenv // #include "./include/west.h" // #include import "C" diff --git a/west_android_arm64.go b/west_android_arm64.go deleted file mode 100644 index a12e633..0000000 --- a/west_android_arm64.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !dev - -//go:generate cp ./target/release/libwest_sys.a ./lib/aarch64-android/libwest.a - -package west diff --git a/west_darwin_amd64.go b/west_darwin_amd64.go deleted file mode 100644 index 1e5f1af..0000000 --- a/west_darwin_amd64.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !dev - -//go:generate cp ./target/release/libwest_sys.a ./lib/x86_64-darwin/libwest.a - -package west diff --git a/west_darwin_arm64.go b/west_darwin_arm64.go deleted file mode 100644 index cf186ec..0000000 --- a/west_darwin_arm64.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !dev - -//go:generate cp ./target/release/libwest_sys.a ./lib/aarch64-darwin/libwest.a - -package west diff --git a/west_linux_amd64.go b/west_linux_amd64.go deleted file mode 100644 index c513a93..0000000 --- a/west_linux_amd64.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !dev - -//go:generate cp ./target/release/libwest_sys.a ./lib/x86_64-linux/libwest.a - -package west diff --git a/west_linux_arm64.go b/west_linux_arm64.go deleted file mode 100644 index 3a24e15..0000000 --- a/west_linux_arm64.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !dev - -//go:generate cp ./target/release/libwest_sys.a ./lib/aarch64-linux/libwest.a - -package west diff --git a/west_linux_riscv64.go b/west_linux_riscv64.go deleted file mode 100644 index 8bb832d..0000000 --- a/west_linux_riscv64.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !dev - -//go:generate cp ./target/release/libwest_sys.a ./lib/riscv64-linux/libwest.a - -package west diff --git a/west_windows_amd64.go b/west_windows_amd64.go deleted file mode 100644 index 841669c..0000000 --- a/west_windows_amd64.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !dev - -//go:generate cp ./target/release/libwest_sys.a ./lib/x86_64-windows/libwest.a - -package west diff --git a/west_windows_arm64.go b/west_windows_arm64.go deleted file mode 100644 index e4385e1..0000000 --- a/west_windows_arm64.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build !dev - -//go:generate cp ./target/release/libwest_sys.a ./lib/aarch64-windows/libwest.a - -package west