Add build infrastructure, installer scripts, and fix build errors

- Create vcpkg.json manifest with all editor dependencies
- Create CMakePresets.json for Windows (MSVC) and Linux (GCC)
- Create Inno Setup installer script (setup.iss) with file associations
- Create Windows build helper (build.ps1) with vcpkg auto-install
- Create Linux build/install scripts (build.sh, install.sh)
- Vendor imgui SDL2 backend locally (removed from vcpkg imgui 1.91+)
- Switch CMakeLists.txt from FetchContent to vcpkg find_package
- Fix ElispGenerator missing pure virtual overrides for memory annotations
- Fix Orchestrator::findNodeById const-correctness
- Fix orchestrator_main.cpp loadFile/saveFile type mismatches
- Fix main.cpp SDL_GL_SwapBuffers -> SDL_GL_SwapWindow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Bill
2026-02-07 22:06:50 -07:00
parent d0a039e567
commit e08fc9e0e0
13 changed files with 1664 additions and 21 deletions

195
installer/linux/build.sh Normal file
View File

@@ -0,0 +1,195 @@
#!/usr/bin/env bash
# Whetstone Editor - Linux Build Script
# Prerequisites: GCC/Clang, CMake 3.20+, vcpkg or system packages
# Usage: ./build.sh [--config Release|Debug] [--vcpkg-root /path/to/vcpkg] [--system-packages] [--package deb|tar]
set -euo pipefail
CONFIG="Release"
VCPKG_ROOT="${VCPKG_ROOT:-}"
USE_SYSTEM_PACKAGES=false
PACKAGE_TYPE=""
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
EDITOR_DIR="$(cd "$SCRIPT_DIR/../../editor" && pwd)"
BUILD_DIR="$EDITOR_DIR/build"
TRIPLET="x64-linux"
# --- Parse arguments ---
while [[ $# -gt 0 ]]; do
case "$1" in
--config) CONFIG="$2"; shift 2 ;;
--vcpkg-root) VCPKG_ROOT="$2"; shift 2 ;;
--system-packages) USE_SYSTEM_PACKAGES=true; shift ;;
--package) PACKAGE_TYPE="$2"; shift 2 ;;
-h|--help)
echo "Usage: $0 [--config Release|Debug] [--vcpkg-root PATH] [--system-packages] [--package deb|tar]"
exit 0 ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
step() {
echo ""
echo "==> $1"
}
# --- Check prerequisites ---
step "Checking prerequisites"
if ! command -v cmake &>/dev/null; then
echo "ERROR: CMake not found. Install cmake 3.20+."
exit 1
fi
echo " CMake: $(cmake --version | head -1)"
if command -v g++ &>/dev/null; then
echo " GCC: $(g++ --version | head -1)"
elif command -v clang++ &>/dev/null; then
echo " Clang: $(clang++ --version | head -1)"
else
echo "ERROR: No C++ compiler found. Install g++ or clang++."
exit 1
fi
# --- Install system dependencies if requested ---
if $USE_SYSTEM_PACKAGES; then
step "Installing system packages"
if command -v apt-get &>/dev/null; then
sudo apt-get update -qq
sudo apt-get install -y -qq \
build-essential cmake \
libsdl2-dev libgl1-mesa-dev libglew-dev \
nlohmann-json3-dev
elif command -v dnf &>/dev/null; then
sudo dnf install -y \
gcc-c++ cmake \
SDL2-devel mesa-libGL-devel glew-devel \
json-devel
elif command -v pacman &>/dev/null; then
sudo pacman -S --noconfirm --needed \
base-devel cmake \
sdl2 mesa glew \
nlohmann-json
else
echo "WARNING: Unknown package manager. Install dependencies manually:"
echo " SDL2-dev, OpenGL dev, nlohmann-json, glad"
fi
echo " System packages installed."
fi
# --- Bootstrap vcpkg if needed ---
if ! $USE_SYSTEM_PACKAGES; then
if [[ -z "$VCPKG_ROOT" ]]; then
# Try common locations
for candidate in "$HOME/vcpkg" "/opt/vcpkg" "/usr/local/vcpkg"; do
if [[ -x "$candidate/vcpkg" ]]; then
VCPKG_ROOT="$candidate"
break
fi
done
fi
if [[ -z "$VCPKG_ROOT" ]]; then
step "Bootstrapping vcpkg"
VCPKG_ROOT="$HOME/vcpkg"
git clone https://github.com/microsoft/vcpkg.git "$VCPKG_ROOT"
"$VCPKG_ROOT/bootstrap-vcpkg.sh" -disableMetrics
fi
echo " vcpkg: $VCPKG_ROOT"
step "Installing vcpkg dependencies"
"$VCPKG_ROOT/vcpkg" install \
"nlohmann-json:$TRIPLET" \
"sdl2:$TRIPLET" \
"imgui[docking-experimental,opengl3-binding]:$TRIPLET" \
"glad:$TRIPLET" \
--recurse
echo " All vcpkg packages installed."
fi
# --- Configure CMake ---
step "Configuring CMake ($CONFIG)"
mkdir -p "$BUILD_DIR"
CMAKE_ARGS=(
-S "$EDITOR_DIR"
-B "$BUILD_DIR"
-DCMAKE_BUILD_TYPE="$CONFIG"
)
if ! $USE_SYSTEM_PACKAGES && [[ -n "$VCPKG_ROOT" ]]; then
CMAKE_ARGS+=(
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake"
-DVCPKG_TARGET_TRIPLET="$TRIPLET"
)
fi
cmake "${CMAKE_ARGS[@]}"
# --- Build ---
step "Building ($CONFIG)"
cmake --build "$BUILD_DIR" --config "$CONFIG" --parallel "$(nproc)"
echo " Build succeeded."
# --- Package (optional) ---
if [[ -n "$PACKAGE_TYPE" ]]; then
step "Packaging ($PACKAGE_TYPE)"
STAGING_DIR="$SCRIPT_DIR/staging"
rm -rf "$STAGING_DIR"
mkdir -p "$STAGING_DIR/usr/local/bin"
for exe in whetstone_editor orchestrator; do
if [[ -f "$BUILD_DIR/$exe" ]]; then
cp "$BUILD_DIR/$exe" "$STAGING_DIR/usr/local/bin/"
echo " Staged $exe"
fi
done
case "$PACKAGE_TYPE" in
deb)
mkdir -p "$STAGING_DIR/DEBIAN"
cat > "$STAGING_DIR/DEBIAN/control" <<CTRL
Package: whetstone-editor
Version: 0.1.0
Section: devel
Priority: optional
Architecture: amd64
Depends: libsdl2-2.0-0, libgl1
Maintainer: Whetstone DSL Project
Description: Whetstone DSL Editor and Orchestrator
A visual editor for the Whetstone domain-specific language
with semantic annotation support.
CTRL
dpkg-deb --build "$STAGING_DIR" "$SCRIPT_DIR/whetstone-editor_0.1.0_amd64.deb"
echo " Created whetstone-editor_0.1.0_amd64.deb"
;;
tar)
tar -czf "$SCRIPT_DIR/whetstone-editor-0.1.0-linux-x64.tar.gz" \
-C "$STAGING_DIR/usr/local" bin/
echo " Created whetstone-editor-0.1.0-linux-x64.tar.gz"
;;
*)
echo "WARNING: Unknown package type '$PACKAGE_TYPE'. Use 'deb' or 'tar'."
;;
esac
fi
step "Done!"
echo " Build output: $BUILD_DIR"
echo ""

