keymanapp / keymanapp/keyman

chore(windows): batch CE mode — pre-builds first, one CE prompt per group

Open
#16,193 0 comments 0 reactions 0 assignees View on GitHub
chore windows/
Dominant language
Pascal
Stars
534
Forks
143
Avg merge
2d 10h
Merged PRs (30d)
113

Description

## Problem

Under Delphi 12 CE (see [#16044](https://github.com/keymanapp/keyman/pull/16044)), each Delphi `.dproj` fires its own CE prompt in the `build.sh` chain. On a warm tree, [#16044](https://github.com/keymanapp/keyman/pull/16044)'s smart-skip in `delphi_msbuild` lets contributors do a single Build All on the parent `.groupproj` and press Enter through each auto-skipped prompt — clean.

**On a fresh clone or after `git clean -fdx`**, the smart-skip can't help. Each project's own pre-build (rc.exe on `version.rc` / `manifest.rc`, custom `.tlb` / `.res` generation) has to run before its `.dproj` can compile, and today those pre-builds are interleaved with individual CE prompts. Result: ~15-20 CE prompts to build the engine+desktop+developer chain from cold.

If the pre-builds and Delphi-tool bootstraps happened in phases, cold-state builds could reach ~9 CE prompts — a ~50% reduction. Not urgent (warm iteration is the common case), but worth capturing for a future onboarding-friction pass.

## Proposed flow (fresh-clone batch mode)

**Stage 1 — Bootstrap Delphi tools + BPLs (~6 CE prompts, unavoidable):**
- `common/windows/delphi/tools/devtools/devtools.dproj` → `devtools.exe`
- `common/windows/delphi/tools/build_standards_data/build_standards_data.dproj` → `build_standards_data.exe`
- `windows/src/global/delphi/keyman_components.dproj` → `keyman_components.bpl`
- `common/windows/delphi/components/common_components.dproj` → `common_components.bpl`
- `common/windows/delphi/ext/cef4delphi/packages/CEF4Delphi.dproj` → `CEF4Delphi.bpl`
- `windows/src/engine/tsysinfox64/tsysinfox64.dproj` (Win64) → `tsysinfox64.exe`

**Stage 2 — Pure shell codegen (0 CE prompts):**
- `devtools -buildmessageconstants` → `MessageIdentifierConsts.pas`
- `devtools -buildsetupstrings` → ~32 `Keyman.Setup.System.Locale.*.pas`
- `build_standards_data` runs → 5 BCP-47 registry `.pas`
- `tsysinfox64.exe → tsysinfox64.bin` + `rc /nologo tsysinfo_x64.rc` → `tsysinfo_x64.res`
- Per-project `rc.exe` for `version.res` / `manifest.res`
- `kmcomapi`: `rc kbd_noicon.rc` + `gentlb -Tkmcomapi.tlb kmcomapi.ridl`

**Stage 3 — Three group Build Alls (~3 CE prompts):**
- `engine.groupproj` Build All (needs [#16192](https://github.com/keymanapp/keyman/issues/16192) reorder + PreBuildEvent to succeed cleanly)
- `desktop.groupproj` Build All
- `developer.groupproj` Build All

**Stage 4 — Pure shell post-build (0 CE prompts):**
- `sentrytool_delphiprep`, `tds2dbg`, staging `cp` per project

Total: ~9 CE prompts vs. today's ~15-20.

## Implementation sketch

- New env-var mode: `KEYMAN_DELPHI_CE_BATCH=1`. Off by default (preserves current per-project flow, which is the right choice for iterating on a single project).
- Every Delphi-using `build.sh do_build()` refactored into three named steps: `do_pre_build()` / `do_delphi_build()` / `do_post_build()`. Under batch mode the parent `build.sh` fans out `pre_build` across all children, then a single `delphi-build-group:project` action per subsystem, then `post_build` across all children.
- The existing smart-skip in `delphi_msbuild` already handles the "output already fresh" case — batch mode just adds the orchestration to make Stage 3's Build All happen while every downstream `delphi_msbuild` call auto-skips.

## Scope

- Touches every `build.sh` in `common/windows/delphi/**` and `windows/src/**` that currently calls `delphi_msbuild` — probably ~15-20 files.
- New action registrations in the builder framework.
- Doc update in `docs/build/windows-delphi-ce.md`.

Non-trivial review surface. Deferred until #16044, #16043, #16191, and #16192 have all merged, so the delta can build on a stable foundation.

## Not-doing-now rationale

1. Warm-state iteration already fast via #16044's smart-skip.
2. Fresh-clone frequency is low; contributors clone once and iterate.
3. Adding this to #16044 would balloon the PR beyond its current scope.
4. #16192 is the smaller adjacent fix (reorder + PreBuildEvent) that also improves the warm-state Build All story — ship that first.

## Context

Surfaced during the CE workflow walkthrough for #16044 while thinking through whether Build All on a `.groupproj` could subsume the per-project CE prompts. Answer today: only in warm state, per this issue's rationale.

Related: [#4599](https://github.com/keymanapp/keyman/issues/4599), [#16192](https://github.com/keymanapp/keyman/issues/16192).

Contributor guide

Open the contributing guide

Research direction

Start with the Delphi-using build.sh files under common/windows/delphi/** and windows/src/**, especially their do_build() flow and delphi_msbuild; read docs/build/windows-delphi-ce.md for the current workflow. Reproduce a cold build with a fresh clone or git clean -fdx, then assess the staged pre-build, group-build, and post-build actions. Done means batch mode is opt-in, the three group builds complete, and the documented prompt reduction is achieved.

Written by the indexing model from the issue text.

Assessment

Tech stack
shell
Domain
build-system
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.