Skip to content

feat: wlroots 0.20.2, and the two packages the pango line was waiting on - #318

Merged
Sunrisepeak merged 6 commits into
mainfrom
feat/wlroots-pcre2-fribidi
Aug 30, 2026
Merged

feat: wlroots 0.20.2, and the two packages the pango line was waiting on#318
Sunrisepeak merged 6 commits into
mainfrom
feat/wlroots-pcre2-fribidi

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

The compositor gate is open. Everything wlroots needs was already in this index — wayland-server/client/protocols/scanner/egl, libdrm, pixman, xkbcommon, libinput, libudev, libseat, egl, glesv2, gbm, libdisplay-info. This is the package that spends them.

package version shape
wlroots.wlroots 0.20.2 fork — six generators in build.mcpp, no sh, no python
compat.pcre2 10.44 descriptor — glib's GRegex is written against it
compat.fribidi 1.0.16 descriptor — the bidi algorithm pango needs for RTL text

Why two are descriptors and one is a fork

The criterion is generators, not line count. pcre2 is 133k lines and needs no fork: the release tarball ships pcre2.h.generic, config.h.generic and pcre2_chartables.c.dist precisely so a build without autotools is possible. fribidi generates seven UCD tables with eight C programs — and ships the output, verified one for one against the seven #include "*.tab.i" in its sources.

wlroots has six generators and ships none of their output.

⚠️ import wlroots; is not a convenience — it is the only way in

wlroots' 121 public headers contain no extern "C", and two of them are not valid C++ at all:

void wlr_scene_rect_set_color(struct wlr_scene_rect *rect,
                              const float color[static 4]);   /* C99 only */

g++ says expected primary-expression before 'static', and then — the parse never recovering — reports every later declaration as "has not been declared", which sends you hunting for missing feature guards. Three struct members are also named namespace, delete and class.

The fork writes C++-safe copies: [static N][N], keyword members given an #ifdef __cplusplus spelling at the same offset with the #else arm upstream verbatim. Same layout, same ABI, one spelling per language.

What the tests assert

Each check names a specific decision, so a failure says which one broke rather than "the package is broken":

  • wlrootsWLR_HAS_* is exactly the default set; wlr_box_intersection computes 60,20 40x30; wlr_scene_rect_set_color is callable (the rewritten [static 4]); namespace_ is reachable from C++; the pinned pnp.ids resolves ACR→Acer and DEL→Dell, and "JJJ" returns NULL. Not an arbitrary byte triple — PNP_ID keeps the low five bits of each character, so "\x01\x02\x03" packs to the same key as "ABC" and returns AboCom System Inc.
  • pcre2\p{Han} and \X prove SUPPORT_UNICODE; . matching one code point with PCRE2_UTF and one byte without proves UTF-8 mode; and byte 0xE9 not being alphabetic proves the C-locale character tables, i.e. that the build did not run pcre2_dftables against a machine locale.
  • fribidi — three different bidi types from one table; a Hebrew run placed first and reversed in an RTL paragraph; ( mirroring to ) while a mirrors to nothing; ALEF right-joining and BEH dual-joining.

The wayland-protocols example moves to 1.49.1 and static_asserts on the enum headers that release added.

Verification

Both toolchains, clean trees. wlroots' own CI is green on both legs (run); the fork release and all three CN mirrors are published.

THE COMPOSITOR GATE IS OPEN. Everything wlroots needs was already here —
wayland-server/client/protocols/scanner/egl, libdrm, pixman, xkbcommon,
libinput, libudev, libseat, egl, glesv2, gbm, libdisplay-info — and this is the
package that spends them.

  wlroots.wlroots  0.20.2   fork, six generators in build.mcpp, no sh, no python
  compat.pcre2     10.44    glib's GRegex is written against it
  compat.fribidi   1.0.16   the bidi algorithm pango needs for RTL text

WHY TWO OF THE THREE ARE DESCRIPTORS AND ONE IS A FORK

The criterion is generators, not line count. pcre2 is 133k lines and needs no
fork: the release tarball ships pcre2.h.generic, config.h.generic and
pcre2_chartables.c.dist precisely so a build without autotools is possible.
fribidi generates seven UCD tables with eight C programs — and ships the output,
verified one for one against the seven `#include "*.tab.i"` in its sources.

wlroots has six generators and ships none of their output.

⚠️ import wlroots; IS NOT A CONVENIENCE

wlroots' 121 public headers contain no `extern "C"`, and two are not valid C++
at all: five declarations use C99 `const float color[static 4]`, and three
struct members are named `namespace`, `delete` and `class`. A C++ consumer
cannot include them under any arrangement of `extern "C"`. The fork writes
C++-safe copies — `[static N]` reduced to `[N]`, keyword members given an
`#ifdef __cplusplus` spelling at the same offset with the `#else` arm upstream
verbatim — and the module wraps the lot.

WHAT THE TESTS ASSERT, AND WHY NOT "IT LINKED"

