Skip to content

chore(windows): support Delphi 11/12 compilation + Delphi 12 CE dev workflow#16039

Draft
MattGyverLee wants to merge 1 commit into
keymanapp:masterfrom
MattGyverLee:delphi-12
Draft

chore(windows): support Delphi 11/12 compilation + Delphi 12 CE dev workflow#16039
MattGyverLee wants to merge 1 commit into
keymanapp:masterfrom
MattGyverLee:delphi-12

Conversation

@MattGyverLee
Copy link
Copy Markdown
Contributor

Summary

Lowers contributor friction on #4599 (deprecate Delphi) by letting developers on the free Delphi 11 / 12 Community Edition tier compile the still-Delphi parts of the tree. None of the compiler / runtime stack moves; this is purely build-environment work plus narrow source-compat patches.

CI is unchanged: with KEYMAN_DELPHI_VERSION unset, every build script keeps using Delphi 10.3 (BDS 20.0) exactly as before. Every Keyman-owned source change is an additive VER350 / VER360 IFDEF arm; the existing VER330 paths are not touched.

Why this matters for the Delphi removal roadmap

Delphi 10.3 Pro is no longer obtainable, and CE 10.3 has been removed from Embarcadero's downloads. New contributors who want to help finish #4599 currently hit a wall: they can install CE 12, but CE blocks the dcc32 CLI that build.sh drives, and the tree itself doesn't compile cleanly against the modern Delphi RTL. This PR closes that gap without shifting CI off 10.3 — it's a bridge that makes the Delphi-side easier to chip away at, not a commitment to keep Delphi alive.

What's in the change

1. Build-script knob (CI-safe)

2. Delphi 11/12 source compat in Keyman-owned code

Five files under common/windows/delphi/. Every change is additive IFDEF arms for VER350 / VER360; the VER330 (10.3) paths are untouched. Each was hit by a real compile failure on Delphi 12 CE; the patch is the minimum needed to keep the existing code shape on 10.3 while letting it compile on 11/12.

File Change Why
tools/devtools/SourceRootPath.pas Add VER350/VER360 → '22.0'/'23.0' DelphiMajorVersion needs to know about the new BDS install dirs
web/Keyman.System.HttpServer.Base.pas Extend the IFNDEF VER330 tripwire to also accept VER340/350/360 Existing comment says "may need to check this with updated versions of Delphi" — this is that check
components/FixedTrackbar.pas Same tripwire extension Same pattern as above
general/CleartypeDrawCharacter.pas EnumFontFamiliesEx integer-return comparison on VER340/350/360 (was VER340-only) The Win32 wrapper return type changed in 10.4+; existing guard only covered 10.4
general/JsonUtil.pas Pass [] options arg to TJSONAncestor.ToChars on VER350/360 Delphi 11+ added a required Options parameter

Plus windows/src/engine/engine.groupproj: drop the inst\insthelper reference. The path doesn't resolve — insthelper.dproj lives at windows/src/engine/insthelper, not .../inst/insthelper — and IDE "Build All" was failing on it. build.sh-based builds were never affected because they don't walk the groupproj.

3. Vendored third-party patches (please look here first)

⚠️ This is the highest-risk piece of the PR. Three files under developer/src/ext/. Each hunk is annotated with a // Keyman local patch comment plus a refresh strategy noting the upstream package and what to re-apply when those projects ship Delphi 12-compatible releases.

File Change Why
jedi/jcl/jcl/source/common/JclSynch.pas Wrap Boolean args to CreateEvent / OpenEvent / CreateWaitableTimer / OpenWaitableTimer / OpenSemaphore / CreateMutex / OpenMutex in explicit BOOL(); switch JclWin32.CreateMutexWinapi.Windows.CreateMutex Delphi 12 tightened implicit Boolean→BOOL conversion at call sites. BOOL() is an ordinal-preserving typecast, equivalent to the implicit conversion 10.3 was doing — no runtime semantic change. The CreateMutex unit-resolution switch matches the file's existing pattern for the other Winapi calls
jedi/jvcl/jvcl/run/JvComponent.pas On VER350+, unconditionally call DoCreate Embarcadero removed the OldCreateOrder property in Delphi 11; the modern default is equivalent to OldCreateOrder=True
mbcolor/mxs.inc Add VER350/VER360 blocks defining DELPHI_5_UPDELPHI_10_UP Without these, HTMLColors.pas silently drops Variants from its uses clause and breaks with "Undeclared identifier: 'null'"

