From c86c7da5dffbfd8e732b94af6928f6718c31846d Mon Sep 17 00:00:00 2001 From: monkey-w1n5t0n Date: Sun, 28 Jun 2026 05:16:39 +0200 Subject: [PATCH] build(vcv): build Windows here in a resource-bounded container + link ws2_32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - vcv/Makefile: include arch.mk early, link -lws2_32 when ARCH_WIN (the OSC server uses Winsock; mingw ignores the MSVC #pragma comment lib). - vcv/build-win.sh: bounded Docker mingw cross-build (hard CPU/mem caps, no extra swap, prebuilt mingw — no toolchain compile). Produces win-x64 .vcvplugin. - DISTRIBUTION.md: reflect the no-dedicated-box reality — Linux + Windows built locally (supervised + bounded), macOS needs the Apple SDK (CI or a Mac). --- vcv/DISTRIBUTION.md | 48 +++++++++++++++++++++++++++++----------- vcv/Makefile | 9 ++++++++ vcv/build-win.sh | 53 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 13 deletions(-) create mode 100755 vcv/build-win.sh diff --git a/vcv/DISTRIBUTION.md b/vcv/DISTRIBUTION.md index f432438..a96e6d6 100644 --- a/vcv/DISTRIBUTION.md +++ b/vcv/DISTRIBUTION.md @@ -15,6 +15,10 @@ official `plugin.mk` `dist` target produces it, named `--.vcvplugin` (e.g. `MEMLNaut-0.2.0-lin-x64.vcvplugin`). Platforms: `lin-x64`, `win-x64`, `mac-x64`, `mac-arm64`. +We have no dedicated build box, so we build **on this host**, but **resource-bounded** +so a build can never starve the live services. Build products (`build/`, `dist/`, +`plugin.so`, `*.vcvplugin`) are git-ignored — they are publish artefacts, not source. + ### Linux x64 — locally (works today) The Rack 2 SDK is installed at `$HOME/.local/share/Rack2/Rack-SDK`: @@ -25,21 +29,39 @@ RACK_DIR=$HOME/.local/share/Rack2/Rack-SDK make dist # -> vcv/dist/MEMLNaut--lin-x64.vcvplugin ``` -This is the only platform we build on the server: the host toolchain is native -Linux x64 and the SDK is already present. Build products (`build/`, `dist/`, -`plugin.so`, `*.vcvplugin`) are git-ignored — they are publish artefacts, not -source. +Native host toolchain, SDK already present — trivial, no caps needed. -### Windows / macOS — cross-built on CI (NOT on the server) +### Windows x64 — locally, resource-bounded (works today) -The other three platforms are cross-built by the official -[VCVRack/rack-plugin-toolchain](https://github.com/VCVRack/rack-plugin-toolchain), -the same Docker cross-builder the VCV Library uses. **We do not run that toolchain -on the production VPS** — its image build compiles mingw + osxcross and pulls the -Apple SDK (multi-GB, multi-hour), which would overload a host that serves live -services. macOS additionally requires the Apple SDK, which we never redistribute. -CI is the right place for all of this; for a local-only macOS build the operator -can use a Mac with the native SDK. +`vcv/build-win.sh` cross-builds Windows in a **hard-capped Docker container** using +**prebuilt mingw-w64** (no GCC/toolchain compile — it only apt-installs mingw and +compiles two `.cpp` files). The container is capped on CPU + memory with no extra +swap, so the cgroup OOM-kills the container rather than the host if it ever exceeded +the cap. In practice the host stays at full free RAM throughout. + +```bash +vcv/build-win.sh # defaults: CPUS=6 MEM=8g, Rack SDK 2.6.4 +CPUS=4 MEM=6g vcv/build-win.sh # tighter caps +# -> vcv/dist/MEMLNaut--win-x64.vcvplugin +``` + +Note: the OSC bridge server needs Winsock on Windows; `vcv/Makefile` links +`-lws2_32` when `ARCH_WIN` is set (mingw ignores the MSVC `#pragma comment(lib,…)`). + +### macOS (x64 + arm64) — Apple SDK required + +macOS cross-builds need Apple's **licensed macOS SDK**, which we never download or +redistribute on this host. Two routes: + +1. **CI** (`.github/workflows/vcv-plugin.yml`) — the + [VCVRack/rack-plugin-toolchain](https://github.com/VCVRack/rack-plugin-toolchain) + builds mac-x64 + mac-arm64 on tagged releases (the toolchain fetches the SDK only + inside its own image build). +2. **A Mac** — build with the native SDK + `RACK_DIR` set to the macOS Rack SDK. + +The full rack-plugin-toolchain image build is **not** run on this host: its Dockerfile +`COPY`s the Apple SDK and compiles osxcross, so it both needs the SDK and is multi-GB +/ multi-hour. That belongs on CI. (Linux + Windows above need none of it.) --- diff --git a/vcv/Makefile b/vcv/Makefile index 7d004b3..eebe201 100644 --- a/vcv/Makefile +++ b/vcv/Makefile @@ -1,5 +1,14 @@ RACK_DIR ?= $(HOME)/.local/share/Rack2/Rack-SDK +# Detect the target arch early (defines ARCH_WIN/ARCH_LIN/ARCH_MAC) so we can add +# per-platform link libs before plugin.mk wires the link rule. The OSC bridge +# server (src/osc_server.hpp) uses Winsock2 on Windows; mingw ignores the +# MSVC-only `#pragma comment(lib, "ws2_32.lib")`, so link it explicitly. +include $(RACK_DIR)/arch.mk +ifdef ARCH_WIN +LDFLAGS += -lws2_32 +endif + FLAGS += -std=c++20 FLAGS += -I$(RACK_DIR)/include -I$(RACK_DIR)/dep/include # The retired nisps-core header tree is gone; the runtime IML/MLP is vendored diff --git a/vcv/build-win.sh b/vcv/build-win.sh new file mode 100755 index 0000000..9189bb1 --- /dev/null +++ b/vcv/build-win.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# +# build-win.sh — cross-build the MEMLNaut VCV plugin for Windows x64, here, in a +# RESOURCE-BOUNDED Docker container (prebuilt mingw-w64; no GCC/toolchain compile). +# +# Why Docker + caps: this host also runs live services. The container is hard- +# capped (CPU + memory + no extra swap) so the build physically cannot starve or +# crash the host — the cgroup OOM-kills the container, not the system, if it ever +# exceeded the cap. In practice this build peaks well under the cap (it only +# apt-installs prebuilt mingw + compiles two .cpp files), and the host stays at +# full free RAM throughout. Tune CPUS / MEM below for your machine. +# +# Output: vcv/dist/MEMLNaut--win-x64.vcvplugin +# Requires: docker. Run from anywhere; paths are resolved from this script. + +set -euo pipefail + +CPUS="${CPUS:-6}" # cores the container may use +MEM="${MEM:-8g}" # hard memory cap (== memory-swap, so no host swap) +RACK_SDK_VERSION="${RACK_SDK_VERSION:-2.6.4}" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # vcv/ +WORK="$(mktemp -d /tmp/vcv-win-build.XXXXXX)" +trap 'rm -rf "$WORK"' EXIT + +echo "==> staging a clean copy of the plugin source" +cp -r "$SCRIPT_DIR/." "$WORK/" +rm -rf "$WORK/build" "$WORK/dist" "$WORK/plugin.so" 2>/dev/null || true + +cat > "$WORK/_in-container.sh" </dev/null +cd /tmp +wget -q "https://vcvrack.com/downloads/Rack-SDK-${RACK_SDK_VERSION}-win-x64.zip" +unzip -q "Rack-SDK-${RACK_SDK_VERSION}-win-x64.zip" +cd /src +export RACK_DIR=/tmp/Rack-SDK +export CC=x86_64-w64-mingw32-gcc-posix CXX=x86_64-w64-mingw32-g++-posix +export STRIP=x86_64-w64-mingw32-strip OBJCOPY=x86_64-w64-mingw32-objcopy +make clean >/dev/null 2>&1 || true +make -j${CPUS} dist +ls -la dist/ +EOF + +echo "==> building Windows plugin in a bounded container (cpus=$CPUS, mem=$MEM, no extra swap)" +docker run --rm --cpus="$CPUS" --memory="$MEM" --memory-swap="$MEM" \ + -v "$WORK:/src" ubuntu:24.04 bash /src/_in-container.sh + +mkdir -p "$SCRIPT_DIR/dist" +cp "$WORK"/dist/*-win-x64.vcvplugin "$SCRIPT_DIR/dist/" +echo "==> done: $(ls "$SCRIPT_DIR"/dist/*-win-x64.vcvplugin)"