← board

GTK version selection at the header and soname layer

Follows decided/decide-which-gtk-a-bare-gtk-gtk-h-means (GTK 3 is now the default). This is the selectable half the owner asked for: "if we (easily) can, gtk 2/3/4 should actually be user selectable, defaulting to 3.. but maybe this creates a library hell."

It does not create library hell at this layer, which is why it is worth doing. It would at the widgetset layer, which is why that is excluded.

In scope

A single version selector — flag or directive — driving the four sites the parent ticket enumerates. Default 3.

Explicitly OUT of scope, and say so in the docs

The PCL widget layer stays GTK 3 only. Selecting 2 or 4 gives a C program the right headers and the right DT_NEEDED; it does not port gtk3widgets.pas.

Naming, from the parent ruling

gtk and gtk3 are not parallel names today — the first two are alias-map entries, gtk3 is a Pascal unit file (lib/pcl/gtk3.pas). Whoever builds the selector should settle that, or the version flag inherits the same confusion.

Blocked in practice for GTK 4

No /usr/include/gtk-4.0 on plexus. libgtk-4-dev is needed before the 4 arm is testable at all — until then, build and test the 2 and 3 arms and refuse 4 with a diagnostic that says why.

2026-09-05 (frankC) — DONE: --gtk=2|3|4, default 3

The resolver half, which is all this ticket ever scoped. CGtkVersion in defs.inc drives two functions and nothing else reads a GTK literal:

They come from one variable ON PURPOSE. Headers and soname disagreeing — GTK 3 headers against a GTK 2 library — is the hazard the parent ruling names, and it is exactly what doing half the change produces. Deriving both from CGtkVersion makes the mismatch unrepresentable rather than merely avoided.

Measured

soname runs
default (no flag) libgtk-3.so.0 yes
--gtk=3 libgtk-3.so.0 yes
--gtk=2 libgtk-x11-2.0.so.0 yes — real window, gtk_main loop
--gtk=4 refuses, naming libgtk-4-dev

The GTK 2 run is the load-bearing row. A soname assertion alone cannot tell a coherent pick from a mismatched one — headers and library disagreeing links fine and dies at run time — so the test asserts the pair.

GTK 4 is PROBED, not hardcoded unavailable

This ticket said to "refuse 4 with a diagnostic that says why" until libgtk-4-dev lands. Implemented as a filesystem probe of /usr/include/gtk-4.0 rather than a literal refusal, because a hardcoded "4 is unsupported" stays wrong after somebody installs the package — the same defect as the hardcoded gcc include version this file's neighbours were fixed for, a fallback that expires silently. The row flips to a build on its own when the headers appear.

The diagnostic names the package and the missing directory, and --gtk=9 still answers unknown option — asserted, because "the flag failed" and "the flag is not recognised" must not read alike.

gtk3_c follows the selector, despite the 3 in its name

The C include list is flat and global — there is no per-unit search path — so one compilation has exactly one GTK's headers. Pinning gtk3_c to GTK 3 while --gtk=2 moved the root would hand it GTK 2 headers against libgtk-3.so.0, which is the mismatch this feature exists to prevent. The flag wins and the halves stay coherent. The naming remains the wart the parent ruling records (gtk/gtk3_c are C aliases, gtk3 is a Pascal unit).

test/gtk3stock/gtk3_c.h's own #error guard catches the combination and refuses loudly — verified. Its advice was stale after the default flip ("pass -I for the gtk-3.0 root") and now says to drop --gtk=2 instead.

Still explicitly OUT of scope, and unchanged

The widgetset half. gtk3.pas, gtk3widgets.pas and gtk3gl.pas bind GTK 3 specifically and GTK 4 reshaped the container, event and drawing models. Selecting 2 or 4 buys the right headers and the right DT_NEEDED; it does not port the PCL widget layer. Verified unchanged: the PCL stack still builds and links libgtk-3.so.0 at the default.

One wart recorded rather than silently reintroduced

GTK 2 alone needs a second, arch-specific root (/usr/lib/<triplet>/gtk-2.0/include/) because its gdkconfig.h lives there; GTK 3 and 4 keep theirs inside /usr/include/gtk-N.0/gdk/. The triplet is spelled literally, which is the pre-existing wart it shares with its neighbours (glib's arch root, /usr/include/<triplet>/, the gcc dirs) — wrong on every non-x86-64 host for all of them at once, so it is one job across the block, not a special case here. The GTK 3 default reaches no literal triplet at all.

Gate

gate.sh quick GREEN 17/17 including the FPC seed canary, run with compiler/** uncommitted. Fixedpoint 546ec0cf30a3.

Log