Skip to content

Commit ff84df0

Browse files
committed
upstream/ is now a directory this fork never touches, and codegen runs at configure time
LAYOUT. Upstream wayland 1.26.0 moves into upstream/ verbatim. Everything the fork adds is under mcpp/ — including config.h, which was at the tree root because wayland-os.c says `#include "../config.h"`. It works from mcpp/ too: the manifests put both mcpp/ and mcpp/include/ on the include path, so "config.h" and "../config.h" resolve to the same single file. Updating upstream is now replacing one directory, and "no upstream file is patched" is visible rather than asserted — CI still builds upstream/ with its own meson. CODEGEN. build.mcpp now RUNS wayland-scanner instead of declaring mcpp::action edges. The declarative shape is nicer and was tried first; it does not work for a DEPENDENCY's own sources. An action's outputs become ninja nodes, but the package's compile edges get no order-only dependency on them: build obj/wayland-server.o : c_object .../wayland-server.c (no || , and no phony gathering the actions) so the compile races the generator and loses — wayland-server.c:334: error: 'WL_DISPLAY_ERROR' undeclared with the header appearing in the output directory moments later. build.mcpp itself runs at configure time, before ninja is written, so doing the work there is ordered by construction. rerun_if_changed(wayland.xml) keeps it incremental, and mcpp::source() hands the generated .c to the build.
1 parent 1b08426 commit ff84df0

209 files changed

Lines changed: 183 additions & 109 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jobs:
7070
- name: the generated protocol code came from THIS scanner
7171
run: |
7272
scanner=$(find mcpp/scanner/target -name wayland-scanner -type f | head -1)
73-
"$scanner" -s public-code protocol/wayland.xml /tmp/wayland-protocol.c
73+
"$scanner" -s public-code upstream/protocol/wayland.xml /tmp/wayland-protocol.c
7474
head -1 /tmp/wayland-protocol.c
7575
grep -q 'Generated by wayland-scanner 1.26.0' /tmp/wayland-protocol.c
7676
@@ -115,5 +115,5 @@ jobs:
115115
- run: |
116116
sudo apt-get update -qq
117117
sudo apt-get install -y -qq meson ninja-build libffi-dev libexpat1-dev
118-
meson setup build-meson -Ddocumentation=false -Ddtd_validation=false
118+
meson setup build-meson upstream -Ddocumentation=false -Ddtd_validation=false
119119
ninja -C build-meson

README.mcpp.md

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -77,25 +77,41 @@ code, split into a workspace member."*
7777
Each library package carries its C library **and** its module, so there is one
7878
package per library rather than a C one and a module one beside it.
7979

80-
## What was added
81-
82-
Nothing upstream was patched:
80+
## Layout
8381

8482
```
85-
config.h the probe results meson's configure_file() writes, for
86-
linux/glibc (wayland-os.c says "../config.h", so it is
87-
at the tree root)
88-
mcpp/include/ wayland-version.h, substituted from src/wayland-version.h.in
89-
mcpp/scanner/ the generator
90-
mcpp/util/ the macro mappings + their test
91-
mcpp/client/ libwayland-client + wayland.client, and build.mcpp
92-
mcpp/server/ libwayland-server + wayland.server, and build.mcpp
83+
upstream/ wayland 1.26.0, verbatim — never touched
84+
mcpp/ everything this fork adds
85+
config.h the probe results meson's configure_file() writes, for
86+
linux/glibc. Two spellings reach it: wayland-shm.c says
87+
"config.h" and wayland-os.c says "../config.h", so the
88+
manifests put both `mcpp/` and `mcpp/include/` on the
89+
include path and one file answers both.
90+
include/ wayland-version.h, substituted from src/wayland-version.h.in
91+
scanner/ the generator
92+
util/ the macro mappings + their test
93+
client/ libwayland-client + wayland.client, and build.mcpp
94+
server/ libwayland-server + wayland.server, and build.mcpp
9395
mcpp.toml the workspace root
9496
```
9597

