- build_dos.sh: Linux-friendly cross-compile to DOS via OpenWatcom V2.
OpenWatcom's wmake on Linux can't apply the .c.obj implicit rule for
subdirectory paths, and Makefile.dos / Makefile.dos16 rely on DOS-
only commands like 'del'. Script invokes wcc / wcc386 directly,
tracks 16-bit vs 32-bit mode via a stamp file (auto-cleans on
switch), generates a wlink directive file (the brace-delimited file
list wouldn't survive shell quoting), and supports clean. The DOS
Makefiles still work on Windows / DOS hosts.
- tests/run_compiler_tests.sh: AOT compiler harness. For each .bas
in tests/programs/, compiles via gwbasic-compile -c, runs the
resulting executable, normalizes output and diffs against the
golden file from tests/expected/. Skip list covers chain/common
multi-file flows, hardware/timing-dependent programs, unnumbered
direct-mode programs (compiler requires line numbers), and
misc_stmts/run_file (interpreter-vs-compiler ON ERROR divergence).
Result: 56/56 pass.
- tests/run_dos_smoke.sh + dos_smoke.bas + expected: runs gwbasic16.exe
under DOSBox-X (flatpak) with a program that exercises arithmetic,
strings, control flow, GOSUB, FOR/NEXT, DATA/READ, DEF FN, OPEN/
PRINT#/CLOSE, and diffs against the interpreter's golden output.
Uses $HOME for the staging dir (DOSBox-X flatpak doesn't see /tmp).
- pkg/GWBASIC.LSM + pkg/build_pkg.sh: FreeDOS submission package.
Produces dist/gwbasic-<VERSION>.zip with the standard FreeDOS
layout (APPINFO/GWBASIC.LSM, BIN/GWBASIC.EXE, DOC/GWBASIC/{README,
CHANGES,LICENSE} with CRLF, SOURCE/GWBASIC/<full source>). Source
tree is filtered through git ls-files to exclude build artifacts.
- docs/Makefile: standard Sphinx Makefile so 'cd docs && make html'
works as documented in README.md.
- .github/workflows/ci.yml: split into two jobs. build-and-test now
also runs the compiler harness. New dos-cross-compile job caches
~/openwatcom-v2, downloads the OpenWatcom V2 snapshot if not
cached, builds both 16-bit and 32-bit DOS binaries, asserts size
bounds, and uploads them as artifacts.
- .gitignore: ignore .dos_build_mode (script's stamp), .link_dir/
(transient wlink directive dir), dist/ (package output).
99 lines
2.9 KiB
Bash
Executable File
99 lines
2.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# build_dos.sh -- Cross-compile GW-BASIC 2026 to DOS using OpenWatcom V2.
|
|
#
|
|
# Usage:
|
|
# ./build_dos.sh # 16-bit real-mode, produces gwbasic16.exe
|
|
# ./build_dos.sh 32 # 32-bit DOS/4GW, produces gwbasic.exe
|
|
# ./build_dos.sh clean # remove .obj files and DOS executables
|
|
#
|
|
# OpenWatcom's wmake on Linux struggles with the .c.obj implicit rule for
|
|
# subdirectory paths, so this script invokes wcc/wcc386 directly. On a
|
|
# Windows or DOS host, use Makefile.dos / Makefile.dos16 with wmake instead.
|
|
#
|
|
# Requires: OpenWatcom V2 with $WATCOM and binl64 (or binl) on PATH.
|
|
# Source ~/openwatcom-v2/setvars.sh first if not already.
|
|
|
|
set -e
|
|
|
|
if [ -z "$WATCOM" ]; then
|
|
if [ -f "$HOME/openwatcom-v2/setvars.sh" ]; then
|
|
. "$HOME/openwatcom-v2/setvars.sh"
|
|
else
|
|
echo "Error: WATCOM not set and ~/openwatcom-v2/setvars.sh not found." >&2
|
|
echo "Install OpenWatcom V2 and set WATCOM to its root." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
INTERP_C=(
|
|
src/main.c src/tokens.c src/tokenizer.c src/error.c
|
|
src/eval.c src/interp.c src/vars.c src/arrays.c
|
|
src/input.c src/math_int.c src/math_float.c
|
|
src/math_transcend.c src/strings.c src/print.c
|
|
src/fileio.c src/program_io.c src/print_using.c
|
|
src/graphics.c src/virmem.c src/portio.c src/strpool.c
|
|
src/sound.c src/tui.c platform/hal_dos.c
|
|
)
|
|
|
|
case "${1:-16}" in
|
|
clean)
|
|
rm -f src/*.obj platform/*.obj gwbasic.exe gwbasic16.exe gwbascom.exe gwrt.lib .dos_build_mode
|
|
echo "cleaned"
|
|
exit 0
|
|
;;
|
|
16)
|
|
CC=wcc
|
|
CFLAGS="-bt=dos -mm -ox -w4 -zq -za99 -Iinclude -D__MSDOS__"
|
|
EXE=gwbasic16.exe
|
|
LINK_SYSTEM="dos option stack=8192"
|
|
;;
|
|
32)
|
|
CC=wcc386
|
|
CFLAGS="-bt=dos -mf -ox -w4 -zq -za99 -Iinclude -D__MSDOS__"
|
|
EXE=gwbasic.exe
|
|
LINK_SYSTEM="dos4g"
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [16|32|clean]" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Track which mode the .obj files were built for; clean if it differs. 16-bit
|
|
# .obj from wcc and 32-bit .obj from wcc386 share names but cannot mix in one
|
|
# link.
|
|
MODE_STAMP=.dos_build_mode
|
|
PREV_MODE=""
|
|
[ -f "$MODE_STAMP" ] && PREV_MODE=$(cat "$MODE_STAMP")
|
|
if [ -n "$PREV_MODE" ] && [ "$PREV_MODE" != "$1" ] && [ "$PREV_MODE" != "${1:-16}" ]; then
|
|
echo " -- previous build was $PREV_MODE, cleaning"
|
|
rm -f src/*.obj platform/*.obj
|
|
fi
|
|
echo "${1:-16}" > "$MODE_STAMP"
|
|
|
|
OBJS=()
|
|
for c in "${INTERP_C[@]}"; do
|
|
obj="${c%.c}.obj"
|
|
OBJS+=("$obj")
|
|
if [ "$c" -nt "$obj" ] || [ ! -f "$obj" ]; then
|
|
printf " CC %s\n" "$c"
|
|
$CC $CFLAGS -fo="$obj" "$c"
|
|
fi
|
|
done
|
|
|
|
printf " LD %s\n" "$EXE"
|
|
LINK_DIR=$(dirname "$0")/.link_dir
|
|
mkdir -p "$LINK_DIR"
|
|
LINK_SCRIPT="$LINK_DIR/link.lnk"
|
|
{
|
|
echo "system $LINK_SYSTEM"
|
|
echo "name $EXE"
|
|
for o in "${OBJS[@]}"; do
|
|
echo "file $o"
|
|
done
|
|
} > "$LINK_SCRIPT"
|
|
wlink @"$LINK_SCRIPT"
|
|
rm -rf "$LINK_DIR"
|
|
|
|
ls -la "$EXE"
|