chore(windows): support Delphi 11/12 compilation + Delphi 12 CE dev workflow#16039
chore(windows): support Delphi 11/12 compilation + Delphi 12 CE dev workflow#16039MattGyverLee wants to merge 4 commits into
Conversation
Add a dev-docs/ folder with five files aimed at two audiences: * External tool builders -- AI extensions for keyboard authoring or submission triage, lint bots, instrumented test rigs, etc., lodged in other repos and consuming Keyman's formats and CLI/library surface. Read keyboard-anatomy.md and external-tooling.md. * Keyman contributors -- read repository-map.md for the architecture and migration-guide.md for what's old, what's new, and what's still in flight. The migration story covers the Delphi removal (umbrella issue keymanapp#4599), LDML keyboards including the still-open touch read side (keymanapp#7238 / epic-ldml), the LDML visual editor scaffolding (keymanapp#12798 / epic-ldml-editor), and KeymanWeb's Core-via-WASM model. Files: * dev-docs/README.md -- entry point that routes the two audiences and surfaces the LDML-first generation strategy. * dev-docs/repository-map.md -- architecture tour with 5 Mermaid diagrams (top-level layout, four-subsystems graph, keystroke sequence, keyboard build flow, build orchestration), tech-stack table, cross-platform matrix. * dev-docs/migration-guide.md -- Delphi removal scorecard, LDML layer-by-layer gap analysis, KeymanWeb modernization, links to the March 2026 roadmap and the relevant epic-* issue labels. * dev-docs/keyboard-anatomy.md -- file-format reference for a Keyman keyboard project (.kpj, .kmn, LDML XML, .kvks, .keyboard_info, .kps, .kmp, .kmx, .kmx+), with schema locations. * dev-docs/external-tooling.md -- operational guide for tools that drive Keyman from outside: kmc CLI, @keymanapp/kmc-* npm packages, schema-based validation, cross-file consistency contract, 9-point triage checklist for keyboard submissions, and the approach for instrumented forks of kmc-* / Keyman Core for desktop-vs-touch comparison work. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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 branch 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 by any of these patches. Context: keymanapp#4599 (filed 2022) tracks the ongoing work to remove Delphi dependencies from Keyman. 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 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. Scripts: * scripts/preflight-resources.ps1: generates manifest.xml and .res files per Delphi project, equivalent to build.sh's rc-step. * scripts/run-codegen.ps1: runs devtools and build_standards_data codegen subcommands plus the tsysinfox64 -> .bin -> tsysinfo_x64.res chicken-and-egg. * scripts/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 (local-only; 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'". Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User Test ResultsTest specification and instructions ERROR: user tests have not yet been defined |
|
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. |
|
Thank you for this contribution. A couple of thoughts:
|
I'm happy you're considering adding it to the repo. :) I'll have to think on this. Implementing this in build.sh wasn't my expectation since the powershell scripts are a workaround to not being able to automate the Delphi parts of the build.sh. Nevetheless, gating this new code by Delphi version and making it interactive (Please build XX.dproj manually in the IDE now.) should work.
Makes perfect sense. |
|
Duh... The 12 upgrades would allow you to upgrade the build server and any paid desktop licenses (which you probably have) in the future. The CE workarounds are just for us cheapskates. Makes perfect sense. I'll see what I can do. |
Yes; we could do the same thing in .sh scripts, and I'd prefer that so there's only one set of instructions needed with minor tweaks for CE. When using CE, building the .groupproj files reduces the manual steps by making only 4 builds I think (there are 7 .groupproj files but only engine, desktop, developer are needed, plus building and installing the design time components, which is currently fragile anyway 😢), so could think about that? |
…nteractive mode Marc's review feedback on keymanapp#16039: PowerShell scripts add maintenance burden and drift from the existing shell-script build chain. Implement the agreed alternative: gate Delphi CE support by version in delphi_msbuild, make it interactive. Changes: - resources/build/win/environment.inc.sh: delphi_msbuild now checks KEYMAN_DELPHI_CE=1; when set, prints an IDE-build prompt and waits for Enter instead of invoking msbuild.exe. Pre-build (rc.exe) and post-build (binary copy, codegen) steps in build.sh run normally around the prompt. - Remove scripts/install-build-env.ps1, scripts/preflight-resources.ps1, scripts/run-codegen.ps1, overlay-dev-builds.ps1. - docs/build/windows-d12.md: rewrite sections 3.1 and 5 to document the shell-based workflow (KEYMAN_DELPHI_CE=1 + build.sh); update canonical build order, running, and troubleshooting sections accordingly. https://claude.ai/code/session_01EqVM8WwyS53pniVUHrBnmR
…tection
builder_describe_platform's delphi-tool check was hardcoded to Studio\20.0,
so machines with only Delphi 12 (23.0) installed had all win,delphi-gated
targets silently skipped even when KEYMAN_DELPHI_VERSION=23.0 was set.
Update the detection to use ${KEYMAN_DELPHI_VERSION:-20.0}, matching the
same default used in configure_environment.inc.sh and delphi_environment.inc.sh.
CI (unset) continues to check for 20.0 unchanged; Delphi 12 Professional users
set KEYMAN_DELPHI_VERSION=23.0 and the full win,delphi build graph is enabled.
CE users additionally set KEYMAN_DELPHI_CE=1 for interactive delphi_msbuild.
Update windows-d12.md section 3.1 to document both Professional and CE cases.
https://claude.ai/code/session_01EqVM8WwyS53pniVUHrBnmR
|
Closing per @mcdurdin's review — split into two PRs:
The PowerShell helper scripts that prompted the original feedback are gone in #16044; the CE workflow now runs through |
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_VERSIONunset, every build script keeps using Delphi 10.3 (BDS 20.0) exactly as before. Every Keyman-owned source change is an additiveVER350/VER360IFDEF arm; the existingVER330paths 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
dcc32CLI thatbuild.shdrives, 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)
resources/build/win/configure_environment.inc.shanddelphi_environment.inc.sh—DELPHI_VERSIONnow reads${KEYMAN_DELPHI_VERSION:-20.0}. Default unchanged. CI doesn't set the var; nothing about the canonical 10.3 flow changes.2. Delphi 11/12 source compat in Keyman-owned code
Five files under
common/windows/delphi/. Every change is additive IFDEF arms forVER350/VER360; theVER330(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.tools/devtools/SourceRootPath.pas'22.0'/'23.0'DelphiMajorVersionneeds to know about the new BDS install dirsweb/Keyman.System.HttpServer.Base.pasIFNDEF VER330tripwire to also accept VER340/350/360components/FixedTrackbar.pasgeneral/CleartypeDrawCharacter.pasEnumFontFamiliesExinteger-return comparison on VER340/350/360 (was VER340-only)general/JsonUtil.pas[]options arg toTJSONAncestor.ToCharson VER350/360Plus
windows/src/engine/engine.groupproj: drop theinst\insthelperreference. The path doesn't resolve —insthelper.dprojlives atwindows/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)
developer/src/ext/. Each hunk is annotated with a// Keyman local patchcomment plus a refresh strategy noting the upstream package and what to re-apply when those projects ship Delphi 12-compatible releases.jedi/jcl/jcl/source/common/JclSynch.pasBooleanargs toCreateEvent/OpenEvent/CreateWaitableTimer/OpenWaitableTimer/OpenSemaphore/CreateMutex/OpenMutexin explicitBOOL(); switchJclWin32.CreateMutex→Winapi.Windows.CreateMutexBOOL()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 callsjedi/jvcl/jvcl/run/JvComponent.pasDoCreateOldCreateOrderproperty in Delphi 11; the modern default is equivalent toOldCreateOrder=Truembcolor/mxs.incDELPHI_5_UP…DELPHI_10_UPHTMLColors.passilently dropsVariantsfrom itsusesclause 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 towindows-d12.mdfrom 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 thetsysinfox64 → .bin → tsysinfo_x64.reschicken-and-egg), install-and-overlay workflow, debugging, troubleshooting catalog, and a section labeling which patches are safe to upstream.windows/scripts/preflight-resources.ps1— runsrc.exeover every.rc, generatesmanifest.xmlfrommanifest.in. Equivalent ofbuild.sh's_prebuild_resourcesphase.windows/scripts/run-codegen.ps1— drivesdevtools.exe+build_standards_data.exeplus thetsysinfox64chicken-and-egg.windows/scripts/overlay-dev-builds.ps1— copies dev binaries onto an installed Keyman 19 (equivalent ofbuild.sh install; needed becauseTKeymanPaths.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 fromwindows/scripts/) and honor$env:KEYMAN_ROOTas an override, so they work from any clone path..gitignore: patterns for per-archversion*.res, mesonwraplockfiles, and the per-script log files that the helper scripts write.Reviewer notes
OldCreateOrder=Trueis what Delphi 11 already does by default. But that's the spot most worth a second pair of eyes.windows/scripts/(not at repo root) to match the existing component-local-helpers convention.engine.groupprojfix is independent of the Delphi-12 work and helps any IDE-driven build — it was just discovered while doing this.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