port: add MSVC600 CPython compatibility layer
This commit is contained in:
Executable
+107
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Minimal reproducible MSVC 6.0 compile probe for the Windows 9x port.
|
||||
#
|
||||
# Runs the external MSVC600 `cl.exe` under Wine against the CPython 3.11.16
|
||||
# baseline in ./cpython, using the project-local compatibility headers in
|
||||
# ./compat/msvc600. Compile-only (/c): this probe measures how far the VC6
|
||||
# front end gets through the public headers, it does not attempt to link.
|
||||
#
|
||||
# The MSVC600 bundle is an external, local-only prerequisite; nothing under
|
||||
# MSVC600/ is part of this project's source.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/vc6-probe.sh # probe Programs/python.c
|
||||
# scripts/vc6-probe.sh path/to/other.c # probe another translation unit
|
||||
#
|
||||
# Environment:
|
||||
# MSVC600_ROOT override the MSVC600 location (default: <repo>/MSVC600)
|
||||
# WINEPREFIX override the Wine prefix (default: ~/.wine-win9xport)
|
||||
|
||||
set -u
|
||||
|
||||
# Absolute POSIX path -> Wine drive Z: path.
|
||||
winpath() { printf 'Z:%s' "${1//\//\\}"; }
|
||||
|
||||
# Strip a literal (non-regex) prefix from every line of stdin.
|
||||
#
|
||||
# sed and bash glob patterns both treat backslashes in the *pattern* as
|
||||
# escape characters, so passing a Windows path (full of literal `\`
|
||||
# separators) as a sed/glob pattern silently fails to match: `\h`, `\u`,
|
||||
# etc. are consumed as (mostly no-op) escapes instead of literal
|
||||
# characters. Quoting the parameter inside a bash `${var//pattern/}`
|
||||
# expansion forces literal (non-glob) matching, which sidesteps the
|
||||
# problem entirely.
|
||||
strip_prefix() {
|
||||
local prefix="$1" line
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
printf '%s\n' "${line//"$prefix"/}"
|
||||
done
|
||||
}
|
||||
|
||||
run_probe() {
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
MSVC600_ROOT="${MSVC600_ROOT:-$REPO_ROOT/MSVC600}"
|
||||
BUILD_DIR="$REPO_ROOT/build/vc6-probe"
|
||||
|
||||
SOURCE_REL="${1:-cpython/Programs/python.c}"
|
||||
SOURCE_ABS="$REPO_ROOT/$SOURCE_REL"
|
||||
|
||||
CL="$MSVC600_ROOT/VC98/Bin/CL.EXE"
|
||||
VCVARS="$MSVC600_ROOT/VC98/Bin/VCVARS32.BAT"
|
||||
|
||||
for required in "$CL" "$VCVARS" "$MSVC600_ROOT/VC98/Include" \
|
||||
"$MSVC600_ROOT/Common/MSDev98/Bin" "$SOURCE_ABS"; do
|
||||
if [ ! -e "$required" ]; then
|
||||
echo "vc6-probe: missing prerequisite: $required" >&2
|
||||
return 2
|
||||
fi
|
||||
done
|
||||
|
||||
if ! command -v wine >/dev/null 2>&1; then
|
||||
echo "vc6-probe: wine is not installed" >&2
|
||||
return 2
|
||||
fi
|
||||
|
||||
export WINEPREFIX="${WINEPREFIX:-$HOME/.wine-win9xport}"
|
||||
export WINEDEBUG="${WINEDEBUG:--all}"
|
||||
|
||||
# CL.EXE loads C1/C2 from VC98/Bin and MSPDB60.DLL from Common/MSDev98/Bin.
|
||||
export WINEPATH="$(winpath "$MSVC600_ROOT/VC98/Bin");$(winpath "$MSVC600_ROOT/Common/MSDev98/Bin")"
|
||||
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
INCLUDE_ARGS=(
|
||||
"$(winpath "$REPO_ROOT/compat/msvc600")"
|
||||
"$(winpath "$REPO_ROOT/cpython/Include")"
|
||||
"$(winpath "$REPO_ROOT/cpython/PC")"
|
||||
"$(winpath "$MSVC600_ROOT/VC98/Include")"
|
||||
)
|
||||
|
||||
echo "== MSVC600 compile probe =="
|
||||
echo "source : $SOURCE_REL"
|
||||
echo "prefix : $WINEPREFIX"
|
||||
echo
|
||||
|
||||
CMD="call $(winpath "$VCVARS") && cd /d $(winpath "$REPO_ROOT/cpython") && cl /nologo"
|
||||
for include_arg in "${INCLUDE_ARGS[@]}"; do
|
||||
CMD+=" /I $include_arg"
|
||||
done
|
||||
CMD+=" /c $(winpath "$SOURCE_ABS") /Fo$(winpath "$BUILD_DIR")\\"
|
||||
|
||||
wine cmd /c "$CMD" 2>&1 |
|
||||
grep -v '^[0-9a-f]\{4\}:err:' |
|
||||
strip_prefix "$(winpath "$REPO_ROOT")\\"
|
||||
|
||||
status="${PIPESTATUS[0]}"
|
||||
echo
|
||||
echo "== cl.exe exit status: $status =="
|
||||
return "$status"
|
||||
}
|
||||
|
||||
# Allow `source scripts/vc6-probe.sh` (e.g. from tests) to pull in
|
||||
# winpath/strip_prefix without running the probe itself.
|
||||
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
|
||||
run_probe "$@"
|
||||
exit "$?"
|
||||
fi
|
||||
Reference in New Issue
Block a user