使用 Wails 进行交叉编译 (2025)
Cross-compilation with Wails (2025)

原始链接: https://chriswheeler.dev/posts/cross-compilation-with-wails/

本摘要评估了 Wails v2.11.0 在 Linux amd64 主机上的交叉编译能力。 Wails 简化了多平台构建流程,允许开发者通过单条命令生成 Windows 和 Linux 的可执行文件及安装程序。虽然 Windows 构建版本采用静态链接,但 Linux 构建版本仍为动态链接;受限于 CGO 依赖,目前尚无实现完全静态链接的直接解决方案。 主要局限性如下: * **平台限制:** 不支持 macOS 交叉编译;目前尝试为 `linux/arm64` 进行交叉编译时,会因汇编器错误而失败。 * **工具问题:** 官方推荐的 `dAppServer/wails-build-action` 存在维护滞后及授权方面的问题,使用体验欠佳。此外,由于 Wails 在构建过程中处理绑定和临时文件的方式,尝试将 Wails 集成到 **GoReleaser** 以实现自动化发布时,目前会导致构建失败。 总结而言,尽管 Wails 在基础的 Windows 和 Linux x64 构建方面表现出色,但其更广泛的交叉编译生态——特别是在 ARM64 和自动化 CI/CD 流水线方面——尚不成熟,仍需手动干预或采取变通方案。

Hacker News 最新 | 往日 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 使用 Wails 进行交叉编译 (2025) (chriswheeler.dev) 3 点积分,作者:auraham,2 小时前 | 隐藏 | 往日 | 收藏 | 讨论 | 帮助 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

On 2025-12-9, I tested the cross-compilation of the official Svelte template of Wails v2.11.0, a desktop app framework for Go, on my amd64 laptop running Ubuntu 24 with Go v1.25.5. Of course, the results may change in the future as Wails and Go are being improved. Go is known for making cross-compilation much easier than most other languages, and that is mostly still true when using frameworks like Wails. Creating executable files and/or installers for each of several platforms is sometimes as simple as listing those platforms in a command:

wails build -clean -nsis \
    -platform 'linux/amd64,windows/amd64,windows/arm64,windows/386'

The above command creates these files:

build
└── bin
    ├── my-app-386.exe
    ├── my-app-amd64.exe
    ├── my-app-amd64-installer.exe
    ├── my-app-arm64.exe
    ├── my-app-arm64-installer.exe
    └── my-app-linux-amd64

With that, we already have executables and installers for Linux and Windows! I didn’t include MacOS in the list of platforms because Apple generally does not allow cross-compilation. I don’t think there’s anything Wails or Go can do about that. (When I include darwin in the list, the platform is skipped with the message WARNING Crosscompiling to Mac not currently supported.)

When I accidentally included a platform that doesn’t exist, I got a helpful message that included this:

Supported platforms: darwin,darwin/amd64,darwin/arm64,darwin/universal,linux,linux/amd64,linux/arm64,linux/arm,windows,windows/amd64,windows/arm64,windows/386

Are they statically linked?

According to Linux’s ldd command (which prints shared object dependencies), the Windows executables and installers are statically linked and the Linux one is dynamically linked:

$ ldd build/bin/*
build/bin/my-app-386.exe:
	not a dynamic executable
build/bin/my-app-amd64.exe:
	not a dynamic executable
build/bin/my-app-amd64-installer.exe:
	not a dynamic executable
build/bin/my-app-arm64.exe:
	not a dynamic executable
build/bin/my-app-arm64-installer.exe:
	not a dynamic executable
build/bin/my-app-linux-amd64:
	linux-vdso.so.1 (0x00007ffdbe4c7000)
	libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x000079e7a3ff0000)
	libwebkit2gtk-4.0.so.37 => /lib/x86_64-linux-gnu/libwebkit2gtk-4.0.so.37 (0x000079e7a0400000)
	libgtk-3.so.0 => /lib/x86_64-linux-gnu/libgtk-3.so.0 (0x000079e79fc00000)
    ...

The file command confirms this:

$ file build/bin/*
build/bin/my-app-386.exe:             PE32 executable (GUI) Intel 80386, for MS Windows, 7 sections
build/bin/my-app-amd64.exe:           PE32+ executable (GUI) x86-64, for MS Windows, 9 sections
build/bin/my-app-amd64-installer.exe: PE32 executable (GUI) Intel 80386 (stripped to external PDB), for MS Windows, Nullsoft Installer self-extracting archive, 7 sections
build/bin/my-app-arm64.exe:           PE32+ executable (GUI) Aarch64, for MS Windows, 7 sections
build/bin/my-app-arm64-installer.exe: PE32 executable (GUI) Intel 80386 (stripped to external PDB), for MS Windows, Nullsoft Installer self-extracting archive, 7 sections
build/bin/my-app-linux-amd64:         ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=8ce9189206c3fc10a0fdfb874b0a5cd7b5f61ec7, for GNU/Linux 3.2.0, stripped

I tried to force static linking for the Linux executable by using -ldflags '-extldflags "-static"', but I got many errors including:

/usr/bin/ld: /tmp/go-link-3304063632/000004.o: in function `_cgo_77133bf98b3a_C2func_getaddrinfo':
/tmp/go-build/cgo_unix_cgo.cgo2.c:60:(.text+0x37): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

There may still be a way to force static linking for the Linux executable, but I’m not aware of it yet.

What about linux/arm64?

Unfortunately, cross-compiling from linux/amd64 to linux/arm64 doesn’t work right now (see output below). I searched Wails’ repo and found others have the same problem. There doesn’t seem to be a workaround. Here’s the output:

$ wails build -platform 'linux/arm64'
Wails CLI v2.11.0


# Build Options

Platform(s)        | linux/arm64
Compiler           | /usr/local/go/bin/go
Skip Bindings      | false
Build Mode         | production
Devtools           | false
Frontend Directory | /home/chris/repos/my-app/frontend
Obfuscated         | false
Skip Frontend      | false
Compress           | false
Package            | true
Clean Bin Dir      | false
LDFlags            |
Tags               | []
Race Detector      | false


# Building target: linux/arm64

  • Generating bindings: Done.
  • Installing frontend dependencies: Done.
  • Compiling frontend: Done.
  • Compiling application: # runtime/cgo
gcc_arm64.S: Assembler messages:
gcc_arm64.S:30: Error: no such instruction: `stp x29,x30,[sp,'
gcc_arm64.S:34: Error: operand size mismatch for `mov'
gcc_arm64.S:36: Error: no such instruction: `stp x19,x20,[sp,'
gcc_arm64.S:39: Error: no such instruction: `stp x21,x22,[sp,'
gcc_arm64.S:42: Error: no such instruction: `stp x23,x24,[sp,'
gcc_arm64.S:45: Error: no such instruction: `stp x25,x26,[sp,'
gcc_arm64.S:48: Error: no such instruction: `stp x27,x28,[sp,'
gcc_arm64.S:52: Error: operand size mismatch for `mov'
gcc_arm64.S:53: Error: operand size mismatch for `mov'
gcc_arm64.S:54: Error: operand size mismatch for `mov'
gcc_arm64.S:56: Error: no such instruction: `blr x20'
gcc_arm64.S:57: Error: no such instruction: `blr x19'
gcc_arm64.S:59: Error: no such instruction: `ldp x27,x28,[sp,'
gcc_arm64.S:62: Error: no such instruction: `ldp x25,x26,[sp,'
gcc_arm64.S:65: Error: no such instruction: `ldp x23,x24,[sp,'
gcc_arm64.S:68: Error: no such instruction: `ldp x21,x22,[sp,'
gcc_arm64.S:71: Error: no such instruction: `ldp x19,x20,[sp,'
gcc_arm64.S:74: Error: no such instruction: `ldp x29,x30,[sp],'
  ERROR   exit status 1

I get the same error message when I use the -compiler option with go1.24.11 or go1.23.12. (You can install multiple versions of Go.)

The dAppServer/wails-build-action GitHub Action

Wails’ website includes a sample GitHub action for building executables which uses the dAppServer/wails-build-action action. I tested the sample with its actions updated to their latest stable versions.

A few things that may or may not make someone hesitant to use dAppServer/wails-build-action:

  • the sample on Wails’ site fails with the error message ditto: Cannot get the real path for source './build/bin/App.app'
  • fixes for that bug have been submitted to the dAppServer/wails-build-action repo in pull requests, but they have been ignored for 5 months and counting (example: https://github.com/Snider/build/pull/49/files)
  • it has a copyleft license
  • much of the project’s documentation was written by an LLM

The error message mentioned above appears if you keep darwin/universal in the list of platforms to target. (The Linux and Windows builds succeeded when I tested it.)

GoReleaser

GoReleaser is an awesome tool that automates releases, including creating executables and installers. I couldn’t get Wails to work with it though.

Here’s part of the .goreleaser.yaml I tried:

builds:
  - id: "wails-build"
    goos:
      - linux
      - windows
    tool: "go1.23.12"
      # how: https://go.dev/doc/manage-install
      # why: https://github.com/wailsapp/wails/issues/4605
    hooks:
      post:
        - wails build -clean -nsis -compiler 'go1.23.12' -platform 'linux/amd64,linux/arm64,windows/amd64,windows/arm64,windows/386'
        - cp ./build/bin/. ./dist

I then tested this with goreleaser release --snapshot --clean and got this error:

  ⨯ release failed after 6s
    error=
    │ post hook failed: shell: 'wails build -clean -nsis -compiler 'go1.23.12' -platform linux/amd64,linux/arm64,windows/amd64,windows/arm64,windows/386': exit status 1: Wails CLI v2.11.0
    │ # Build Options
    │
    │ Platform(s)        | linux/amd64,linux/arm64,windows/amd64,windows/arm64,windows/386
    │ Compiler           | /home/chris/go/bin/go1.23.12
    │ Skip Bindings      | false
    │ Build Mode         | production
    │ Devtools           | false
    │ Frontend Directory | /home/chris/repos/my-app/frontend
    │ Obfuscated         | false
    │ Skip Frontend      | false
    │ Compress           | false
    │ Package            | true
    │ Clean Bin Dir      | true
    │ LDFlags            |
    │ Tags               | []
    │ Race Detector      | false
    │ # Building target: linux/amd64
    │
    │   • Generating bindings:   ERROR
    │
    │           fork/exec /tmp/wailsbindings: no such file or directory
    │   ERROR
    │
    │           fork/exec /tmp/wailsbindings: no such file or directory

I got the same error with go1.24.11, and with using Go v1.25.5 by not specifying the tool and compiler. I searched Wails’ repo for any issues, PRs, etc. that might help with this, but I couldn’t find anything promising. There might be a way to get it working, but I might just create releases manually for now.

Just in case the error only occurs when I run goreleaser release --snapshot --clean and not when it runs in GitHub Actions, I tried the latter as well. The error message changed, but still doesn’t seem to have a workaround:

  ⨯ release failed after 5s                         
    error=
Error:     │ build failed: exit status 1: main.go:11:12: pattern all:frontend/dist: no matching files found
    target=linux_386_sse2
Error: The process '/opt/hostedtoolcache/goreleaser-action/2.13.1/x64/goreleaser' failed with exit code 1
联系我们 contact @ memedata.com