PCL — compile-time widgetset selection + sparse-matrix hard-fail
- Type: feature (Track B —
lib/pcl+ a small compiler CLI/define touch). Gate =make lib-testgreen; the default (gtk3/linux) unchanged. - Status: done [[feature-pcl-seam-seal]] (so there's a real seam to select against), but the CLI + matrix scaffolding can land alongside.
- Owner: trackB-agent
- Opened: 2026-07-21, GUI-scope session.
Problem
Widgetset is hardwired: lib/pcl/interfaces.pas:6 does uses gtk3widgets
unconditionally. There is no --widgetset, no OS×widgetset matrix, and nothing stops a
nonsensical combination — it would just fail deep in the build with a confusing error.
LCL solved this: -ws gtk3 selects the widgetset at compile time, baked into the
one binary (matches pxx's zero-dep, no-runtime-plugin identity). Copy that.
Shape
-
--widgetset=<gtk3|win32|...>selects the backend; drives which widgetset unitinterfaces.paspulls in (via a define the compiler sets, e.g.WIDGETSET_GTK3). Default =gtk3(today's behaviour, unchanged). -
Sparse matrix, enforced at compile time. A small table of supported (widgetset × target-OS) cells; an unsupported/untested cell is a hard compile error with a reason, never a silent broken build:
--widgetset=qt --target=x86_64-windows → error: widgetset 'qt' not supported/tested on target 'windows' (no bundled Qt DLLs). supported on 'windows': win32. --widgetset=gtk3 --target=x86_64-windows → error: gtk3 on windows means a 30-40 MB DLL bundle; refused by design. use --widgetset=win32. -
Starting matrix (grows by adding a table row, not rewiring):
widgetset linux windows gtk3 ✅ ❌ refuse (DLL swarm) win32 ❌ n/a ⚠️ best-effort (see [[feature-pcl-win32-widgetset]]) qt 🔜 future ❌ not delivered
Acceptance
--widgetset=gtk3(or omitted) on linux = today's build, byte-unchanged;make lib-test/demosgreen.- Every unsupported cell above fails at compile time with the shown reason.
- Adding a future widgetset = one matrix row + one
TWidgetSetsubclass, no changes to the selection machinery.
Note
The compiler touch is tiny (parse --widgetset, set a define, thread it to the OS×ws
guard). If that guard is cleaner as a Track A CLI addition, file the CLI slice as a
small Track A ticket per lane rules; the lib/pcl side stays Track B.
RESOLVED 2026-07-31 — selection + the matrix, with no compiler change at all
lib/pcl/interfaces.pas was uses uwidgetset, gtk3widgets; and nothing else.
It is now the single place that decides the backend, and it needed no compiler
touch: an ordinary define does the whole job.
pxx -dWIDGETSET_GTK3 ... # also the default when none is given
pxx -dWIDGETSET_WIN32 ... # refused, by name, at compile time
The matrix is a table in one file
Each cell asserts itself before its backend is pulled in, so an unsupported combination is a HARD COMPILE ERROR naming the reason — never a silent build that dies in the linker or at run time. Measured, not asserted:
$ pxx -dWIDGETSET_WIN32 ... test_pcl_widgets.pas
pascal26:32: error: widgetset win32 exists only on windows. On this target use -dWIDGETSET_GTK3.
$ pxx -dWIDGETSET_QT ... test_pcl_widgets.pas
pascal26:32: error: widgetset qt is not delivered yet. Supported today: gtk3 on linux.
and gtk3-on-windows carries the refusal this ticket asked for — the 30-40 MB DLL bundle, refused by design rather than by omission.
Acceptance, checked
-dWIDGETSET_GTK3and no flag produce a byte-identical binary (cmp, in the suite — not just "both compiled").- Every unsupported cell fails at compile time with a reason that names the widgetset.
- Adding a widgetset is one arm here plus one
TWidgetSetsubclass. That is only true because [[feature-pcl-seam-seal]] landed first — before it, a new backend could not have implemented all of PCL no matter how it was selected.
Asserted in tools/gui_suite.sh as widgetset selection + matrix, ahead of the
per-widget tests, and the whole suite is otherwise unchanged.
Filed rather than done here
--widgetset=<name>, the Lazarus-style spelling, is pure CLI sugar over the
define and is the only part that needs a compiler change — filed as
[[feature-cli-widgetset-flag]] (Track A) per this ticket's own note. Keeping the
matrix out of the compiler is deliberate: teaching the compiler about widgetsets
would put half the rule in the wrong layer and break the one-arm property.
Log
- 2026-07-31 — resolved, commit ffb8794a7.