build: package haul as a macOS .app bundle
Double-clicking the bare binary in Finder opens a Terminal window alongside the app: Finder has no better idea what to do with a Mach-O executable than hand it to Terminal.app, and the terminal stays up as long as the process does. macOS has no counterpart to -H=windowsgui, so the only fix is to ship an application bundle, which Finder launches directly. Add `make package-darwin`, which runs a pinned `fyne package --target darwin` to produce ./haul.app. Its metadata comes from cmd/haul/FyneApp.toml — the app ID there must stay in step with the one app.NewWithID uses, or macOS treats the bundle and the running app as separate applications. The icon is a placeholder; `fyne package` will not run without one. Note that `fyne package` rewrites FyneApp.toml in place on every run, so the file is left in that tool's canonical formatting rather than a commented version it would only strip again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
/bin/
|
/bin/
|
||||||
/dist/
|
/dist/
|
||||||
|
/haul.app/
|
||||||
|
|||||||
@@ -7,7 +7,12 @@ LDFLAGS := -s -w
|
|||||||
# prefer that toolchain and fall back to whatever `go` is in PATH elsewhere.
|
# prefer that toolchain and fall back to whatever `go` is in PATH elsewhere.
|
||||||
GO ?= $(shell test -x $(HOME)/.local/go/bin/go && echo $(HOME)/.local/go/bin/go || echo go)
|
GO ?= $(shell test -x $(HOME)/.local/go/bin/go && echo $(HOME)/.local/go/bin/go || echo go)
|
||||||
|
|
||||||
.PHONY: build install test vet check run run-xvfb dist clean
|
# The packaging tool lives outside the Fyne library repo since v2.5. Pinned and
|
||||||
|
# run through `go run` so no separate install step is needed; override with
|
||||||
|
# FYNE=/path/to/fyne if you'd rather use an installed copy.
|
||||||
|
FYNE ?= $(GO) run fyne.io/tools/cmd/fyne@v1.7.2
|
||||||
|
|
||||||
|
.PHONY: build install test vet check run run-xvfb dist package-darwin clean
|
||||||
|
|
||||||
build: ## Build a native binary into ./bin/haul
|
build: ## Build a native binary into ./bin/haul
|
||||||
$(GO) build -trimpath -ldflags "$(LDFLAGS)" -o bin/haul ./cmd/haul
|
$(GO) build -trimpath -ldflags "$(LDFLAGS)" -o bin/haul ./cmd/haul
|
||||||
@@ -60,5 +65,20 @@ dist: ## Build the release binary for this host into ./dist
|
|||||||
$(GO) build -trimpath -ldflags "$(LDFLAGS)" -o dist/haul-linux-amd64 ./cmd/haul
|
$(GO) build -trimpath -ldflags "$(LDFLAGS)" -o dist/haul-linux-amd64 ./cmd/haul
|
||||||
@echo "built dist/haul-linux-amd64 (see the Makefile for cross-compiling)"
|
@echo "built dist/haul-linux-amd64 (see the Makefile for cross-compiling)"
|
||||||
|
|
||||||
|
# Finder hands a bare Unix executable to Terminal.app, so double-clicking the
|
||||||
|
# raw binary opens a terminal window alongside the GUI. Nothing in the code can
|
||||||
|
# stop that — the fix is to ship a .app bundle instead, which Finder launches
|
||||||
|
# directly. `fyne package` writes the Info.plist (CFBundlePackageType APPL and
|
||||||
|
# friends) and converts cmd/haul/Icon.png into Contents/Resources/icon.icns; the
|
||||||
|
# rest of the metadata comes from cmd/haul/FyneApp.toml.
|
||||||
|
#
|
||||||
|
# Run this ON a Mac: it compiles the binary with the host cgo toolchain, and it
|
||||||
|
# builds for the host architecture, so an Intel Mac gives an amd64 bundle and
|
||||||
|
# Apple silicon an arm64 one. The .app is unsigned, so first launch needs
|
||||||
|
# right-click -> Open (or `xattr -dr com.apple.quarantine haul.app`).
|
||||||
|
package-darwin: ## Package haul.app for macOS (run this on a Mac)
|
||||||
|
$(FYNE) package --target darwin --src ./cmd/haul --release
|
||||||
|
@echo "built ./haul.app — drag it into /Applications"
|
||||||
|
|
||||||
clean: ## Remove build artifacts
|
clean: ## Remove build artifacts
|
||||||
rm -rf bin dist
|
rm -rf bin dist haul.app
|
||||||
|
|||||||
@@ -205,6 +205,51 @@ Unlike Linux, Windows needs no graphics development *packages* to build: OpenGL
|
|||||||
ships with the operating system. Getting a usable OpenGL at **run** time is a
|
ships with the operating system. Getting a usable OpenGL at **run** time is a
|
||||||
separate matter — see below.
|
separate matter — see below.
|
||||||
|
|
||||||
|
### Packaging on macOS
|
||||||
|
|
||||||
|
`make build` produces a plain Unix executable, and that is all you need if you
|
||||||
|
launch haul from a shell. **Double-click it in Finder, though, and macOS opens a
|
||||||
|
Terminal window alongside the app.** That is not a bug in haul and no build flag
|
||||||
|
fixes it — it is what Finder does with any bare executable: having no better
|
||||||
|
idea what a Mach-O file is, it hands it to Terminal.app to run, and the terminal
|
||||||
|
stays on screen for as long as the process does. macOS has no equivalent of
|
||||||
|
Windows' `-H=windowsgui`.
|
||||||
|
|
||||||
|
The fix is to ship an application *bundle* — a `haul.app` directory carrying an
|
||||||
|
`Info.plist` — which Finder launches directly, with a Dock icon and no terminal:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make package-darwin # -> ./haul.app
|
||||||
|
```
|
||||||
|
|
||||||
|
Then drag `haul.app` into `/Applications`. Run it on a Mac: it compiles with the
|
||||||
|
host cgo toolchain, and it builds for the host architecture, so an Intel Mac
|
||||||
|
gives you an `amd64` bundle and Apple silicon an `arm64` one.
|
||||||
|
|
||||||
|
Under the hood that target runs [`fyne
|
||||||
|
package`](https://docs.fyne.io/started/packaging), which reads its metadata from
|
||||||
|
`cmd/haul/FyneApp.toml`, converts `cmd/haul/Icon.png` into the bundle's
|
||||||
|
`.icns` icon, and writes the `Info.plist`. Without `make`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go run fyne.io/tools/cmd/fyne@v1.7.2 package --target darwin --src ./cmd/haul --release
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that `fyne package` **rewrites `cmd/haul/FyneApp.toml` in place**, bumping
|
||||||
|
`Build` on every run and dropping any comments you add to it. That is by design;
|
||||||
|
commit the bump or discard it as you prefer.
|
||||||
|
|
||||||
|
The bundle is unsigned, so Gatekeeper blocks the first launch on any Mac that
|
||||||
|
did not build it. Right-click the app and choose **Open** (once — after that it
|
||||||
|
starts normally), or clear the quarantine flag:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
xattr -dr com.apple.quarantine /Applications/haul.app
|
||||||
|
```
|
||||||
|
|
||||||
|
Signing and notarising properly needs a paid Apple Developer ID, after which
|
||||||
|
`fyne release --target darwin --certificate <name>` handles it.
|
||||||
|
|
||||||
### Running over Remote Desktop (or in a VM)
|
### Running over Remote Desktop (or in a VM)
|
||||||
|
|
||||||
A build that compiles perfectly will still fail to start in an RDP session with:
|
A build that compiles perfectly will still fail to start in an RDP session with:
|
||||||
@@ -269,7 +314,8 @@ Software rendering is slower than a GPU, but haul draws two tables and some text
|
|||||||
| `make run` | Build, then run (needs a `DISPLAY`) |
|
| `make run` | Build, then run (needs a `DISPLAY`) |
|
||||||
| `make run-xvfb` | Build, then run against a virtual X display |
|
| `make run-xvfb` | Build, then run against a virtual X display |
|
||||||
| `make dist` | Release binary into `./dist` |
|
| `make dist` | Release binary into `./dist` |
|
||||||
| `make clean` | Remove `bin/` and `dist/` |
|
| `make package-darwin` | macOS `.app` bundle into `./haul.app` (run on a Mac) |
|
||||||
|
| `make clean` | Remove `bin/`, `dist/` and `haul.app/` |
|
||||||
|
|
||||||
The Makefile picks up a Go toolchain at `~/.local/go/bin/go` if one is there,
|
The Makefile picks up a Go toolchain at `~/.local/go/bin/go` if one is there,
|
||||||
falling back to whatever `go` is on `PATH` — so it works on machines where Go
|
falling back to whatever `go` is on `PATH` — so it works on machines where Go
|
||||||
@@ -297,7 +343,9 @@ toolchain:
|
|||||||
| `windows/amd64` | `gcc-mingw-w64` |
|
| `windows/amd64` | `gcc-mingw-w64` |
|
||||||
| `darwin/*` | a Mac, or [osxcross](https://github.com/tpoechtrager/osxcross) |
|
| `darwin/*` | a Mac, or [osxcross](https://github.com/tpoechtrager/osxcross) |
|
||||||
|
|
||||||
For that reason `make dist` builds only the native binary. The practical route
|
For that reason `make dist` builds only the native binary — and on macOS the
|
||||||
|
binary alone is not the artefact you want to hand out, see [Packaging on
|
||||||
|
macOS](#packaging-on-macos). The practical route
|
||||||
to the others is [`fyne-cross`](https://github.com/fyne-io/fyne-cross), which
|
to the others is [`fyne-cross`](https://github.com/fyne-io/fyne-cross), which
|
||||||
does each build inside a Docker image carrying the right toolchain:
|
does each build inside a Docker image carrying the right toolchain:
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
Website = "https://gitea.apointless.space/bsncubed/haul"
|
||||||
|
|
||||||
|
[Details]
|
||||||
|
Icon = "Icon.png"
|
||||||
|
Name = "haul"
|
||||||
|
ID = "space.apointless.haul"
|
||||||
|
Version = "0.1.0"
|
||||||
|
Build = 1
|
||||||
|
|
||||||
|
[LinuxAndBSD]
|
||||||
|
GenericName = "SFTP Client"
|
||||||
|
Categories = ["Network", "FileTransfer", "Utility"]
|
||||||
|
Comment = "Two-pane SFTP file browser over SSH"
|
||||||
|
Keywords = ["sftp", "ssh", "scp", "file transfer"]
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
Reference in New Issue
Block a user