The annotations point future contributors back at the patched hunk when those projects bump (and let a reviewer audit the local delta cleanly).

4. Docs + helper scripts

  • docs/build/windows.md: one-line pointer to windows-d12.md from the existing "Delphi 10.3 CE no longer available" warning, so future CE users find the workaround instead of dead-ending.
  • docs/build/windows-d12.md: ~990-line guide — prerequisites, registry library-path setup, source patches, the canonical build order (including the tsysinfox64 → .bin → tsysinfo_x64.res chicken-and-egg), install-and-overlay workflow, debugging, troubleshooting catalog, and a section labeling which patches are safe to upstream.
  • windows/scripts/preflight-resources.ps1 — runs rc.exe over every .rc, generates manifest.xml from manifest.in. Equivalent of build.sh's _prebuild_resources phase.
  • windows/scripts/run-codegen.ps1 — drives devtools.exe + build_standards_data.exe plus the tsysinfox64 chicken-and-egg.
  • windows/scripts/overlay-dev-builds.ps1 — copies dev binaries onto an installed Keyman 19 (equivalent of build.sh install; needed because TKeymanPaths.KeymanDesktopInstallPath() is hardcoded to Program Files).
  • windows/scripts/install-build-env.ps1 — one-time toolchain installer.

All four PowerShell scripts auto-detect the repo root via $PSScriptRoot (two levels up from windows/scripts/) and honor $env:KEYMAN_ROOT as an override, so they work from any clone path.

  • .gitignore: patterns for per-arch version*.res, meson wraplock files, and the per-script log files that the helper scripts write.

Reviewer notes

  • The vendored ext patches in section 3 are the only place real behaviour potentially shifts. The intent is no runtime change — every cast is value-preserving, and OldCreateOrder=True is what Delphi 11 already does by default. But that's the spot most worth a second pair of eyes.
  • The helper scripts intentionally live under windows/scripts/ (not at repo root) to match the existing component-local-helpers convention.
  • The engine.groupproj fix is independent of the Delphi-12 work and helps any IDE-driven build — it was just discovered while doing this.
  • Untouched on purpose: the compiler stack (kmcmplib, kmc-*, developer/src/kmc-*, Keyman Core). Those are already Delphi-free per chore(windows): Deprecate use of Delphi #4599 progress and shouldn't be in this PR's blast radius.

User Testing

User testing not required: build-environment / docs change with no runtime behaviour modification. CI will exercise the 10.3 default path; CE flow is manually validated via the steps in docs/build/windows-d12.md.

Relates-to

Relates-to: #4599

…orkflow

Delphi Community Edition (10.4 and 12) does not allow command-line
compilation -- only the Delphi IDE can drive dcc32. This blocks the
repo's build.sh chain for any Keyman component that requires Delphi,
which means contributors without a paid Delphi Professional license
cannot build Engine, Desktop, or Developer from CLI. Community Edition
is currently the only free way to do Keyman Windows development.

This commit captures a working Delphi-IDE-based workflow for Delphi 12
CE, plus source patches that bring Delphi 11/12 compatibility to the
existing tree without breaking Delphi 10.3.

The changes here target the still-Delphi UI/engine layer (TIKE,
kmshell, the engine COM/TSF plumbing). The compiler stack (kmcmplib,
kmc-*, Keyman Core) is already Delphi-free and is not touched.

Context: keymanapp#4599 (filed 2022) tracks the ongoing work to
remove Delphi dependencies. Until that migration completes, this branch
provides a bridge for contributors building locally on the free Delphi
tier.

CI safety: with KEYMAN_DELPHI_VERSION unset, all build-script defaults
match the current Delphi 10.3 CI behavior. All Keyman-owned source
patches are additive -- they introduce VER350/VER360 (Delphi 11/12)
IFDEF cases without altering the VER330 (10.3) paths, or add explicit
casts that the older compiler would have applied implicitly.

Build scripts:
* resources/build/win/{configure,delphi}_environment.inc.sh: make
  DELPHI_VERSION configurable via the KEYMAN_DELPHI_VERSION env var,
  defaulting to 20.0 (existing 10.3 behavior preserved).
