使用 Wails 进行交叉编译(2025)

Hacker News Top 工具

摘要

一位开发者在 Ubuntu 上测试交叉编译 Wails v2.11.0 Svelte 应用,成功构建了 Windows 和 Linux 的可执行文件/安装程序,并指出了 Linux 静态链接的问题。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/08/09 20:29

# 使用 Wails 进行交叉编译 来源:https://chriswheeler.dev/posts/cross-compilation-with-wails/ 2025年12月9日,我在一台运行 Ubuntu 24、使用 Go v1.25.5 的 amd64 笔记本电脑上,测试了 Wails(https://github.com/wailsapp/wails)v2.11.0 官方 Svelte 模板的交叉编译。Wails 是一个基于 Go 的桌面应用框架。当然,随着 Wails 和 Go 的不断改进,未来的结果可能会有所不同。众所周知,Go 让交叉编译比大多数其他语言容易得多,而在使用像 Wails 这样的框架时,这一点大体上仍然成立。要为多个平台分别生成可执行文件和/或安装程序,有时只需在一条命令中列出这些平台即可: `` wails build -clean -nsis \ -platform 'linux/amd64,windows/amd64,windows/arm64,windows/386' `` 上面的命令会生成以下文件: `` 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 `` 这样,我们就已经拥有了 Linux 和 Windows 的可执行文件和安装程序!我没有在平台列表中加入 macOS,因为 Apple 通常不允许交叉编译。我认为 Wails 或 Go 对此也无能为力。(当我把 darwin 加入列表时,该平台会被跳过,并显示消息 `WARNING Crosscompiling to Mac not currently supported`。) 当我意外地加入了一个不存在的平台时,我得到了一条有用的提示消息,内容如下: `` Supported platforms: darwin,darwin/amd64,darwin/arm64,darwin/universal,linux,linux/amd64,linux/arm64,linux/arm,windows,windows/amd64,windows/arm64,windows/386 `` ## 它们是静态链接的吗? 根据 Linux 的 `ldd` 命令(该命令打印共享对象依赖项),Windows 可执行文件和安装程序是静态链接的,而 Linux 可执行文件是动态链接的: `` $ 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) ... `` `file` 命令证实了这一点: `` $ 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 `` 我尝试使用 `-ldflags '-extldflags "-static"'` 强制对 Linux 可执行文件进行静态链接,但遇到了许多错误,包括: `` /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 `` 也许仍然有办法强制对 Linux 可执行文件进行静态链接,但我目前还不知道。 ## 那 `linux/arm64` 呢? 遗憾的是,目前从 `linux/amd64` 交叉编译到 `linux/arm64` 还不可行(见下面的输出)。我搜索了 Wails 的仓库,发现其他人也遇到了同样的问题。似乎没有变通方法。以下是输出: `` $ 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 `` 当我使用 `-compiler` 选项并指定 `go1\.24\.11` 或 `go1\.23\.12` 时,也会出现相同的错误消息。(你可以安装多个版本的 Go(https://go.dev/doc/manage-install)。) ## `dAppServer/wails-build-action` GitHub Action Wails 的网站提供了一个用于构建可执行文件的 GitHub Action 示例(https://wails.io/docs/guides/crossplatform-build/),该示例使用了 `dAppServer/wails-build-action` 这个 action。我测试了这个示例,并已将其中的 actions 更新到最新的稳定版本。 以下几点可能会让一些人犹豫是否使用 `dAppServer/wails-build-action`: - Wails 网站上的示例会失败,并出现错误消息 `ditto: Cannot get the real path for source './build/bin/App.app'` - 针对该错误的修复已通过 pull request 提交到 `dAppServer/wails-build-action` 仓库,但已被忽略 5 个月,并且还在继续(示例:https://github.com/Snider/build/pull/49/files) - 它采用 copyleft 许可证 - 该项目的大部分文档是由 LLM 撰写的 如果你在目标平台列表中保留 `darwin/universal`,就会出现上面提到的错误消息。(我测试时 Linux 和 Windows 的构建都成功了。) ## GoReleaser GoReleaser(https://goreleaser.com/)是一个非常棒的工具,可以自动化发布,包括创建可执行文件和安装程序。不过,我无法让 Wails 与它配合使用。 以下是我尝试过的 `.goreleaser.yaml` 的一部分: `` 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 `` 然后我使用 `goreleaser release --snapshot --clean` 进行了测试,得到了这个错误: `` ⨯ 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 `` 使用 `go1\.24\.11` 时,以及不指定 `tool` 和 `compiler` 而使用 Go v1.25.5 时,我遇到了同样的错误。我搜索了 Wails 的仓库,查找可能对此有帮助的 issues、PR 等,但没有找到任何有希望的东西。也许有办法让它工作,但我目前可能会手动创建发布。 为了以防万一,该错误只在我运行 `goreleaser release --snapshot --clean` 时出现,而在 GitHub Actions 中运行时不会出现,我也尝试了后者。错误消息变了,但似乎仍然没有变通方法: `` ⨯ release failed after 5s error= Error:

相似文章

weblings:在 WASM 内部将 Rust 编译为 WASM

Lobsters Hottest

Weblings 是一个编译为 WebAssembly 的 Rust 编译器工具链,通过带有 playground 和 Rustlings 练习的网页 UI,支持在浏览器中直接编译和执行 Rust 代码。

在 Linux 和 Unix 系统上编译 Emacs 以提升性能的技术指南

Lobsters Hottest

本技术指南提供了在各类 Linux 发行版上从源码编译 Emacs 的详细步骤,旨在通过 CPU 特定指令集和 Wayland 等现代显示协议来优化性能。文中还涵盖了依赖项配置以及微调原生 Lisp 编译器以提升执行速度的相关内容。