A preservation fork of Free Pascal Compiler 2.6.4 for BBS and retro software. Release r3 (2026-07-12), patched r3.1 (2026-07-14). Codepage-aware AnsiStrings, DOS TCP/IP sockets (Watt-32), COFF object writer fix, cross-build from Linux with bundled tools, OS/2 cross-compilation (import linking solved plus the first-ever OS/2 TProcess for fcl-process). Ships the FPC text-mode IDE and Lazarus 1.2.6 LCL, each self-contained. Proven end-to-end: Mystic BBS v1.10 A38irc compiles 56/56 across native Linux, Windows, DOS, and OS/2. 169 string/socket assertions + 75 tool/platform checks; binary-protocol safe.
See MILESTONE-R3.md for the full r3 summary.
- Native
ldlinker fix: link.res (a full replacement linker script) is now passed with-T, fixing hangs and "Can't call the linker" errors on modern binutils (2.19+, e.g. 2.42 on current Ubuntu). Backported from FPC 3.2.2's approach. - Prebuilt FPC packages for all six targets: fcl-net (netdb), hash (md5,
sha1, crc), paszlib (7 units), fcl-process (pipes, process). Consumers no
longer need extra
-Fupaths for these packages. - Mystic socket layer: pure-Pascal resolver — the Unix branch of
m_io_sockets.pasnow uses FPC'snetdbinstead of the externalcNetDBlibc glue. No libc dependency for name resolution on Unix. Non-Unix paths (Winsock2/WinSock/Watt-32) unchanged. - cNetDB retired to
attic/retired-units/(not deleted; restore instructions indocs/removed/cnetdb-retired.md). - Test harness (run-tests.sh): cross-target socket tests now fall back to compile-only verification when the target cross-linker isn't installed; OS/2 section fixed to use bundled emx tools. Result: 9/9 passed, 169 assertions, ALL AVAILABLE TESTS PASSED.
- Register allocator backports from FPC 3.0:
is_subhspill offset correction + LEA→ADD spill conversion inx86/rgx86.pas.
type AnsiString(CP_UTF8)syntax — parser backported from FPC 3.0- Automatic codepage conversion on assignment
UnicodeStringfull support (8/8 tests pass)widestringmanagercodepage parametersTAnsiRecwithCodePage+ElementSizefieldsTSystemCodePage,CP_UTF8,CP_ACP,CP_NONE,RawByteStringStringCodePage(),StringElementSize(),StringRefCount(),SetCodePage()- 47-check binary protocol safety test — telnet/BinkP/Zmodem/ANSI wire data survives all string operations without corruption
Uses Socketsworks on go32v2 — backed by Watt-32/libwatt.a- Full fp* BSD API + select + FD_SET + DNS resolver + ioctlSocket
{$linklib watt}auto-links libwatt.a- Mystic BBS compiles with plain
Uses Socketson all 6 platforms
- Fixed COFF section symbol storage class: C_STAT (3) not C_SECTION (104)
- Stock DJGPP binutils (2.35+) work without
-Aasworkaround
-Aoflag — pass extra options to assembler$EXTRAOPTin all assembler command templates- Error 127 fix: Makefile guard clears BINUTILSPREFIX for native/multilib builds (Fix A + Fix B — documented, no shim)
- Import-by-name uses
MangledName + Cprefix(backported from 3.0.4) - 7 cherry-picks: FileNameCasePreserving, MaxPathLen 260, error 206/290 mappings, exception parameters fix, FileOpen label fix, FSApi64
- 60 OS/2 RTL units compile (crt, sockets, so32dll added in r3)
- Linking solved: 7-part binutils patch resolves N_IMP1/N_IMP2 import
symbols (
patches/os2-cross/binutils-2.30-emx-nimp.patch);-Ttext 0x10000in the ld command sets the emxbind-required entry point - Produces a.out with zero undefined references (all DLL imports resolve)
- emxbind ported to Linux (builds and validates the a.out); final bind
needs
emxl.exefrom the EMX runtime - See
docs/os2_linking_solved.md
- StackLength -256 (prt0 safety margin)
- FileNameCasePreserving variable
- dpmiexcp.pp typo fix
-WSflag embeds CWSDSTUB into go32v2 EXE at link timeCWSDSTUB.EXEbundled inlib/cwsdpmi/
as,ld,ar,makebundled for all 6 platforms- System tools preferred → bundled binary fallback → source build guidance
- Source included: binutils-2.42, binutils-2.30 (EMX), make-4.3
- Zero symlinks (Windows-safe)
fpc264irc/
├── src/ # Full FPC 2.6.4 source (14,994 files)
│ ├── compiler/ # Modified: globtype, symdef, psystem,
│ │ # pdecl, ptype, ncnv, ogcoff, options,
│ │ # globals, assemble, aggas, agx86att,
│ │ # asmutils, t_os2, i_go32v2
│ ├── rtl/ # Modified: systemh, system, astrings,
│ │ # go32v2/sockets.pp (NEW),
│ │ # go32v2/system.pp, go32v2/dpmiexcp.pp,
│ │ # os2/system.pas, os2/sysos.inc,
│ │ # emx/system.pas, emx/sysutils.pp
│ └── ... # packages, ide, utils (stock)
├── bin/
│ ├── ppc386 # i386 compiler
│ ├── ppcx64 # x86_64 compiler
│ ├── units/ # Compiled RTL per target
│ │ ├── x86_64-linux/ # 62 units
│ │ ├── i386-linux/
│ │ ├── i386-go32v2/
│ │ ├── i386-win32/
│ │ ├── i386-freebsd/
│ │ └── i386-os2/ # 60 units (linking WORKS, TProcess added)
│ └── tools/ # Bundled cross-tools (zero symlinks)
│ ├── make # GNU Make 4.3
│ ├── x86_64-linux/ # binutils 2.42
│ ├── i386-linux/ # binutils 2.42 (multilib)
│ ├── i386-go32v2/ # DJGPP binutils 2.35
│ ├── i386-win32/ # MinGW binutils 2.41
│ ├── i386-freebsd/ # FreeBSD binutils 2.42
│ └── i386-emx/ # Patched binutils 2.30 (a.out)
├── lib/
│ ├── watt32/ # Watt-32 TCP/IP source
│ ├── cwsdpmi/ # CWSDPMI r7 binaries + source
│ └── build-tools/ # Source: binutils-2.42, 2.30, make-4.3
├── test/ # 11 test programs + 5 test scripts
│ ├── test_string_baseline.pas # 65 checks
│ ├── test_string_codepage.pas # 34 checks
│ ├── test_binary_protocol_safety.pas # 47 checks
│ ├── test_auto_convert.pas # 12 checks
│ ├── test_unicode_basic.pas # 8 checks
│ ├── test_*_sockets.pas # 6 platform socket tests
│ ├── run-tests.sh # Per-target test runner
│ ├── test-tools.sh # 31 tool checks
│ ├── test-tool-fallback.sh # 44 fallback checks
│ ├── test-all-platforms.sh # 6-platform verification
│ └── test-os2-build.sh # OS/2 build chain test
├── patches/os2-cross/ # BFD patch + emxbind source
├── docs/
│ ├── error127_debug_log.md # Error 127 root cause + fix
│ └── tier_fallback_system.md # 3-tier tool fallback design
├── fpc264irc.patch # All changes as unified diff
├── BACKPORT-METHOD.md # 6-step cherry-pick discipline
├── MILESTONE-R2.md # Phase plan (5 phases)
├── CHANGELOG-IRC.md
├── build-linux.sh # 3-tier fallback build script
├── build-windows.bat
├── README.md
└── LICENSE
bin/ppcx64 -iW # 2.6.4irc
bin/ppcx64 -Fubin/units/x86_64-linux prog.pas # Linux native
bin/ppc386 -Tgo32v2 -Fubin/units/i386-go32v2 -Fllib/watt32/lib p.pas # DOS
bin/ppc386 -Twin32 -Fubin/units/i386-win32 p.pas # Windows
bin/ppc386 -Tfreebsd -Fubin/units/i386-freebsd p.pas # FreeBSD
bin/ppc386 -Tgo32v2 -WSlib/cwsdpmi/CWSDSTUB.EXE -Fubin/units/i386-go32v2 p.pas # standalone DOScd src/rtl
make clean OS_TARGET=linux CPU_TARGET=x86_64 FPC=../../bin/ppcx64
make all OS_TARGET=linux CPU_TARGET=x86_64 FPC=../../bin/ppcx64 BINUTILSPREFIX=
# Units go to src/rtl/units/x86_64-linux/Important: The trailing BINUTILSPREFIX= (empty) is required for native
and i386-on-x86_64 builds. Without it, the Makefile may auto-set a prefix
and fail with Error 127. This is a standard make variable override, not a
workaround. If you use build-linux.sh, this is handled automatically.
| Platform | Sockets | Cross from Linux | Tools | RTL | Link |
|---|---|---|---|---|---|
| x86_64-linux | RTL native | n/a (native) | ✅ | ✅ 84 units | ✅ |
| i386-linux | RTL native | multilib | ✅ | ✅ | ✅ |
| i386-go32v2 (DOS) | Watt-32 | DJGPP binutils | ✅ | ✅ | ✅ |
| i386-win32 | RTL native | MinGW binutils | ✅ | ✅ | ✅ |
| i386-freebsd | RTL native | FreeBSD binutils | ✅ | ✅ | ✅ |
| i386-emx (OS/2) | RTL native | patched binutils | ✅ | ✅ 72 units | ✅ resolves* |
*OS/2 link resolves all import symbols and produces a valid a.out; the
final a.out→LX packaging uses emxbind (ported, builds on Linux) plus the
redistributable emxl.exe runtime loader. See docs/os2_linking_solved.md.
DOS is 32-bit only (16-bit in progress). DOS support targets go32v2
(32-bit protected mode). 16-bit real-mode DOS (i8086-msdos) is under
active development on a separate branch (i8086_work/) — the i8086
backend is a full backport from FPC 3.0, currently deep in Stage 4 (RTL
system.pp compilation). It is not in any release yet.
test/run-tests.sh # string + codepage + socket tests
test/test-tools.sh # verify bundled tools (31 checks)
test/test-tool-fallback.sh # verify 3-tier fallback (44 checks)
test/test-all-platforms.sh # full 6-platform verification
test/test-os2-build.sh # OS/2 build chain status| Test | Checks | Status |
|---|---|---|
| String baseline | 65/65 | ✅ PASS |
| Codepage infrastructure | 34/34 | ✅ PASS |
| Binary protocol safety | 47/47 | ✅ PASS |
| Auto conversion | 12/12 | ✅ PASS |
| Linux sockets | 11/11 | ✅ PASS |
| String + socket total | 169/169 | ALL PASS |
| Cross-socket (DOS, win32, FreeBSD, OS/2) | 4/4 | ✅ compile-verified |
| Full harness (run-tests.sh) | 9/9 | ✅ ALL AVAILABLE TESTS PASSED |
| Tools (all platforms) | 31/31 | ✅ PASS |
| Tool fallback | 44/44 | ✅ PASS |
- Phase 1: Codepage compiler support (4/4 items complete)
- Phase 2: go32v2 cherry-picks (3 fixes, gated)
- Phase 2: OS/2 cherry-picks (7 fixes, 44 RTL units, linking solved)
- Phase 2: i8086 — scoped and deferred to a future release (full
backend port, not a fix; ~28K lines + 32 shared-file edits + PPU-format
work + NASM/WLINK toolchain). See
docs/i8086_scoping.md. r3 ships 32-bit DOS via go32v2. - FPC text-mode IDE — self-contained 3-tier system: bundled
bin/ide/fp+ units (Tier 2),build-ide.shfrom in-tree source (Tier 3),tools/get-ide.shprovisioner - Lazarus 1.2.6 LCL — self-contained 3-tier system per widgetset: bundled units incl. form resources (Tier 2),
build-lcl.shfrom in-tree source (Tier 3),tools/get-lcl.shprovisioner. win32 verified (PE32 GUI .exe), gtk2 + qt built, nogui run-verified (headless). Seedocs/lazarus_lcl.md - Phase 4: Prove it works — Mystic BBS v1.10 A38irc cross-compiles
56/56: 14/14 each on native Linux, win32, go32v2 DOS, and OS/2 (OS/2 links
with all symbols resolved). Completing OS/2 required building 3 RTL units
(crt, sockets, so32dll), fixing 2 upstream RTL bugs, and writing the first
OS/2 TProcess implementation for fcl-process (upstream FPC never had one).
See
docs/mystic_build.md. - [~] Phase 5: Release (tag 2.6.4irc-r3) — release docs, commit messages,
and GitHub About text prepared in
RELEASE-r3/; seeMILESTONE-R3.mdandRELEASE-r3/CHECKLIST.md.
Note: Phase 3 (AArch64/Apple Silicon) deferred to Option B — separate modern
FPC track. See docs/ for the Modern Platform Bridge document. ARM64 is a
compiler backend and cannot be added to 2.6.4irc as an RTL add-on.
ld: warning: ... has a LOAD segment with RWX permissions — this is a
modern binutils (2.39+) security warning about FPC 2.6.4's linker scripts.
The generated executables have segments that are both writable and executable,
which is normal for this era of compiler. The warning is harmless and does not
affect functionality.
Compiler: GPL v2 (same as upstream FPC). RTL/packages: modified LGPL.
See LICENSE and src/rtl/COPYING.FPC.
Bundled tools: GPL v3+ (source in lib/build-tools/).