Files

141 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Minimal VC6 link-frontier probe for the Windows 9x port.
#
# This is deliberately smaller than CPython's full PCbuild/pythoncore.vcxproj:
# it compiles only the translation units already proven by the core compile
# probes plus the tiny Programs/python.c executable entry point, then invokes
# LINK.EXE under Wine. A successful executable link is not expected yet; the
# purpose of this milestone is to verify that the build can get past CL.EXE
# for the current frontier and reach a real VC6 linker diagnostic with a
# reproducible command line.
#
# The MSVC600 bundle is an external, local-only prerequisite; nothing under
# MSVC600/ is part of this project's source.
#
# Usage:
# scripts/vc6-probe-minlink.sh
#
# Environment:
# MSVC600_ROOT override the MSVC600 location (default: <repo>/MSVC600)
# WINEPREFIX override the Wine prefix (default: ~/.wine-win9xport)
set -u
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# Reuse winpath()/strip_prefix() from vc6-probe.sh instead of duplicating
# them; sourcing it does not run the probe itself (see its own guard).
# shellcheck source=scripts/vc6-probe.sh
source "$REPO_ROOT/scripts/vc6-probe.sh"
run_probe_minlink() {
MSVC600_ROOT="${MSVC600_ROOT:-$REPO_ROOT/MSVC600}"
BUILD_DIR="$REPO_ROOT/build/vc6-probe-minlink"
CL="$MSVC600_ROOT/VC98/Bin/CL.EXE"
LINK="$MSVC600_ROOT/VC98/Bin/LINK.EXE"
VCVARS="$MSVC600_ROOT/VC98/Bin/VCVARS32.BAT"
# Keep this list intentionally tiny and aligned with the post-core-probe
# milestone: python.vcxproj's single executable TU plus the three core TUs
# that are currently known to compile under scripts/vc6-probe-core.sh.
SOURCES=(
"cpython/Programs/python.c"
"cpython/Modules/main.c"
"cpython/Python/pylifecycle.c"
"cpython/Python/pystate.c"
)
for required in "$CL" "$LINK" "$VCVARS" "$MSVC600_ROOT/VC98/Include" \
"$MSVC600_ROOT/VC98/Lib" "$MSVC600_ROOT/Common/MSDev98/Bin"; do
if [ ! -e "$required" ]; then
echo "vc6-probe-minlink: missing prerequisite: $required" >&2
return 2
fi
done
local source_rel
for source_rel in "${SOURCES[@]}"; do
if [ ! -e "$REPO_ROOT/$source_rel" ]; then
echo "vc6-probe-minlink: missing source: $REPO_ROOT/$source_rel" >&2
return 2
fi
done
if ! command -v wine >/dev/null 2>&1; then
echo "vc6-probe-minlink: 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;
# LINK.EXE also needs the VC98 tools and default libraries.
export WINEPATH="$(winpath "$MSVC600_ROOT/VC98/Bin");$(winpath "$MSVC600_ROOT/Common/MSDev98/Bin")"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
INCLUDE_ARGS=(
"$(winpath "$REPO_ROOT/compat/msvc600")"
"$(winpath "$REPO_ROOT/cpython/Include/internal")"
"$(winpath "$REPO_ROOT/cpython/Include")"
"$(winpath "$REPO_ROOT/cpython/PC")"
"$(winpath "$MSVC600_ROOT/VC98/Include")"
)
echo "== MSVC600 minimal link-frontier probe =="
echo "sources:"
for source_rel in "${SOURCES[@]}"; do
echo " - $source_rel"
done
echo "prefix : $WINEPREFIX"
echo
local obj_args=""
local source_abs obj_name obj_abs cmd status
for source_rel in "${SOURCES[@]}"; do
source_abs="$REPO_ROOT/$source_rel"
obj_name="${source_rel#cpython/}"
obj_name="${obj_name//\//_}"
obj_name="${obj_name%.c}.obj"
obj_abs="$BUILD_DIR/$obj_name"
obj_args+=" $(winpath "$obj_abs")"
cmd="call $(winpath "$VCVARS") && cd /d $(winpath "$REPO_ROOT/cpython") && cl /nologo /D Py_BUILD_CORE /D Py_BUILD_CORE_BUILTIN /D Py_ENABLE_SHARED /D _USRDLL"
for include_arg in "${INCLUDE_ARGS[@]}"; do
cmd+=" /I $include_arg"
done
cmd+=" /c $(winpath "$source_abs") /Fo$(winpath "$obj_abs")"
wine cmd /c "$cmd" 2>&1 |
grep -v '^[0-9a-f]\{4\}:err:' |
strip_prefix "$(winpath "$REPO_ROOT")\\"
status="${PIPESTATUS[0]}"
if [ "$status" -ne 0 ]; then
echo
echo "== cl.exe exit status: $status =="
echo "vc6-probe-minlink: compile failed before link at $source_rel" >&2
return "$status"
fi
done
echo
echo "== LINK.EXE attempt =="
cmd="call $(winpath "$VCVARS") && cd /d $(winpath "$REPO_ROOT/cpython") && link /nologo /subsystem:console /out:$(winpath "$BUILD_DIR/python-min.exe") /libpath:$(winpath "$MSVC600_ROOT/VC98/Lib")$obj_args kernel32.lib user32.lib advapi32.lib shell32.lib version.lib ws2_32.lib"
wine cmd /c "$cmd" 2>&1 |
grep -v '^[0-9a-f]\{4\}:err:' |
strip_prefix "$(winpath "$REPO_ROOT")\\"
status="${PIPESTATUS[0]}"
echo
echo "== link.exe exit status: $status =="
return "$status"
}
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
run_probe_minlink "$@"
exit "$?"
fi