-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathcompat.catch2.lua
More file actions
238 lines (230 loc) · 12.1 KB
/
Copy pathcompat.catch2.lua
File metadata and controls
238 lines (230 loc) · 12.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
-- Form B inline descriptor for Catch2 — a modern C++-native test framework.
--
-- ONE package, TWO majors. v2 and v3 have completely different source layouts
-- (`single_include/catch2/catch.hpp` vs `src/catch2/**`), and this descriptor
-- covers both by taking the UNION of the two layouts' globs. That works only
-- because the two sets are DISJOINT:
--
-- | glob | 2.13.10 | 3.15.2 |
-- |-------------------------|---------------------------------|--------|
-- | */single_include | exists | absent |
-- | */src/catch2/**/*.cpp | 0 matches — v2's only src/ file | 107 |
-- | | is src/catch_with_main.cpp, | |
-- | | NOT under src/catch2/ | |
--
-- So each version lights up exactly one half and the other degenerates to
-- empty: v2 resolves to header-only (single_include + the anchor TU below),
-- v3 to a 106-TU static library. An include_dir whose glob matches nothing is
-- not an error, which is what makes the union safe.
--
-- THIS DISJOINTNESS IS THE LOAD-BEARING PREMISE, and it is a property of the
-- two upstream trees rather than something this descriptor can enforce. Re-
-- check the table above when adding a version. The right long-term shape is
-- per-version build blocks — mcpp-community/mcpp#290 — after which this
-- collapses into explicit ["2.x"] / ["3.x"] tables and the assumption goes
-- away entirely. Splitting into two packages was rejected: it encodes a
-- version into the `name` segment, which SPEC-001 identity reserves for an
-- atomic name, and it breaks semver across the major (a consumer could not
-- write `catch2 = "^3"`).
--
-- Features (sources-only gate):
-- `main` — compiles a GENERATED TU supplying a default entry point. It
-- branches on __has_include(<catch2/catch_user_config.hpp.in>) — upstream's
-- CMake template, present only in v3's SOURCE tree and never installed — to
-- pick the v3 (Catch::Session) or v2 (CATCH_CONFIG_MAIN) spelling. The probe
-- has to be source-only because __has_include searches the system dirs too;
-- see the note above the generated TU. Excluded by default; request
-- `features = ["main"]`.
--
-- It deliberately does NOT point at upstream's
-- src/catch2/internal/catch_main.cpp. That file is matched by the sources
-- glob and must be `!`-negated, else a consumer with its own main() gets
-- `multiple definition of 'main'`; and a `!` negation is an ABSOLUTE
-- exclusion that a feature cannot add back — pointing the feature at the
-- negated path yields a feature that silently does nothing and an
-- `undefined reference to 'main'` at link time. Both directions were
-- measured on mcpp 0.0.109. Note this is NOT `compat.gtest`'s shape:
-- gtest lists gtest_main.cc as a LITERAL `sources` entry, and feature
-- gating matches literal entries — a file pulled in by a glob is not gated
-- at all. A generated TU sidesteps the whole conflict.
--
-- Cost of not reusing upstream's file: no LeakDetector registration (a
-- Windows CRT-debug nicety) and no wmain variant (reachable only under
-- _UNICODE on Windows). Consumers needing either write their own main().
--
-- All `mcpp` paths are GLOBS relative to the verdir; the leading `*` absorbs
-- the GitHub tarball's `Catch2-<tag>/` wrap layer.
package = {
spec = "1",
namespace = "compat",
name = "catch2",
description = "A modern, C++-native test framework for unit-tests, TDD and BDD",
licenses = {"BSL-1.0"},
repo = "https://github.com/catchorg/Catch2",
type = "package",
xpm = {
linux = {
["2.13.10"] = {
url = {
GLOBAL = "https://github.com/catchorg/Catch2/archive/refs/tags/v2.13.10.tar.gz",
CN = "https://gitcode.com/mcpp-res/catch2/releases/download/2.13.10/catch2-2.13.10.tar.gz",
},
sha256 = "d54a712b7b1d7708bc7a819a8e6e47b2fde9536f487b89ccbca295072a7d9943",
},
["3.15.2"] = {
url = {
GLOBAL = "https://github.com/catchorg/Catch2/archive/refs/tags/v3.15.2.tar.gz",
CN = "https://gitcode.com/mcpp-res/catch2/releases/download/3.15.2/catch2-3.15.2.tar.gz",
},
sha256 = "acfae120892c2b67a74142d36d060c0caa96f1c3aaa8aabd96e19961163d0420",
},
},
macosx = {
["2.13.10"] = {
url = {
GLOBAL = "https://github.com/catchorg/Catch2/archive/refs/tags/v2.13.10.tar.gz",
CN = "https://gitcode.com/mcpp-res/catch2/releases/download/2.13.10/catch2-2.13.10.tar.gz",
},
sha256 = "d54a712b7b1d7708bc7a819a8e6e47b2fde9536f487b89ccbca295072a7d9943",
},
["3.15.2"] = {
url = {
GLOBAL = "https://github.com/catchorg/Catch2/archive/refs/tags/v3.15.2.tar.gz",
CN = "https://gitcode.com/mcpp-res/catch2/releases/download/3.15.2/catch2-3.15.2.tar.gz",
},
sha256 = "acfae120892c2b67a74142d36d060c0caa96f1c3aaa8aabd96e19961163d0420",
},
},
windows = {
["2.13.10"] = {
url = {
GLOBAL = "https://github.com/catchorg/Catch2/archive/refs/tags/v2.13.10.tar.gz",
CN = "https://gitcode.com/mcpp-res/catch2/releases/download/2.13.10/catch2-2.13.10.tar.gz",
},
sha256 = "d54a712b7b1d7708bc7a819a8e6e47b2fde9536f487b89ccbca295072a7d9943",
},
["3.15.2"] = {
url = {
GLOBAL = "https://github.com/catchorg/Catch2/archive/refs/tags/v3.15.2.tar.gz",
CN = "https://gitcode.com/mcpp-res/catch2/releases/download/3.15.2/catch2-3.15.2.tar.gz",
},
sha256 = "acfae120892c2b67a74142d36d060c0caa96f1c3aaa8aabd96e19961163d0420",
},
},
},
mcpp = {
language = "c++23",
import_std = false,
c_standard = "c11", -- for the anchor TU below
-- Union of both layouts. v2 resolves */single_include, v3 resolves
-- */src; the other one matches nothing and is skipped. mcpp_generated
-- carries catch2/catch_user_config.hpp for v3 and the v2 <new> shim.
--
-- ORDER MATTERS: mcpp_generated goes FIRST so the shim below is found
-- before upstream's own catch2/catch.hpp, which it then reaches with
-- #include_next. This is the only lever available — a descriptor's
-- cflags do not reach CONSUMER translation units (verified: a consumer
-- TU gets the include_dirs and -std, nothing else), and the consumer is
-- exactly who includes catch.hpp.
include_dirs = { "mcpp_generated", "*/single_include", "*/src" },
generated_files = {
-- v2 only, and only because upstream 2.13.10 is wrong: its
-- single header calls `new(std::nothrow)` twice (catch.hpp:977
-- and :14594) and never includes <new>. libstdc++ happens to
-- drag <new> in through another header, so gcc has always been
-- green; libc++ does not, so every clang consumer fails with
-- "no member named 'nothrow' in namespace 'std'". Catch2 v2 is
-- EOL upstream, so this is not getting fixed there.
--
-- A shim rather than a patched copy of the 17k-line header: it
-- keeps the sha256-pinned tarball as the only source of truth.
-- #include_next resumes the search AFTER this file's directory,
-- which is why mcpp_generated must sort first in include_dirs.
--
-- CAVEAT for whoever touches the v2/v3 discriminator: this file
-- is on the include path for BOTH majors, so
-- `__has_include(<catch2/catch.hpp>)` is now unconditionally true
-- and can never be used to detect v2. (On v3 it would be found
-- and then fail in #include_next, since there is no upstream
-- catch.hpp behind it — but __has_include never gets that far.)
-- The discriminator probes catch_user_config.hpp.in instead, which
-- is unaffected. See the header comment for why per-version
-- blocks (mcpp#290) are the real answer here.
["mcpp_generated/catch2/catch.hpp"] = [==[
#ifndef MCPP_COMPAT_CATCH2_NOTHROW_SHIM
#define MCPP_COMPAT_CATCH2_NOTHROW_SHIM
#include <new>
#include_next <catch2/catch.hpp>
#endif
]==],
-- v3 only. Upstream ships catch_user_config.hpp.in and lets CMake
-- materialise it. Only the two VALUE defines are mandatory —
-- everything else in the .in is a #cmakedefine, i.e. absent means
-- "use the compiler-detected default", which is what we want.
-- #ifndef-guarded so a consumer can override via -D.
-- Re-read the upstream .in when bumping v3: a newly added
-- mandatory value-define would otherwise break silently here.
-- v2 never includes this file.
["mcpp_generated/catch2/catch_user_config.hpp"] = [==[
#ifndef CATCH_USER_CONFIG_HPP_INCLUDED
#define CATCH_USER_CONFIG_HPP_INCLUDED
#ifndef CATCH_CONFIG_DEFAULT_REPORTER
#define CATCH_CONFIG_DEFAULT_REPORTER "console"
#endif
#ifndef CATCH_CONFIG_CONSOLE_WIDTH
#define CATCH_CONFIG_CONSOLE_WIDTH 80
#endif
#endif // CATCH_USER_CONFIG_HPP_INCLUDED
]==],
-- Required for v2, where the sources glob below matches nothing
-- and a lib target still needs at least one TU (same shape as
-- compat.eigen / compat.khrplatform). Inert extra object on v3.
["mcpp_generated/catch2_anchor.c"] = [==[
int mcpp_compat_catch2_anchor(void) { return 0; }
]==],
-- The `main` feature's TU. See the header comment for why this is
-- generated rather than upstream's catch_main.cpp.
-- The discriminator probes a file upstream ships as a CMake
-- TEMPLATE and never installs: `catch_user_config.hpp.in`. It has
-- to be something a SYSTEM Catch2 cannot supply, because
-- __has_include searches the system dirs too — and the obvious
-- probe, catch_all.hpp, is installed by every distro's catch2
-- package. On a box with system Catch2 v3 present, a v2 consumer
-- was answered "v3", compiled the Catch::Session entry point and
-- died at link time on undefined Catch::Session::Session().
--
-- Verified on clang 22.1.8 and gcc 16.1.0, all three cases:
-- vendored v3 on -I -> v3 (both probes agree)
-- vendored v2 on -I -> v2 (catch_all.hpp says v3: the bug)
-- only system v3 -> v2 (catch_all.hpp says v3)
--
-- Re-check when bumping v3: if upstream ever materialises this
-- file in-tree instead of shipping the .in, or a distro starts
-- installing the template, the probe needs another source-only
-- marker. mcpp#290's per-version build blocks retire the whole
-- question by naming the major outright.
["mcpp_generated/catch2_main.cpp"] = [==[
#if __has_include(<catch2/catch_user_config.hpp.in>)
// Catch2 v3: the library is compiled in; just drive a session.
# include <catch2/catch_session.hpp>
int main(int argc, char* argv[]) { return Catch::Session().run(argc, argv); }
#else
// Catch2 v2 is header-only: this TU is also where the implementation lands.
# define CATCH_CONFIG_MAIN
# include <catch2/catch.hpp>
#endif
]==],
},
sources = {
"mcpp_generated/catch2_anchor.c",
"*/src/catch2/**/*.cpp",
-- Upstream's default main(); would collide with a consumer's own.
"!*/src/catch2/internal/catch_main.cpp",
},
targets = { ["catch2"] = { kind = "lib" } },
features = {
["main"] = { sources = { "mcpp_generated/catch2_main.cpp" } },
},
deps = { },
},
}