Replaces the generated dagger scaffold with a real BuildLinux function that compiles swap-watchdog, force-quit-gui, and kdotool (not packaged for Fedora, so built from source via cargo) inside an ephemeral nixos/nix container -- no gtk3-devel/dbus-devel/rust toolchain needs installing on the host. The host's own Go toolchain is mounted in so the build matches go.mod's required version exactly. Nix's glibc uses a non-FHS dynamic linker path that doesn't exist outside the container, so the built binaries are patched with patchelf to point at the host's real ld.so; the stale nix-store RUNPATH entries are harmless since ld.so just skips nonexistent directories and falls through to the host's normal library search path, where the real libgtk-3/libdbus-1/etc already live. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
81 lines
3.3 KiB
Go
81 lines
3.3 KiB
Go
// Builds swap-watchdog's binaries (including kdotool, which isn't packaged
|
|
// for Fedora) without installing any build-time dev headers on the host.
|
|
//
|
|
// gtk3-devel and dbus-devel (needed to compile force-quit-gui and kdotool,
|
|
// respectively) are fetched inside an ephemeral Nix-provisioned container,
|
|
// never on the host. This only works because the corresponding *runtime*
|
|
// shared libraries (libgtk-3, libdbus-1, ...) are already present on any
|
|
// normal Linux desktop -- so the binaries built here link against the
|
|
// host's own runtime libs the moment they're copied out. Nothing is
|
|
// bundled or vendored.
|
|
//
|
|
// The Go toolchain itself is passed in from the host (see install.sh) rather
|
|
// than pulled from nixpkgs, so the build always uses the exact same `go`
|
|
// version the host's go.mod requires, with no risk of nixpkgs happening to
|
|
// carry an older/newer one.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
|
|
"dagger/swap-watchdog/internal/dagger"
|
|
)
|
|
|
|
type SwapWatchdog struct{}
|
|
|
|
// BuildLinux compiles swap-watchdog, force-quit-gui, and kdotool and returns
|
|
// a Directory containing all three, ready to export into bin/.
|
|
func (m *SwapWatchdog) BuildLinux(ctx context.Context,
|
|
// +defaultPath="."
|
|
src *dagger.Directory,
|
|
// Host Go toolchain root (i.e. `go env GOROOT`), mounted in so the
|
|
// container builds with the exact same `go` version go.mod requires.
|
|
goToolchain *dagger.Directory,
|
|
) *dagger.Directory {
|
|
nixPkgs := "gtk3 dbus pkg-config gcc cargo rustc git patchelf"
|
|
|
|
// nixpkgs' glibc uses a non-FHS dynamic linker path
|
|
// (/nix/store/.../ld-linux-x86-64.so.2), which doesn't exist outside the
|
|
// build container. The runtime libs themselves resolve fine via the
|
|
// host's normal SONAME search path (ldd confirms this against the
|
|
// host's own libgtk-3/libdbus-1/...) -- only the ELF interpreter is
|
|
// wrong, so patchelf is enough; nothing needs bundling.
|
|
const hostInterp = "/lib64/ld-linux-x86-64.so.2"
|
|
|
|
base := dag.Container().
|
|
From("nixos/nix:latest").
|
|
WithDirectory("/usr/local/go", goToolchain).
|
|
WithEnvVariable("PATH", "/usr/local/go/bin:/root/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/usr/bin:/bin").
|
|
WithEnvVariable("GOROOT", "/usr/local/go").
|
|
WithMountedCache("/root/.cache/go-build", dag.CacheVolume("swap-watchdog-go-build")).
|
|
WithMountedCache("/root/.cargo/registry", dag.CacheVolume("swap-watchdog-cargo-registry"))
|
|
|
|
goBuilt := base.
|
|
WithDirectory("/src", src).
|
|
WithWorkdir("/src").
|
|
WithExec([]string{"sh", "-c", `set -e
|
|
nix-shell -p ` + nixPkgs + ` --run '
|
|
set -e
|
|
mkdir -p /out
|
|
CGO_ENABLED=1 go build -o /out/swap-watchdog ./cmd/swap-watchdog
|
|
CGO_ENABLED=1 go build -o /out/force-quit-gui ./cmd/force-quit-gui
|
|
patchelf --set-interpreter ` + hostInterp + ` /out/force-quit-gui
|
|
'`})
|
|
|
|
kdotoolBuilt := base.
|
|
WithExec([]string{"sh", "-c", `set -e
|
|
nix-shell -p ` + nixPkgs + ` --run '
|
|
set -e
|
|
git clone --depth 1 https://github.com/jinliu/kdotool /tmp/kdotool
|
|
cd /tmp/kdotool
|
|
cargo build --release
|
|
mkdir -p /out
|
|
cp target/release/kdotool /out/kdotool
|
|
patchelf --set-interpreter ` + hostInterp + ` /out/kdotool
|
|
'`})
|
|
|
|
return dag.Directory().
|
|
WithFile("swap-watchdog", goBuilt.File("/out/swap-watchdog")).
|
|
WithFile("force-quit-gui", goBuilt.File("/out/force-quit-gui")).
|
|
WithFile("kdotool", kdotoolBuilt.File("/out/kdotool"))
|
|
}
|