Each check names a specific decision, so a failure says which one broke:

  wlroots   WLR_HAS_* is exactly the default set; wlr_box_intersection computes
            60,20 40x30; wlr_scene_rect_set_color is callable (the rewritten
            [static 4]); namespace_ is reachable from C++; the PINNED pnp.ids
            resolves ACR to Acer and DEL to Dell — and "JJJ", whose 15-bit key
            no entry occupies, returns NULL. Not an arbitrary byte triple:
            PNP_ID keeps the low five bits of each character, so "\x01\x02\x03"
            packs to the same key as "ABC" and returns AboCom System Inc.

  pcre2     \p{Han} and \X prove SUPPORT_UNICODE; `.` matching one code point
            with PCRE2_UTF and one byte without proves UTF-8 mode; and byte
            0xE9 NOT being alphabetic proves the C-locale character tables, i.e.
            that the build did not run pcre2_dftables against a machine locale.

  fribidi   three different bidi types from one table; a Hebrew run placed first
            and reversed in an RTL paragraph; "(" mirroring to ")" while "a"
            mirrors to nothing; ALEF right-joining and BEH dual-joining.

Also: the wayland-protocols example moves to 1.49.1 and now static_asserts on
the enum headers that release added.

Verified on both toolchains from clean trees. wlroots' own CI is green on both
legs; its fork release and all three CN mirrors are published.
CI on this PR failed with

  wlr_layer_shell_v1.h:73: use of enum
  'zwlr_layer_surface_v1_keyboard_interactivity' without previous declaration

from a build that passed locally. The shim that renames the `namespace`
argument — layer-shell is the only one of 133 generated protocol headers that
is not valid C++ — reached the scanner's real output with `#include_next`, and
that is an include which can SUCCEED and deliver the wrong file. A missing file
would have said so.

The fork now names the file by absolute path (mcpplibs/wlroots, CI green on
both toolchains) and 0.20.2 is re-cut. Safe here and only here: the descriptor
had never been published, so nothing in the world had extracted it.

CN URL moves to the `0.20.2-1` container: gitcode refuses to replace an asset
of the same name in an existing release, so the corrected bytes needed a new
one. Verified — its sha256 equals the GLOBAL tarball's.
The previous tarball still put wayland-scanner's headers in the build
program's out dir, which is appended AFTER every dependency's include
directory. In CI — never locally, across four differently-cleaned trees, both
mcpp releases and both standalone and workspace invocations — that produced

  wlr_output_power_management_v1.h:39: use of enum
  'zwlr_output_power_v1_mode' without previous declaration

from a header that includes its protocol header on line 5. An include that
SUCCEEDED and delivered the wrong file: the failure a search path can have.

Every generated header now goes to the directory the manifest names FIRST,
which is where config.h already was and for the same reason. Fork CI green on
both toolchains.

CN container moves to 0.20.2-2: gitcode will not replace an asset of the same
name, so each corrected tarball needs a new container. Only the last is
referenced.
Four CI rounds, one cause, never reproducible locally:

  wlr_layer_shell_v1.h:73: use of enum
  'zwlr_layer_surface_v1_keyboard_interactivity' without previous declaration

`mcpp::action` schedules a generated .c before the compile that needs it,
because mcpp fixes the source set during prepare. It cannot do the same for a
HEADER: nothing declares a dependency on one, and the MODULE INTERFACE UNIT is
compiled first since every other TU needs its BMI. So the module was compiled
against files the action had created and not yet filled — an include that
SUCCEEDED and delivered nothing. A missing file says so; this never did, which
is finally what identified it.

wayland-scanner now runs inside build.mcpp via posix_spawn (no shell), so every
generated header exists before any compiler starts, and each invocation is
checked for spawn, exit status AND a non-empty output. Fork CI green on both
toolchains; verified here against the published tarball with every store
cleared.

Also adds §19 to the design doc: the compositor gate, the GObject stack, the
four 'include succeeded and gave the wrong file' failures, and the measured
boundary of what is left (gdbus-codegen, 8351 lines, blocking gio and
therefore pango).
They cannot be verified in THIS PR, and the reason is structural rather than a
missing step: gnome.glib depends on compat.pcre2, which this PR is what
publishes. An example redirects ONE namespace at a package's index — mcpp
registers at most one project index repo — so `gnome` points at this
checkout and `compat.pcre2` is looked up in the published index, where it does
not exist yet.

wlroots now passes here (all twelve assertions, including the pinned pnp.ids
resolving ACR to Acer), so this PR is complete on its own. glib, gobject and
gmodule 2.82.5 are built, tested on both toolchains, released and mirrored;
their descriptors and examples land as soon as compat.pcre2 is on the index.
macOS and Windows failed while both Linux legs passed, and the cause was in
this PR rather than in any package: the 1.49.1 enum-header includes were
appended at the END of the file, past the `#endif` that closes
`#ifdef __linux__`. So they compiled on platforms where the dependency is
never fetched — the example gates it with `cfg(linux)` — and the scan failed
before anything was built.

Appending to a file is not the same as adding to it. Moved above the `#else`,
where the rest of the test lives; verified it still passes on Linux.
@Sunrisepeak
Sunrisepeak merged commit c8e21ab into main Aug 30, 2026
11 checks passed
@Sunrisepeak
Sunrisepeak deleted the feat/wlroots-pcre2-fribidi branch August 30, 2026 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant