Files
Daybreak/Scripts/PublishLinuxWineX86.sh
2026-06-29 22:36:44 +02:00

102 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Linux equivalent of Scripts/PublishWindowsX86.ps1.
#
# Publishes Daybreak.Injector (x86) and Daybreak.API (x86) for Windows by
# running the Windows .NET SDK under Wine, using lld-link as the platform
# linker and the MSVC CRT + Windows SDK x86 libraries extracted by xwin.
#
# Run Scripts/SetupWinePrefix.sh once before using this.
#
# Usage: Scripts/PublishLinuxWineX86.sh [Configuration]
# Env vars:
# WINEPREFIX — wine prefix to use (default: ~/.wine-daybreak)
set -euo pipefail
CONFIGURATION="${1:-Release}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$REPO_ROOT"
export WINEPREFIX="${WINEPREFIX:-$HOME/.wine-daybreak}"
DOTNET_EXE="$WINEPREFIX/drive_c/dotnet/dotnet.exe"
PROPS_FILE='C:\wine-aot.props'
if [[ ! -f "$DOTNET_EXE" ]]; then
echo "Wine prefix is not set up. Run Scripts/SetupWinePrefix.sh first." >&2
exit 1
fi
if [[ ! -f "$WINEPREFIX/drive_c/wine-aot.props" ]]; then
echo "Missing C:\\wine-aot.props in wine prefix. Re-run Scripts/SetupWinePrefix.sh." >&2
exit 1
fi
# Map repo into wine as R:\
ln -sfn "$REPO_ROOT" "$WINEPREFIX/dosdevices/r:"
# Environment for wine + dotnet
export WINEDLLOVERRIDES="mscoree=b"
export WINEDEBUG="${WINEDEBUG:--all}"
export DOTNET_NOLOGO=1
export DOTNET_CLI_TELEMETRY_OPTOUT=1
export DOTNET_GENERATE_ASPNET_CERTIFICATE=false
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
INJECTOR_OUT='R:\Publish\Injector'
API_OUT='R:\Publish\Api'
# Clean previous outputs so MSBuild incremental can't get confused. The
# generator + shared projects are also wiped because their bin/Debug is
# shared with the Linux dotnet build (same netstandard2.0 / net10.0 TFM),
# which can leave the wine build half-incremental and CSC then fails to
# locate the generator dll mid-publish.
rm -rf "$REPO_ROOT/Publish/Injector" "$REPO_ROOT/Publish/Api"
for p in Daybreak.Injector Daybreak.API Daybreak.Generators Daybreak.Shared; do
rm -rf "$REPO_ROOT/$p/obj" "$REPO_ROOT/$p/bin"
done
# Kill any stale daemons from a previous wine session (these wedge stdout)
pkill_pat() {
pgrep -af "$1" 2>/dev/null | awk '{print $1}' | xargs -r kill -9 2>/dev/null || true
}
pkill_pat 'VBCSCompiler'
pkill_pat 'MSBuild.dll.*nodemode'
dotnet_publish() {
local proj="$1" out="$2" tag="$3"
local log="/tmp/wine-${tag}-publish.log"
echo "=== Publishing $proj$out (log: $log) ===" >&2
if ! wine "$DOTNET_EXE" publish "$proj" \
-c "$CONFIGURATION" -r win-x86 \
-o "$out" \
-nodeReuse:false -m:1 \
-p:UseSharedCompilation=false \
-p:EnableSourceLink=false \
-p:CustomAfterMicrosoftCommonProps="$PROPS_FILE" \
-v:m 2>&1 | tee "$log"; then
local rc=${PIPESTATUS[0]}
echo "!!! publish failed (exit $rc). Full log: $log" >&2
return "$rc"
fi
# MSBuild can exit 0 even when a build error was reported via Exec'd subprocess
if grep -qE '^[^[:space:]].*: error |error MSB[0-9]+|Build FAILED|build failed' "$log"; then
echo "!!! publish reported errors (see $log)" >&2
grep -E ': error |error MSB[0-9]+|Build FAILED' "$log" >&2 | head -20
return 1
fi
}
dotnet_publish 'R:\Daybreak.Injector\Daybreak.Injector.csproj' "$INJECTOR_OUT" injector
dotnet_publish 'R:\Daybreak.API\Daybreak.API.csproj' "$API_OUT" api
# wine spawns long-lived build-server processes that keep the parent shell's
# stdout pipe open even after publish returns. Reap them so this script exits.
pkill_pat 'VBCSCompiler'
pkill_pat 'MSBuild.dll.*nodemode'
wineserver -k 2>/dev/null || true
echo "=== Linux/Wine x86 publish complete ==="
echo "Injector: $REPO_ROOT/Publish/Injector"
echo "API: $REPO_ROOT/Publish/Api"