wayland 1.26.0:源码构建 + C++23 模块层(Form A fork) - #290
Merged
Conversation
This was referenced Aug 30, 2026
Sunrisepeak
force-pushed
the
feat/wayland-source-modules
branch
from
August 30, 2026 03:17
b4c2e5d to
89be039
Compare
Sunrisepeak
pushed a commit
to mcpp-community/mcpp
that referenced
this pull request
Aug 30, 2026
mcpplibs/mcpp-index#290 replaced compat.wayland with freedesktop.wayland and freedesktop.wayland-server, built from source out of mcpplibs/wayland. They are two packages because they are two SONAMEs and Mesa's libEGL_mesa has DT_NEEDED on both, and because mcpp links every library target in a package against all of that package's sources — one package cannot emit two libraries with disjoint contents. So the -lwayland-server escape hatch this example used to demonstrate is gone: a compositor asks for the server package by name. The closure is re-measured. Four of the twelve entries are now this project's own build output — libdrm, libffi and both wayland libraries — and the first of those is the interesting one: Mesa's libgbm has an absolute RUNPATH into the payload's libdrm and still binds to ours, because a soname already in the link map is reused.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
wayland 从"绑定
xim:wayland"改为源码构建,并带上 C++23 模块层。承接 #289。为什么它没能像 libdrm 那样直接内联
wayland 大部分是生成出来的:
protocol/wayland.xml描述每个接口,wayland-scanner从它生成约 13000 行 —— 两个库的主体。而生成器是同一棵树里的 C 程序,必须先被编译才能跑。内联描述符没有构建步骤;
install()也做不到 —— mcpp 是在消费者构建期才编译包源码,别的包安装时不存在任何包产物。build.mcpp正是为此而设,而它只存在于真实 mcpp 工程里。所以走 Form A fork:mcpplibs/wayland,和mcpplibs/grpc-m同形态。仓的布局按"上游隔离"来:
更新上游 = 换掉一个目录。CI 每次都用上游自己的 meson 重建
upstream/,所以"没改上游文件"是有测试的,不是承诺。四个包,不是一个
freedesktop.wayland-scannerkind = "bin")freedesktop.waylandlibwayland-client.so.0+import wayland.client;freedesktop.wayland-serverlibwayland-server.so.0+import wayland.server;freedesktop.wayland-utilimport wayland.util;—— 宏,变成模块能导出的实体client 与 server 必须是两个文件:它们是两个不同 SONAME,而 Mesa 的
libEGL_mesa对两者都有 DT_NEEDED。而 mcpp 把包的源码编一次、让每个库 target 链接全部对象 —— 实测:feature 门控的第二个 target 照样拿到该 feature 的对象。mcpp 自己的告警点了办法:"split into a workspace member"。模块层与库同包(opencv 那种形态),所以是一库一包,而不是 C 一个、模块一个。
模块层不增加 API
import wayland.client;替掉#include <wayland-client.h>,其余什么都不变 —— 导出名全是上游的、拼写一样、语义一样,没有包装类型、没有 RAII、没有改名。导出列表是从公开头生成的,不是手维护,所以版本一动不会悄悄少一个名字。新增的
tests/examples/wayland/tests/modules.cpp一个 wayland 头都不 include,纯import调用原样 API —— 少一个导出就编不过,改过名也编不过。它和原来那个基于头文件的测试同时跑,因为模块层是增量不是替代。宏是唯一过不去的东西:
export命名的是实体而宏不是。wayland.util把每个映射成它实际是的东西:WL_MARSHAL_FLAG_DESTROYinline constexpr—— 拼写完全不变wl_container_of(p, sample, member)wl_container_of<&T::member>(p)wl_list_for_each(p, head, member)for (T *p : wl_list_each<&T::member>(head))wl_list_for_each_safe/_reverse/_reverse_safewl_list_each_*rangewl_array_for_each(p, array)for (T *p : wl_array_each<T>(array))_safe保留了上游"循环体内可删除当前元素"的保证,并且测到了。wayland-util包不链接任何库(它就是模板和常量),所以它的测试自己接链表,不为测试引入依赖。生成的协议代码是签入的,不是构建产物
wayland-client.h里有#include "wayland-client-protocol.h",所以生成的头是这个包的公开接口 —— 每个 include<wayland-client.h>的消费者都要它在自己的 include 路径上。build.mcpp给不了这个:mcpp::include_dir()按设计只作用于本包 TU、不传播给消费者(docs/07 明说了"消费者要看见的 include 目录属于公开接口,应当写在声明式清单里")。先用 build.mcpp 做过,结果是包自己编过了、消费者编不过:生成期还另有一个竞态(mcpp#534):action 的产物成了 ninja 节点,但该包的编译边没有 order-only 依赖指向它们,于是
wayland-server.c:334: error: 'WL_DISPLAY_ERROR' undeclared。两个问题同源:把确定性产物当成了构建产物。它由固定的
wayland.xml唯一决定,所以签入mcpp/generated/,用会传播的普通include_dirs声明,并由 CI 每轮重新生成后 diff —— 不可能漂移。freedesktop.wayland-scanner仍然是独立的包:compositor 要为wayland-protocols的 XML 生成绑定,需要的正是这个工具,而按名字请求它就把版本钉死成同一个。一条实测记录
1.26.0 比 1.23.1 多一个构建修正:
scanner.c现在调用strndup(),而-std=c11会把它藏起来,所以 scanner 需要-D_GNU_SOURCE=(空值:event-loop.c不自己定义它,而wayland-client.c/connection.c自己定义,空值两边都不冲突)。版本
1.26.0,上游当前发布号 —— 也比生态的xim:wayland@1.23.1新,顺带绕开 mcpp-community/mcpp#533(store 已安装查找忽略 namespace)。旧的compat.wayland@2026.08.30随本 PR 移除。验证
freedesktop走本仓 checkout、compat.libffi/expat走已发布索引 → scanner 被构建并执行 → 两个库产出 → 两个测试(头文件版 + 模块版)全绿upstream/Refs #289, #291