Skip to content

feat(pkgs): add cJSON (compat) + nlohmann.json (C++23 module) + per-pkg CI#48

Merged
Sunrisepeak merged 5 commits into
mainfrom
feat/add-cjson-nlohmann-json
Jun 27, 2026
Merged

feat(pkgs): add cJSON (compat) + nlohmann.json (C++23 module) + per-pkg CI#48
Sunrisepeak merged 5 commits into
mainfrom
feat/add-cjson-nlohmann-json

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

What

Adds two third-party JSON libraries to the index, plus a per-changed-package CI mechanism.

compat.cjson @ 1.7.19

Pure-C source build, same shape as compat.zlib: compiles cJSON.c into a lib, exposes cJSON.h via include_dirs. The optional cJSON_Utils extension is gated behind feature utils (mirrors how compat.gtest gates gtest_main behind main).

#include <cJSON.h>   // header self-guards with extern "C"

nlohmann.json @ 3.12.0 → import nlohmann.json; out of the box

Released v3.12.0 is header-only and ships no module interface unit. Upstream has authored an official one at src/modules/json.cppm (export module nlohmann.json;) but it lives on develop only (not in any release tag yet). So this package provides it ourselves via mcpp generated_files, embedding upstream's official json.cppm verbatim (literals + the MSVC #3970 detail re-exports); base headers stay pinned to the reproducible v3.12.0 tarball.

import std;
import nlohmann.json;
using namespace nlohmann::literals;   // for the _json UDL

Idiomatic: pair with import std;. Don't mix the module import with textual #include <string> — GCC's modules implementation clashes on the std headers the module already attaches. When upstream ships the .cppm in a release, switch sources to */src/modules/json.cppm and drop generated_files (noted in the descriptor).

CN mirrors

Both tarballs mirrored to GitCode via tools/gtc, byte-identical to source (sha256 verified):

  • mcpp-res/cjson 1.7.19 → CN url 200
  • mcpp-res/nlohmann-json 3.12.0 → CN url 200

Per-changed-package CI

tests/examples/<pkg>/ holds a minimal, self-contained project per library (also runnable by hand: cd tests/examples/cjson && mcpp run). validate.yml now:

  • PR: runs only the example(s) for the packages whose descriptor changed (tests/run_example.sh);
  • push / nightly / dispatch / scaffolding change / changed pkg without an example: runs the full legacy smoke regression.
  • lint + mirror-cn-reachable always run over all descriptors.
  • mcpp pin bumped 0.0.46 → 0.0.67.

Verification (local, real mcpp pipeline)

Both packages were built+run through real mcpp (fetch from the CN mirror → generate → compile → link → run):

  • cjson ok=1 json={"answer":42,"lib":"cJSON"}
  • nlohmann.json ok=true dump={"answer":42,"list":[1,2,3]}

Design doc

.agents/docs/2026-06-27-add-cjson-and-nlohmann-json-plan.md

…kg CI

- compat.cjson @1.7.19 — pure-C source build like compat.zlib; cJSON.c core,
  cJSON_Utils gated behind feature `utils`. CN mirror mcpp-res/cjson.
- nlohmann.json @3.12.0 — exposes `import nlohmann.json;` out of the box.
  Released v3.12.0 ships no module unit, so we provide upstream's official
  src/modules/json.cppm (develop) VERBATIM via generated_files; headers
  pinned to the v3.12.0 release tarball. CN mirror mcpp-res/nlohmann-json.
- tests/examples/<pkg>/ minimal projects + tests/run_example.sh runner.
- validate.yml: PRs run only the example(s) for changed packages; full smoke
  regression runs on push/nightly/dispatch or scaffolding changes. mcpp 0.0.67.
- Both packages verified locally: real mcpp fetch (CN mirror) → generate →
  compile → run.

Design: .agents/docs/2026-06-27-add-cjson-and-nlohmann-json-plan.md
…ump)

The whole-suite portable/full smoke fails on 0.0.67 because that mcpp honors
the gtest `main` feature gating (gtest_main.cc excluded by default → the
legacy gtest smoke link-errors on undefined main). That is pre-existing drift
unrelated to cJSON/nlohmann; updating those smoke scripts belongs in its own
PR. Scope the version: new example jobs run on current 0.0.67 (what users
have, already green), legacy regression stays on its authored 0.0.46.
…rent mcpp

