ci: build the DOS (DJGPP) target and consolidate the toolchain file

A new Linux job installs the andrewwutw DJGPP v3.4 cross-toolchain
(gcc 12.2.0, sha256-pinned), cross-compiles uc2.exe with
cmake/djgpp.cmake, and verifies the result is a DJGPP go32 DOS
executable. The DOS build had no CI coverage and could regress
silently.

The repo carried two diverged DJGPP toolchain files. djgpp.cmake
(referenced by the build docs) forces -nostdinc with explicit DJGPP
include paths, so it builds cleanly even on hosts where /usr/include
would otherwise leak past the cross-compiler. djgpp-toolchain.cmake
(previously referenced by the README) relied on the cross-gcc finding
its own headers and broke in that case. Keep djgpp.cmake as the single
toolchain file, point the README and roadmap at it, and drop
djgpp-toolchain.cmake.
This commit is contained in:
Eremey Valetov
2026-06-13 07:53:46 -04:00
parent c394106c56
commit 09cdc80986
4 changed files with 51 additions and 61 deletions
+31
View File
@@ -71,3 +71,34 @@ jobs:
run: cmake --build build -j
- name: Round-trip test
run: ctest --test-dir build --output-on-failure -R libarchive_roundtrip
djgpp:
runs-on: ubuntu-latest
name: DOS (DJGPP)
env:
DJGPP_URL: https://github.com/andrewwutw/build-djgpp/releases/download/v3.4/djgpp-linux64-gcc1220.tar.bz2
DJGPP_SHA256: 8464f17017d6ab1b2bb2df4ed82357b5bf692e6e2b7fee37e315638f3d505f00
# Keep host include dirs out of the cross-compiler's search path in
# every step (the toolchain file also forces -nostdinc, but a stray
# CPATH on the runner would otherwise leak glibc headers).
CPATH: ''
CPLUS_INCLUDE_PATH: ''
steps:
- uses: actions/checkout@v4
- name: Install DJGPP cross-toolchain
run: |
curl -fsSL -o djgpp.tar.bz2 "$DJGPP_URL"
echo "${DJGPP_SHA256} djgpp.tar.bz2" | sha256sum -c -
sudo tar xjf djgpp.tar.bz2 -C /opt # -> /opt/djgpp
- name: Configure (DJGPP toolchain)
run: |
cmake -B build-dos \
-DCMAKE_TOOLCHAIN_FILE=cmake/djgpp.cmake \
-DDJGPP_ROOT=/opt/djgpp -DCMAKE_BUILD_TYPE=Release
- name: Build
run: cmake --build build-dos -j
- name: Verify DOS executable
run: |
file build-dos/cli/uc2.exe
file build-dos/cli/uc2.exe | grep -q "DJGPP go32 DOS extender" \
|| { echo "uc2.exe is not a DJGPP DOS executable"; exit 1; }
+13 -1
View File
@@ -105,7 +105,7 @@ No mainstream archiver offers post-quantum encryption.
## Phase 6: DOS / FreeDOS / Retro-Computing
- [x] DJGPP cross-compilation toolchain: `cmake/djgpp-toolchain.cmake`
- [x] DJGPP cross-compilation toolchain: `cmake/djgpp.cmake`
builds `uc2.exe` against the prebuilt DJGPP gcc 7.2 / 12.2 from
`andrewwutw/build-djgpp`. Output is a 32-bit DPMI DOS executable
(MZ + COFF + go32 stub). See `cmake/README-djgpp.md` for the
@@ -294,3 +294,15 @@ Bobrowski already shipped prototypes; update for UC2 v3.
Found debugging extraction on sdf.org (NetBSD 10) but reproducible
everywhere. New regression test: cli_bigfile. Follow-up filed:
bf73896 (ftell offsets >4GB truncate silently; P2).
- 2026-06-13: DOS build now has CI coverage (DJGPP v3.4 toolchain,
sha-pinned; builds uc2.exe via cmake/djgpp.cmake; git-bug 9379647).
Consolidated the two DJGPP toolchain files onto djgpp.cmake and
removed the redundant djgpp-toolchain.cmake.
- 2026-06-13: Damaged-archive decode hardening (git-bug f049d6d):
decompress_block match-length overflow guard (runtime check
replacing an NDEBUG assert), decompress_cdir end-bounding, and a
CLI handle/FILE leak fix on the cdir-error path. A prefix-sweep
fuzzer drove the fixes; a residual rare cdir-parser OOB it surfaces
is tracked for a systematic hardening + fuzzing pass (git-bug
69e8e52).
+7 -5
View File
@@ -31,7 +31,7 @@ the bundled `cwsdpmi.exe` extender (or any DPMI host).
```sh
unset CPATH CPLUS_INCLUDE_PATH
cmake -B build-djgpp \
-DCMAKE_TOOLCHAIN_FILE=cmake/djgpp-toolchain.cmake \
-DCMAKE_TOOLCHAIN_FILE=cmake/djgpp.cmake \
-DDJGPP_ROOT=/opt/djgpp
cmake --build build-djgpp
```
@@ -42,7 +42,9 @@ plus `cwsdpmi.exe` (shipped with DJGPP at
## Status
- Compiles clean against DJGPP gcc 7.2.0 and 12.2.0.
- Compiles clean against the DJGPP gcc 12.2.0 toolchain (the
`cmake/djgpp.cmake` include paths are pinned to that version; the
CI job and the andrewwutw v3.4 release both use 12.2.0).
- Library (`libuc2.a`) builds without changes.
- CLI uses the DOS compat layer in `cli/src/compat/compat_dos.c` for
the BSD `err.h` and POSIX `fnmatch` shims.
@@ -69,9 +71,9 @@ not installed.
## Notes
- The toolchain file forces `CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY`
because the compiler check would otherwise try to execute a DOS .exe
on the host kernel and fail.
- The toolchain sets `CMAKE_SYSTEM_NAME Generic` and `-nostdinc` with
explicit DJGPP include paths, so the compiler check links a test
binary (rather than running one) and host headers never leak in.
- DJGPP's `unistd.h` provides POSIX-shaped APIs; most of the existing
source compiles unchanged. The library has no DOS-specific code
paths.
-55
View File
@@ -1,55 +0,0 @@
# CMake toolchain file for DJGPP cross-compile (DOS / FreeDOS).
#
# Usage:
# cmake -B build-djgpp -DCMAKE_TOOLCHAIN_FILE=cmake/djgpp-toolchain.cmake
# cmake --build build-djgpp
#
# Requires the DJGPP cross-toolchain on PATH or at DJGPP_ROOT. The standard
# layout from andrewwutw/build-djgpp and the djfdyuruiry/djgpp docker image
# is /usr/local/bin/djgpp/. Override with -DDJGPP_ROOT=<path> if installed
# elsewhere.
set(CMAKE_SYSTEM_NAME Generic) # bare DJGPP DOS, no OS abstractions
set(CMAKE_SYSTEM_PROCESSOR i386)
# Project source uses `if(DJGPP)` to gate the DOS compat layer (cli/src/
# compat/compat_dos.c, sys-include/dos shim). Set the variable up front
# so those guards activate.
set(DJGPP TRUE)
# Locate the toolchain prefix.
if(NOT DEFINED DJGPP_ROOT)
if(EXISTS /usr/local/bin/djgpp)
set(DJGPP_ROOT /usr/local/bin/djgpp)
elseif(EXISTS /opt/djgpp)
set(DJGPP_ROOT /opt/djgpp)
endif()
endif()
if(DEFINED DJGPP_ROOT AND EXISTS ${DJGPP_ROOT})
set(_DJGPP_BIN ${DJGPP_ROOT}/bin)
else()
set(_DJGPP_BIN "")
endif()
set(CMAKE_C_COMPILER ${_DJGPP_BIN}/i586-pc-msdosdjgpp-gcc)
set(CMAKE_CXX_COMPILER ${_DJGPP_BIN}/i586-pc-msdosdjgpp-g++)
set(CMAKE_AR ${_DJGPP_BIN}/i586-pc-msdosdjgpp-ar CACHE FILEPATH "")
set(CMAKE_RANLIB ${_DJGPP_BIN}/i586-pc-msdosdjgpp-ranlib CACHE FILEPATH "")
set(CMAKE_STRIP ${_DJGPP_BIN}/i586-pc-msdosdjgpp-strip CACHE FILEPATH "")
if(DEFINED DJGPP_ROOT)
set(CMAKE_FIND_ROOT_PATH ${DJGPP_ROOT}/i586-pc-msdosdjgpp)
endif()
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# DJGPP can produce static binaries; tests run inside DOSBox-X.
set(CMAKE_EXE_LINKER_FLAGS_INIT "")
# CMake's compiler check tries to build a test binary. DJGPP-produced
# .exe binaries are valid COFF executables that the host kernel will
# refuse to run, so use STATIC_LIBRARY mode.
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)