144
installer/linux/install.sh Normal file
View File

@@ -0,0 +1,144 @@
#!/usr/bin/env bash
# Whetstone Editor - Linux Install Script
# Installs system dependencies, builds from source, and installs to /usr/local/bin
# Usage: ./install.sh [--prefix /usr/local] [--no-build]
set -euo pipefail
PREFIX="/usr/local"
DO_BUILD=true
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
EDITOR_DIR="$REPO_DIR/editor"
BUILD_DIR="$EDITOR_DIR/build"
# --- Parse arguments ---
while [[ $# -gt 0 ]]; do
case "$1" in
--prefix) PREFIX="$2"; shift 2 ;;
--no-build) DO_BUILD=false; shift ;;
-h|--help)
echo "Usage: $0 [--prefix /usr/local] [--no-build]"
echo " --prefix PATH Install prefix (default: /usr/local)"
echo " --no-build Skip build, install pre-built binaries only"
exit 0 ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
step() {
echo ""
echo "==> $1"
}
# --- Install system dependencies ---
step "Installing system dependencies"
if command -v apt-get &>/dev/null; then
sudo apt-get update -qq
sudo apt-get install -y -qq \
build-essential cmake git \
libsdl2-dev libgl1-mesa-dev \
nlohmann-json3-dev
elif command -v dnf &>/dev/null; then
sudo dnf install -y \
gcc-c++ cmake git \
SDL2-devel mesa-libGL-devel \
json-devel
elif command -v pacman &>/dev/null; then
sudo pacman -S --noconfirm --needed \
base-devel cmake git \
sdl2 mesa \
nlohmann-json
else
echo "WARNING: Unknown package manager. Please install manually:"
echo " - C++ compiler (g++ or clang++)"
echo " - CMake 3.20+"
echo " - SDL2 development libraries"
echo " - OpenGL development libraries"
echo " - nlohmann-json"
fi
# --- Build from source ---
if $DO_BUILD; then
step "Building from source"
# Use the build script if available
if [[ -x "$SCRIPT_DIR/build.sh" ]]; then
"$SCRIPT_DIR/build.sh" --config Release --system-packages
else
mkdir -p "$BUILD_DIR"
cmake -S "$EDITOR_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=Release
cmake --build "$BUILD_DIR" --config Release --parallel "$(nproc)"
fi
fi
# --- Install binaries ---
step "Installing to $PREFIX/bin"
sudo mkdir -p "$PREFIX/bin"
for exe in whetstone_editor orchestrator; do
if [[ -f "$BUILD_DIR/$exe" ]]; then
sudo install -m 755 "$BUILD_DIR/$exe" "$PREFIX/bin/$exe"
echo " Installed $exe"
else
echo " WARNING: $exe not found in build directory"
fi
done
# --- Create desktop entry ---
step "Creating desktop entry"
DESKTOP_FILE="$HOME/.local/share/applications/whetstone-editor.desktop"
mkdir -p "$(dirname "$DESKTOP_FILE")"
cat > "$DESKTOP_FILE" <<DESKTOP
[Desktop Entry]
Type=Application
Name=Whetstone Editor
Comment=Visual editor for the Whetstone domain-specific language
Exec=$PREFIX/bin/whetstone_editor %F
Terminal=false
Categories=Development;IDE;TextEditor;
MimeType=text/x-whetstone;text/x-semanno;
Keywords=whetstone;dsl;semantic;annotation;
DESKTOP
echo " Created $DESKTOP_FILE"
# --- Create MIME types ---
MIME_DIR="$HOME/.local/share/mime/packages"
mkdir -p "$MIME_DIR"
cat > "$MIME_DIR/whetstone.xml" <<MIME
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="text/x-whetstone">
<comment>Whetstone Source File</comment>
<glob pattern="*.whet"/>
</mime-type>
<mime-type type="text/x-semanno">
<comment>Semantic Annotation File</comment>
<glob pattern="*.semanno"/>
</mime-type>
</mime-info>
MIME
if command -v update-mime-database &>/dev/null; then
update-mime-database "$HOME/.local/share/mime" 2>/dev/null || true
fi
echo " Registered .whet and .semanno MIME types"
step "Installation complete!"
echo " Binaries: $PREFIX/bin/whetstone_editor, $PREFIX/bin/orchestrator"
echo " Desktop entry: $DESKTOP_FILE"
echo ""