* windows/src/engine/engine.groupproj: drop the inst\insthelper
  reference. The path doesn't resolve (insthelper.dproj lives at
  windows/src/engine/insthelper, not .../inst/insthelper); IDE
  "Build All" was failing on it. build.sh-based builds were
  unaffected.
* .gitignore: add patterns for per-arch version*.res, meson
  wraplock files, and dev-workflow local artifacts.

Docs:
* docs/build/windows.md: one-line pointer to windows-d12.md from the
  "Delphi 10.3 Community no longer available" warning, so future CE
  users find the workaround instead of dead-ending.
* docs/build/windows-d12.md: full IDE-workflow guide -- prerequisites,
  library Search Path registry setup, source patches, build order
  (including chicken-and-egg patterns), install-and-overlay run
  workflow, debugging, troubleshooting catalog, and an upstreaming
  guide for which patches are safe to PR back.

Helper scripts under windows/scripts/:
* preflight-resources.ps1: generates manifest.xml and .res files per
  Delphi project, equivalent to build.sh's rc-step.
* run-codegen.ps1: runs devtools and build_standards_data codegen
  subcommands plus the tsysinfox64 -> .bin -> tsysinfo_x64.res
  chicken-and-egg.
* install-build-env.ps1: one-time toolchain installer (Chocolatey, VS
  2022, nvm/node, Emscripten, release tools).
* overlay-dev-builds.ps1: copies dev binaries onto an installed
  Keyman 19, equivalent to what `build.sh install` would do. All
  four scripts auto-detect the repo root via $PSScriptRoot and honor
  $env:KEYMAN_ROOT as an override.

Delphi 11/12 source compat (Keyman-owned, additive on 10.3):
* common/windows/delphi/tools/devtools/SourceRootPath.pas: add VER350
  ('22.0') and VER360 ('23.0') cases to DelphiMajorVersion.
* common/windows/delphi/web/Keyman.System.HttpServer.Base.pas: extend
  the VER330 tripwire to accept VER340/VER350/VER360.
* common/windows/delphi/components/FixedTrackbar.pas: extend the
  nested IFNDEF tripwire similarly.
* common/windows/delphi/general/CleartypeDrawCharacter.pas: use
  integer-return comparison for EnumFontFamiliesEx on
  VER340/VER350/VER360 (was VER340 only; RTL return type changed
  in 10.4+).
* common/windows/delphi/general/JsonUtil.pas: pass `[]` options arg
  to TJSONAncestor.ToChars on VER350/VER360 (Delphi 11+ added a
  required Options parameter).

Vendored third-party patches (refresh from upstream when those
projects ship Delphi 12-compatible releases). Each hunk is annotated
with a "Keyman local patch" comment.
* developer/src/ext/jedi/jcl/jcl/source/common/JclSynch.pas: add
  explicit BOOL() casts to Win32-API Boolean arguments (Delphi 12
  tightened implicit Boolean->BOOL conversion at call sites); switch
  JclWin32.CreateMutex to Winapi.Windows.CreateMutex to match the
  file's existing pattern and avoid 12's unit-resolution ambiguity.
* developer/src/ext/jedi/jvcl/jvcl/run/JvComponent.pas: skip the
  OldCreateOrder property check on VER350/VER360 (Embarcadero
  removed the property in Delphi 11; modern behavior is equivalent
  to OldCreateOrder=True).
* developer/src/ext/mbcolor/mxs.inc: add VER350/VER360 cases that
  set DELPHI_5_UP through DELPHI_10_UP. Without this, HTMLColors.pas
  silently drops `Variants` from its uses clause and breaks with
  "Undeclared identifier: 'null'".

Relates-to: keymanapp#4599

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-project-automation github-project-automation Bot moved this to Todo in Keyman May 29, 2026
@keymanapp-test-bot keymanapp-test-bot Bot added has-user-test user-test-missing User tests have not yet been defined for the PR labels May 29, 2026
@keymanapp-test-bot
Copy link
Copy Markdown

User Test Results

Test specification and instructions

ERROR: user tests have not yet been defined

@keymanapp-test-bot keymanapp-test-bot Bot added this to the A19S30 milestone May 29, 2026
@keyman-server
Copy link
Copy Markdown
Collaborator

This pull request is from an external repo and will not automatically be built. The build must still be passed before it can be merged. Ask one of the team members to make a manual build of this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

has-user-test user-test-missing User tests have not yet been defined for the PR

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants