Skip to content

Commit 5b3d23a

Browse files
ZheFeng7110Sunrisepeak
authored andcommitted
add compat.catch2 v3.15.2 and compat.catch2-v2 v2.13.10
Catch2 is a modern C++ test framework. - compat.catch2 (v3): C-source compat static library built from individual source files under src/catch2/. Includes generated catch_user_config.hpp (normally CMake-generated). Default main suppressed via -DCATCH_AMALGAMATED_CUSTOM_MAIN; `main` feature gates a generated default main TU (same pattern as compat.gtest). - compat.catch2-v2 (v2): header-only, single-include via single_include/catch2/catch.hpp with anchor TU. `main` feature gates a generated TU with CATCH_CONFIG_MAIN. Both use GitHub tag archive tarballs. No CN mirror yet (no mcpp-res write access). Local `mcpp test -p catch2` and `mcpp test -p catch2-v2` pass on mcpp 0.0.108 (x86_64-windows-msvc).
1 parent 0adb288 commit 5b3d23a

9 files changed

Lines changed: 318 additions & 0 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Design doc: add Catch2 to mcpp-index
2+
3+
Date: 2026-07-26
4+
5+
## Source
6+
7+
- Repo: [catchorg/Catch2](https://github.com/catchorg/Catch2)
8+
- License: BSL-1.0 (Boost Software License 1.0)
9+
- Upstream release model: amalgamated files published as GitHub release assets
10+
11+
Catch2 has two major versions with incompatible APIs and source layouts:
12+
13+
| Version | Source layout | Shape |
14+
|---------|--------------|-------|
15+
| v2.13.10 | `single_include/catch2/catch.hpp` (single amalgamated header) | **header-only** |
16+
| v3.15.2 | `src/catch2/**/*.{hpp,cpp}` (individual source files) | **C-source compat (static lib)** |
17+
18+
The v2→v3 jump changed the repo layout completely (`single_include/``src/catch2/`),
19+
so the two versions cannot share a single `mcpp` block. Two separate packages are used:
20+
21+
- `compat.catch2` — v3, C-source compat (static library from individual source files)
22+
- `compat.catch2-v2` — v2, header-only
23+
24+
## Package shape decision
25+
26+
### compat.catch2 (v3)
27+
28+
- **Shape**: C-source compat static library (same as compat.cjson / compat.gtest)
29+
- **Sources**: `*/src/catch2/**/*.cpp` — all Catch2 implementation files (107 TUs)
30+
- **include_dirs**: `{ "*/src", "mcpp_generated" }` — exposes `<catch2/catch_all.hpp>`
31+
etc. from the source tree, and `catch2/catch_user_config.hpp` from generated files
32+
- **catch_user_config.hpp**: materialised via `generated_files` (normally
33+
CMake-generated; provides `CATCH_CONFIG_DEFAULT_REPORTER` and
34+
`CATCH_CONFIG_CONSOLE_WIDTH`). Both value-defines use `#ifndef` guards so
35+
users can override them via `cxxflags = ["-DCATCH_CONFIG_DEFAULT_REPORTER=xml"]`
36+
in their own `mcpp.toml`. Other boolean toggles (e.g. `CATCH_CONFIG_WCHAR`)
37+
are auto-detected by `catch_compiler_capabilities.hpp` and can likewise be
38+
forced on/off via `-D` flags.
39+
- **catch_main.cpp**: provides a default `main()`. Excluded from the default
40+
source set via `!` negation (`"!*/src/catch2/internal/catch_main.cpp"`);
41+
only compiled when `features = ["main"]` is requested (same pattern as
42+
`compat.gtest`'s `main` feature gating `gtest_main.cc`)
43+
44+
### compat.catch2-v2 (v2)
45+
46+
- **Shape**: header-only (same as compat.eigen / compat.opengl)
47+
- **include_dirs**: `{ "*/single_include" }` — consumers `#include <catch2/catch.hpp>`
48+
- **Anchor**: trivial `.c` TU (`mcpp_generated/catch2_v2_anchor.c`) to give mcpp
49+
a buildable lib target
50+
- **`main` feature**: gates a generated `main.cpp` that defines
51+
`CATCH_CONFIG_MAIN` and includes `<catch2/catch.hpp>`, providing a ready-made
52+
`main()`. Excluded by default
53+
54+
## Download URLs
55+
56+
Both packages use GitHub tag archive tarballs (not individual release assets)
57+
because xpm supports one URL per version.
58+
59+
| Package | Version | GitHub archive URL | SHA256 |
60+
|---------|---------|--------------------|--------|
61+
| compat.catch2 | 3.15.2 | `https://github.com/catchorg/Catch2/archive/refs/tags/v3.15.2.tar.gz` | `acfae120892c2b67a74142d36d060c0caa96f1c3aaa8aabd96e19961163d0420` |
62+
| compat.catch2-v2 | 2.13.10 | `https://github.com/catchorg/Catch2/archive/refs/tags/v2.13.10.tar.gz` | `d54a712b7b1d7708bc7a819a8e6e47b2fde9536f487b89ccbca295072a7d9943` |
63+
64+
### Individual release asset SHAs (for reference)
65+
66+
| File | Release URL | SHA256 |
67+
|------|------------|--------|
68+
| catch.hpp (v2.13.10) | `https://github.com/catchorg/Catch2/releases/download/v2.13.10/catch.hpp` | `3725c0f0a75f376a5005dde31ead0feb8f7da7507644c201b814443de8355170` |
69+
| catch_amalgamated.cpp (v3.15.2) | `https://github.com/catchorg/Catch2/releases/download/v3.15.2/catch_amalgamated.cpp` | `1ec0b0c0d6133f76fea521295be3e69e3aa5464ab92972897414ca59b7f674d5` |
70+
| catch_amalgamated.hpp (v3.15.2) | `https://github.com/catchorg/Catch2/releases/download/v3.15.2/catch_amalgamated.hpp` | `f0573f46ac989896a20c524085307b633f01c8e1cdbbe6d9b39f63827c2d6c5e` |
71+
72+
## CN mirror
73+
74+
Not configured yet — no `mcpp-res` write access. Using plain-string upstream URLs
75+
(no `{ GLOBAL=…, CN=… }` table). CN users will fall back to the upstream source.
76+
Mirrors can be added later by a maintainer.
77+
78+
## Test examples
79+
80+
- **tests/examples/catch2/**: v3 static library build. Includes
81+
`<catch2/catch_all.hpp>`, provides own `main()` using
82+
`Catch::Session().run()`, runs two `TEST_CASE`s.
83+
- **tests/examples/catch2-v2/**: v2 header-only. Defines `CATCH_CONFIG_MAIN` to
84+
get a built-in main, includes `<catch2/catch.hpp>`, runs two `TEST_CASE`s
85+
within a single TU.
86+
87+
## Verification
88+
89+
- SHA256 computed twice (confirmed stable) via `sha256sum` on the codeload tarballs
90+
- File paths confirmed by `tar -tzf` against tag archives
91+
- Both packages pass `mcpp xpkg parse` lint
92+
- `mcpp test -p catch2`**test result ok** (2 assertions in 2 test cases)
93+
- `mcpp test -p catch2-v2`**test result ok** (2 assertions in 2 test cases)
94+
- Tested with mcpp 0.0.108 (matching CI `MCPP_VERSION`) on x86_64-windows-msvc
95+
96+
## Notes
97+
98+
- Catch2 v3 static library requires `catch_user_config.hpp` (normally
99+
CMake-generated). A minimal version is materialised via `generated_files` at
100+
`mcpp_generated/catch2/catch_user_config.hpp` with `#ifndef` guards on the
101+
two value-defines (`CATCH_CONFIG_DEFAULT_REPORTER` and
102+
`CATCH_CONFIG_CONSOLE_WIDTH`), allowing users to override them via `-D` flags.
103+
- `catch_main.cpp` is gated via `!` negation in `sources` + feature listing,
104+
following the exact `compat.gtest` pattern. No `-DCATCH_AMALGAMATED_CUSTOM_MAIN`
105+
needed.
106+
- Catch2 v3 requires C++14 or later; v2 requires C++11; both compatible with
107+
mcpp's `language = "c++23"`.
108+
- No `c_standard` needed for v3 (pure C++); anchor for v2 uses
109+
`c_standard = "c11"`.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ mcpp self config --mirror CN # 切换至国内镜像,默认使用 GLOBAL 上
3535
| 原生模块库(Form A) | [`mcpplibs.xpkg`](pkgs/x/xpkg.lua) · [`mcpplibs.tinyhttps`](pkgs/t/tinyhttps.lua) · [`tensorvia-cpu`](pkgs/t/tensorvia-cpu.lua) · [`ffmpeg`](pkgs/f/ffmpeg.lua)(模块层,源码经 `compat.ffmpeg` 直编) · [`opencv`](pkgs/o/opencv.lua)(单仓库:模块层与 OpenCV 5 全源码构建同在包内,索引侧只留本描述符) |
3636
| C 源码 compat(含 `features`) | [`compat.cjson`](pkgs/c/compat.cjson.lua) · [`compat.zlib`](pkgs/c/compat.zlib.lua) |
3737
| header-only(含 `features`) | [`compat.eigen`](pkgs/c/compat.eigen.lua) |
38+
| 单包多 major(形态随版本切换) | [`compat.catch2`](pkgs/c/compat.catch2.lua)(3.x 编 `src/catch2/` 出静态库;2.x 走 `single_include/` header-only) |
3839
| 外部构建系统(`install()` 从源码构建) | [`compat.openblas`](pkgs/c/compat.openblas.lua)(Make) · [`compat.openssl`](pkgs/c/compat.openssl.lua)(Perl Configure + Make,静态 libssl/libcrypto) |
3940
| 全源码直编(config 快照 + 源列表,零外部构建系统) | [`compat.ffmpeg`](pkgs/c/compat.ffmpeg.lua)(2281 TU 含 NASM 汇编,28 个目录 glob 声明) |
4041
| C++23 module wrapper | [`nlohmann.json`](pkgs/n/nlohmann.json.lua) · [`marzer.tomlplusplus`](pkgs/m/marzer.tomlplusplus.lua) |

mcpp.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ members = [
1111
"tests/examples/asio-module",
1212
"tests/examples/asio-ssl",
1313
"tests/examples/build-mcpp",
14+
"tests/examples/catch2",
15+
"tests/examples/catch2-v2",
1416
"tests/examples/cjson",
1517
"tests/examples/core",
1618
"tests/examples/eigen",

pkgs/c/compat.catch2-v2.lua

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
-- Form B inline descriptor for Catch2 v2 — a modern C++ test framework.
2+
-- v2 is HEADER-ONLY: the amalgamated single header (catch.hpp) contains
3+
-- the full implementation. Define `CATCH_CONFIG_MAIN` before including it
4+
-- in exactly one TU to get a ready-made main(), or define
5+
-- `CATCH_CONFIG_RUNNER` to write your own.
6+
--
7+
-- This descriptor exposes the header via include_dirs and carries a tiny
8+
-- anchor TU so mcpp always has a buildable lib target (same shape as
9+
-- compat.eigen / compat.opengl / compat.khrplatform).
10+
--
11+
-- Features (sources-only gate):
12+
-- `main` — compiles a generated TU that defines CATCH_CONFIG_MAIN and
13+
-- includes <catch2/catch.hpp>, providing a default main(). Excluded by
14+
-- default; request features = ["main"] for a no-config entry point.
15+
--
16+
-- All `mcpp` paths are GLOBS relative to the verdir; the leading `*`
17+
-- absorbs the GitHub tarball's `Catch2-<tag>/` wrap layer.
18+
package = {
19+
spec = "1",
20+
namespace = "compat",
21+
name = "catch2-v2",
22+
description = "A modern, C++-native test framework for unit-tests, TDD and BDD — v2 (C++11, header-only)",
23+
licenses = {"BSL-1.0"},
24+
repo = "https://github.com/catchorg/Catch2",
25+
type = "package",
26+
27+
xpm = {
28+
linux = {
29+
["2.13.10"] = {
30+
url = "https://github.com/catchorg/Catch2/archive/refs/tags/v2.13.10.tar.gz",
31+
sha256 = "d54a712b7b1d7708bc7a819a8e6e47b2fde9536f487b89ccbca295072a7d9943",
32+
},
33+
},
34+
macosx = {
35+
["2.13.10"] = {
36+
url = "https://github.com/catchorg/Catch2/archive/refs/tags/v2.13.10.tar.gz",
37+
sha256 = "d54a712b7b1d7708bc7a819a8e6e47b2fde9536f487b89ccbca295072a7d9943",
38+
},
39+
},
40+
windows = {
41+
["2.13.10"] = {
42+
url = "https://github.com/catchorg/Catch2/archive/refs/tags/v2.13.10.tar.gz",
43+
sha256 = "d54a712b7b1d7708bc7a819a8e6e47b2fde9536f487b89ccbca295072a7d9943",
44+
},
45+
},
46+
},
47+
48+
mcpp = {
49+
language = "c++23",
50+
import_std = false,
51+
c_standard = "c11",
52+
include_dirs = { "*/single_include" },
53+
generated_files = {
54+
["mcpp_generated/catch2_v2_anchor.c"] = [==[
55+
int mcpp_compat_catch2_v2_anchor(void) { return 0; }
56+
]==],
57+
["mcpp_generated/catch2_v2_main.cpp"] = [==[
58+
#define CATCH_CONFIG_MAIN
59+
#include <catch2/catch.hpp>
60+
]==],
61+
},
62+
sources = { "mcpp_generated/catch2_v2_anchor.c" },
63+
targets = { ["catch2-v2"] = { kind = "lib" } },
64+
features = {
65+
["main"] = { sources = { "mcpp_generated/catch2_v2_main.cpp" } },
66+
},
67+
deps = { },
68+
},
69+
}