165
installer/windows/build.ps1 Normal file
View File

@@ -0,0 +1,165 @@
# Whetstone Editor - Windows Build Script
# Prerequisites: Visual Studio 2022, CMake 3.20+, vcpkg
# Usage: .\build.ps1 [-Config Release|Debug] [-VcpkgRoot E:\vcpkg]
param(
[ValidateSet("Release", "Debug")]
[string]$Config = "Release",
[string]$VcpkgRoot = $env:VCPKG_ROOT
)
$ErrorActionPreference = "Stop"
$EditorDir = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$EditorDir = Join-Path $EditorDir "editor"
$BuildDir = Join-Path $EditorDir "build"
$StagingDir = Join-Path $PSScriptRoot "staging"
$Triplet = "x64-windows"
function Write-Step($msg) {
Write-Host "`n==> $msg" -ForegroundColor Cyan
}
function Test-Command($cmd) {
return [bool](Get-Command $cmd -ErrorAction SilentlyContinue)
}
# --- Check prerequisites ---
Write-Step "Checking prerequisites"
# CMake
if (-not (Test-Command "cmake")) {
Write-Error "CMake not found. Install CMake 3.20+ and add it to PATH."
}
$cmakeVersion = (cmake --version | Select-Object -First 1)
Write-Host " CMake: $cmakeVersion"
# Visual Studio
$vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
if (Test-Path $vsWhere) {
$vsPath = & $vsWhere -latest -property installationPath
Write-Host " Visual Studio: $vsPath"
} else {
Write-Warning "vswhere not found - Visual Studio may not be installed."
}
# vcpkg
if (-not $VcpkgRoot) {
# Try common locations
$candidates = @("E:\vcpkg", "C:\vcpkg", "$env:USERPROFILE\vcpkg")
foreach ($c in $candidates) {
if (Test-Path (Join-Path $c "vcpkg.exe")) {
$VcpkgRoot = $c
break
}
}
}
if (-not $VcpkgRoot -or -not (Test-Path (Join-Path $VcpkgRoot "vcpkg.exe"))) {
Write-Error "vcpkg not found. Set VCPKG_ROOT or pass -VcpkgRoot <path>."
}
Write-Host " vcpkg: $VcpkgRoot"
$vcpkgExe = Join-Path $VcpkgRoot "vcpkg.exe"
$toolchainFile = Join-Path $VcpkgRoot "scripts\buildsystems\vcpkg.cmake"
# --- Install vcpkg dependencies ---
Write-Step "Installing vcpkg dependencies"
$packages = @(
"nlohmann-json:$Triplet",
"sdl2:$Triplet",
"imgui[docking-experimental,opengl3-binding]:$Triplet",
"glad:$Triplet"
)
foreach ($pkg in $packages) {
Write-Host " Installing $pkg ..."
& $vcpkgExe install $pkg --recurse 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Warning "vcpkg install $pkg returned exit code $LASTEXITCODE (may already be installed)"
}
}
Write-Host " All vcpkg packages installed." -ForegroundColor Green
# --- Configure CMake ---
Write-Step "Configuring CMake ($Config)"
if (-not (Test-Path $BuildDir)) {
New-Item -ItemType Directory -Path $BuildDir | Out-Null
}
cmake -S $EditorDir -B $BuildDir `
-G "Visual Studio 17 2022" -A x64 `
-DCMAKE_TOOLCHAIN_FILE="$toolchainFile" `
-DVCPKG_TARGET_TRIPLET="$Triplet"
if ($LASTEXITCODE -ne 0) {
Write-Error "CMake configure failed."
}
# --- Build ---
Write-Step "Building ($Config)"
$targets = @("whetstone_editor", "orchestrator")
foreach ($t in $targets) {
cmake --build $BuildDir --config $Config --target $t --parallel
if ($LASTEXITCODE -ne 0) {
Write-Error "Build of $t failed."
}
}
Write-Host "`n Build succeeded." -ForegroundColor Green
# --- Stage output for installer ---
Write-Step "Staging build output to $StagingDir"
if (Test-Path $StagingDir) {
Remove-Item -Recurse -Force $StagingDir
}
New-Item -ItemType Directory -Path $StagingDir | Out-Null
# Copy executables
$binDir = Join-Path $BuildDir $Config
$exes = @("whetstone_editor.exe", "orchestrator.exe")
foreach ($exe in $exes) {
$src = Join-Path $binDir $exe
if (Test-Path $src) {
Copy-Item $src $StagingDir
Write-Host " Copied $exe"
} else {
Write-Warning " $exe not found at $src"
}
}
# Copy DLLs from vcpkg installed dir
$vcpkgBinDir = Join-Path $VcpkgRoot "installed\$Triplet\bin"
if (Test-Path $vcpkgBinDir) {
$dlls = @("SDL2.dll")
foreach ($dll in $dlls) {
$src = Join-Path $vcpkgBinDir $dll
if (Test-Path $src) {
Copy-Item $src $StagingDir
Write-Host " Copied $dll"
}
}
}
# Also copy any DLLs that ended up in the build output directory
Get-ChildItem -Path $binDir -Filter "*.dll" -ErrorAction SilentlyContinue | ForEach-Object {
if (-not (Test-Path (Join-Path $StagingDir $_.Name))) {
Copy-Item $_.FullName $StagingDir
Write-Host " Copied $($_.Name) (from build output)"
}
}
Write-Step "Done!"
Write-Host " Executables staged in: $StagingDir"
Write-Host " To create the installer, compile setup.iss with Inno Setup."
Write-Host ""

