211 lines
6.9 KiB
Text
211 lines
6.9 KiB
Text
---
|
||
title: Build & Packaging Pipeline
|
||
description: What happens under the hood when you run `wails3 build`, how cross-platform binaries are produced, and how installers are generated for each OS.
|
||
sidebar:
|
||
order: 6
|
||
---
|
||
|
||
`wails3 build` is a **single command** that drives a _multi-stage_ pipeline:
|
||
|
||
1. **Frontend production build** (Vite / React / …)
|
||
2. **Asset embedding** into Go sources
|
||
3. **Native compilation** for the target OS/arch
|
||
4. **Post-processing** (icon injection, version info, codesign)
|
||
5. **Packaging** into a distributable artefact (AppImage, DMG, MSI, …)
|
||
|
||
This document follows every stage, shows where the code lives, and explains how
|
||
to customise or debug it.
|
||
|
||
---
|
||
|
||
## 1. Entry Point: `internal/commands/build-assets.go`
|
||
|
||
```
|
||
wails3 build # cmd/wails3/main.go
|
||
└─ internal/commands.Build() # build-assets.go
|
||
```
|
||
|
||
High-level tasks are delegated to **Taskfile** targets so the same logic runs in
|
||
CI or locally.
|
||
|
||
| Stage | Taskfile target | Go implementation |
|
||
|-------|-----------------|-------------------|
|
||
| Frontend build | `frontend:build` | `internal/commands/task.go` |
|
||
| Embed assets | `embed:assets` | generated `bundled_assetserver.go` |
|
||
| Go compile | `build:go` | `tool_buildinfo.go`, `tool_package.go` |
|
||
| Package | `package:*` | `internal/packager`, `internal/commands/*` |
|
||
|
||
---
|
||
|
||
## 2. Frontend Production Build
|
||
|
||
1. The CLI changes into `frontend/` and executes the `build` task found in the
|
||
project `Taskfile.yml` (`npm run build` by default).
|
||
2. Output is written to `frontend/dist/`.
|
||
3. A **content hash** manifest is produced (`manifest.json`) so cache-busting
|
||
works out of the box.
|
||
|
||
If the task fails the pipeline aborts early, returning the exit code of your
|
||
build tool.
|
||
|
||
---
|
||
|
||
## 3. Embedding Assets
|
||
|
||
Implemented in `internal/assetserver/build_production.go`:
|
||
|
||
* Walks `frontend/dist` and generates a `go:embed` file
|
||
`bundled_assetserver.go` (ignored by git).
|
||
* Adds the `production` build tag.
|
||
|
||
Result: the final binary contains every HTML/JS/CSS byte, so the executable is
|
||
self-contained.
|
||
|
||
---
|
||
|
||
## 4. Native Compilation
|
||
|
||
### Build Flags
|
||
|
||
| Flag | Purpose |
|
||
|------|---------|
|
||
| `-tags production` | Select prod asset server & runtime stubs |
|
||
| `-ldflags "-s -w"` | Strip symbol table & DWARF (smaller binaries) |
|
||
| `-X internal/buildinfo.BuildTime=$(date)` | Embed reproducible metadata |
|
||
|
||
`internal/commands/tool_buildinfo.go` collects version, git commit, and build
|
||
time then injects them using `go build -ldflags`.
|
||
|
||
### Cross Compilation Matrix
|
||
|
||
| OS | Arch | Build Tag | CGO | Notes |
|
||
|----|------|-----------|-----|-------|
|
||
| Windows | amd64 / arm64 | `windows` | cgo enabled for WebView2 | Generates `.syso` via `internal/commands/syso.go` |
|
||
| macOS | amd64 / arm64 | `darwin` | cgo enabled (Objective-C) | Codesign & notarisation tasks available |
|
||
| Linux | amd64 / arm64 | `linux` | pure Go (webkit option) | GTK/WebKitGTK headers required for CGO build |
|
||
|
||
`wails3 build -platform darwin/arm64` overrides GOOS/GOARCH.
|
||
If CGO is needed on the host that can't compile the target (e.g. building
|
||
Windows from Linux), the CLI falls back to **Docker** images (`ghcr.io/wailsapp/cross-compiler`).
|
||
|
||
---
|
||
|
||
## 5. Post-Processing
|
||
|
||
### Icons & Resources
|
||
|
||
* **Windows** – `syso.go` merges your PNG/ICO into a `.syso` that `go build`
|
||
links automatically. Also writes `manifest.xml` enabling High-DPI support.
|
||
* **macOS** – `icons.go` turns `icon.png` → `.icns`, injects into
|
||
`MyApp.app/Contents/Resources`.
|
||
* **Linux** – `.desktop` files are generated in `/usr/share/applications`
|
||
by each packager backend.
|
||
|
||
### Code Signing (Optional)
|
||
|
||
* macOS: `codesign` + `xcrun altool --notarize-app`
|
||
* Windows: `signtool.exe`
|
||
* Linux: Not common (repository GPG handled externally)
|
||
|
||
Task targets: `sign:mac`, `sign:windows`.
|
||
|
||
---
|
||
|
||
## 6. Packaging Back-Ends
|
||
|
||
### Linux
|
||
|
||
| Artefact | Code Path | Tooling |
|
||
|----------|-----------|---------|
|
||
| **AppImage** (default) | `internal/commands/appimage.go` | `linuxdeploy` + `linuxdeploy-plugin-gtk` |
|
||
| **deb / rpm / pacman** | `internal/packager` | `fpm` (invoked via Go) |
|
||
|
||
Flags:
|
||
|
||
```
|
||
wails3 build -package deb # produces myapp_1.0.0_amd64.deb
|
||
wails3 build -package rpm
|
||
```
|
||
|
||
### macOS
|
||
|
||
* **DMG** – `internal/commands/packager.go` calls `appdmg` to generate a
|
||
drag-&-drop installer.
|
||
* **ZIP** – fallback if `appdmg` is missing.
|
||
* Sets CFBundle identifiers and version plist automatically.
|
||
|
||
### Windows
|
||
|
||
* **MSI** – `internal/commands/packager.go` wraps **WiX** candle & light tools.
|
||
Heat autogenerates the component tree from the built `.exe`.
|
||
|
||
Extra resources:
|
||
|
||
* `internal/commands/windows_resources/` contains templated **.wxs** fragments.
|
||
* Version info injected via `rsrc` utility.
|
||
|
||
---
|
||
|
||
## 7. Build Artefact Layout
|
||
|
||
After a successful build the CLI prints:
|
||
|
||
```
|
||
build/bin/
|
||
├── myapp-linux-amd64
|
||
└── myapp-linux-amd64.AppImage
|
||
|
||
build/package/
|
||
└── myapp_1.0.0_amd64.deb
|
||
```
|
||
|
||
The exact files depend on `-platform` and `-package` flags.
|
||
|
||
---
|
||
|
||
## 8. Customising the Pipeline
|
||
|
||
| Need | Approach |
|
||
|------|----------|
|
||
| Run a linter before build | Add a `lint` task in **Taskfile.yml** and make `build` depend on it. |
|
||
| Extra linker flags | `wails3 build -ldflags "-H windowsgui"` |
|
||
| Skip packaging | `wails3 build -skip-package` (keeps raw binary). |
|
||
| Bring your own packager | Implement `internal/packager/<name>.go`, register in `packager.go`. |
|
||
|
||
All Taskfile targets use environment variables exported by the CLI, so you can
|
||
reference values like `$WAILS_VERSION` or `$WAILS_PLATFORM` inside custom tasks.
|
||
|
||
---
|
||
|
||
## 9. Troubleshooting
|
||
|
||
| Symptom | Likely Cause | Fix |
|
||
|---------|--------------|-----|
|
||
| **`ld: framework not found WebKit` (mac)** | Xcode CLI tools missing | `xcode-select --install` |
|
||
| **Blank window in prod build** | Frontend build failed or SPA routing | Check `frontend/dist/index.html` exists and `History API Fallback` is set. |
|
||
| **`wixl` not found** (Linux MSI cross-build) | WiX toolset not installed in Docker image | Use `--docker` build or install WiX manually. |
|
||
| **Duplicated symbol `_WinMain`** | Mixed `windowsgui` flag and syso | Remove custom `-ldflags` or let Wails manage resources. |
|
||
|
||
Verbose mode: `wails3 build -verbose` dumps every command executed.
|
||
|
||
---
|
||
|
||
## 10. Key Source Map
|
||
|
||
| Concern | File |
|
||
|---------|------|
|
||
| Task runner glue | `internal/commands/task_wrapper.go` |
|
||
| Build dispatcher | `internal/commands/build-assets.go` |
|
||
| AppImage builder | `internal/commands/appimage.go` |
|
||
| Generic packager interface | `internal/packager/packager.go` |
|
||
| Windows resource generator | `internal/commands/syso.go` |
|
||
| Build info injector | `internal/commands/tool_buildinfo.go` |
|
||
| Version constants | `internal/version/version.go` |
|
||
|
||
Keep this table handy when you trace a build failure.
|
||
|
||
---
|
||
|
||
You now have the full picture from **source code** to **installer**. Armed with
|
||
this knowledge you can tweak the pipeline, add new packaging targets, or debug
|
||
cross-compilation issues without fear. Happy shipping!
|