pkgs/c/compat.catch2.lua

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
-- Form B inline descriptor for Catch2 v3 — a modern C++ test framework.
2+
-- Built as a static library from the individual source files under
3+
-- src/catch2/ (NOT the amalgamated distribution). Consumers include
4+
-- <catch2/catch_all.hpp> (or more specific headers) and provide their
5+
-- own main() using Catch::Session, or request the `main` feature for a
6+
-- ready-made default entry point.
7+
--
8+
-- Features (sources-only gate):
9+
-- `main` — compiles catch_main.cpp (upstream's default main via
10+
-- Catch::Session). Excluded from the default source set via `!`
11+
-- negation; only compiled when features = ["main"] is requested
12+
-- (same pattern as compat.gtest's `main` feature).
13+
--
14+
-- All `mcpp` paths are GLOBS relative to the verdir; the leading `*`
15+
-- absorbs the GitHub tarball's `Catch2-<tag>/` wrap layer.
16+
package = {
17+
spec = "1",
18+
namespace = "compat",
19+
name = "catch2",
20+
description = "A modern, C++-native test framework for unit-tests, TDD and BDD — v3 (C++14+)",
21+
licenses = {"BSL-1.0"},
22+
repo = "https://github.com/catchorg/Catch2",
23+
type = "package",
24+
25+
xpm = {
26+
linux = {
27+
["3.15.2"] = {
28+
url = "https://github.com/catchorg/Catch2/archive/refs/tags/v3.15.2.tar.gz",
29+
sha256 = "acfae120892c2b67a74142d36d060c0caa96f1c3aaa8aabd96e19961163d0420",
30+
},
31+
},
32+
macosx = {
33+
["3.15.2"] = {
34+
url = "https://github.com/catchorg/Catch2/archive/refs/tags/v3.15.2.tar.gz",
35+
sha256 = "acfae120892c2b67a74142d36d060c0caa96f1c3aaa8aabd96e19961163d0420",
36+
},
37+
},
38+
windows = {
39+
["3.15.2"] = {
40+
url = "https://github.com/catchorg/Catch2/archive/refs/tags/v3.15.2.tar.gz",
41+
sha256 = "acfae120892c2b67a74142d36d060c0caa96f1c3aaa8aabd96e19961163d0420",
42+
},
43+
},
44+
},
45+
46+
mcpp = {
47+
language = "c++23",
48+
import_std = false,
49+
-- expose src/ so that #include <catch2/…> resolves to
50+
-- Catch2-<tag>/src/catch2/…
51+
-- mcpp_generated/ provides catch2/catch_user_config.hpp (normally
52+
-- CMake-generated; we materialise a reasonable default here).
53+
include_dirs = { "*/src", "mcpp_generated" },
54+
-- catch_main.cpp provides a default main(). Excluded via `!`
55+
-- negation from the default source set; only compiled when
56+
-- features = ["main"] is requested (same pattern as compat.gtest).
57+
generated_files = {
58+
["mcpp_generated/catch2/catch_user_config.hpp"] = [==[
59+
#ifndef CATCH_USER_CONFIG_HPP_INCLUDED
60+
#define CATCH_USER_CONFIG_HPP_INCLUDED
61+
62+
#ifndef CATCH_CONFIG_DEFAULT_REPORTER
63+
#define CATCH_CONFIG_DEFAULT_REPORTER "console"
64+
#endif
65+
#ifndef CATCH_CONFIG_CONSOLE_WIDTH
66+
#define CATCH_CONFIG_CONSOLE_WIDTH 80
67+
#endif
68+
69+
#endif
70+
]==],
71+
},
72+
sources = {
73+
"*/src/catch2/**/*.cpp",
74+
"!*/src/catch2/internal/catch_main.cpp",
75+
},
76+
targets = { ["catch2"] = { kind = "lib" } },
77+
features = {
78+
["main"] = { sources = { "*/src/catch2/internal/catch_main.cpp" } },
79+
},
80+
deps = { },
81+
},
82+
}

tests/examples/catch2-v2/mcpp.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Catch2 v2 test project: depends on compat.catch2-v2 (header-only via this
2+
# repo's own index) and asserts behavior under `mcpp test`.
3+
# Part of the mcpp-index self-referential workspace.
4+
[package]
5+
name = "catch2-v2-tests"
6+
version = "0.1.0"
7+
8+
[indices]
9+
compat = { path = "../../.." }
10+
11+
[dependencies.compat]
12+
catch2-v2 = "2.13.10"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#define CATCH_CONFIG_MAIN
2+
#include <catch2/catch.hpp>
3+
4+
static unsigned int factorial(unsigned int n) {
5+
return n <= 1 ? 1 : n * factorial(n - 1);
6+
}
7+
8+
TEST_CASE("factorial of 5 is 120", "[math]") {
9+
REQUIRE(factorial(5) == 120);
10+
}
11+
12+
TEST_CASE("factorial of 0 is 1", "[math]") {
13+
REQUIRE(factorial(0) == 1);
14+
}

tests/examples/catch2/mcpp.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Catch2 v3 test project: depends on compat.catch2 (compiled from amalgamated
2+
# source via this repo's own index) and asserts behavior under `mcpp test`.
3+
# Part of the mcpp-index self-referential workspace.
4+
[package]
5+
name = "catch2-tests"
6+
version = "0.1.0"
7+
8+
[indices]
9+
compat = { path = "../../.." }
10+
11+
[dependencies.compat]
12+
catch2 = "3.15.2"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <catch2/catch_all.hpp>
2+
3+
static unsigned int factorial(unsigned int n) {
4+
return n <= 1 ? 1 : n * factorial(n - 1);
5+
}
6+
7+
TEST_CASE("factorial of 5 is 120", "[math]") {
8+
REQUIRE(factorial(5) == 120);
9+
}
10+
11+
TEST_CASE("factorial of 0 is 1", "[math]") {
12+
REQUIRE(factorial(0) == 1);
13+
}
14+
15+
int main(int argc, char* argv[]) {
16+
return Catch::Session().run(argc, argv);
17+
}

0 commit comments

Comments
 (0)