96-
`build.mcpp` declares the wayland-scanner invocations as build-graph edges, so
97-
they re-run exactly when `protocol/wayland.xml` changes and a failure is
98-
attributed to the edge rather than to "build.mcpp exited 1".
98+
Updating upstream is replacing `upstream/`. Nothing this fork adds lives inside
99+
it, so a diff against a fresh release tarball is empty there by construction —
100+
and CI checks that by building `upstream/` with its own meson on every run.
101+
102+
`build.mcpp` runs wayland-scanner at CONFIGURE time rather than declaring
103+
`mcpp::action` edges. The declarative shape was tried first and does not work
104+
for a dependency's own sources: an action's outputs become ninja nodes, but the
105+
package's compile edges get no order-only dependency on them, so
106+
`wayland-server.o` races the generator —
107+
108+
```
109+
wayland-server.c:334: error: 'WL_DISPLAY_ERROR' undeclared
110+
```
111+
112+
with the header landing in the output directory moments later. build.mcpp runs
113+
before ninja is written, so doing the work there is ordered by construction;
114+
`rerun_if_changed(wayland.xml)` keeps it incremental.
99115

100116
## Upstream
101117

mcpp.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# wayland — Wayland with mcpp build support.
22
#
3-
# A fork of freedesktop's wayland at 1.26.0, unmodified except for this
4-
# directory tree: `mcpp/` adds manifests, `config.h` and `mcpp/include/` add the
5-
# two headers upstream's meson generates. No upstream source file is patched.
3+
# LAYOUT: upstream/ is wayland 1.26.0 verbatim and is never touched — updating it
4+
# is replacing that one directory. Everything this fork adds is under mcpp/,
5+
# including the two headers upstream's meson would generate (config.h and
6+
# include/wayland-version.h), so `git diff` against a fresh tarball is empty
7+
# inside upstream/ by construction.
68
#
79
# WHY A FORK RATHER THAN AN INLINE INDEX DESCRIPTOR
810
#

mcpp/client/build.mcpp

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,95 @@
11
// Generate the protocol sources for libwayland-client.
22
//
3-
// wayland's libraries are mostly GENERATED: protocol/wayland.xml describes
4-
// every interface, and wayland-scanner emits the marshalling code and the
5-
// headers from it. Upstream does this with meson custom_targets; here it is
6-
// three mcpp::action edges, which means the work is DECLARED rather than done
7-
// — it re-runs exactly when wayland.xml changes, and a failure is attributed
8-
// to the edge instead of to "build.mcpp exited 1".
3+
// wayland's libraries are mostly GENERATED: upstream/protocol/wayland.xml
4+
// describes every interface, and wayland-scanner emits the marshalling code and
5+
// the headers from it — most of what this package compiles.
96
//
10-
// The scanner is the one this build produced (compat.wayland-scanner, asked
11-
// for with `tools = ["wayland-scanner"]`), never a host one. That matters
12-
// more than it looks: a system wayland-scanner 1.22 rejects 1.23's
13-
// wayland.xml outright — it does not know the `deprecated-since` attribute —
14-
// so a build that reached for the host would fail or, worse, silently emit
15-
// code for a different protocol revision than the headers describe.
7+
// The scanner is the one this build produced (freedesktop.wayland-scanner, asked
8+
// for with `tools = ["wayland-scanner"]`), never a host one. A system
9+
// wayland-scanner 1.22 rejects 1.26's wayland.xml outright — it does not know the
10+
// `deprecated-since` attribute — so a build that reached for whatever is on
11+
// PATH would fail, or worse emit code for a different protocol revision than the
12+
// headers describe.
13+
//
14+
// WHY THIS RUNS THE SCANNER INSTEAD OF DECLARING mcpp::action EDGES
15+
//
16+
// Declaring them is the nicer shape and was tried first. It does not work for a
17+
// DEPENDENCY's own sources: an action's outputs become ninja nodes, but the
18+
// package's compile edges get no order-only dependency on them, so
19+
// `wayland-server.o` races the generator and usually loses —
20+
//
21+
// wayland-server.c:334: error: 'WL_DISPLAY_ERROR' undeclared
22+
//
23+
// with the header appearing in the output directory moments later. build.mcpp
24+
// itself runs at CONFIGURE time, before ninja is written, so doing the work here
25+
// is ordered by construction. `rerun_if_changed` keeps it incremental.
1626
#include <cstdio>
27+
#include <cstdlib>
1728
#include <string>
1829

1930
import mcpp;
2031

21-
int main() {
32+
namespace {
33+
34+
// One scanner invocation. Returns false and explains itself rather than
35+
// letting a silent partial generation surface later as a missing symbol.
36+
bool generate(const std::string &scanner, const std::string &mode,
37+
const std::string &core, const std::string &xml,
38+
const std::string &out)
39+
{
40+
std::string cmd = "'" + scanner + "' -s " + mode;
41+
if (!core.empty()) {
42+
cmd += " " + core;
43+
}
44+
cmd += " '" + xml + "' '" + out + "'";
45+
46+
if (std::system(cmd.c_str()) != 0) {
47+
std::fprintf(stderr, "wayland-scanner failed: %s\n", cmd.c_str());
48+
return false;
49+
}
50+
return true;
51+
}
52+
53+
} // namespace
54+
55+
int main()
56+
{
2257
const std::string root = mcpp::manifest_dir();
2358
const std::string out = mcpp::out_dir();
2459

2560
const char *scanner = mcpp::dep_bin("wayland-scanner", "wayland-scanner");
2661
if (scanner == nullptr || *scanner == '\0') {
27-
std::fputs("no wayland-scanner: declare compat.wayland-scanner = "
28-
"{ version = \"1.23.1\", tools = [\"wayland-scanner\"] }\n",
62+
std::fputs("no wayland-scanner: declare freedesktop.wayland-scanner = "
63+
"{ version = \"1.26.0\", tools = [\"wayland-scanner\"] }\n",
2964
stderr);
3065
return 1;
3166
}
3267

33-
const std::string xml = root + "/../../protocol/wayland.xml";
68+
const std::string xml = root + "/../../upstream/protocol/wayland.xml";
69+
mcpp::rerun_if_changed(xml.c_str());
3470

35-
struct Gen { const char *id; const char *mode; const char *core; const char *output; };
71+
struct Gen { const char *mode; const char *core; const char *output; };
3672
const Gen work[] = {
37-
// The marshalling code: wl_interface tables and the proxy/resource
38-
// stubs. Both libraries carry it — upstream does the same, and
73+
// The marshalling code: the wl_interface tables and the proxy/resource
74+
// stubs. BOTH libraries carry it — upstream does the same, and
3975
// `wl_display_interface` is exported from libwayland-client.so.0 and
4076
// libwayland-server.so.0 alike.
41-
{ "wayland:protocol-code", "public-code", nullptr, "wayland-protocol.c" },
42-
{ "wayland:client-header", "client-header", nullptr, "wayland-client-protocol.h" },
77+
{ "public-code", nullptr, "wayland-protocol.c" },
78+
{ "client-header", nullptr, "wayland-client-protocol.h" },
4379
// The -c variant: the same header without the convenience wrappers.
44-
// Not installed by upstream, but the .c above includes it.
45-
{ "wayland:client-core", "client-header", "-c", "wayland-client-protocol-core.h" },
80+
// Upstream does not install it, but the generated .c includes it.
81+
{ "client-header", "-c", "wayland-client-protocol-core.h" },
4682
};
4783

4884
for (const Gen &g : work) {
49-
const std::string output = out + "/" + g.output;
50-
mcpp::action a;
51-
a.id = g.id;
52-
a.role = "source";
53-
const std::string desc = std::string("wayland-scanner -> ") + g.output;
54-
a.description = desc.c_str();
55-
a.arg(scanner).arg("-s").arg(g.mode);
56-
if (g.core != nullptr) {
57-
a.arg(g.core);
85+
if (!generate(scanner, g.mode, g.core == nullptr ? "" : g.core,
86+
xml, out + "/" + g.output)) {
87+
return 1;
5888
}
59-
a.arg(xml.c_str())
60-
.arg(output.c_str())
61-
.input(xml.c_str())
62-
.output(output.c_str())
63-
.submit();
6489
}
6590

91+
// The generated .c is a translation unit of this package; the headers are
92+
// reached through the include directory.
93+
mcpp::source((out + "/wayland-protocol.c").c_str());
6694
mcpp::include_dir(out.c_str());
6795
}

mcpp/client/mcpp.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ standard = "c++23"
1919
# (connection.c, wayland-os.c) and `wayland_util` (wayland-util.c). The
2020
# generated wayland-protocol.c arrives from build.mcpp, not from here.
2121
sources = [
22-
"../../src/wayland-client.c",
23-
"../../src/connection.c",
24-
"../../src/wayland-os.c",
25-
"../../src/wayland-util.c",
22+
"../../upstream/src/wayland-client.c",
23+
"../../upstream/src/connection.c",
24+
"../../upstream/src/wayland-os.c",
25+
"../../upstream/src/wayland-util.c",
2626
# the module wrapper; see src/wayland-client.cppm
2727
"src/wayland-client.cppm",
2828
]
29-
include_dirs = ["../..", "../../src", "../include"]
29+
include_dirs = ["..", "../../upstream/src", "../include"]
3030
# -include config.h is how upstream delivers the probe results; the sources
3131
# have no #include for it and the `#ifndef HAVE_STRNDUP` fallback would
3232
# otherwise compile a second strndup() that shadows glibc's process-wide.
File renamed without changes.

mcpp/scanner/mcpp.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ standard = "c++23"
1919
[build]
2020
# wayland-util.c is upstream's `wayland_util` static library — the scanner
2121
# links it for wl_list/wl_array.
22-
sources = ["../../src/wayland-util.c"]
22+
sources = ["../../upstream/src/wayland-util.c"]
2323
# ../../src for wayland-util.h; ../include for the committed config.h and
2424
# wayland-version.h that scanner.c includes.
25-
include_dirs = ["../..", "../../src", "../include"]
25+
include_dirs = ["..", "../../upstream/src", "../include"]
2626
# `-include config.h` is how upstream delivers it (meson's
2727
# `scanner_args = ['-include', 'config.h']`); scanner.c has no #include for
2828
# it. Without this its `#ifndef HAVE_STRNDUP` fallback compiles a second
@@ -37,7 +37,7 @@ cflags = ["-D_GNU_SOURCE=", "-DHAVE_STRNDUP=1"]
3737

3838
[targets.wayland-scanner]
3939
kind = "bin"
40-
main = "../../src/scanner.c"
40+
main = "../../upstream/src/scanner.c"
4141

4242
[dependencies]
4343
compat.expat = "2.7.1"

mcpp/server/build.mcpp

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,95 @@
11
// Generate the protocol sources for libwayland-server.
22
//
3-
// wayland's libraries are mostly GENERATED: protocol/wayland.xml describes
4-
// every interface, and wayland-scanner emits the marshalling code and the
5-
// headers from it. Upstream does this with meson custom_targets; here it is
6-
// three mcpp::action edges, which means the work is DECLARED rather than done
7-
// — it re-runs exactly when wayland.xml changes, and a failure is attributed
8-
// to the edge instead of to "build.mcpp exited 1".
3+
// wayland's libraries are mostly GENERATED: upstream/protocol/wayland.xml
4+
// describes every interface, and wayland-scanner emits the marshalling code and
5+
// the headers from it — most of what this package compiles.
96
//
10-
// The scanner is the one this build produced (compat.wayland-scanner, asked
11-
// for with `tools = ["wayland-scanner"]`), never a host one. That matters
12-
// more than it looks: a system wayland-scanner 1.22 rejects 1.23's
13-
// wayland.xml outright — it does not know the `deprecated-since` attribute —
14-
// so a build that reached for the host would fail or, worse, silently emit
15-
// code for a different protocol revision than the headers describe.
7+
// The scanner is the one this build produced (freedesktop.wayland-scanner, asked
8+
// for with `tools = ["wayland-scanner"]`), never a host one. A system
9+
// wayland-scanner 1.22 rejects 1.26's wayland.xml outright — it does not know the
10+
// `deprecated-since` attribute — so a build that reached for whatever is on
11+
// PATH would fail, or worse emit code for a different protocol revision than the
12+
// headers describe.
13+
//
14+
// WHY THIS RUNS THE SCANNER INSTEAD OF DECLARING mcpp::action EDGES
15+
//
16+
// Declaring them is the nicer shape and was tried first. It does not work for a
17+
// DEPENDENCY's own sources: an action's outputs become ninja nodes, but the
18+
// package's compile edges get no order-only dependency on them, so
19+
// `wayland-server.o` races the generator and usually loses —
20+
//
21+
// wayland-server.c:334: error: 'WL_DISPLAY_ERROR' undeclared
22+
//
23+
// with the header appearing in the output directory moments later. build.mcpp
24+
// itself runs at CONFIGURE time, before ninja is written, so doing the work here
25+
// is ordered by construction. `rerun_if_changed` keeps it incremental.
1626
#include <cstdio>
27+
#include <cstdlib>
1728
#include <string>
1829

1930
import mcpp;
2031

21-
int main() {
32+
namespace {
33+
34+
// One scanner invocation. Returns false and explains itself rather than
35+
// letting a silent partial generation surface later as a missing symbol.
36+
bool generate(const std::string &scanner, const std::string &mode,
37+
const std::string &core, const std::string &xml,
38+
const std::string &out)
39+
{
40+
std::string cmd = "'" + scanner + "' -s " + mode;
41+
if (!core.empty()) {
42+
cmd += " " + core;
43+
}
44+
cmd += " '" + xml + "' '" + out + "'";
45+
46+
if (std::system(cmd.c_str()) != 0) {
47+
std::fprintf(stderr, "wayland-scanner failed: %s\n", cmd.c_str());
48+
return false;
49+
}
50+
return true;
51+
}
52+
53+
} // namespace
54+
55+
int main()
56+
{
2257
const std::string root = mcpp::manifest_dir();
2358
const std::string out = mcpp::out_dir();
2459

2560
const char *scanner = mcpp::dep_bin("wayland-scanner", "wayland-scanner");
2661
if (scanner == nullptr || *scanner == '\0') {
27-
std::fputs("no wayland-scanner: declare compat.wayland-scanner = "
28-
"{ version = \"1.23.1\", tools = [\"wayland-scanner\"] }\n",
62+
std::fputs("no wayland-scanner: declare freedesktop.wayland-scanner = "
63+
"{ version = \"1.26.0\", tools = [\"wayland-scanner\"] }\n",
2964
stderr);
3065
return 1;
3166
}
3267

33-
const std::string xml = root + "/../../protocol/wayland.xml";
68+
const std::string xml = root + "/../../upstream/protocol/wayland.xml";
69+
mcpp::rerun_if_changed(xml.c_str());
3470

35-
struct Gen { const char *id; const char *mode; const char *core; const char *output; };
71+
struct Gen { const char *mode; const char *core; const char *output; };
3672
const Gen work[] = {
37-
// The marshalling code: wl_interface tables and the proxy/resource
38-
// stubs. Both libraries carry it — upstream does the same, and
73+
// The marshalling code: the wl_interface tables and the proxy/resource
74+
// stubs. BOTH libraries carry it — upstream does the same, and
3975
// `wl_display_interface` is exported from libwayland-client.so.0 and
4076
// libwayland-server.so.0 alike.
41-
{ "wayland:protocol-code", "public-code", nullptr, "wayland-protocol.c" },
42-
{ "wayland:server-header", "server-header", nullptr, "wayland-server-protocol.h" },
77+
{ "public-code", nullptr, "wayland-protocol.c" },
78+
{ "server-header", nullptr, "wayland-server-protocol.h" },
4379
// The -c variant: the same header without the convenience wrappers.
44-
// Not installed by upstream, but the .c above includes it.
45-
{ "wayland:server-core", "server-header", "-c", "wayland-server-protocol-core.h" },
80+
// Upstream does not install it, but the generated .c includes it.
81+
{ "server-header", "-c", "wayland-server-protocol-core.h" },
4682
};
4783

4884
for (const Gen &g : work) {
49-
const std::string output = out + "/" + g.output;
50-
mcpp::action a;
51-
a.id = g.id;
52-
a.role = "source";
53-
const std::string desc = std::string("wayland-scanner -> ") + g.output;
54-
a.description = desc.c_str();
55-
a.arg(scanner).arg("-s").arg(g.mode);
56-
if (g.core != nullptr) {
57-
a.arg(g.core);
85+
if (!generate(scanner, g.mode, g.core == nullptr ? "" : g.core,
86+
xml, out + "/" + g.output)) {
87+
return 1;
5888
}
59-
a.arg(xml.c_str())
60-
.arg(output.c_str())
61-
.input(xml.c_str())
62-
.output(output.c_str())
63-
.submit();
6489
}
6590

91+
// The generated .c is a translation unit of this package; the headers are
92+
// reached through the include directory.
93+
mcpp::source((out + "/wayland-protocol.c").c_str());
6694
mcpp::include_dir(out.c_str());
6795
}

0 commit comments

Comments
 (0)