diff --git a/README.md b/README.md index c932007..d2b84da 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ If a session drops, use the **Reconnect** button in the disconnected overlay. - Product overview: [docs/overview.md](docs/overview.md) - Quick start (shareable): [docs/quick-start.md](docs/quick-start.md) - User manual: [docs/user-manual.md](docs/user-manual.md) +- Build and release: [docs/build-and-release.md](docs/build-and-release.md) ## Keyboard shortcuts diff --git a/build-all.sh b/build-all.sh index e52d7b0..875900a 100755 --- a/build-all.sh +++ b/build-all.sh @@ -16,6 +16,14 @@ log() { echo -e "${GREEN}[nexus]${NC} $1"; } warn() { echo -e "${YELLOW}[nexus]${NC} $1"; } err() { echo -e "${RED}[nexus]${NC} $1" >&2; } +build_tags() { + if command -v pkg-config >/dev/null 2>&1 \ + && pkg-config --exists webkit2gtk-4.1 \ + && ! pkg-config --exists webkit2gtk-4.0; then + echo "webkit2_41" + fi +} + build_version() { local tag local commit @@ -100,6 +108,8 @@ build_target() { local version="$4" local ldflags ldflags="$(build_ldflags "${version}")" + local tags + tags="$(build_tags)" local platform="${target_os}/${target_arch}" local cc="" @@ -114,9 +124,17 @@ build_target() { log "Building ${platform}…" if [ -n "$cc" ]; then - CC="$cc" CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" + if [ -n "$tags" ]; then + CC="$cc" CGO_ENABLED=1 wails build -platform "$platform" -tags "$tags" -ldflags "$ldflags" + else + CC="$cc" CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" + fi else - CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" + if [ -n "$tags" ]; then + CGO_ENABLED=1 wails build -platform "$platform" -tags "$tags" -ldflags "$ldflags" + else + CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" + fi fi } diff --git a/build.sh b/build.sh index c394099..6e51bd0 100755 --- a/build.sh +++ b/build.sh @@ -17,6 +17,14 @@ log() { echo -e "${GREEN}[nexus]${NC} $1"; } warn() { echo -e "${YELLOW}[nexus]${NC} $1"; } err() { echo -e "${RED}[nexus]${NC} $1" >&2; } +build_tags() { + if command -v pkg-config >/dev/null 2>&1 \ + && pkg-config --exists webkit2gtk-4.1 \ + && ! pkg-config --exists webkit2gtk-4.0; then + echo "webkit2_41" + fi +} + build_version() { local tag local commit @@ -81,7 +89,14 @@ build() { log "Building production binary…" local version version="$(build_version)" - wails build -ldflags "$(build_ldflags "${version}")" + local tags + tags="$(build_tags)" + if [ -n "$tags" ]; then + log "Using Wails build tags: ${tags}" + wails build -tags "$tags" -ldflags "$(build_ldflags "${version}")" + else + wails build -ldflags "$(build_ldflags "${version}")" + fi log "Build complete: build/bin/" } diff --git a/docs/build-and-release.md b/docs/build-and-release.md new file mode 100644 index 0000000..71add66 --- /dev/null +++ b/docs/build-and-release.md @@ -0,0 +1,77 @@ +# Build and Release + +This project uses [Wails](https://wails.io/) for desktop packaging. + +## Ubuntu 24.04 prerequisites + +Install the Linux build toolchain and Wails runtime headers with: + +```bash +sudo apt-get update +sudo apt-get install -y \ + build-essential \ + libgtk-3-dev \ + libwebkit2gtk-4.1-dev \ + libayatana-appindicator3-dev \ + pkg-config \ + zip +``` + +Notes: + +- Ubuntu 24.04 does not ship `libwebkit2gtk-4.0-dev`. +- Wails `v2.12.0` supports Ubuntu 24.04 by building with the `webkit2_41` tag. +- The local build scripts detect that package layout automatically and add the tag when needed. + +You will also need these tools available in `PATH`: + +- `go` +- `node` +- `npm` +- `wails` + +Install the Wails CLI with: + +```bash +go install github.com/wailsapp/wails/v2/cmd/wails@latest +export PATH="$PATH:$(go env GOPATH)/bin" +``` + +## Build commands + +Build the app binary for the current host: + +```bash +./build.sh +``` + +Build a packaged release for the current host platform: + +```bash +./release.sh +``` + +By default, `./release.sh` now builds only the current host OS/architecture. On this Ubuntu 24.04 `amd64` host that means `linux/amd64`. + +## Optional cross-compilers + +If you want to add extra Linux/Windows targets from Ubuntu, install the relevant cross-compiler packages first: + +```bash +sudo apt-get install -y \ + gcc-aarch64-linux-gnu \ + gcc-mingw-w64-x86-64 +``` + +Then request explicit targets: + +```bash +NEXUS_RELEASE_TARGETS=linux/amd64,windows/amd64 ./release.sh +``` + +## Platform caveats + +- macOS targets cannot be cross-built from Linux with Wails. Build those on macOS. +- `windows/arm64` is not covered by the default Ubuntu toolchain here. +- `linux/arm64` needs more than `gcc-aarch64-linux-gnu`; it also needs an `arm64` sysroot and target GTK/WebKit development libraries for CGO to link cleanly. +- Tested on Ubuntu 24.04 `amd64`: `linux/amd64` and `windows/amd64` build successfully; `linux/arm64` does not in the default host setup above. diff --git a/release.sh b/release.sh index 98612c7..a301442 100755 --- a/release.sh +++ b/release.sh @@ -18,6 +18,53 @@ log() { echo -e "${GREEN}[nexus]${NC} $1"; } warn() { echo -e "${YELLOW}[nexus]${NC} $1"; } err() { echo -e "${RED}[nexus]${NC} $1" >&2; } +host_os() { + case "$(uname -s)" in + Darwin) echo "darwin" ;; + Linux) echo "linux" ;; + *) echo "unknown" ;; + esac +} + +host_arch() { + case "$(uname -m)" in + x86_64|amd64) echo "amd64" ;; + arm64|aarch64) echo "arm64" ;; + *) echo "unknown" ;; + esac +} + +build_tags() { + if command -v pkg-config >/dev/null 2>&1 \ + && pkg-config --exists webkit2gtk-4.1 \ + && ! pkg-config --exists webkit2gtk-4.0; then + echo "webkit2_41" + fi +} + +default_targets() { + local os + local arch + os="$(host_os)" + arch="$(host_arch)" + + if [ "$os" = "unknown" ] || [ "$arch" = "unknown" ]; then + err "Unsupported host platform: $(uname -s)/$(uname -m)" + exit 1 + fi + + echo "${os}/${arch}" +} + +release_targets() { + if [ -n "${NEXUS_RELEASE_TARGETS:-}" ]; then + echo "$NEXUS_RELEASE_TARGETS" | tr ',' '\n' | sed '/^[[:space:]]*$/d' + return + fi + + default_targets +} + check_deps() { command -v go >/dev/null 2>&1 || { err "Go is not installed"; exit 1; } command -v node >/dev/null 2>&1 || { err "Node.js is not installed"; exit 1; } @@ -132,6 +179,8 @@ build_target() { log "Building ${platform}..." local ldflags ldflags="$(build_ldflags "$version")" + local tags + tags="$(build_tags)" if [ -n "$cc" ]; then local cc_cmd="$cc" if [ -n "$zig_target" ]; then @@ -141,12 +190,22 @@ build_target() { cc_cmd="zig cc -target ${zig_target}-windows-gnu" fi fi - if ! CC="$cc_cmd" CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" -o "$output_path"; then + if [ -n "$tags" ]; then + if ! CC="$cc_cmd" CGO_ENABLED=1 wails build -platform "$platform" -tags "$tags" -ldflags "$ldflags" -o "$output_path"; then + warn "Build failed for ${platform}" + return 1 + fi + elif ! CC="$cc_cmd" CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" -o "$output_path"; then warn "Build failed for ${platform}" return 1 fi else - if ! CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" -o "$output_path"; then + if [ -n "$tags" ]; then + if ! CGO_ENABLED=1 wails build -platform "$platform" -tags "$tags" -ldflags "$ldflags" -o "$output_path"; then + warn "Build failed for ${platform}" + return 1 + fi + elif ! CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" -o "$output_path"; then warn "Build failed for ${platform}" return 1 fi @@ -273,13 +332,27 @@ main() { log "Building release ${version}..." : > "${out_dir}/.release-files" + local targets + mapfile -t targets < <(release_targets) + if [ "${#targets[@]}" -eq 0 ]; then + err "No release targets selected." + exit 1 + fi + local errors=0 - if ! build_target "darwin" "amd64" "$version" "$out_dir"; then errors=1; fi - if ! build_target "darwin" "arm64" "$version" "$out_dir"; then errors=1; fi - if ! build_target "linux" "amd64" "$version" "$out_dir"; then errors=1; fi - if ! build_target "linux" "arm64" "$version" "$out_dir"; then errors=1; fi - if ! build_target "windows" "amd64" "$version" "$out_dir"; then errors=1; fi - if ! build_target "windows" "arm64" "$version" "$out_dir"; then errors=1; fi + local target + for target in "${targets[@]}"; do + local target_os="${target%%/*}" + local target_arch="${target##*/}" + if [ "$target_os" = "$target_arch" ] || [ -z "$target_os" ] || [ -z "$target_arch" ]; then + err "Invalid release target: ${target}" + errors=1 + continue + fi + if ! build_target "$target_os" "$target_arch" "$version" "$out_dir"; then + errors=1 + fi + done write_manifest "$version" "$out_dir" "$release_root"