View File

@@ -0,0 +1,76 @@
; Whetstone Editor - Inno Setup Script
; Requires Inno Setup 6.x (https://jrsoftware.org/isinfo.php)
;
; Build the editor first using build.ps1, then compile this script.
#define MyAppName "Whetstone Editor"
#define MyAppVersion "0.1.0"
#define MyAppPublisher "Whetstone DSL Project"
#define MyAppURL "https://github.com/billthemaker/Whetstone_DSL"
#define MyAppExeName "whetstone_editor.exe"
[Setup]
AppId={{B7E3F2A1-4D5C-6E7F-8A9B-0C1D2E3F4A5B}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
OutputDir=..\..\editor\build\installer
OutputBaseFilename=WhetstoneEditor-{#MyAppVersion}-setup
Compression=lzma2
SolidCompression=yes
WizardStyle=modern
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
; LicenseFile=..\..\LICENSE
; Uncomment the following line to require admin privileges:
; PrivilegesRequired=admin
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "fileassoc_whet"; Description: "Associate .whet files with Whetstone Editor"; GroupDescription: "File Associations:"
Name: "fileassoc_semanno"; Description: "Associate .semanno files with Whetstone Editor"; GroupDescription: "File Associations:"
[Files]
; Main executables
Source: "staging\whetstone_editor.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "staging\orchestrator.exe"; DestDir: "{app}"; Flags: ignoreversion
; Runtime DLLs from vcpkg
Source: "staging\SDL2.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "staging\*.dll"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist
; Data files (if any)
Source: "staging\data\*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs createallsubdirs skipifsourcedoesntexist
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\Whetstone Orchestrator"; Filename: "{app}\orchestrator.exe"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Registry]
; .whet file association
Root: HKA; Subkey: "Software\Classes\.whet"; ValueType: string; ValueName: ""; ValueData: "WhetstoneFile"; Flags: uninsdeletevalue; Tasks: fileassoc_whet
Root: HKA; Subkey: "Software\Classes\WhetstoneFile"; ValueType: string; ValueName: ""; ValueData: "Whetstone Source File"; Flags: uninsdeletekey; Tasks: fileassoc_whet
Root: HKA; Subkey: "Software\Classes\WhetstoneFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: fileassoc_whet
Root: HKA; Subkey: "Software\Classes\WhetstoneFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: fileassoc_whet
; .semanno file association
Root: HKA; Subkey: "Software\Classes\.semanno"; ValueType: string; ValueName: ""; ValueData: "SemannoFile"; Flags: uninsdeletevalue; Tasks: fileassoc_semanno
Root: HKA; Subkey: "Software\Classes\SemannoFile"; ValueType: string; ValueName: ""; ValueData: "Semantic Annotation File"; Flags: uninsdeletekey; Tasks: fileassoc_semanno
Root: HKA; Subkey: "Software\Classes\SemannoFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"; Tasks: fileassoc_semanno
Root: HKA; Subkey: "Software\Classes\SemannoFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Tasks: fileassoc_semanno
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
[UninstallDelete]
Type: filesandordirs; Name: "{app}\data"