Root cause of the 0.0.67 macos/windows smoke failure (ld64.lld: undefined
symbol: main): smoke_compat_{core,portable}.sh build gtest TEST() cases with
no main() of their own, relying on gtest_main. mcpp 0.0.67 honors the
compat.gtest 'main' feature gating (#168) and excludes gtest_main.cc by
default, so the link fails. 0.0.46 ignored features and always linked it.

Proper fix (verified locally on 0.0.66): declare the dependency as
gtest = { version = "1.15.2", features = ["main"] } — the intended opt-in
that re-includes gtest_main. Smoke now links and runs on the latest mcpp, so
validate.yml is back to a single 0.0.67 across all jobs.
@Sunrisepeak

Copy link
Copy Markdown
Member Author

CI runs on the current release (0.0.67), incl. legacy smoke — root cause of an initial macOS/Windows failure

First CI run bumped mcpp 0.0.46 → 0.0.67 globally and the legacy smoke-macos/smoke-windows jobs failed with ld64.lld: error: undefined symbol: main.

Root cause: smoke_compat_{core,portable}.sh build gtest TEST() cases with no main() of their own, relying on gtest_main. The #168 fix gates gtest_main.cc behind the main feature; mcpp 0.0.67 honors the gating (excludes it by default → no main), while 0.0.46 ignored features and always linked it. So 0.0.46 was masking old-style gtest usage, not being "more correct".

Fix (not a version pin): declare the intended opt-in gtest = { version = "1.15.2", features = ["main"] }. Verified locally on 0.0.66 — full smoke_compat_core.sh runs (Running main() from gtest_main.cc, 2 tests PASSED). validate.yml is therefore unified on 0.0.67 for every job.

@Sunrisepeak

Copy link
Copy Markdown
Member Author

These two legacy smokes depend on compat.glfw (abi=glibc) + GLX runtime. On
mcpp 0.0.67 the window demo resolves a clang/libc++ toolchain for compat.glfw
despite a gcc@16.1.0 pin → 'ABI mismatch: requires abi=glibc'. Same scripts
pass on 0.0.66 locally and glfw builds fine on 0.0.67 elsewhere (linux imgui
smoke, mac/windows portable), so it's an mcpp toolchain-resolution regression
unrelated to package descriptors. Keep them off the PR-blocking path (already
optional, display/ABI-sensitive) but still run on nightly + manual dispatch.
Blocking full-linux keeps core/imgui/archive on 0.0.67.
@Sunrisepeak Sunrisepeak merged commit dd7ff48 into main Jun 27, 2026
9 checks passed
@Sunrisepeak Sunrisepeak deleted the feat/add-cjson-nlohmann-json branch June 27, 2026 10:16
Sunrisepeak added a commit that referenced this pull request Jun 28, 2026
Codifies the full process used for cjson/nlohmann/eigen into a reusable skill
under .agents/skills/add-mcpp-index-package/:
- SKILL.md — 12-step SOP, the sources-only feature gate (+ mandatory negative
  test), version-matched local verification, red-flags/common mistakes.
- package-types.md — descriptor templates for the four shapes (C-source
  compat / header-only / C++23 module via generated wrapper / external Form-A
  module repo), each with real sample paths.
- cn-mirror.md — gtc/gitcode mcpp-res mirror closed loop + every known gotcha.
- references.md — repo layout, descriptor schema cheat-sheet, validate.yml CI
  behavior, one-shot local lint, real worked examples (#48 / #50).
Sunrisepeak added a commit that referenced this pull request Jun 28, 2026
Codifies the full process used for cjson/nlohmann/eigen into a reusable skill
under .agents/skills/add-mcpp-index-package/:
- SKILL.md — 12-step SOP, the sources-only feature gate (+ mandatory negative
  test), version-matched local verification, red-flags/common mistakes.
- package-types.md — descriptor templates for the four shapes (C-source
  compat / header-only / C++23 module via generated wrapper / external Form-A
  module repo), each with real sample paths.
- cn-mirror.md — gtc/gitcode mcpp-res mirror closed loop + every known gotcha.
- references.md — repo layout, descriptor schema cheat-sheet, validate.yml CI
  behavior, one-shot local lint, real worked examples (#48 / #50).
Sunrisepeak added a commit that referenced this pull request Jun 28, 2026
* docs(skills): add `add-mcpp-index-package` agent skill (SOP)

Codifies the full process used for cjson/nlohmann/eigen into a reusable skill
under .agents/skills/add-mcpp-index-package/:
- SKILL.md — 12-step SOP, the sources-only feature gate (+ mandatory negative
  test), version-matched local verification, red-flags/common mistakes.
- package-types.md — descriptor templates for the four shapes (C-source
  compat / header-only / C++23 module via generated wrapper / external Form-A
  module repo), each with real sample paths.
- cn-mirror.md — gtc/gitcode mcpp-res mirror closed loop + every known gotcha.
- references.md — repo layout, descriptor schema cheat-sheet, validate.yml CI
  behavior, one-shot local lint, real worked examples (#48 / #50).

* docs(readme): slim down to intro + usage + contribution + links

Drop the package tables/dependency tree/smoke breakdown/Form-A-B examples from
the index README — the browsable site (mcpplibs.github.io/mcpp-index) is the
package list, and the how-to detail lives in the add-mcpp-index-package skill.
README now = what it is, mcpp add/build usage, the two package categories
(native module libs / third-party compat) with a pointer to the skill, and
related tools / community.

* docs: add docs/, README example table + agent prompt; skill mirror fallback

- Move the skill's reference files into a human-facing docs/ folder (single
  source): package-types.md, cn-mirror.md, repository-and-schema.md (+ index
  docs/README.md). SKILL.md now links to ../../../docs/*; the skill dir keeps
  just SKILL.md (the agent SOP).
- README: add a "参考示例" table linking typical descriptors by shape
  (Form-A module / C-source compat / header-only / module wrapper), a
  copy-paste agent prompt that drives the skill end-to-end, and links to docs/.
- skill + docs: document the no-`mcpp-res`-permission fallback — use a
  plain-string upstream `url` (lint forbids a {GLOBAL,CN} table whose CN isn't
  gitcode/mcpp-res; plain strings are unconstrained). Real precedent:
  pkgs/t/tensorvia-cpu.lua.
- skill step 1 now distinguishes the two sources: a third-party upstream lib
  vs. the user's own mcpp-based library (Form A, lighter research).

* docs: rewrite README/docs/skill in a formal declarative register

Rewrite all prose across README.md, docs/*, and the add-mcpp-index-package
skill into declarative, academic-style Chinese: remove colloquial terms
(一把梭 / 踩坑 / 丢给 / 硬凑 / 藏不住 …) and decorative emoji (⚠️✅❌📘✓),
and reformulate fragments as complete declarative sentences. The red-flag
table becomes a "错误做法 / 正确做法" table; section headings are normalized
(e.g. "本地 lint 一把梭" → "本地 lint 复现(等价于 CI lint job)",
"踩坑" → "注意事项", "CI 兜底" → "CI 保障"). Technical content, commands,
code samples, and links are unchanged.
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