From 6c1663f8885cfb73a49b6bbaa51f3ded407f296e Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sat, 6 Jun 2026 06:01:08 +0800 Subject: [PATCH] docs: add English docs as default language; move Chinese to docs/zh + README.zh-CN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - README.md and docs/ are now English (international default) - Chinese moved to README.zh-CN.md and docs/zh/, content unchanged - Language switch links (English | 简体中文) at the top of both READMEs and both docs indices - Fixed parent-relative links in docs/zh (one level deeper) and the README install anchor in docs/00 - Added missing 06-workspace entry to both docs indices - Existing docs/*.md links from src/, skills, and CHANGELOG keep resolving (English now lives at the original paths) --- README.md | 258 +++++++++--------- README.zh-CN.md | 284 ++++++++++++++++++++ docs/00-getting-started.md | 97 ++++--- docs/01-examples.md | 68 ++--- docs/02-pack-and-release.md | 121 +++++---- docs/03-toolchains.md | 100 +++---- docs/04-build-from-source.md | 109 ++++---- docs/05-mcpp-toml.md | 360 +++++++++++++------------ docs/06-workspace.md | 122 ++++----- docs/README.md | 17 +- docs/zh/00-getting-started.md | 128 +++++++++ docs/zh/01-examples.md | 43 +++ docs/zh/02-pack-and-release.md | 126 +++++++++ docs/zh/03-toolchains.md | 141 ++++++++++ docs/zh/04-build-from-source.md | 104 ++++++++ docs/zh/05-mcpp-toml.md | 449 ++++++++++++++++++++++++++++++++ docs/zh/06-workspace.md | 218 ++++++++++++++++ docs/zh/README.md | 11 + 18 files changed, 2139 insertions(+), 617 deletions(-) create mode 100644 README.zh-CN.md create mode 100644 docs/zh/00-getting-started.md create mode 100644 docs/zh/01-examples.md create mode 100644 docs/zh/02-pack-and-release.md create mode 100644 docs/zh/03-toolchains.md create mode 100644 docs/zh/04-build-from-source.md create mode 100644 docs/zh/05-mcpp-toml.md create mode 100644 docs/zh/06-workspace.md create mode 100644 docs/zh/README.md diff --git a/README.md b/README.md index 7ae84a7e..11ba3862 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,57 @@ # mcpp -> 一个 现代C++ 模块化构建工具 — 纯 C++23 模块编写,已实现自举 +> A modern C++ module-first build tool — written in pure C++23 modules, fully self-hosted + +**English** | [简体中文](README.zh-CN.md) [![Release](https://img.shields.io/github/v/release/mcpp-community/mcpp)](https://github.com/mcpp-community/mcpp/releases) [![C++23](https://img.shields.io/badge/C%2B%2B-23-blue.svg)](https://en.cppreference.com/w/cpp/23) [![Module](https://img.shields.io/badge/module-ok-green.svg)](https://en.cppreference.com/w/cpp/language/modules) [![License](https://img.shields.io/badge/license-Apache_2.0-blue.svg)](LICENSE) -| [文档](docs/) · [快速开始](docs/00-getting-started.md) · [mcpp.toml 指南](docs/05-mcpp-toml.md) · [示例项目](docs/01-examples.md) · [工具链管理](docs/03-toolchains.md) | +| [Documentation](docs/) · [Getting Started](docs/00-getting-started.md) · [mcpp.toml Guide](docs/05-mcpp-toml.md) · [Examples](docs/01-examples.md) · [Toolchains](docs/03-toolchains.md) | |:---:| -| [包索引 mcpp-index](https://github.com/mcpp-community/mcpp-index) · [模块化库 mcpplibs](https://github.com/mcpplibs) · [社区论坛](https://forum.d2learn.org/category/20) · [Issues](https://github.com/mcpp-community/mcpp/issues) · [Releases](https://github.com/mcpp-community/mcpp/releases) | +| [Package index mcpp-index](https://github.com/mcpp-community/mcpp-index) · [Module libraries mcpplibs](https://github.com/mcpplibs) · [Community Forum](https://forum.d2learn.org/category/20) · [Issues](https://github.com/mcpp-community/mcpp/issues) · [Releases](https://github.com/mcpp-community/mcpp/releases) | | [![ci-linux](https://github.com/mcpp-community/mcpp/actions/workflows/ci-linux.yml/badge.svg?branch=main)](https://github.com/mcpp-community/mcpp/actions/workflows/ci-linux.yml) [![ci-macos](https://github.com/mcpp-community/mcpp/actions/workflows/ci-macos.yml/badge.svg?branch=main)](https://github.com/mcpp-community/mcpp/actions/workflows/ci-macos.yml) [![ci-windows](https://github.com/mcpp-community/mcpp/actions/workflows/ci-windows.yml/badge.svg?branch=main)](https://github.com/mcpp-community/mcpp/actions/workflows/ci-windows.yml) |

mcpp demo

-## 核心特性 +## Highlights -- **C++23 模块原生支持** — `import std` 自动处理,文件级增量构建,模块依赖自动分析,零手动配置 -- **纯模块化自举** — mcpp 自身由 43+ 个 C++23 模块组成,用自己构建自己,模块系统经实战验证 -- **开箱即用** — 一条命令安装,内置 GCC 16 / LLVM 20 工具链,自动下载到隔离沙盒,不污染系统 -- **集成依赖管理** — SemVer 约束解析、锁文件、跨项目 BMI 缓存、自定义包索引 -- **多包工作空间** — Workspace 统一锁文件与版本管理,适合大型项目 +- **Native C++23 module support** — `import std` handled automatically, file-level incremental builds, automatic module dependency analysis, zero manual configuration +- **Pure modular self-hosting** — mcpp itself consists of 43+ C++23 modules and builds itself; the module pipeline is battle-tested +- **Works out of the box** — one-command install, bundled GCC 16 / LLVM 20 toolchains downloaded into an isolated sandbox, never polluting your system +- **Integrated dependency management** — SemVer constraint resolution, lockfile, cross-project BMI cache, custom package indices +- **Multi-package workspaces** — unified lockfile and version management for larger projects -## 为什么选择 mcpp +## Why mcpp -mcpp 专门为 **C++23 模块化开发** 打造。如果你想在项目中使用 `import std`、模块接口单元(`.cppm`)、模块分区等现代 C++ 特性,mcpp 在 Linux 和 macOS ARM64 上能为你提供便捷且友好的开发体验: +mcpp is built specifically for **C++23 module-first development**. If you want to use `import std`, module interface units (`.cppm`), module partitions, and other modern C++ features in your project, mcpp gives you a smooth, friendly experience on Linux and macOS ARM64: -- **默认模块化** — `mcpp new` 创建的项目模板直接使用 C++23 模块,`import std` 开箱即用 -- **文件级增量构建** — 基于 P1689 dyndep 的三层优化(前端脏检查 + 逐文件扫描 + BMI restat),只重编真正变化的模块 -- **一键创建 & 构建** — `mcpp new hello && cd hello && mcpp build`,工具链自动安装,无需手动配置编译器和构建系统 -- **模块化生态** — [mcpplibs](https://github.com/mcpplibs) 提供一系列可直接 `import` 的 C++ 模块化库,支持自定义包索引 +- **Modular by default** — projects created by `mcpp new` use C++23 modules directly; `import std` just works +- **File-level incremental builds** — three-layer optimization based on P1689 dyndep (front-end dirty check + per-file scanning + BMI restat); only the modules that actually changed get recompiled +- **Create & build in one go** — `mcpp new hello && cd hello && mcpp build`; toolchains install automatically, no compiler or build-system setup required +- **A modular ecosystem** — [mcpplibs](https://github.com/mcpplibs) offers a growing set of directly `import`-able C++ module libraries, plus support for custom package indices > [!NOTE] -> **早期版本** — mcpp 仍在积极开发中,接口和行为可能在后续版本调整。 -> 欢迎对现代 C++ 模块化构建工具感兴趣的开发者[参与贡献](#参与贡献)。 -> 问题 / 反馈 / 想法欢迎在 [issues](https://github.com/mcpp-community/mcpp/issues) 留言。 +> **Early-stage project** — mcpp is under active development; interfaces and behavior may change in future releases. +> Developers interested in modern C++ module-first build tooling are welcome to [contribute](#contributing). +> Questions / feedback / ideas — drop a note in [issues](https://github.com/mcpp-community/mcpp/issues). -## 快速开始 +## Getting Started -### 安装 +### Install -**方式一:使用 xlings 安装(推荐)** +**Option 1: install via xlings (recommended)** ```bash xlings install mcpp -y ```
-还没有 xlings?点击查看安装命令 +Don't have xlings yet? Click for the install command **Linux / macOS** ```bash @@ -61,29 +63,29 @@ curl -fsSL https://d2learn.org/xlings-install.sh | bash irm https://d2learn.org/xlings-install.ps1.txt | iex ``` -> xlings 详情 → [xlings.d2learn.org](https://xlings.d2learn.org) +> More about xlings → [xlings.d2learn.org](https://xlings.d2learn.org)
-**方式二:一键安装脚本** +**Option 2: one-line install script** ```bash curl -fsSL https://github.com/mcpp-community/mcpp/releases/latest/download/install.sh | bash ``` -安装到 `~/.mcpp/`,自动加进 shell PATH。删除 `~/.mcpp` 即可干净卸载。 +Installs into `~/.mcpp/` and adds it to your shell PATH. Deleting `~/.mcpp` uninstalls cleanly. -**方式三:让 AI 助手帮你安装** +**Option 3: let an AI assistant install it for you** -将以下提示词复制给你的 AI 编码助手(Claude Code / Cursor / Copilot 等): +Copy the following prompt to your AI coding assistant (Claude Code / Cursor / Copilot, etc.): ``` -阅读 https://github.com/mcpp-community/mcpp 的 README, -帮我安装 mcpp 并创建一个 C++23 模块项目,构建并运行。 -项目的 .agents/skills/mcpp-usage/SKILL.md 有详细的使用指南。 +Read the README of https://github.com/mcpp-community/mcpp, +then install mcpp for me and create a C++23 module project, build and run it. +The repo's .agents/skills/mcpp-usage/SKILL.md has a detailed usage guide. ``` -### 创建项目 & 构建运行 +### Create, build & run a project ```bash mcpp new hello @@ -92,15 +94,15 @@ mcpp build mcpp run ``` -> 注:首次构建会初始化环境并获取工具链,可能需要一些时间。 +> Note: the first build initializes the environment and fetches the toolchain, which may take a while. -### 项目结构 +### Project layout ``` hello/ -├── mcpp.toml ← 工程描述 +├── mcpp.toml ← project manifest └── src/ - └── main.cpp ← import std; 直接可用 + └── main.cpp ← import std; works directly ``` ```toml @@ -113,170 +115,170 @@ kind = "bin" main = "src/main.cpp" ``` -### 使用模块化库 +### Using module libraries -在 `mcpp.toml` 中添加两行依赖,即可引用 [mcpplibs](https://github.com/mcpplibs) 社区模块化库: +Add a two-line dependency to `mcpp.toml` to pull in a community module library from [mcpplibs](https://github.com/mcpplibs): ```toml [dependencies] cmdline = "0.0.2" ``` -然后在代码中直接 `import`: +Then `import` it directly in your code: ```cpp import mcpplibs.cmdline; ``` -> 更多依赖配置方式(版本约束、命名空间、Git 引用、本地路径等)参见 [mcpp.toml 指南 — 依赖管理](docs/05-mcpp-toml.md)。 +> For more dependency options (version constraints, namespaces, Git references, local paths, etc.), see the [mcpp.toml guide — dependency management](docs/05-mcpp-toml.md). -## 功能概览 +## Feature Overview
-构建系统 +Build system -- C++20/23 模块原生支持(接口单元、实现单元、模块分区) -- `import std` / `import std.compat` 全自动预编译与缓存 -- 三层增量优化:前端脏检查 + 逐文件 P1689 dyndep + BMI copy-if-different restat -- 指纹化 BMI 缓存:按编译器/标志/标准库哈希,跨项目共享 -- Ninja 后端:自动生成 build.ninja,并行编译 -- compile_commands.json 自动生成(clangd / ccls 即用) -- C 语言一等支持:`.c` 文件自动检测,混合 C/C++ 项目 -- 用户自定义 cflags / cxxflags / ldflags / c_standard +- Native C++20/23 module support (interface units, implementation units, module partitions) +- Fully automatic precompilation and caching of `import std` / `import std.compat` +- Three-layer incremental optimization: front-end dirty check + per-file P1689 dyndep + BMI copy-if-different restat +- Fingerprinted BMI cache: hashed by compiler/flags/standard library, shared across projects +- Ninja backend: auto-generated build.ninja, parallel compilation +- compile_commands.json generated automatically (ready for clangd / ccls) +- First-class C support: `.c` files auto-detected, mixed C/C++ projects +- User-defined cflags / cxxflags / ldflags / c_standard
-工具链管理 +Toolchain management -- 内置 GCC 16.1.0 + LLVM/Clang 20.1.7,一键安装 -- musl-gcc 全静态工具链(默认) -- 多版本共存:`mcpp toolchain install gcc 16` / `mcpp toolchain install llvm 20` -- 隔离沙盒:所有工具链在 `~/.mcpp/registry/`,不影响系统 -- 按平台指定:`linux = "gcc@16"`, `macos = "llvm@20"` -- GCC + Clang 编译管线平权(`BmiTraits` 抽象层驱动) +- Bundled GCC 16.1.0 + LLVM/Clang 20.1.7, one-command install +- Fully static musl-gcc toolchain (default) +- Multiple versions side by side: `mcpp toolchain install gcc 16` / `mcpp toolchain install llvm 20` +- Isolated sandbox: all toolchains live in `~/.mcpp/registry/`, leaving the system untouched +- Per-platform selection: `linux = "gcc@16"`, `macos = "llvm@20"` +- GCC and Clang compile pipelines at parity (driven by the `BmiTraits` abstraction layer)
-包管理与依赖 +Package & dependency management -- SemVer 约束解析:`^`、`~`、范围、精确版本 -- 三级解析:约束合并 → 多版本 mangling 回退 → 精确匹配 -- 锁文件 mcpp.lock(v2 格式:索引快照 + 命名空间) -- 命名空间系统:`[dependencies.myteam] foo = "1.0"` -- 自定义包索引:`[indices] acme = "git@..."` / `{ path = "..." }` -- 项目级索引隔离(`.mcpp/` 目录,不污染全局) -- 依赖来源:索引 / Git / 本地路径 +- SemVer constraint resolution: `^`, `~`, ranges, exact versions +- Three-stage resolution: constraint merging → multi-version mangling fallback → exact match +- Lockfile mcpp.lock (v2 format: index snapshot + namespaces) +- Namespace system: `[dependencies.myteam] foo = "1.0"` +- Custom package indices: `[indices] acme = "git@..."` / `{ path = "..." }` +- Project-level index isolation (`.mcpp/` directory, no global pollution) +- Dependency sources: index / Git / local path
-工作空间 +Workspaces - `[workspace] members = ["libs/*", "apps/*"]` -- 统一锁文件 + 统一 target 目录 -- 版本集中管理:`[workspace.dependencies]` + `.workspace = true` -- 选择性构建:`mcpp build -p member-name` -- 配置继承:工具链、构建标志、索引从根级联到成员 +- Unified lockfile + unified target directory +- Centralized version management: `[workspace.dependencies]` + `.workspace = true` +- Selective builds: `mcpp build -p member-name` +- Config inheritance: toolchains, build flags, and indices cascade from root to members
-打包与发布 +Packaging & publishing -- `mcpp pack`:三种 Linux 发布模式 — static(musl全静态)/ bundle-project / bundle-all -- musl 全静态二进制:单文件可分发,无 glibc 依赖(Linux x86_64) -- `mcpp publish`:生成 xpkg.lua + 发布到包索引 -- 自动 patchelf 修正 RPATH(Linux) +- `mcpp pack`: three Linux release modes — static (fully static musl) / bundle-project / bundle-all +- Fully static musl binaries: single-file distribution, no glibc dependency (Linux x86_64) +- `mcpp publish`: generates xpkg.lua + publishes to a package index +- Automatic RPATH fix-up via patchelf (Linux)
-开发体验 +Developer experience -- `mcpp new` — 创建模块化项目;`--template [@ver][:]` 使用**库自带模板**(如 `--template imgui`),`--list-templates ` 列举 -- `mcpp run [-- args]` — 构建并运行 -- `mcpp test [-- args]` — 自动发现并运行测试 -- `mcpp search` — 搜索包索引 -- `mcpp add / remove / update` — 依赖管理 -- `mcpp explain E0001` — 错误码详细解释 -- `mcpp self doctor` — 环境自诊断 +- `mcpp new` — create a modular project; `--template [@ver][:]` uses a **library-provided template** (e.g. `--template imgui`); `--list-templates ` lists them +- `mcpp run [-- args]` — build and run +- `mcpp test [-- args]` — auto-discover and run tests +- `mcpp search` — search package indices +- `mcpp add / remove / update` — dependency management +- `mcpp explain E0001` — detailed error-code explanations +- `mcpp self doctor` — environment self-diagnosis
-## 平台支持 +## Platform Support | OS / arch | GCC (glibc) | GCC (musl) | Clang / LLVM | MSVC | |------------------|:-----------:|:----------:|:------------:|:----:| -| Linux x86_64 | ✅ | ✅ *默认* | ✅ | — | +| Linux x86_64 | ✅ | ✅ *default* | ✅ | — | | Linux aarch64 | 🔄 | 🔄 | 🔄 | — | -| macOS arm64 | — | — | ✅ *默认* | — | +| macOS arm64 | — | — | ✅ *default* | — | | macOS x86_64 | — | — | 🔄 | — | -| Windows x86_64 | — | — | ✅ ¹ *默认* | 🔄 | +| Windows x86_64 | — | — | ✅ ¹ *default* | 🔄 | -✅ 已支持 | 🔄 计划中 +✅ supported | 🔄 planned -> *默认*:Linux 默认工具链为 musl-gcc,release 二进制走 musl 全静态; -> macOS ARM64 / Windows x86_64 默认工具链均为 LLVM/Clang。 +> *default*: the default toolchain on Linux is musl-gcc; release binaries are fully static musl builds. +> The default toolchain on macOS ARM64 / Windows x86_64 is LLVM/Clang. > -> ¹ Windows 上 Clang/LLVM 当前依赖系统已安装 **MSVC BuildTools 或 Visual Studio** -> (提供 UCRT、Windows SDK、MSVC STL)。零-MSVC 依赖的 `llvm-mingw` 路线在规划中 -> ([讨论](https://github.com/mcpp-community/mcpp/issues))。 +> ¹ On Windows, Clang/LLVM currently requires an existing **MSVC BuildTools or Visual Studio** installation +> (providing the UCRT, Windows SDK, and MSVC STL). A zero-MSVC `llvm-mingw` route is planned +> ([discussion](https://github.com/mcpp-community/mcpp/issues)). -## 文档 +## Documentation -- [快速开始](docs/00-getting-started.md) — 5 分钟完成 install → new → build → run -- [示例项目](docs/01-examples.md) -- [发布打包](docs/02-pack-and-release.md) -- [工具链管理](docs/03-toolchains.md) -- [从源码构建](docs/04-build-from-source.md) -- [mcpp.toml 指南](docs/05-mcpp-toml.md) -- [工作空间](docs/06-workspace.md) +- [Getting Started](docs/00-getting-started.md) — install → new → build → run in 5 minutes +- [Examples](docs/01-examples.md) +- [Packaging & Release](docs/02-pack-and-release.md) +- [Toolchain Management](docs/03-toolchains.md) +- [Building from Source](docs/04-build-from-source.md) +- [mcpp.toml Guide](docs/05-mcpp-toml.md) +- [Workspaces](docs/06-workspace.md) -任意命令的完整选项可通过 `mcpp --help` 查阅。 +Full options for any command are available via `mcpp --help`. -**AI 辅助学习**:你可以将以下提示词发给 AI 编码助手,让它帮你快速了解 mcpp: +**AI-assisted learning**: send the following prompt to an AI coding assistant to get up to speed with mcpp quickly: ``` -阅读 https://github.com/mcpp-community/mcpp 仓库的 -.agents/skills/mcpp-usage/SKILL.md 和 docs/ 目录下的文档, -告诉我如何用 mcpp 创建一个带依赖的 C++23 模块项目。 +Read .agents/skills/mcpp-usage/SKILL.md and the docs/ directory of the +https://github.com/mcpp-community/mcpp repository, +then tell me how to create a C++23 module project with dependencies using mcpp. ``` -## 参与贡献 +## Contributing -欢迎通过 Issue 和 PR 参与项目开发。项目接受开发者使用 AI Agent 参与开发与贡献。 +Contributions via issues and PRs are welcome. The project accepts contributions developed with AI agents. -**基本流程** +**Basic workflow** -1. 创建 Issue — Bug 修复、新功能、优化等,先在 [issues](https://github.com/mcpp-community/mcpp/issues) 创建讨论 -2. 实现改动 — Fork 仓库,创建分支,实现并验证(`mcpp build` + E2E 测试) -3. 提交 PR — 使用 `gh pr create`,确保 CI 通过 -4. CI 必须通过 — CI 不通过的 PR 不会被合入 +1. Open an issue — for bug fixes, new features, or improvements, start a discussion in [issues](https://github.com/mcpp-community/mcpp/issues) first +2. Implement the change — fork the repo, create a branch, implement and verify (`mcpp build` + E2E tests) +3. Submit a PR — use `gh pr create` and make sure CI passes +4. CI must pass — PRs with failing CI will not be merged -**提交信息规范**:`feat:` / `fix:` / `test:` / `docs:` / `refactor:` 前缀 +**Commit message convention**: `feat:` / `fix:` / `test:` / `docs:` / `refactor:` prefixes -**AI Agent 贡献**:项目的 [`.agents/skills/mcpp-contributing/SKILL.md`](.agents/skills/mcpp-contributing/SKILL.md) 提供了完整的 Agent 贡献流程和项目结构说明。将以下提示词发给 AI 助手即可: +**AI agent contributions**: the repo's [`.agents/skills/mcpp-contributing/SKILL.md`](.agents/skills/mcpp-contributing/SKILL.md) provides a complete agent contribution workflow and project structure guide. Just send this prompt to your AI assistant: ``` -阅读 https://github.com/mcpp-community/mcpp 仓库的 -.agents/skills/mcpp-contributing/SKILL.md, -按照指南帮我给 mcpp 项目提交一个贡献。 +Read .agents/skills/mcpp-contributing/SKILL.md of the +https://github.com/mcpp-community/mcpp repository, +then follow the guide to help me submit a contribution to mcpp. ``` -## 社区 & 生态 +## Community & Ecosystem -- [社区论坛](https://forum.d2learn.org/category/20) — 交流群 (Q: 1067245099) -- [mcpp-index](https://github.com/mcpp-community/mcpp-index) — 默认包索引 -- [mcpplibs](https://github.com/mcpplibs) — 模块化 C++ 库集合 +- [Community Forum](https://forum.d2learn.org/category/20) — chat group (QQ: 1067245099) +- [mcpp-index](https://github.com/mcpp-community/mcpp-index) — default package index +- [mcpplibs](https://github.com/mcpplibs) — collection of modular C++ libraries -### 致谢 +### Acknowledgements -项目依赖和灵感来源: +Dependencies and sources of inspiration: -- [xlings](https://github.com/d2learn/xlings) — 工具链 / 包管理底座 -- [mcpplibs.cmdline](https://github.com/mcpplibs/cmdline) — CLI 框架 -- [ninja](https://github.com/ninja-build/ninja) — 底层构建引擎 -- [xmake](https://github.com/xmake-io/xmake) — 跨平台构建工具 -- [cargo](https://github.com/rust-lang/cargo) — Rust 包管理器 +- [xlings](https://github.com/d2learn/xlings) — toolchain / package-management foundation +- [mcpplibs.cmdline](https://github.com/mcpplibs/cmdline) — CLI framework +- [ninja](https://github.com/ninja-build/ninja) — underlying build engine +- [xmake](https://github.com/xmake-io/xmake) — cross-platform build tool +- [cargo](https://github.com/rust-lang/cargo) — Rust package manager diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 00000000..783438de --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,284 @@ +# mcpp + +> 一个 现代C++ 模块化构建工具 — 纯 C++23 模块编写,已实现自举 + +[English](README.md) | **简体中文** + +[![Release](https://img.shields.io/github/v/release/mcpp-community/mcpp)](https://github.com/mcpp-community/mcpp/releases) +[![C++23](https://img.shields.io/badge/C%2B%2B-23-blue.svg)](https://en.cppreference.com/w/cpp/23) +[![Module](https://img.shields.io/badge/module-ok-green.svg)](https://en.cppreference.com/w/cpp/language/modules) +[![License](https://img.shields.io/badge/license-Apache_2.0-blue.svg)](LICENSE) + +| [文档](docs/zh/) · [快速开始](docs/zh/00-getting-started.md) · [mcpp.toml 指南](docs/zh/05-mcpp-toml.md) · [示例项目](docs/zh/01-examples.md) · [工具链管理](docs/zh/03-toolchains.md) | +|:---:| +| [包索引 mcpp-index](https://github.com/mcpp-community/mcpp-index) · [模块化库 mcpplibs](https://github.com/mcpplibs) · [社区论坛](https://forum.d2learn.org/category/20) · [Issues](https://github.com/mcpp-community/mcpp/issues) · [Releases](https://github.com/mcpp-community/mcpp/releases) | +| [![ci-linux](https://github.com/mcpp-community/mcpp/actions/workflows/ci-linux.yml/badge.svg?branch=main)](https://github.com/mcpp-community/mcpp/actions/workflows/ci-linux.yml) [![ci-macos](https://github.com/mcpp-community/mcpp/actions/workflows/ci-macos.yml/badge.svg?branch=main)](https://github.com/mcpp-community/mcpp/actions/workflows/ci-macos.yml) [![ci-windows](https://github.com/mcpp-community/mcpp/actions/workflows/ci-windows.yml/badge.svg?branch=main)](https://github.com/mcpp-community/mcpp/actions/workflows/ci-windows.yml) | + +

+ mcpp demo +

+ +## 核心特性 + +- **C++23 模块原生支持** — `import std` 自动处理,文件级增量构建,模块依赖自动分析,零手动配置 +- **纯模块化自举** — mcpp 自身由 43+ 个 C++23 模块组成,用自己构建自己,模块系统经实战验证 +- **开箱即用** — 一条命令安装,内置 GCC 16 / LLVM 20 工具链,自动下载到隔离沙盒,不污染系统 +- **集成依赖管理** — SemVer 约束解析、锁文件、跨项目 BMI 缓存、自定义包索引 +- **多包工作空间** — Workspace 统一锁文件与版本管理,适合大型项目 + +## 为什么选择 mcpp + +mcpp 专门为 **C++23 模块化开发** 打造。如果你想在项目中使用 `import std`、模块接口单元(`.cppm`)、模块分区等现代 C++ 特性,mcpp 在 Linux 和 macOS ARM64 上能为你提供便捷且友好的开发体验: + +- **默认模块化** — `mcpp new` 创建的项目模板直接使用 C++23 模块,`import std` 开箱即用 +- **文件级增量构建** — 基于 P1689 dyndep 的三层优化(前端脏检查 + 逐文件扫描 + BMI restat),只重编真正变化的模块 +- **一键创建 & 构建** — `mcpp new hello && cd hello && mcpp build`,工具链自动安装,无需手动配置编译器和构建系统 +- **模块化生态** — [mcpplibs](https://github.com/mcpplibs) 提供一系列可直接 `import` 的 C++ 模块化库,支持自定义包索引 + +> [!NOTE] +> **早期版本** — mcpp 仍在积极开发中,接口和行为可能在后续版本调整。 +> 欢迎对现代 C++ 模块化构建工具感兴趣的开发者[参与贡献](#参与贡献)。 +> 问题 / 反馈 / 想法欢迎在 [issues](https://github.com/mcpp-community/mcpp/issues) 留言。 + +## 快速开始 + +### 安装 + +**方式一:使用 xlings 安装(推荐)** + +```bash +xlings install mcpp -y +``` + +
+还没有 xlings?点击查看安装命令 + +**Linux / macOS** +```bash +curl -fsSL https://d2learn.org/xlings-install.sh | bash +``` + +**Windows — PowerShell** +```powershell +irm https://d2learn.org/xlings-install.ps1.txt | iex +``` + +> xlings 详情 → [xlings.d2learn.org](https://xlings.d2learn.org) + +
+ +**方式二:一键安装脚本** + +```bash +curl -fsSL https://github.com/mcpp-community/mcpp/releases/latest/download/install.sh | bash +``` + +安装到 `~/.mcpp/`,自动加进 shell PATH。删除 `~/.mcpp` 即可干净卸载。 + +**方式三:让 AI 助手帮你安装** + +将以下提示词复制给你的 AI 编码助手(Claude Code / Cursor / Copilot 等): + +``` +阅读 https://github.com/mcpp-community/mcpp 的 README, +帮我安装 mcpp 并创建一个 C++23 模块项目,构建并运行。 +项目的 .agents/skills/mcpp-usage/SKILL.md 有详细的使用指南。 +``` + +### 创建项目 & 构建运行 + +```bash +mcpp new hello +cd hello +mcpp build +mcpp run +``` + +> 注:首次构建会初始化环境并获取工具链,可能需要一些时间。 + +### 项目结构 + +``` +hello/ +├── mcpp.toml ← 工程描述 +└── src/ + └── main.cpp ← import std; 直接可用 +``` + +```toml +# mcpp.toml +[package] +name = "hello" + +[targets.hello] +kind = "bin" +main = "src/main.cpp" +``` + +### 使用模块化库 + +在 `mcpp.toml` 中添加两行依赖,即可引用 [mcpplibs](https://github.com/mcpplibs) 社区模块化库: + +```toml +[dependencies] +cmdline = "0.0.2" +``` + +然后在代码中直接 `import`: + +```cpp +import mcpplibs.cmdline; +``` + +> 更多依赖配置方式(版本约束、命名空间、Git 引用、本地路径等)参见 [mcpp.toml 指南 — 依赖管理](docs/zh/05-mcpp-toml.md)。 + +## 功能概览 + +
+构建系统 + +- C++20/23 模块原生支持(接口单元、实现单元、模块分区) +- `import std` / `import std.compat` 全自动预编译与缓存 +- 三层增量优化:前端脏检查 + 逐文件 P1689 dyndep + BMI copy-if-different restat +- 指纹化 BMI 缓存:按编译器/标志/标准库哈希,跨项目共享 +- Ninja 后端:自动生成 build.ninja,并行编译 +- compile_commands.json 自动生成(clangd / ccls 即用) +- C 语言一等支持:`.c` 文件自动检测,混合 C/C++ 项目 +- 用户自定义 cflags / cxxflags / ldflags / c_standard + +
+ +
+工具链管理 + +- 内置 GCC 16.1.0 + LLVM/Clang 20.1.7,一键安装 +- musl-gcc 全静态工具链(默认) +- 多版本共存:`mcpp toolchain install gcc 16` / `mcpp toolchain install llvm 20` +- 隔离沙盒:所有工具链在 `~/.mcpp/registry/`,不影响系统 +- 按平台指定:`linux = "gcc@16"`, `macos = "llvm@20"` +- GCC + Clang 编译管线平权(`BmiTraits` 抽象层驱动) + +
+ +
+包管理与依赖 + +- SemVer 约束解析:`^`、`~`、范围、精确版本 +- 三级解析:约束合并 → 多版本 mangling 回退 → 精确匹配 +- 锁文件 mcpp.lock(v2 格式:索引快照 + 命名空间) +- 命名空间系统:`[dependencies.myteam] foo = "1.0"` +- 自定义包索引:`[indices] acme = "git@..."` / `{ path = "..." }` +- 项目级索引隔离(`.mcpp/` 目录,不污染全局) +- 依赖来源:索引 / Git / 本地路径 + +
+ +
+工作空间 + +- `[workspace] members = ["libs/*", "apps/*"]` +- 统一锁文件 + 统一 target 目录 +- 版本集中管理:`[workspace.dependencies]` + `.workspace = true` +- 选择性构建:`mcpp build -p member-name` +- 配置继承:工具链、构建标志、索引从根级联到成员 + +
+ +
+打包与发布 + +- `mcpp pack`:三种 Linux 发布模式 — static(musl全静态)/ bundle-project / bundle-all +- musl 全静态二进制:单文件可分发,无 glibc 依赖(Linux x86_64) +- `mcpp publish`:生成 xpkg.lua + 发布到包索引 +- 自动 patchelf 修正 RPATH(Linux) + +
+ +
+开发体验 + +- `mcpp new` — 创建模块化项目;`--template [@ver][:]` 使用**库自带模板**(如 `--template imgui`),`--list-templates ` 列举 +- `mcpp run [-- args]` — 构建并运行 +- `mcpp test [-- args]` — 自动发现并运行测试 +- `mcpp search` — 搜索包索引 +- `mcpp add / remove / update` — 依赖管理 +- `mcpp explain E0001` — 错误码详细解释 +- `mcpp self doctor` — 环境自诊断 + +
+ +## 平台支持 + +| OS / arch | GCC (glibc) | GCC (musl) | Clang / LLVM | MSVC | +|------------------|:-----------:|:----------:|:------------:|:----:| +| Linux x86_64 | ✅ | ✅ *默认* | ✅ | — | +| Linux aarch64 | 🔄 | 🔄 | 🔄 | — | +| macOS arm64 | — | — | ✅ *默认* | — | +| macOS x86_64 | — | — | 🔄 | — | +| Windows x86_64 | — | — | ✅ ¹ *默认* | 🔄 | + +✅ 已支持 | 🔄 计划中 + +> *默认*:Linux 默认工具链为 musl-gcc,release 二进制走 musl 全静态; +> macOS ARM64 / Windows x86_64 默认工具链均为 LLVM/Clang。 +> +> ¹ Windows 上 Clang/LLVM 当前依赖系统已安装 **MSVC BuildTools 或 Visual Studio** +> (提供 UCRT、Windows SDK、MSVC STL)。零-MSVC 依赖的 `llvm-mingw` 路线在规划中 +> ([讨论](https://github.com/mcpp-community/mcpp/issues))。 + +## 文档 + +- [快速开始](docs/zh/00-getting-started.md) — 5 分钟完成 install → new → build → run +- [示例项目](docs/zh/01-examples.md) +- [发布打包](docs/zh/02-pack-and-release.md) +- [工具链管理](docs/zh/03-toolchains.md) +- [从源码构建](docs/zh/04-build-from-source.md) +- [mcpp.toml 指南](docs/zh/05-mcpp-toml.md) +- [工作空间](docs/zh/06-workspace.md) + +任意命令的完整选项可通过 `mcpp --help` 查阅。 + +**AI 辅助学习**:你可以将以下提示词发给 AI 编码助手,让它帮你快速了解 mcpp: + +``` +阅读 https://github.com/mcpp-community/mcpp 仓库的 +.agents/skills/mcpp-usage/SKILL.md 和 docs/ 目录下的文档, +告诉我如何用 mcpp 创建一个带依赖的 C++23 模块项目。 +``` + +## 参与贡献 + +欢迎通过 Issue 和 PR 参与项目开发。项目接受开发者使用 AI Agent 参与开发与贡献。 + +**基本流程** + +1. 创建 Issue — Bug 修复、新功能、优化等,先在 [issues](https://github.com/mcpp-community/mcpp/issues) 创建讨论 +2. 实现改动 — Fork 仓库,创建分支,实现并验证(`mcpp build` + E2E 测试) +3. 提交 PR — 使用 `gh pr create`,确保 CI 通过 +4. CI 必须通过 — CI 不通过的 PR 不会被合入 + +**提交信息规范**:`feat:` / `fix:` / `test:` / `docs:` / `refactor:` 前缀 + +**AI Agent 贡献**:项目的 [`.agents/skills/mcpp-contributing/SKILL.md`](.agents/skills/mcpp-contributing/SKILL.md) 提供了完整的 Agent 贡献流程和项目结构说明。将以下提示词发给 AI 助手即可: + +``` +阅读 https://github.com/mcpp-community/mcpp 仓库的 +.agents/skills/mcpp-contributing/SKILL.md, +按照指南帮我给 mcpp 项目提交一个贡献。 +``` + +## 社区 & 生态 + +- [社区论坛](https://forum.d2learn.org/category/20) — 交流群 (Q: 1067245099) +- [mcpp-index](https://github.com/mcpp-community/mcpp-index) — 默认包索引 +- [mcpplibs](https://github.com/mcpplibs) — 模块化 C++ 库集合 + +### 致谢 + +项目依赖和灵感来源: + +- [xlings](https://github.com/d2learn/xlings) — 工具链 / 包管理底座 +- [mcpplibs.cmdline](https://github.com/mcpplibs/cmdline) — CLI 框架 +- [ninja](https://github.com/ninja-build/ninja) — 底层构建引擎 +- [xmake](https://github.com/xmake-io/xmake) — 跨平台构建工具 +- [cargo](https://github.com/rust-lang/cargo) — Rust 包管理器 diff --git a/docs/00-getting-started.md b/docs/00-getting-started.md index 13c48c07..5525a1ae 100644 --- a/docs/00-getting-started.md +++ b/docs/00-getting-started.md @@ -1,30 +1,28 @@ -# 00 — 快速开始 +# 00 — Getting Started -> 5 分钟完成 install → new → build → run → pack 全流程。 +> Go from install → new → build → run → pack in 5 minutes. -## 安装 +## Installation -仅需 Linux x86_64 或 macOS ARM64 环境,无需预先安装 GCC、xlings 或其他依赖。 -mcpp 在首次运行时会将默认工具链安装至独立沙盒(`~/.mcpp/`)。 -Linux 默认使用 musl-gcc,macOS 默认使用 LLVM/Clang。 +You only need a Linux x86_64 or macOS ARM64 environment — no need to install GCC, xlings, or any other dependencies beforehand. +On its first run, mcpp installs the default toolchain into an isolated sandbox (`~/.mcpp/`). +Linux defaults to musl-gcc, while macOS defaults to LLVM/Clang. -推荐通过 [xlings](https://xlings.d2learn.org) 进行安装,可与系统 -环境保持隔离: +We recommend installing via [xlings](https://xlings.d2learn.org), which keeps mcpp isolated from your system environment: ```bash xlings install mcpp -y ``` -或使用一键安装脚本(内置 xlings,统一安装至 `~/.mcpp/`): +Alternatively, use the one-line installer script (xlings is bundled, and everything is installed under `~/.mcpp/`): ```bash curl -fsSL https://github.com/mcpp-community/mcpp/releases/latest/download/install.sh | bash ``` -完整安装说明(包括 xlings 安装命令、Windows 支持等)参见 -[README 的"安装"小节](../README.md#安装)。 +For full installation instructions (including xlings install commands, Windows support, and more), see the ["Installation" section of the README](../README.md#install). -安装完成后,启动新的 shell 会话或执行 `source ~/.bashrc`,然后验证: +Once installation is complete, start a new shell session or run `source ~/.bashrc`, then verify: ```bash mcpp --version @@ -32,27 +30,28 @@ mcpp --version ``` > [!TIP] -> 若提示 `command not found`,通常是 `~/.mcpp/bin` 尚未加入当前 shell -> 的 PATH。重启终端,或执行 `source ~/.bashrc`(zsh 对应 `~/.zshrc`, -> fish 使用 `exec fish`)即可生效。也可直接通过绝对路径 -> `~/.mcpp/bin/mcpp` 调用。 +> If you get `command not found`, it usually means `~/.mcpp/bin` has not yet +> been added to the current shell's PATH. Restart your terminal, or run +> `source ~/.bashrc` (use `~/.zshrc` for zsh, or `exec fish` for fish) to +> apply the change. You can also invoke mcpp directly via its absolute path +> `~/.mcpp/bin/mcpp`. -## 创建项目 +## Creating a Project ```bash mcpp new hello && cd hello ``` -生成的目录结构如下: +This generates the following directory structure: ``` hello/ -├── mcpp.toml ← 工程描述 +├── mcpp.toml ← project manifest └── src/ └── main.cpp ``` -`src/main.cpp` 默认为 C++23 模块化的 hello world: +By default, `src/main.cpp` is a C++23 modular hello world: ```cpp import std; @@ -63,7 +62,7 @@ int main() { } ``` -## 构建与运行 +## Building and Running ```bash mcpp build @@ -75,54 +74,54 @@ mcpp run # Built with import std + std::println on modular C++23. ``` -首次构建需下载默认工具链(Linux 为 musl-gcc 15.1,macOS 为 LLVM/Clang 20.1), -期间显示进度与速度。下载完成后,所有 mcpp 项目共用同一份沙盒。 +The first build downloads the default toolchain (musl-gcc 15.1 on Linux, LLVM/Clang 20.1 on macOS), +showing progress and speed along the way. Once downloaded, all mcpp projects share the same sandbox. -## 增量编译与测试 +## Incremental Compilation and Testing ```bash -mcpp build # 增量构建 -mcpp clean # 清理 target/ -mcpp test # 编译并运行 tests/**/*.cpp(gtest 风格) +mcpp build # incremental build +mcpp clean # clean target/ +mcpp test # compile and run tests/**/*.cpp (gtest style) ``` -## 添加依赖 +## Adding Dependencies -在 `mcpp.toml` 中声明依赖: +Declare dependencies in `mcpp.toml`: ```toml [dependencies] "mcpplibs.cmdline" = "^0.0.1" ``` -`mcpp build` 将自动从 -[mcpp-index](https://github.com/mcpp-community/mcpp-index) 解析 SemVer -约束、拉取源码并加入编译图。完整示例参见 -[01 — 示例项目](01-examples.md) 中的 `02-with-deps`。 +`mcpp build` automatically resolves SemVer constraints against the +[mcpp-index](https://github.com/mcpp-community/mcpp-index), fetches the source, +and adds it to the build graph. For a complete example, see `02-with-deps` in +[01 — Examples](01-examples.md). -## 生成发布包 +## Producing a Release Package -`mcpp pack` 将构建产物与运行期依赖打包为可独立分发的 tarball: +`mcpp pack` bundles your build artifacts and runtime dependencies into a self-contained tarball that can be distributed independently: ```bash -mcpp pack # 默认 bundle-project,包含项目第三方 .so -mcpp pack --mode static # 全静态(musl) -mcpp pack --mode bundle-all # 全自包含,含 libc 与 ld-linux +mcpp pack # default bundle-project, includes the project's third-party .so files +mcpp pack --mode static # fully static (musl) +mcpp pack --mode bundle-all # fully self-contained, including libc and ld-linux ``` -三种模式的差异及产物布局参见 [02 — 发布打包](02-pack-and-release.md)。 +For the differences between the three modes and their artifact layouts, see [02 — Packaging and Release](02-pack-and-release.md). -## 后续阅读 +## Further Reading -- [01 — 示例项目](01-examples.md) — 可直接运行的最小工程集合 -- [02 — 发布打包](02-pack-and-release.md) — 构建可分发产物 -- [03 — 工具链管理](03-toolchains.md) — 切换编译器与多版本管理 -- 任意命令的完整选项可通过 `mcpp --help` 查阅 +- [01 — Examples](01-examples.md) — a collection of ready-to-run minimal projects +- [02 — Packaging and Release](02-pack-and-release.md) — building distributable artifacts +- [03 — Toolchain Management](03-toolchains.md) — switching compilers and managing multiple versions +- The full set of options for any command is available via `mcpp --help` -## 更多入口 +## More Entry Points -- GUI 起步:`mcpp new myapp --template imgui`(模板随 imgui 库分发、版本自动对齐; - `mcpp new --list-templates imgui` 查看库提供的全部模板,`--template imgui:docking` 选指定模板)。 -- 解释默认决策:`mcpp why [toolchain|runtime|deps]`;主机能力体检:`mcpp self doctor`; - 机器可读解析清单:构建产物 `target///resolution.json`。 +- GUI quickstart: `mcpp new myapp --template imgui` (templates are distributed with the imgui library and their versions are aligned automatically; + run `mcpp new --list-templates imgui` to see all templates the library provides, or use `--template imgui:docking` to select a specific one). +- Explaining default decisions: `mcpp why [toolchain|runtime|deps]`; host capability checkup: `mcpp self doctor`; + machine-readable resolution manifest: the build artifact `target///resolution.json`. diff --git a/docs/01-examples.md b/docs/01-examples.md index 329c29e4..20c7cdb1 100644 --- a/docs/01-examples.md +++ b/docs/01-examples.md @@ -1,10 +1,11 @@ -# 01 — 示例项目 +# 01 — Examples -> 仓库的 [`examples/`](../examples) 目录下提供了一组循序渐进的最小工程, -> 覆盖从单文件 `import std` 到全静态发布包的常见场景。每个示例都可以 -> 独立进入并通过 `mcpp build` 完成构建。 +> The repository's [`examples/`](../examples) directory provides a set of +> progressively more advanced minimal projects, covering common scenarios from +> a single-file `import std` to a fully static release package. Each example can +> be entered on its own and built with `mcpp build`. -## 运行方式 +## How to Run ```bash git clone https://github.com/mcpp-community/mcpp @@ -12,32 +13,37 @@ cd mcpp/examples/01-hello mcpp build && mcpp run ``` -每个示例附带独立的 README,仅说明该示例相对前一个引入的新概念。 -安装步骤、工具链初始化等通用内容统一放在 -[00 — 快速开始](00-getting-started.md) 中,不再在示例内重复。 +Each example ships with its own README that only explains the new concepts it +introduces relative to the previous one. Common material such as installation +steps and toolchain initialization lives in +[00 — Getting Started](00-getting-started.md) and is not repeated within the +examples. -## 示例列表 +## Example List -| # | 路径 | 说明 | 涉及的关键概念 | +| # | Path | Description | Key Concepts | |---|---|---|---| -| 01 | [`examples/01-hello`](../examples/01-hello/) | 单文件 + `import std` 的最小工程 | `mcpp new` 的默认产物结构 | -| 02 | [`examples/02-with-deps`](../examples/02-with-deps/) | 引入依赖 `mcpplibs.cmdline` 解析命令行参数 | `[dependencies]`、SemVer、`mcpp.lock` | -| 03 | [`examples/03-pack-static`](../examples/03-pack-static/) | 通过 `mcpp pack --mode static` 生成全静态发布包 | `[target.]` 与 `[pack]` 配置 | - -## 推荐阅读顺序 - -建议按编号依次阅读: - -1. **`01-hello`** 展示 mcpp 工程的最小骨架(`mcpp.toml` 与 `src/main.cpp`), - 并演示 `import std` 的基本用法。 -2. **`02-with-deps`** 在前一示例基础上引入外部依赖,涵盖锁文件机制 - 与模块化包索引的工作方式。 -3. **`03-pack-static`** 演示如何将构建产物打包为可独立分发的单文件 - 二进制;打包细节可参考 [02 — 发布打包](02-pack-and-release.md)。 - -## 新增示例 - -示例工程遵循统一的目录结构:`mcpp.toml` + `src/` + `README.md`。 -新增示例时,在 `examples/` 下创建编号目录(如 `04-xxx/`),并在 -README 中简要说明该示例演示的概念,然后提交 PR。提交规范见 -[04 — 从源码构建 & 参与贡献](04-build-from-source.md)。 +| 01 | [`examples/01-hello`](../examples/01-hello/) | Minimal single-file project with `import std` | The default output structure of `mcpp new` | +| 02 | [`examples/02-with-deps`](../examples/02-with-deps/) | Adds the `mcpplibs.cmdline` dependency to parse command-line arguments | `[dependencies]`, SemVer, `mcpp.lock` | +| 03 | [`examples/03-pack-static`](../examples/03-pack-static/) | Produces a fully static release package via `mcpp pack --mode static` | `[target.]` and `[pack]` configuration | + +## Suggested Reading Order + +We recommend reading them in numerical order: + +1. **`01-hello`** shows the minimal skeleton of an mcpp project (`mcpp.toml` and + `src/main.cpp`) and demonstrates the basic usage of `import std`. +2. **`02-with-deps`** builds on the previous example by introducing an external + dependency, covering the lock-file mechanism and how the modular package + index works. +3. **`03-pack-static`** demonstrates how to package build artifacts into a + standalone, independently distributable single-file binary; for packaging + details, see [02 — Packaging and Release](02-pack-and-release.md). + +## Adding a New Example + +Example projects follow a consistent directory structure: `mcpp.toml` + `src/` + +`README.md`. To add a new example, create a numbered directory under +`examples/` (e.g. `04-xxx/`), briefly describe the concept it demonstrates in +its README, and then open a PR. For contribution guidelines, see +[04 — Build from Source & Contributing](04-build-from-source.md). diff --git a/docs/02-pack-and-release.md b/docs/02-pack-and-release.md index 431e1cef..751e0e21 100644 --- a/docs/02-pack-and-release.md +++ b/docs/02-pack-and-release.md @@ -1,77 +1,81 @@ -# 02 — 发布打包 +# 02 — Packaging for Release -> `mcpp build` 产生的二进制仅可在本机运行 —— loader 与 RUNPATH 均指向 -> `~/.mcpp/`。如需分发至其他机器或部署至服务器,应使用 `mcpp pack` -> 生成自包含 tarball。 +> The binary produced by `mcpp build` only runs on the local machine —— both +> the loader and the RUNPATH point into `~/.mcpp/`. To distribute it to other +> machines or deploy it to a server, use `mcpp pack` to produce a +> self-contained tarball. -## 三种模式 +## Three Modes -| 模式 | 说明 | 体积增量 | 兼容性 | +| Mode | Description | Size Increase | Compatibility | |---|---|---|---| -| `static` | musl 全静态,无运行期依赖 | +5–10 MB | 任意 Linux x86_64 | -| `bundle-project`(默认) | 仅打包项目第三方 .so | +几 MB | 主流发行版(Ubuntu 22+, Debian 12+, RHEL 9+ 等) | -| `bundle-all` | 包含 ld-linux、libc、libstdc++ 与项目 .so | +30–50 MB | 包含老旧版本在内的任意 Linux | +| `static` | Fully static via musl, no runtime dependencies | +5–10 MB | Any Linux x86_64 | +| `bundle-project` (default) | Bundles only the project's third-party `.so` files | +a few MB | Mainstream distros (Ubuntu 22+, Debian 12+, RHEL 9+, etc.) | +| `bundle-all` | Includes ld-linux, libc, libstdc++ and the project's `.so` files | +30–50 MB | Any Linux, including older versions | -选择建议: +How to choose: -- 命令行工具,或目标为 Docker scratch、Alpine 等最小镜像 → `static` -- 桌面或服务端发布,目标为主流 Linux 发行版 → `bundle-project`(默认) -- 需兼容老旧 CentOS、麒麟等 glibc 版本较低的环境 → `bundle-all` +- Command-line tools, or targets like Docker scratch or Alpine minimal images → `static` +- Desktop or server releases targeting mainstream Linux distros → `bundle-project` (default) +- Environments that need compatibility with older glibc versions such as legacy CentOS or Kylin → `bundle-all` -## 命令 +## Commands ```bash -mcpp pack # 默认 bundle-project +mcpp pack # bundle-project by default mcpp pack --mode static mcpp pack --mode bundle-all -mcpp pack --target x86_64-linux-musl # 等价 --mode static -mcpp pack --format dir # 输出为目录,不打包 tarball -mcpp pack -o myapp.tar.gz # 仅文件名:落到 target/dist/myapp.tar.gz -mcpp pack -o /abs/path/myapp.tar.gz # 含目录:按字面路径输出 +mcpp pack --target x86_64-linux-musl # equivalent to --mode static +mcpp pack --format dir # output as a directory, no tarball +mcpp pack -o myapp.tar.gz # filename only: lands at target/dist/myapp.tar.gz +mcpp pack -o /abs/path/myapp.tar.gz # includes a directory: output to the literal path ``` -`-o` 接受裸文件名时自动归到 `target/dist/`;含目录(相对或绝对) -时按字面路径输出。 +When `-o` is given a bare filename, the output is placed under `target/dist/`; +when it includes a directory (relative or absolute), the literal path is used. -完整选项参见 `mcpp pack --help`。 +For the full set of options, see `mcpp pack --help`. -## 产物布局 +## Output Layout -tarball 内容包在一个顶层目录里,该目录的名字与 tarball 文件名(去掉 -`.tar.gz`)保持一致 —— 这样图形界面"右键解压"和命令行 `tar -xzf` 都 -得到同一个自包含的目录,不会把内容散到当前路径。 +The tarball contents are wrapped in a single top-level directory whose name +matches the tarball filename (minus the `.tar.gz`) —— this way both a GUI +"right-click extract" and a command-line `tar -xzf` yield the same +self-contained directory, instead of scattering the contents across the current +path. ### Mode `static` ``` target/dist/myapp-0.1.0-x86_64-linux-musl-static.tar.gz └── myapp-0.1.0-x86_64-linux-musl-static/ - ├── bin/myapp ← 全静态 ELF(无 PT_INTERP / RUNPATH) - ├── myapp ← 顶层入口(thin shell wrapper,可直接执行 ./myapp) - ├── README.md ← 自动从项目根目录拷贝 + ├── bin/myapp ← fully static ELF (no PT_INTERP / RUNPATH) + ├── myapp ← top-level entry point (thin shell wrapper, run ./myapp directly) + ├── README.md ← copied automatically from the project root └── LICENSE ``` -### Mode `bundle-project`(默认) +### Mode `bundle-project` (default) ``` target/dist/myapp-0.1.0-x86_64-linux-gnu.tar.gz └── myapp-0.1.0-x86_64-linux-gnu/ - ├── bin/myapp ← 动态链接,RUNPATH=$ORIGIN/../lib + ├── bin/myapp ← dynamically linked, RUNPATH=$ORIGIN/../lib │ PT_INTERP=/lib64/ld-linux-x86-64.so.2 ├── lib/ - │ ├── libcurl.so.4 ← 项目第三方依赖 + │ ├── libcurl.so.4 ← project third-party dependency │ ├── libssl.so.3 │ └── ... - ├── myapp ← 顶层入口 + ├── myapp ← top-level entry point ├── README.md └── LICENSE ``` -跳过列表参考 +The skip list follows [PEP 600 / manylinux2014](https://peps.python.org/pep-0600/) —— -`libc`、`libm`、`libstdc++`、`libgcc_s`、`ld-linux-*` 等基础库默认 -假设目标系统已具备,不打包进 tarball。 +base libraries such as `libc`, `libm`, `libstdc++`, `libgcc_s`, and +`ld-linux-*` are assumed to already exist on the target system and are not +bundled into the tarball. ### Mode `bundle-all` @@ -80,47 +84,52 @@ target/dist/myapp-0.1.0-x86_64-linux-gnu-bundle-all.tar.gz └── myapp-0.1.0-x86_64-linux-gnu-bundle-all/ ├── bin/myapp ├── lib/ - │ ├── ld-linux-x86-64.so.2 ← 完整 loader 与 libc + │ ├── ld-linux-x86-64.so.2 ← complete loader and libc │ ├── libc.so.6 │ ├── libstdc++.so.6 │ ├── libgcc_s.so.1 - │ └── ...项目依赖 - ├── myapp ← 双入口之一 - ├── run.sh ← 双入口之二(内容相同) + │ └── ...project dependencies + ├── myapp ← one of two entry points + ├── run.sh ← the other entry point (identical contents) ├── README.md └── LICENSE ``` -`-o foo.tar.gz` 时顶层目录名也会变成 `foo`(包名 - 目录名 始终一致)。 +With `-o foo.tar.gz`, the top-level directory name also becomes `foo` (the +package name and directory name always stay in sync). -ELF 规范限制 `PT_INTERP` 不能使用 `$ORIGIN`,因此 bundle-all 模式 -通过 `run.sh`(及顶层同名 wrapper)以绝对路径方式调用 loader: +The ELF specification forbids `PT_INTERP` from using `$ORIGIN`, so in +bundle-all mode the loader is invoked by absolute path through `run.sh` (and +the top-level wrapper of the same name): ```sh exec "$here/lib/ld-linux-x86-64.so.2" --library-path "$here/lib" "$here/bin/myapp" "$@" ``` -## 配置项 +## Configuration -打包行为通过 `mcpp.toml` 中的 `[pack]` 节配置,常用字段如下: +Packaging behavior is configured via the `[pack]` section in `mcpp.toml`. The +common fields are: ```toml [pack] -default_mode = "static" # 不带 --mode 时的默认模式 -include = ["share/**", "config/*.toml"] # 额外打包的文件 +default_mode = "static" # default mode when --mode is omitted +include = ["share/**", "config/*.toml"] # extra files to bundle exclude = ["debug/**"] -# 微调 bundle-project 的过滤策略 +# Fine-tune the bundle-project filtering policy [pack.bundle-project] -also_skip = ["libcustom.so"] # 假定目标系统已具备的库 -force_bundle = ["libfoo.so"] # 即使命中 PEP 600 名单也强制打包 +also_skip = ["libcustom.so"] # libraries assumed to exist on the target system +force_bundle = ["libfoo.so"] # bundle even if matched by the PEP 600 list ``` -`static` 模式还需在 `[target.]` 中配置 musl 工具链,完整写法 -参见 [`examples/03-pack-static`](../examples/03-pack-static/) 的 `mcpp.toml`。 +The `static` mode additionally requires a musl toolchain configured under +`[target.]`; for the full setup, see the `mcpp.toml` in +[`examples/03-pack-static`](../examples/03-pack-static/). -## 待支持 +## Planned Support -macOS dylib、Windows DLL,以及 `.deb` / `.rpm` / AppImage 等分发格式 -尚在规划中。本文档随 `mcpp pack` 实现演进,最新选项以 -`mcpp pack --help` 为准。 +macOS dylib, Windows DLL, and distribution formats such as `.deb` / `.rpm` / +AppImage are still on the roadmap. This document evolves alongside the +`mcpp pack` implementation; for the latest options, refer to +`mcpp pack --help`. diff --git a/docs/03-toolchains.md b/docs/03-toolchains.md index ae81891e..b7e1422b 100644 --- a/docs/03-toolchains.md +++ b/docs/03-toolchains.md @@ -1,19 +1,14 @@ -# 03 — 工具链管理 +# 03 — Toolchain Management -> mcpp 维护一个独立的工具链沙盒,与系统 PATH 完全隔离。 +> mcpp maintains an independent toolchain sandbox, fully isolated from the system PATH. -## 设计动机 +## Motivation -C++23 模块对编译器版本较为敏感,不同版本的 GCC / Clang 在模块语义 -处理上存在明显差异。系统包管理器提供的版本通常滞后,且多版本共存 -存在维护成本。mcpp 将工具链统一安装在沙盒目录 -(`~/.mcpp/registry/data/xpkgs/`)中,允许项目按需选择版本,且不会 -影响系统环境。 +C++23 modules are fairly sensitive to compiler versions, and different releases of GCC / Clang differ noticeably in how they handle module semantics. The versions shipped by system package managers tend to lag behind, and keeping multiple versions side by side carries a maintenance burden. mcpp installs all toolchains into a single sandbox directory (`~/.mcpp/registry/data/xpkgs/`), letting each project pick the version it needs without touching the system environment. -## 自动安装 +## Automatic Installation -首次运行 `mcpp build` 时,若尚未配置工具链,mcpp 会自动安装当前平台 -的默认工具链并将其设为全局默认: +The first time you run `mcpp build`, if no toolchain is configured yet, mcpp automatically installs the default toolchain for your platform and sets it as the global default: ``` First run no toolchain configured — installing gcc@15.1.0-musl (musl, static) as default @@ -21,45 +16,43 @@ Downloading xim:musl-gcc@15.1.0 [====> ] 312 MB / 808 MB 3.7 MB/s Default set to gcc@15.1.0-musl ``` -Linux 默认使用 `gcc@15.1.0-musl`; macOS 默认使用 `llvm@20.1.7`。 +Linux defaults to `gcc@15.1.0-musl`; macOS defaults to `llvm@20.1.7`. -后续构建不再触发该流程。 +Subsequent builds do not trigger this process again. > [!TIP] -> 在 CI 或离线环境中,可通过设置 `MCPP_NO_AUTO_INSTALL=1` 关闭自动 -> 安装行为。此时若未安装工具链,`mcpp build` 将直接报错而不会发起 -> 网络请求。 +> In CI or offline environments, you can disable automatic installation by setting `MCPP_NO_AUTO_INSTALL=1`. With this set, if no toolchain is installed, `mcpp build` fails immediately instead of making any network requests. -## 手动安装 +## Manual Installation ```bash -mcpp toolchain install gcc 16.1.0 # GNU libc,适用于动态链接默认场景 -mcpp toolchain install gcc 15.1.0-musl # musl libc,适用于全静态构建 -mcpp toolchain install musl-gcc 15.1.0 # 等价于上一条 -mcpp toolchain install llvm 20.1.7 # LLVM/Clang,macOS 默认工具链 +mcpp toolchain install gcc 16.1.0 # GNU libc, for the default dynamic-linking case +mcpp toolchain install gcc 15.1.0-musl # musl libc, for fully static builds +mcpp toolchain install musl-gcc 15.1.0 # equivalent to the line above +mcpp toolchain install llvm 20.1.7 # LLVM/Clang, the default toolchain on macOS ``` -版本号支持部分匹配: +Version numbers support partial matching: ```bash -mcpp toolchain install gcc 15 # 安装 15.x.y 中的最高版本(15.1.0) -mcpp toolchain install gcc@16 # 同样支持 @ 形式 +mcpp toolchain install gcc 15 # installs the highest 15.x.y version (15.1.0) +mcpp toolchain install gcc@16 # the @ form works too ``` -## 切换默认工具链 +## Switching the Default Toolchain ```bash mcpp toolchain default gcc@16.1.0 -mcpp toolchain default gcc 15 # 部分版本时,从已安装的版本中选择最高 +mcpp toolchain default gcc 15 # with a partial version, picks the highest installed match ``` -## 查看工具链状态 +## Inspecting Toolchain Status ```bash mcpp toolchain list ``` -输出形式如下: +The output looks like this: ``` Installed: @@ -74,68 +67,59 @@ Available (run `mcpp toolchain install `): ... ``` -带有 `*` 标记的条目为当前默认工具链。`@mcpp/...` 是 `~/.mcpp/...` -的简写形式,用于减少输出宽度。 +The entry marked with `*` is the current default toolchain. `@mcpp/...` is shorthand for `~/.mcpp/...`, used to keep the output narrower. -## 项目级版本锁定 +## Project-Level Version Pinning -若项目需固定特定版本而不依赖全局默认,可在项目的 `mcpp.toml` 中声明: +If a project needs to pin a specific version rather than rely on the global default, declare it in the project's `mcpp.toml`: ```toml [toolchain] default = "gcc@16.1.0" -# 也可按平台分发 +# you can also dispatch by platform [toolchain] linux = "gcc@15.1.0-musl" macos = "llvm@20" ``` -项目级声明优先于全局默认配置。 +A project-level declaration takes precedence over the global default configuration. -## 跨工具链构建 +## Cross-Toolchain Builds ```bash mcpp build --target x86_64-linux-musl ``` -mcpp 将读取 `mcpp.toml` 中 `[target.x86_64-linux-musl]` 节,覆盖默认的 -工具链与 linkage 设置。该机制配合 `mcpp pack --mode static` 可生成 -全静态发布包,完整示例参见 -[`examples/03-pack-static`](../examples/03-pack-static/)。 +mcpp reads the `[target.x86_64-linux-musl]` section in `mcpp.toml`, overriding the default toolchain and linkage settings. Combined with `mcpp pack --mode static`, this lets you produce a fully static release package; for a complete example, see [`examples/03-pack-static`](../examples/03-pack-static/). -## 卸载 +## Uninstalling ```bash mcpp toolchain remove gcc@16.1.0 ``` -## 重置沙盒 +## Resetting the Sandbox ```bash -rm -rf ~/.mcpp # 删除整个沙盒 -mcpp build # 后续构建将再次触发首次安装 +rm -rf ~/.mcpp # remove the entire sandbox +mcpp build # the next build triggers first-run installation again ``` -## 环境变量 +## Environment Variables -mcpp 的运行行为可通过以下环境变量调整: +mcpp's runtime behavior can be adjusted with the following environment variables: -| 变量 | 用途 | +| Variable | Purpose | |---|---| -| `MCPP_HOME` | 覆盖沙盒位置(默认 `~/.mcpp/`),绝对路径优先级最高 | -| `MCPP_NO_AUTO_INSTALL=1` | 禁用工具链自动安装,适用于 CI 与离线环境 | -| `MCPP_NO_COLOR=1` / `NO_COLOR=1` | 禁用彩色输出 | -| `MCPP_LOG=trace\|debug\|info\|warn\|error` | 日志级别 | +| `MCPP_HOME` | Override the sandbox location (default `~/.mcpp/`); an absolute path takes top priority | +| `MCPP_NO_AUTO_INSTALL=1` | Disable automatic toolchain installation; useful for CI and offline environments | +| `MCPP_NO_COLOR=1` / `NO_COLOR=1` | Disable colored output | +| `MCPP_LOG=trace\|debug\|info\|warn\|error` | Log level | -未显式设置 `MCPP_HOME` 时,mcpp 将基于二进制所在目录的上一级路径 -自动定位沙盒位置(release tarball 解压至 `~/.mcpp/` 后,`~/.mcpp/` -即为 home),因此 release 版本无需任何环境变量配置即可运行。 +When `MCPP_HOME` is not set explicitly, mcpp locates the sandbox automatically based on the parent directory of the binary (after a release tarball is extracted to `~/.mcpp/`, `~/.mcpp/` is the home), so the release build runs without any environment variable configuration. -## ABI 能力强制 +## ABI Capability Enforcement -依赖可声明 `abi:` 能力(如 `compat.glfw` 声明 `abi:glibc`)。解析出的 -工具链 ABI 不满足任一依赖的 abi 要求时,构建会**尽早失败**并给出修复建议 -(例如 musl-static 工具链遇到 abi:glibc 依赖),取代深层的链接/头文件报错。 -查看:`mcpp why toolchain`。 +A dependency can declare an `abi:` capability (for example, `compat.glfw` declares `abi:glibc`). When the resolved toolchain's ABI does not satisfy any dependency's abi requirement, the build **fails early** with a suggested fix (for example, a musl-static toolchain encountering an abi:glibc dependency), replacing deeper link/header errors. Inspect with: `mcpp why toolchain`. diff --git a/docs/04-build-from-source.md b/docs/04-build-from-source.md index 56f35957..8fd2e06d 100644 --- a/docs/04-build-from-source.md +++ b/docs/04-build-from-source.md @@ -1,104 +1,97 @@ -# 04 — 从源码构建 & 参与贡献 +# 04 — Building from Source & Contributing -> mcpp 采用自托管模式 —— 通过 mcpp 自身从源码构建 mcpp。 -> 任何已具备可运行 mcpp 二进制的环境均可完成源码构建。 +> mcpp is self-hosting — mcpp builds mcpp from source using mcpp itself. +> Any environment that already has a working mcpp binary can build from source. -## 准备 +## Prerequisites -参照 [00 — 快速开始](00-getting-started.md) 安装一份现成的 mcpp, -然后克隆仓库: +Follow [00 — Getting Started](00-getting-started.md) to install a working copy of mcpp, then clone the repository: ```bash git clone https://github.com/mcpp-community/mcpp cd mcpp ``` -## 构建与测试 +## Building and Testing ```bash -mcpp build # 使用现成 mcpp 编译当前源码 → ./target/.../bin/mcpp -mcpp run -- --version # 运行刚构建出的产物 -mcpp test # 执行 tests/unit 与 tests/e2e +mcpp build # compile the current source with the existing mcpp → ./target/.../bin/mcpp +mcpp run -- --version # run the artifact you just built +mcpp test # run tests/unit and tests/e2e ``` -首次构建会自动拉取默认工具链,详见 -[03 — 工具链管理](03-toolchains.md)。 +The first build automatically fetches the default toolchain; see [03 — Toolchain Management](03-toolchains.md) for details. -如需生成与 release 一致的全静态二进制(对应 `release.yml` 走的路径): +To produce a fully static binary identical to a release (the path taken by `release.yml`): ```bash mcpp build --target x86_64-linux-musl -# → target/x86_64-linux-musl/.../bin/mcpp 为全静态 ELF +# → target/x86_64-linux-musl/.../bin/mcpp is a fully static ELF ``` -## 源码结构 +## Source Layout ``` src/ -├── main.cpp 入口 -├── cli.cppm 命令分发与参数解析 -├── manifest.cppm mcpp.toml 解析 +├── main.cpp entry point +├── cli.cppm command dispatch and argument parsing +├── manifest.cppm mcpp.toml parsing ├── lockfile.cppm mcpp.lock -├── version_req.cppm SemVer 约束 -├── fetcher.cppm 依赖下载(git / index / path) +├── version_req.cppm SemVer constraints +├── fetcher.cppm dependency download (git / index / path) ├── config.cppm ~/.mcpp/config.toml -├── bmi_cache.cppm 跨项目 BMI 缓存 -├── dyndep.cppm ninja dyndep 生成 -├── ui.cppm 进度条与输出格式 -├── build/ 构建编排与 ninja 后端 -├── modgraph/ P1689 模块扫描与依赖图 -├── toolchain/ 工具链探测、指纹与 std 模块 -├── pack/ mcpp pack 实现 -├── publish/ mcpp publish 与 xpkg 生成 -└── libs/ 第三方依赖(toml 解析等) +├── bmi_cache.cppm cross-project BMI cache +├── dyndep.cppm ninja dyndep generation +├── ui.cppm progress bars and output formatting +├── build/ build orchestration and ninja backend +├── modgraph/ P1689 module scanning and dependency graph +├── toolchain/ toolchain detection, fingerprinting, and std module +├── pack/ mcpp pack implementation +├── publish/ mcpp publish and xpkg generation +└── libs/ third-party dependencies (toml parsing, etc.) tests/ -├── unit/ 各 .cppm 模块的 gtest 单元测试 -└── e2e/ 端到端 shell 脚本(run_all.sh 为 CI 入口) +├── unit/ gtest unit tests for each .cppm module +└── e2e/ end-to-end shell scripts (run_all.sh is the CI entry point) ``` -## 测试组织 +## Test Organization -测试分为两层: +Tests are split into two layers: -- **单元测试** 位于 `tests/unit/test_.cpp`,与 `src/.cppm` - 按模块一一对应。 -- **e2e 测试** 位于 `tests/e2e/NN_.sh`,通过执行真实的 `mcpp` - 二进制覆盖端到端行为;`run_all.sh` 为 CI 调用入口。 +- **Unit tests** live in `tests/unit/test_.cpp`, corresponding one-to-one with `src/.cppm` per module. +- **e2e tests** live in `tests/e2e/NN_.sh` and cover end-to-end behavior by exercising the real `mcpp` binary; `run_all.sh` is the CI entry point. -修改 `src/` 下任意 `.cppm` 模块时,应同步检查对应单元测试是否覆盖了 -变更点;新增功能优先补充 e2e 用例。 +When changing any `.cppm` module under `src/`, check that the corresponding unit test covers your changes; for new features, prefer adding e2e cases. -执行单个 e2e 脚本: +Run a single e2e script: ```bash cd tests/e2e MCPP=$(realpath ../../target/x86_64-linux-musl/*/bin/mcpp) ./02_new_build_run.sh ``` -## Issue 与 PR 提交规范 +## Issue and PR Guidelines -### Issue +### Issues -提交至 [github.com/mcpp-community/mcpp/issues](https://github.com/mcpp-community/mcpp/issues), -建议附带以下信息: +File issues at [github.com/mcpp-community/mcpp/issues](https://github.com/mcpp-community/mcpp/issues), ideally including the following: -- `mcpp self env` 的完整输出 -- 失败命令的完整输出(配合 `MCPP_LOG=debug` 可获得更详细信息) -- 操作系统、发行版、glibc 版本(可通过 `ldd --version` 查看) +- The full output of `mcpp self env` +- The full output of the failing command (`MCPP_LOG=debug` gives more detail) +- Your operating system, distribution, and glibc version (check with `ldd --version`) -### Pull Request +### Pull Requests -mcpp 处于早期迭代阶段,接口可能调整,提交 PR 前请注意: +mcpp is in early iteration and its interfaces may change. Before submitting a PR, please note: -1. 涉及 CLI 或 `mcpp.toml` schema 的改动,建议先开 issue 对齐方向。 -2. 单个 PR 聚焦单一改动;commit 标题使用英文 imperative 形式 - (`fix: ...` / `feat: ...`)。 -3. 提交前确认 `mcpp test` 全部通过。 +1. For changes touching the CLI or the `mcpp.toml` schema, open an issue first to align on direction. +2. Keep each PR focused on a single change; write commit titles in English imperative form (`fix: ...` / `feat: ...`). +3. Confirm that `mcpp test` passes in full before submitting. -## 社区资源 +## Community Resources -- [社区论坛](https://forum.d2learn.org/category/20) -- 交流群 QQ: 1067245099 -- [mcpp-index](https://github.com/mcpp-community/mcpp-index) — 默认包索引 -- [mcpplibs](https://github.com/mcpplibs) — 配套的模块化 C++ 库集合 +- [Community forum](https://forum.d2learn.org/category/20) +- Chat group QQ: 1067245099 +- [mcpp-index](https://github.com/mcpp-community/mcpp-index) — the default package index +- [mcpplibs](https://github.com/mcpplibs) — the companion collection of modular C++ libraries diff --git a/docs/05-mcpp-toml.md b/docs/05-mcpp-toml.md index d22b4770..a8d24d6f 100644 --- a/docs/05-mcpp-toml.md +++ b/docs/05-mcpp-toml.md @@ -1,12 +1,12 @@ -# mcpp.toml 工程文件指南 +# The mcpp.toml Manifest Guide -`mcpp.toml` 是 mcpp 构建工具的项目配置文件,类似 Cargo 的 `Cargo.toml` 或 Node 的 `package.json`。放在项目根目录下,`mcpp build` 会自动发现并读取它。 +`mcpp.toml` is the project configuration file for the mcpp build tool, analogous to Cargo's `Cargo.toml` or Node's `package.json`. Place it in your project root and `mcpp build` will discover and read it automatically. -## 1. 最小化示例 +## 1. Minimal Examples -mcpp 的设计原则是 **约定优于配置** —— 大多数字段都有合理默认值,最简单的 `mcpp.toml` 只需几行: +mcpp is designed around **convention over configuration** — most fields have sensible defaults, so the simplest `mcpp.toml` is just a few lines: -### 1.1 可执行程序(最简) +### 1.1 Executable (minimal) ```toml [package] @@ -14,13 +14,13 @@ name = "hello" version = "0.1.0" ``` -mcpp 自动推断: -- 源文件: `src/**/*.{cppm,cpp,cc,c}` -- 入口: `src/main.cpp` → 生成 `hello` 二进制 -- 标准: C++23 -- 模块: 扫描 `export module ...` 声明自动建立依赖图 +mcpp infers automatically: +- Source files: `src/**/*.{cppm,cpp,cc,c}` +- Entry point: `src/main.cpp` → produces the `hello` binary +- Standard: C++23 +- Modules: scans `export module ...` declarations and builds the dependency graph automatically -### 1.2 库项目(最简) +### 1.2 Library project (minimal) ```toml [package] @@ -31,275 +31,297 @@ version = "0.1.0" kind = "lib" ``` -lib-root 约定:主模块接口默认在 `src/mylib.cppm`(包名的最后一段)。 +lib-root convention: the primary module interface defaults to `src/mylib.cppm` (the last segment of the package name). -## 2. 完整字段参考 +## 2. Full Field Reference -### 2.1 `[package]` — 包元数据 +### 2.1 `[package]` — Package Metadata ```toml [package] -name = "myapp" # 包名(必填) -version = "0.1.0" # 语义化版本(必填) -standard = "c++23" # C++ 标准(默认 c++23; 可设 c++26) -description = "My awesome app" # 简介(可选) -license = "MIT" # 许可证(可选) -authors = ["Alice", "Bob"] # 作者列表(可选) -repo = "https://github.com/user/myapp" # 仓库地址(可选) +name = "myapp" # Package name (required) +version = "0.1.0" # Semantic version (required) +standard = "c++23" # C++ standard (default c++23; can be set to c++26) +description = "My awesome app" # Description (optional) +license = "MIT" # License (optional) +authors = ["Alice", "Bob"] # Author list (optional) +repo = "https://github.com/user/myapp" # Repository URL (optional) ``` -`standard` 是 C++ 语言标准的一等配置。推荐值: +`standard` is the first-class setting for the C++ language standard. Recommended values: -- `c++23`:默认值,适合当前模块化默认模板。 -- `c++26`:需要 C++26 语言特性时使用。 -- `c++2c`:兼容别名,解析后归一为 `c++26`。 -- `gnu++23` / `gnu++26`:需要 GNU dialect 时使用,会进入 fingerprint 和 std BMI cache key。 -- `c++latest`:跟随当前 mcpp 支持的最新标准,适合本地试验,不推荐要求可复现的发布包使用。 +- `c++23`: the default, suited to the current module-based default templates. +- `c++26`: use when you need C++26 language features. +- `c++2c`: a compatibility alias, normalized to `c++26` after parsing. +- `gnu++23` / `gnu++26`: use when you need a GNU dialect; this enters the fingerprint and the std BMI cache key. +- `c++latest`: follows the newest standard mcpp currently supports. Good for local experimentation, but not recommended for release packages that require reproducibility. -### 2.2 `[targets.]` — 构建目标 +### 2.2 `[targets.]` — Build Targets ```toml -# 可执行程序(默认,有 src/main.cpp 时自动推断) +# Executable (default; inferred automatically when src/main.cpp exists) [targets.myapp] kind = "bin" -main = "src/main.cpp" # 可选,默认 src/main.cpp +main = "src/main.cpp" # Optional, defaults to src/main.cpp -# 静态库 +# Static library [targets.mylib] kind = "lib" -# 共享库 +# Shared library [targets.mylib] kind = "shared" -soname = "libmylib.so.1" # 可选: ELF/Mach-O ABI 名称,运行时会生成同名 alias +soname = "libmylib.so.1" # Optional: ELF/Mach-O ABI name; an alias of the same name is generated at runtime ``` -`soname` 用于共享库的 ABI 名称,类似 Autotools/CMake 中的 -`SOVERSION`/`SONAME`。在 Linux 上,mcpp 会向链接器传递 -`-Wl,-soname,`,并在输出目录生成 ` -> lib.so` alias, -让下游程序可通过标准 ABI 名称 `DT_NEEDED` 或 `dlopen()` 加载该库。 -该字段只对 `kind = "shared"` 有效,值必须是文件名 basename。 +`soname` is the ABI name for a shared library, analogous to `SOVERSION`/`SONAME` in +Autotools/CMake. On Linux, mcpp passes `-Wl,-soname,` to the linker and +generates a ` -> lib.so` alias in the output directory, so that +downstream programs can load the library via its standard ABI name through +`DT_NEEDED` or `dlopen()`. This field only applies to `kind = "shared"`, and the +value must be a filename basename. -### 2.3 `[build]` — 构建配置 +### 2.3 `[build]` — Build Configuration ```toml [build] -sources = ["src/**/*.cppm", "src/**/*.cpp"] # 源文件 glob(默认: src/**/*.{cppm,cpp,cc,c}) -include_dirs = ["include", "third_party/include"] # 头文件搜索路径 -c_standard = "c11" # C 源文件的标准(默认 c11) -cflags = ["-DFOO=1"] # 额外 C 编译参数 -cxxflags = ["-DBAR=2"] # 额外 C++ 编译参数(不要放 -std=...) -ldflags = ["-lfoo"] # 额外链接参数 -static_stdlib = true # 静态链接 libstdc++(默认 true) -macos_deployment_target = "14.0" # macOS 产物的最低支持系统版本(仅 macOS 生效) +sources = ["src/**/*.cppm", "src/**/*.cpp"] # Source globs (default: src/**/*.{cppm,cpp,cc,c}) +include_dirs = ["include", "third_party/include"] # Header search paths +c_standard = "c11" # Standard for C source files (default c11) +cflags = ["-DFOO=1"] # Extra C compile flags +cxxflags = ["-DBAR=2"] # Extra C++ compile flags (do not put -std=... here) +ldflags = ["-lfoo"] # Extra link flags +static_stdlib = true # Statically link libstdc++ (default true) +macos_deployment_target = "14.0" # Minimum supported OS version for macOS artifacts (macOS only) ``` -`macos_deployment_target` 设定产物 Mach-O 头里的最低系统版本 -(`LC_BUILD_VERSION minos`),即二进制能运行的最老 macOS。优先级与各生态 -惯例一致:环境变量 `MACOSX_DEPLOYMENT_TARGET`(单次调用的显式覆盖, -cargo/rustc、cc 等同样尊重该变量)> 本字段(项目默认,类似 SwiftPM 的 -`platforms:`)> **内建默认 `14.0`**(rustc 风格——每个 target 都有基线, -14.0 即 LLVM 官方静态库自身的下限)。该值会进入 BMI 指纹——切换 target -会自动重建模块缓存。 - -**默认即静态运行时(portable by default)**:`static_stdlib = true` -(默认)时,macOS 链接会静态链入 LLVM 自带的 libc++/libc++abi —— -系统 libc++ 会把实际可运行版本钉死在构建机的 OS(老系统缺新符号, -如 `std::print` 的支撑符号),静态化才能真正兑现 floor。因此默认构建的 -产物在任何 macOS ≥ 14 上开箱即用。设 `static_stdlib = false` 退回动态 -系统 libc++(产物只保证在构建机同版本及以上运行)。更低 floor(11–13) -需自建 libc++ 归档(已验证可行,数据级切换,按需提供)。 - -C++ 标准不要通过 `build.cxxflags = ["-std=..."]` 配置。请使用: +`macos_deployment_target` sets the minimum system version in the artifact's +Mach-O header (`LC_BUILD_VERSION minos`), i.e. the oldest macOS the binary can +run on. The precedence follows ecosystem convention: the `MACOSX_DEPLOYMENT_TARGET` +environment variable (an explicit per-invocation override, honored the same way by +cargo/rustc, cc, etc.) > this field (the project default, similar to SwiftPM's +`platforms:`) > the **built-in default `14.0`** (rustc-style — every target has a +baseline, and 14.0 is the floor of LLVM's official static libraries themselves). +This value enters the BMI fingerprint, so switching targets automatically rebuilds +the module cache. + +**Static runtime by default (portable by default)**: when `static_stdlib = true` +(the default), macOS linking statically links in LLVM's bundled libc++/libc++abi — +the system libc++ would otherwise pin the actual runnable version to the build +machine's OS (older systems lack newer symbols, e.g. the support symbols behind +`std::print`), and only static linking can truly deliver the floor. As a result, +the default build's artifacts work out of the box on any macOS ≥ 14. Set +`static_stdlib = false` to fall back to the dynamic system libc++ (the artifact is +then only guaranteed to run on the build machine's version and above). A lower +floor (11–13) requires a self-built libc++ archive (already verified to work, a +data-level switch, available on request). + +Do not configure the C++ standard via `build.cxxflags = ["-std=..."]`. Instead use: ```toml [package] standard = "c++26" ``` -mcpp 会把同一个标准用于普通 C++ 编译、模块扫描、`compile_commands.json` 和 `import std` 的标准库 BMI 构建。 +mcpp applies the same standard to ordinary C++ compilation, module scanning, +`compile_commands.json`, and the standard library BMI build for `import std`. -**glob 排除**(`!` 前缀,mcpp 0.0.4+): +**glob exclusion** (`!` prefix, mcpp 0.0.4+): ```toml [build] sources = [ "src/**/*.cpp", - "!src/**/*_test.cpp", # 排除测试文件 - "!src/**/*_fuzzer.cpp", # 排除 fuzzer + "!src/**/*_test.cpp", # Exclude test files + "!src/**/*_fuzzer.cpp", # Exclude fuzzers ] ``` -### 2.4 `[lib]` — 库根模块约定 +### 2.4 `[lib]` — Library Root Module Convention ```toml [lib] -path = "src/capi/lua.cppm" # 覆盖默认的 lib-root 位置 +path = "src/capi/lua.cppm" # Override the default lib-root location ``` -默认约定:`src/<包名最后一段>.cppm`(如包名 `mcpplibs.cmdline` → `src/cmdline.cppm`)。 +Default convention: `src/.cppm` (e.g. package name `mcpplibs.cmdline` → `src/cmdline.cppm`). -### 2.5 `[dependencies]` — 运行时依赖 +### 2.5 `[dependencies]` — Runtime Dependencies ```toml -# 默认包空间(mcpplibs)下的包 +# Packages under the default package namespace (mcpplibs) [dependencies] -gtest = "1.15.2" # 精确版本 +gtest = "1.15.2" # Exact version mbedtls = "3.6.1" ftxui = "6.1.9" -# dotted selector: 先匹配 mcpplibs., 找不到再匹配同级 peer root。 -# 例如 imgui.core 会按顺序尝试 mcpplibs.imgui/core, imgui/core。 +# Dotted selector: try mcpplibs. first, then fall back to the sibling peer root. +# For example, imgui.core is tried in order as mcpplibs.imgui/core, then imgui/core. [dependencies] capi.lua = "0.0.3" compat.gtest = "1.15.2" imgui.core = "0.0.1" imgui.backend.glfw_opengl3 = "0.0.1" -# 命名空间子表写法 +# Namespace sub-table form [dependencies.mcpplibs] cmdline = "0.0.2" tinyhttps = "0.2.2" llmapi = "0.2.5" [dependencies.compat] -glfw = "3.4" # 显式 namespace, 不走 mcpplibs 优先候选 +glfw = "3.4" # Explicit namespace, skips the mcpplibs-first candidate -# 路径依赖(本地开发) +# Path dependency (local development) [dependencies] mylib = { path = "../mylib" } -# Git 依赖 +# Git dependency [dependencies] mylib = { git = "https://github.com/user/mylib.git", tag = "v1.0.0" } -# 长式 dep spec:features 与 backend 旋钮 +# Long-form dep spec: features and backend knobs [dependencies] -imgui = { version = "0.0.3", features = ["docking"] } # 请求该依赖的 feature -widget = { version = "1.0", backend = "glfw_opengl3" } # 糖:= features=["backend-glfw_opengl3"] +imgui = { version = "0.0.3", features = ["docking"] } # Request a feature of this dependency +widget = { version = "1.0", backend = "glfw_opengl3" } # Sugar for: features=["backend-glfw_opengl3"] ``` -`backend = ""` 是**通用约定糖**:1:1 脱糖为请求该依赖的 `backend-` -feature(库若支持该旋钮,应在自己的 `[features]` 中声明 `backend-*` 系列)。 -若目标包声明了 `[features]` 但不含所请求的 feature(含 backend 脱糖结果), -默认给出 warning,`mcpp build --strict` 下报错。 +`backend = ""` is **general-purpose convention sugar**: it desugars 1:1 into +requesting the dependency's `backend-` feature (a library that supports this +knob should declare a `backend-*` family in its own `[features]`). If the target +package declares `[features]` but does not include the requested feature (including +the result of backend desugaring), a warning is issued by default, and an error +under `mcpp build --strict`. -**SemVer 约束**: +**SemVer constraints**: ```toml [dependencies] -foo = "^1.2.3" # >= 1.2.3, < 2.0.0 (caret,默认) +foo = "^1.2.3" # >= 1.2.3, < 2.0.0 (caret, default) bar = "~1.2.3" # >= 1.2.3, < 1.3.0 (tilde) -baz = "=1.2.3" # 精确匹配 -qux = ">=1.0, <2.0" # 范围组合 +baz = "=1.2.3" # Exact match +qux = ">=1.0, <2.0" # Range combination ``` -### 2.6 `[dev-dependencies]` — 测试依赖 +### 2.6 `[dev-dependencies]` — Test Dependencies ```toml [dev-dependencies] gtest = "1.15.2" ``` -`mcpp build` 忽略这些;`mcpp test` 解析并使用。`mcpp test` 会自动发现 `tests/**/*.cpp` 并编译为测试二进制。 +`mcpp build` ignores these; `mcpp test` resolves and uses them. `mcpp test` automatically discovers `tests/**/*.cpp` and compiles them into test binaries. -### 2.7 `[toolchain]` — 工具链配置 +### 2.7 `[toolchain]` — Toolchain Configuration ```toml [toolchain] default = "gcc@16.1.0" -# 跨编译目标覆盖 +# Cross-compilation target override [target.x86_64-linux-musl] toolchain = "gcc@15.1.0-musl" linkage = "static" ``` -### 2.8 `[features]` — 特性(Cargo 式,加性) +### 2.8 `[features]` — Features (Cargo-style, additive) ```toml [features] -default = ["base"] # 默认激活集 +default = ["base"] # Default activation set base = [] -docking = ["extra"] # 激活 docking 时隐含激活 extra(传递闭包) +docking = ["extra"] # Activating docking implies activating extra (transitive closure) extra = [] ``` -- 激活来源:包自身 `default` 集 ∪ 显式请求(根包 `mcpp build --features a,b`; - 依赖经长式 dep spec `features = [...]` / `backend = "..."` 糖)。 -- 每个激活的 feature 在该包的编译中得到宏 `-DMCPP_FEATURE_` - (名字转大写,非字母数字转 `_`,如 `backend-a` → `MCPP_FEATURE_BACKEND_A`)。 -- **strict 校验**:目标包声明了 `[features]` 表时,请求未声明的 feature 给出 - warning;`--strict` 下报错。未声明 `[features]` 的包接受任意请求(纯宏用法)。 +- Activation sources: the package's own `default` set ∪ explicit requests (the root + package via `mcpp build --features a,b`; dependencies via the long-form dep spec's + `features = [...]` / `backend = "..."` sugar). +- Each activated feature gets the macro `-DMCPP_FEATURE_` during that package's + compilation (the name is uppercased and non-alphanumerics become `_`, e.g. + `backend-a` → `MCPP_FEATURE_BACKEND_A`). +- **strict validation**: when the target package declares a `[features]` table, + requesting an undeclared feature produces a warning; an error under `--strict`. A + package that does not declare `[features]` accepts any request (pure macro usage). -### 2.9 `[profile.]` — 构建档案 +### 2.9 `[profile.]` — Build Profiles ```toml [profile.dist] -opt = 3 # -O 级别(数字或 "s"/"z" 字符串) +opt = 3 # -O level (a number, or the string "s"/"z") debug = false # -g -lto = true # -flto(注意:部分打包 gcc 未启用 LTO 插件) -strip = true # 链接期 -s -# passthrough 逃生口(固定键、开放值): +lto = true # -flto (note: some packaged gcc builds ship without the LTO plugin) +strip = true # -s at link time +# passthrough escape hatch (fixed keys, open values): cflags = ["-fno-plt"] cxxflags = ["-fno-plt"] ldflags = [] ``` -- 选择:`mcpp build --profile `,默认 `release`。 -- 内置档案:`release`(-O2)/ `dev`、`debug`(-O0 -g)/ `dist`(-O3 + strip; - **不默认开 lto**)。`[profile.<内置名>]` 可整体覆盖内置定义。 +- Selection: `mcpp build --profile `, defaulting to `release`. +- Built-in profiles: `release` (-O2) / `dev`, `debug` (-O0 -g) / `dist` (-O3 + strip; + **LTO is not enabled by default**). `[profile.]` can override a + built-in definition wholesale. -### 2.10 `[runtime]` — 主机运行时能力 +### 2.10 `[runtime]` — Host Runtime Capabilities ```toml [runtime] -library_dirs = ["vendor/lib"] # 烤进产物 RUNPATH 的目录(相对包根) -dlopen_libs = ["libGL.so.1"] # 运行期 dlopen 的 soname(doctor 校验) -capabilities = ["opengl.glx.driver"] # 需要的主机能力(开放命名空间) -provides = ["opengl.glx.driver"] # 显式声明本包兑现的能力(强 provider) +library_dirs = ["vendor/lib"] # Directories baked into the artifact's RUNPATH (relative to the package root) +dlopen_libs = ["libGL.so.1"] # sonames dlopen'd at runtime (validated by doctor) +capabilities = ["opengl.glx.driver"] # Host capabilities required (open namespace) +provides = ["opengl.glx.driver"] # Explicitly declares capabilities this package fulfills (strong provider) -# 显式 provider 覆盖(三档旋钮的"显式"档) +# Explicit provider override (the "explicit" notch of the three-way knob) [runtime."opengl.glx.driver"] provider = "compat.glx-runtime" ``` -- **provider 选择**:声明 `provides` 的包(强)优先于仅在 `capabilities` 列出 - 能力的包(弱,向后兼容);`[runtime.] provider=` 显式覆盖最优先, - 指向依赖图中不存在的 provider 时给出 warning。 -- 解析结果可经 `mcpp why runtime`、`mcpp self doctor` 与构建产物 - `target///resolution.json` 查看(默认不是魔法)。 -- 能力命名约定:分层小写 `domain.sub.role`(如 `opengl.glx.driver`、 - `x11.display`)与前缀类 `abi:`(如 `abi:glibc`,参与工具链 ABI 强制)。 +- **Provider selection**: a package that declares `provides` (strong) takes precedence + over one that merely lists a capability under `capabilities` (weak, backward + compatible); `[runtime.] provider=` is an explicit override with the highest + precedence, and pointing at a provider not present in the dependency graph produces + a warning. +- The resolved result can be inspected via `mcpp why runtime`, `mcpp self doctor`, and + the build artifact `target///resolution.json` (it is not magic by + default). +- Capability naming convention: layered lowercase `domain.sub.role` (e.g. + `opengl.glx.driver`, `x11.display`) and prefix-style `abi:` (e.g. `abi:glibc`, + which participates in toolchain ABI enforcement). -### 2.11 `[package] platforms` — 平台声明 +### 2.11 `[package] platforms` — Platform Declaration ```toml [package] platforms = ["linux", "macos", "windows"] ``` -声明包支持的平台(CI 矩阵提示,经 `mcpp why` 展示)。词表由 mcpp 固定 -(它拥有 target/triple 体系):`linux | macos | windows`;未知值 warning, -`--strict` 下报错。 +Declares the platforms the package supports (a CI matrix hint, shown via `mcpp why`). +The vocabulary is fixed by mcpp (which owns the target/triple system): +`linux | macos | windows`; unknown values produce a warning, and an error under +`--strict`. -## 附录 A. Schema 所有权原则(新字段准入标准) +## Appendix A. Schema Ownership Principle (admission criteria for new fields) -> **语法封闭,词汇开放**:谁拥有解析语义谁定义键;谁拥有领域知识谁定义值。 +> **Closed syntax, open vocabulary**: whoever owns the parsing semantics defines the keys; whoever owns the domain knowledge defines the values. -- mcpp 只定义**机制**(features 并集/闭包、capability require/provide/override、 - profile→编译器旗标、platform→triple),键与形状固定;feature 名、能力名、 - 后端名等**领域词汇只出现在值里**,不进 mcpp 代码。 -- **不支持包自定义 toml 键**:键合法性不得依赖"先解析目标包",否则 manifest - 失去静态可解析性(lockfile/LSP/审计的前提)。包的扩展点 = 固定机制内的开放值域。 -- 包级旋钮统一收敛进 features;糖键(如 `backend=`)进入核心语法须满足: - ① 领域中立(跨生态通用模式)② 1:1 脱糖、零新增解析语义。 -- 字段归属总表与定型决策见 - `.agents/docs/2026-06-04-manifest-schema-ownership.md`。 +- mcpp only defines **mechanisms** (feature union/closure, capability + require/provide/override, profile→compiler flags, platform→triple); the keys and + shapes are fixed. Domain vocabulary such as feature names, capability names, and + backend names **appears only in values**, never in mcpp's code. +- **Package-custom toml keys are not supported**: key legitimacy must not depend on + "first parsing the target package," otherwise the manifest loses static + parseability (a prerequisite for lockfiles/LSP/auditing). A package's extension + point = open value domains within fixed mechanisms. +- Package-level knobs all converge into features; for sugar keys (such as `backend=`) + to enter the core syntax, they must satisfy: ① domain-neutral (a cross-ecosystem + general pattern) ② 1:1 desugaring with zero new parsing semantics. +- See `.agents/docs/2026-06-04-manifest-schema-ownership.md` for the full field-ownership + table and the finalized decisions. -## 3. 实战示例 +## 3. Worked Examples -### 3.1 简单 Hello World +### 3.1 Simple Hello World ```toml [package] @@ -317,7 +339,7 @@ int main() { std::println("Hello, mcpp!"); } mcpp build && mcpp run ``` -### 3.2 模块化库 + 测试 +### 3.2 Module-based Library + Tests ```toml [package] @@ -345,11 +367,11 @@ TEST(Math, Add) { EXPECT_EQ(add(1, 2), 3); } ``` ```bash -mcpp build # 编译库 -mcpp test # 编译 + 跑测试 +mcpp build # Compile the library +mcpp test # Compile + run tests ``` -### 3.3 依赖其他包的应用 +### 3.3 An Application Depending on Other Packages ```toml [package] @@ -364,12 +386,12 @@ cmdline = "0.0.2" llmapi = "0.2.5" ``` -mcpp 自动: -1. 从 mcpp-index 下载源码 tarball -2. 按 `[build].include_dirs` 传播头文件路径 -3. 传递依赖自动入图(llmapi → tinyhttps → mbedtls 全自动) +mcpp automatically: +1. Downloads source tarballs from mcpp-index +2. Propagates header search paths per `[build].include_dirs` +3. Pulls transitive dependencies into the graph (llmapi → tinyhttps → mbedtls, fully automatic) -### 3.4 纯 C 库 +### 3.4 Pure C Library ```toml [package] @@ -385,7 +407,7 @@ sources = ["src/**/*.c"] kind = "lib" ``` -### 3.5 混合 C / C++23 模块项目 +### 3.5 Mixed C / C++23 Module Project ```toml [package] @@ -397,13 +419,13 @@ include_dirs = ["include"] c_standard = "c11" [dependencies] -lua = "5.4.7" # 纯 C 库,mcpp 自动用 C 编译器编译 .c 文件 +lua = "5.4.7" # Pure C library; mcpp compiles .c files with the C compiler automatically [targets.hybrid] kind = "bin" ``` -### 3.6 跨编译静态发布 +### 3.6 Cross-Compiled Static Release ```toml [package] @@ -420,30 +442,30 @@ linkage = "static" ```bash mcpp build --target x86_64-linux-musl -# → 产出完全静态链接的二进制,可直接 scp 到任意 Linux x86_64 机器运行 +# → Produces a fully statically linked binary that can be scp'd directly to any Linux x86_64 machine and run ``` -## 4. 约定与默认值速查 +## 4. Conventions and Defaults Cheat Sheet -| 项目 | 默认值 | 说明 | +| Item | Default | Notes | |---|---|---| -| 源文件 | `src/**/*.{cppm,cpp,cc,c}` | 自动递归扫描 | -| 入口 | `src/main.cpp` | 有这个文件就推断为 `bin` 目标 | -| 库根 | `src/.cppm` | 可用 `[lib].path` 覆盖 | -| C++ 标准 | `c++23` | 用 `[package].standard` 配置; 支持 `c++26` / `c++2c` | -| C 标准 | `c11` | `.c` 文件自动走 C 编译器 | -| 静态 stdlib | `true` | 便携二进制 | -| 头文件 | `include/`(如果存在) | 自动加到 `-I` | -| 测试 | `tests/**/*.cpp` | `mcpp test` 自动发现 | -| 依赖命名空间 | `mcpp`(默认) | 平铺写法走默认 ns | +| Source files | `src/**/*.{cppm,cpp,cc,c}` | Scanned recursively and automatically | +| Entry point | `src/main.cpp` | If this file exists, a `bin` target is inferred | +| Library root | `src/.cppm` | Override with `[lib].path` | +| C++ standard | `c++23` | Configure with `[package].standard`; supports `c++26` / `c++2c` | +| C standard | `c11` | `.c` files go through the C compiler automatically | +| Static stdlib | `true` | Portable binary | +| Headers | `include/` (if present) | Added to `-I` automatically | +| Tests | `tests/**/*.cpp` | Discovered automatically by `mcpp test` | +| Dependency namespace | `mcpp` (default) | The flat form uses the default ns | -### 4.1 旧 `[language]` 兼容层 +### 4.1 Legacy `[language]` Compatibility Layer -旧配置仍可读取: +The old configuration is still readable: ```toml [language] standard = "c++26" ``` -新项目请使用 `[package].standard`。如果两个位置都出现,`[package].standard` 是权威配置。 +New projects should use `[package].standard`. If both locations are present, `[package].standard` is authoritative. diff --git a/docs/06-workspace.md b/docs/06-workspace.md index b5183d4c..be6e8793 100644 --- a/docs/06-workspace.md +++ b/docs/06-workspace.md @@ -1,22 +1,22 @@ -# 工作空间 (Workspace) +# Workspace -工作空间允许在同一个仓库中组织和管理多个相关的 mcpp 包(库或应用程序)。各成员包共享统一的依赖版本配置和工具链设置,同时保持独立的 `mcpp.toml` 工程文件。 +A workspace lets you organize and manage multiple related mcpp packages (libraries or applications) within a single repository. Member packages share a unified set of dependency versions and toolchain settings while each keeping its own `mcpp.toml` project file. -## 1. 概述 +## 1. Overview -工作空间解决以下问题: +Workspaces address the following problems: -- **依赖版本统一管理** — 多个子包使用相同版本的第三方依赖,避免重复声明和版本不一致 -- **工具链配置共享** — 在工作空间根目录统一声明工具链,各成员继承或覆盖 -- **多包协同开发** — 库与应用在同一仓库中开发,通过 `path` 依赖相互引用 +- **Unified dependency-version management** — multiple sub-packages use the same versions of third-party dependencies, avoiding duplicate declarations and version drift. +- **Shared toolchain configuration** — declare the toolchain once at the workspace root; members inherit it or override it as needed. +- **Multi-package co-development** — libraries and applications are developed in the same repository and reference one another through `path` dependencies. -工作空间不改变依赖声明方式。成员之间通过已有的 `path = "..."` 机制声明依赖关系,与非工作空间项目的用法完全一致。 +A workspace does not change how dependencies are declared. Members reference one another through the existing `path = "..."` mechanism, exactly as in a non-workspace project. -## 2. 工程文件结构 +## 2. Project File Structure -### 2.1 工作空间根 +### 2.1 The Workspace Root -在仓库根目录的 `mcpp.toml` 中声明 `[workspace]`: +Declare `[workspace]` in the `mcpp.toml` at the repository root: ```toml [workspace] @@ -27,9 +27,9 @@ members = [ ] ``` -`members` 列出各成员包的相对路径,每个路径下须包含独立的 `mcpp.toml`。 +`members` lists the relative path of each member package; every such path must contain its own `mcpp.toml`. -可选 `exclude` 字段排除特定路径: +The optional `exclude` field excludes specific paths: ```toml [workspace] @@ -37,17 +37,17 @@ members = ["libs/*"] exclude = ["libs/experimental"] ``` -### 2.2 虚拟工作空间与根包工作空间 +### 2.2 Virtual Workspaces vs. Root-Package Workspaces -**虚拟工作空间**:根 `mcpp.toml` 仅包含 `[workspace]`,不包含 `[package]`。根目录不产出构建产物,仅作为管理节点。 +**Virtual workspace**: the root `mcpp.toml` contains only `[workspace]` and no `[package]`. The root produces no build artifacts and serves purely as a management node. ```toml -# 虚拟工作空间 — 只有 [workspace] +# Virtual workspace — [workspace] only [workspace] members = ["libs/core", "apps/server"] ``` -**根包工作空间**:根 `mcpp.toml` 同时包含 `[package]` 和 `[workspace]`。根目录本身也是一个可构建的包。 +**Root-package workspace**: the root `mcpp.toml` contains both `[package]` and `[workspace]`. The root itself is also a buildable package. ```toml [workspace] @@ -61,9 +61,9 @@ version = "0.1.0" core = { path = "libs/core" } ``` -### 2.3 成员工程文件 +### 2.3 Member Project Files -各成员维护独立的 `mcpp.toml`,结构与普通项目一致: +Each member maintains its own `mcpp.toml`, structured just like a regular project: ```toml # libs/core/mcpp.toml @@ -76,7 +76,7 @@ version = "0.1.0" kind = "lib" ``` -成员之间通过 `path` 依赖引用: +Members reference one another through `path` dependencies: ```toml # libs/http/mcpp.toml @@ -92,12 +92,12 @@ core = { path = "../core" } mbedtls.workspace = true ``` -## 3. 依赖版本继承 +## 3. Inheriting Dependency Versions -在 `[workspace.dependencies]` 中集中声明依赖版本,成员通过 `.workspace = true` 继承: +Declare dependency versions centrally under `[workspace.dependencies]`; members inherit them with `.workspace = true`: ```toml -# 根 mcpp.toml +# root mcpp.toml [workspace.dependencies] cmdline = "0.0.2" capi.lua = "0.0.3" # dotted selector: mcpplibs.capi/lua, then capi/lua @@ -108,35 +108,35 @@ gtest = "1.15.2" ``` ```toml -# 成员 mcpp.toml +# member mcpp.toml [dependencies.compat] -mbedtls.workspace = true # 继承版本 → "3.6.1" +mbedtls.workspace = true # inherits version → "3.6.1" [dev-dependencies.compat] -gtest.workspace = true # 继承版本 → "1.15.2" +gtest.workspace = true # inherits version → "1.15.2" ``` -成员可以覆盖继承的版本: +A member can override an inherited version: ```toml [dependencies.compat] -mbedtls = "4.0.0" # 覆盖,不使用 workspace 版本 +mbedtls = "4.0.0" # override; does not use the workspace version ``` -## 4. 工具链与构建配置继承 +## 4. Inheriting Toolchain and Build Configuration -工作空间根的 `[toolchain]` 和 `[target.]` 配置自动继承到所有成员。成员可在自身的工程文件中覆盖。 +The workspace root's `[toolchain]` and `[target.]` settings are automatically inherited by all members. A member can override them in its own project file. -配置优先级(从高到低): +Configuration precedence (highest to lowest): -1. 命令行参数(`--target`、`--static`) -2. 成员 `mcpp.toml` 中的声明 -3. 工作空间根 `mcpp.toml` 中的声明 -4. 全局配置(`~/.mcpp/config.toml`) -5. 内置默认值 +1. Command-line arguments (`--target`, `--static`) +2. Declarations in the member `mcpp.toml` +3. Declarations in the workspace-root `mcpp.toml` +4. Global configuration (`~/.mcpp/config.toml`) +5. Built-in defaults ```toml -# 工作空间根 +# workspace root [toolchain] default = "gcc@16.1.0" @@ -146,47 +146,47 @@ linkage = "static" ``` ```toml -# 某成员覆盖工具链 +# a member overrides the toolchain [toolchain] default = "clang@19.0" ``` -## 5. 构建命令 +## 5. Build Commands -### 5.1 从工作空间根目录构建 +### 5.1 Building from the Workspace Root ```bash -mcpp build # 构建默认目标(自动选择含二进制目标的成员) -mcpp build -p server # 构建指定成员及其依赖 -mcpp build -p core # 构建指定库成员 +mcpp build # build the default target (auto-selects the member with a binary target) +mcpp build -p server # build a specific member and its dependencies +mcpp build -p core # build a specific library member ``` -### 5.2 从成员子目录构建 +### 5.2 Building from a Member Subdirectory ```bash cd libs/http -mcpp build # 自动检测工作空间,构建当前成员 +mcpp build # auto-detects the workspace and builds the current member ``` -mcpp 从当前目录向上搜索,若发现包含 `[workspace]` 的 `mcpp.toml` 且当前目录在 `members` 列表中,则自动进入工作空间模式,继承工作空间配置。 +mcpp searches upward from the current directory; if it finds an `mcpp.toml` containing `[workspace]` and the current directory is listed in `members`, it automatically enters workspace mode and inherits the workspace configuration. -### 5.3 `-p, --package` 选项 +### 5.3 The `-p, --package` Option -`-p` 可用于 `build`、`test`、`run` 等命令,指定构建的目标成员。参数值为成员路径的最后一段目录名或完整相对路径: +`-p` works with `build`, `test`, `run`, and other commands to select the target member. Its value is either the last path segment of a member's directory name or the full relative path: ```bash -mcpp build -p server # 匹配 apps/server -mcpp test -p core # 匹配 libs/core +mcpp build -p server # matches apps/server +mcpp test -p core # matches libs/core mcpp run -p server -- --port 8080 ``` -## 6. 目录布局 +## 6. Directory Layout -工作空间推荐的目录布局: +The recommended directory layout for a workspace: ``` myproject/ -├── mcpp.toml # [workspace] 声明 +├── mcpp.toml # [workspace] declaration ├── libs/ │ ├── core/ │ │ ├── mcpp.toml # [package] namespace="myproject" name="core" @@ -203,16 +203,16 @@ myproject/ └── main.cpp # import myproject.http; ``` -各成员的构建产物位于各自的 `target/` 子目录下。 +Each member's build artifacts live under its own `target/` subdirectory. -## 7. 与 C++ 模块的关系 +## 7. Relationship to C++ Modules -工作空间与 C++23 模块机制协同工作: +Workspaces work in concert with the C++23 module mechanism: -- **接口可见性由语言控制** — `export module` 和 `import` 语句决定模块的公开接口,工作空间不做额外的可见性限制 -- **模块名由库作者决定** — 工作空间不强制模块名与包名或命名空间一致 -- **partition 用于内部组织** — `import :internal;`(不带 `export`)的 partition 对消费者不可见,无需构建工具介入 +- **Interface visibility is controlled by the language** — `export module` and `import` statements determine a module's public interface; the workspace imposes no additional visibility restrictions. +- **Module names are chosen by the library author** — the workspace does not require module names to match the package name or namespace. +- **Partitions are for internal organization** — a partition imported via `import :internal;` (without `export`) is invisible to consumers, with no build-tool involvement required. -## 8. 完整示例 +## 8. Complete Example -参见 [`examples/04-workspace/`](../examples/04-workspace/),包含一个三成员工作空间的完整可运行示例。 +See [`examples/04-workspace/`](../examples/04-workspace/) for a complete, runnable example of a three-member workspace. diff --git a/docs/README.md b/docs/README.md index 9cc8b67a..eda9cc94 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,11 @@ -# 用户文档目录 +# User Documentation -- [00 - 快速开始](00-getting-started.md) -- [01 - 示例项目](01-examples.md) -- [02 - 发布打包](02-pack-and-release.md) -- [03 - 工具链管理](03-toolchains.md) -- [04 - 从源码构建 & 参与贡献](04-build-from-source.md) -- [05 - mcpp.toml 工程文件指南](05-mcpp-toml.md) +**English** | [简体中文](zh/README.md) + +- [00 - Getting Started](00-getting-started.md) +- [01 - Examples](01-examples.md) +- [02 - Packaging & Release](02-pack-and-release.md) +- [03 - Toolchain Management](03-toolchains.md) +- [04 - Building from Source & Contributing](04-build-from-source.md) +- [05 - mcpp.toml Manifest Guide](05-mcpp-toml.md) +- [06 - Workspaces](06-workspace.md) diff --git a/docs/zh/00-getting-started.md b/docs/zh/00-getting-started.md new file mode 100644 index 00000000..34490dd7 --- /dev/null +++ b/docs/zh/00-getting-started.md @@ -0,0 +1,128 @@ +# 00 — 快速开始 + +> 5 分钟完成 install → new → build → run → pack 全流程。 + +## 安装 + +仅需 Linux x86_64 或 macOS ARM64 环境,无需预先安装 GCC、xlings 或其他依赖。 +mcpp 在首次运行时会将默认工具链安装至独立沙盒(`~/.mcpp/`)。 +Linux 默认使用 musl-gcc,macOS 默认使用 LLVM/Clang。 + +推荐通过 [xlings](https://xlings.d2learn.org) 进行安装,可与系统 +环境保持隔离: + +```bash +xlings install mcpp -y +``` + +或使用一键安装脚本(内置 xlings,统一安装至 `~/.mcpp/`): + +```bash +curl -fsSL https://github.com/mcpp-community/mcpp/releases/latest/download/install.sh | bash +``` + +完整安装说明(包括 xlings 安装命令、Windows 支持等)参见 +[README 的"安装"小节](../../README.zh-CN.md#安装)。 + +安装完成后,启动新的 shell 会话或执行 `source ~/.bashrc`,然后验证: + +```bash +mcpp --version +# mcpp 0.0.1 +``` + +> [!TIP] +> 若提示 `command not found`,通常是 `~/.mcpp/bin` 尚未加入当前 shell +> 的 PATH。重启终端,或执行 `source ~/.bashrc`(zsh 对应 `~/.zshrc`, +> fish 使用 `exec fish`)即可生效。也可直接通过绝对路径 +> `~/.mcpp/bin/mcpp` 调用。 + +## 创建项目 + +```bash +mcpp new hello && cd hello +``` + +生成的目录结构如下: + +``` +hello/ +├── mcpp.toml ← 工程描述 +└── src/ + └── main.cpp +``` + +`src/main.cpp` 默认为 C++23 模块化的 hello world: + +```cpp +import std; + +int main() { + std::println("Hello from hello!"); + std::println("Built with import std + std::println on modular C++23."); +} +``` + +## 构建与运行 + +```bash +mcpp build +# Compiling hello v0.1.0 (.) +# Finished release [optimized] in 1.6s + +mcpp run +# Hello from hello! +# Built with import std + std::println on modular C++23. +``` + +首次构建需下载默认工具链(Linux 为 musl-gcc 15.1,macOS 为 LLVM/Clang 20.1), +期间显示进度与速度。下载完成后,所有 mcpp 项目共用同一份沙盒。 + +## 增量编译与测试 + +```bash +mcpp build # 增量构建 +mcpp clean # 清理 target/ +mcpp test # 编译并运行 tests/**/*.cpp(gtest 风格) +``` + +## 添加依赖 + +在 `mcpp.toml` 中声明依赖: + +```toml +[dependencies] +"mcpplibs.cmdline" = "^0.0.1" +``` + +`mcpp build` 将自动从 +[mcpp-index](https://github.com/mcpp-community/mcpp-index) 解析 SemVer +约束、拉取源码并加入编译图。完整示例参见 +[01 — 示例项目](01-examples.md) 中的 `02-with-deps`。 + +## 生成发布包 + +`mcpp pack` 将构建产物与运行期依赖打包为可独立分发的 tarball: + +```bash +mcpp pack # 默认 bundle-project,包含项目第三方 .so +mcpp pack --mode static # 全静态(musl) +mcpp pack --mode bundle-all # 全自包含,含 libc 与 ld-linux +``` + +三种模式的差异及产物布局参见 [02 — 发布打包](02-pack-and-release.md)。 + +## 后续阅读 + +- [01 — 示例项目](01-examples.md) — 可直接运行的最小工程集合 +- [02 — 发布打包](02-pack-and-release.md) — 构建可分发产物 +- [03 — 工具链管理](03-toolchains.md) — 切换编译器与多版本管理 +- 任意命令的完整选项可通过 `mcpp --help` 查阅 + + +## 更多入口 + +- GUI 起步:`mcpp new myapp --template imgui`(模板随 imgui 库分发、版本自动对齐; + `mcpp new --list-templates imgui` 查看库提供的全部模板,`--template imgui:docking` 选指定模板)。 +- 解释默认决策:`mcpp why [toolchain|runtime|deps]`;主机能力体检:`mcpp self doctor`; + 机器可读解析清单:构建产物 `target///resolution.json`。 diff --git a/docs/zh/01-examples.md b/docs/zh/01-examples.md new file mode 100644 index 00000000..7bb74088 --- /dev/null +++ b/docs/zh/01-examples.md @@ -0,0 +1,43 @@ +# 01 — 示例项目 + +> 仓库的 [`examples/`](../../examples) 目录下提供了一组循序渐进的最小工程, +> 覆盖从单文件 `import std` 到全静态发布包的常见场景。每个示例都可以 +> 独立进入并通过 `mcpp build` 完成构建。 + +## 运行方式 + +```bash +git clone https://github.com/mcpp-community/mcpp +cd mcpp/examples/01-hello +mcpp build && mcpp run +``` + +每个示例附带独立的 README,仅说明该示例相对前一个引入的新概念。 +安装步骤、工具链初始化等通用内容统一放在 +[00 — 快速开始](00-getting-started.md) 中,不再在示例内重复。 + +## 示例列表 + +| # | 路径 | 说明 | 涉及的关键概念 | +|---|---|---|---| +| 01 | [`examples/01-hello`](../../examples/01-hello/) | 单文件 + `import std` 的最小工程 | `mcpp new` 的默认产物结构 | +| 02 | [`examples/02-with-deps`](../../examples/02-with-deps/) | 引入依赖 `mcpplibs.cmdline` 解析命令行参数 | `[dependencies]`、SemVer、`mcpp.lock` | +| 03 | [`examples/03-pack-static`](../../examples/03-pack-static/) | 通过 `mcpp pack --mode static` 生成全静态发布包 | `[target.]` 与 `[pack]` 配置 | + +## 推荐阅读顺序 + +建议按编号依次阅读: + +1. **`01-hello`** 展示 mcpp 工程的最小骨架(`mcpp.toml` 与 `src/main.cpp`), + 并演示 `import std` 的基本用法。 +2. **`02-with-deps`** 在前一示例基础上引入外部依赖,涵盖锁文件机制 + 与模块化包索引的工作方式。 +3. **`03-pack-static`** 演示如何将构建产物打包为可独立分发的单文件 + 二进制;打包细节可参考 [02 — 发布打包](02-pack-and-release.md)。 + +## 新增示例 + +示例工程遵循统一的目录结构:`mcpp.toml` + `src/` + `README.md`。 +新增示例时,在 `examples/` 下创建编号目录(如 `04-xxx/`),并在 +README 中简要说明该示例演示的概念,然后提交 PR。提交规范见 +[04 — 从源码构建 & 参与贡献](04-build-from-source.md)。 diff --git a/docs/zh/02-pack-and-release.md b/docs/zh/02-pack-and-release.md new file mode 100644 index 00000000..6e7e00df --- /dev/null +++ b/docs/zh/02-pack-and-release.md @@ -0,0 +1,126 @@ +# 02 — 发布打包 + +> `mcpp build` 产生的二进制仅可在本机运行 —— loader 与 RUNPATH 均指向 +> `~/.mcpp/`。如需分发至其他机器或部署至服务器,应使用 `mcpp pack` +> 生成自包含 tarball。 + +## 三种模式 + +| 模式 | 说明 | 体积增量 | 兼容性 | +|---|---|---|---| +| `static` | musl 全静态,无运行期依赖 | +5–10 MB | 任意 Linux x86_64 | +| `bundle-project`(默认) | 仅打包项目第三方 .so | +几 MB | 主流发行版(Ubuntu 22+, Debian 12+, RHEL 9+ 等) | +| `bundle-all` | 包含 ld-linux、libc、libstdc++ 与项目 .so | +30–50 MB | 包含老旧版本在内的任意 Linux | + +选择建议: + +- 命令行工具,或目标为 Docker scratch、Alpine 等最小镜像 → `static` +- 桌面或服务端发布,目标为主流 Linux 发行版 → `bundle-project`(默认) +- 需兼容老旧 CentOS、麒麟等 glibc 版本较低的环境 → `bundle-all` + +## 命令 + +```bash +mcpp pack # 默认 bundle-project +mcpp pack --mode static +mcpp pack --mode bundle-all +mcpp pack --target x86_64-linux-musl # 等价 --mode static +mcpp pack --format dir # 输出为目录,不打包 tarball +mcpp pack -o myapp.tar.gz # 仅文件名:落到 target/dist/myapp.tar.gz +mcpp pack -o /abs/path/myapp.tar.gz # 含目录:按字面路径输出 +``` + +`-o` 接受裸文件名时自动归到 `target/dist/`;含目录(相对或绝对) +时按字面路径输出。 + +完整选项参见 `mcpp pack --help`。 + +## 产物布局 + +tarball 内容包在一个顶层目录里,该目录的名字与 tarball 文件名(去掉 +`.tar.gz`)保持一致 —— 这样图形界面"右键解压"和命令行 `tar -xzf` 都 +得到同一个自包含的目录,不会把内容散到当前路径。 + +### Mode `static` + +``` +target/dist/myapp-0.1.0-x86_64-linux-musl-static.tar.gz +└── myapp-0.1.0-x86_64-linux-musl-static/ + ├── bin/myapp ← 全静态 ELF(无 PT_INTERP / RUNPATH) + ├── myapp ← 顶层入口(thin shell wrapper,可直接执行 ./myapp) + ├── README.md ← 自动从项目根目录拷贝 + └── LICENSE +``` + +### Mode `bundle-project`(默认) + +``` +target/dist/myapp-0.1.0-x86_64-linux-gnu.tar.gz +└── myapp-0.1.0-x86_64-linux-gnu/ + ├── bin/myapp ← 动态链接,RUNPATH=$ORIGIN/../lib + │ PT_INTERP=/lib64/ld-linux-x86-64.so.2 + ├── lib/ + │ ├── libcurl.so.4 ← 项目第三方依赖 + │ ├── libssl.so.3 + │ └── ... + ├── myapp ← 顶层入口 + ├── README.md + └── LICENSE +``` + +跳过列表参考 +[PEP 600 / manylinux2014](https://peps.python.org/pep-0600/) —— +`libc`、`libm`、`libstdc++`、`libgcc_s`、`ld-linux-*` 等基础库默认 +假设目标系统已具备,不打包进 tarball。 + +### Mode `bundle-all` + +``` +target/dist/myapp-0.1.0-x86_64-linux-gnu-bundle-all.tar.gz +└── myapp-0.1.0-x86_64-linux-gnu-bundle-all/ + ├── bin/myapp + ├── lib/ + │ ├── ld-linux-x86-64.so.2 ← 完整 loader 与 libc + │ ├── libc.so.6 + │ ├── libstdc++.so.6 + │ ├── libgcc_s.so.1 + │ └── ...项目依赖 + ├── myapp ← 双入口之一 + ├── run.sh ← 双入口之二(内容相同) + ├── README.md + └── LICENSE +``` + +`-o foo.tar.gz` 时顶层目录名也会变成 `foo`(包名 - 目录名 始终一致)。 + +ELF 规范限制 `PT_INTERP` 不能使用 `$ORIGIN`,因此 bundle-all 模式 +通过 `run.sh`(及顶层同名 wrapper)以绝对路径方式调用 loader: + +```sh +exec "$here/lib/ld-linux-x86-64.so.2" --library-path "$here/lib" "$here/bin/myapp" "$@" +``` + +## 配置项 + +打包行为通过 `mcpp.toml` 中的 `[pack]` 节配置,常用字段如下: + +```toml +[pack] +default_mode = "static" # 不带 --mode 时的默认模式 +include = ["share/**", "config/*.toml"] # 额外打包的文件 +exclude = ["debug/**"] + +# 微调 bundle-project 的过滤策略 +[pack.bundle-project] +also_skip = ["libcustom.so"] # 假定目标系统已具备的库 +force_bundle = ["libfoo.so"] # 即使命中 PEP 600 名单也强制打包 +``` + +`static` 模式还需在 `[target.]` 中配置 musl 工具链,完整写法 +参见 [`examples/03-pack-static`](../../examples/03-pack-static/) 的 `mcpp.toml`。 + +## 待支持 + +macOS dylib、Windows DLL,以及 `.deb` / `.rpm` / AppImage 等分发格式 +尚在规划中。本文档随 `mcpp pack` 实现演进,最新选项以 +`mcpp pack --help` 为准。 diff --git a/docs/zh/03-toolchains.md b/docs/zh/03-toolchains.md new file mode 100644 index 00000000..499b5a77 --- /dev/null +++ b/docs/zh/03-toolchains.md @@ -0,0 +1,141 @@ +# 03 — 工具链管理 + +> mcpp 维护一个独立的工具链沙盒,与系统 PATH 完全隔离。 + +## 设计动机 + +C++23 模块对编译器版本较为敏感,不同版本的 GCC / Clang 在模块语义 +处理上存在明显差异。系统包管理器提供的版本通常滞后,且多版本共存 +存在维护成本。mcpp 将工具链统一安装在沙盒目录 +(`~/.mcpp/registry/data/xpkgs/`)中,允许项目按需选择版本,且不会 +影响系统环境。 + +## 自动安装 + +首次运行 `mcpp build` 时,若尚未配置工具链,mcpp 会自动安装当前平台 +的默认工具链并将其设为全局默认: + +``` +First run no toolchain configured — installing gcc@15.1.0-musl (musl, static) as default +Downloading xim:musl-gcc@15.1.0 [====> ] 312 MB / 808 MB 3.7 MB/s +Default set to gcc@15.1.0-musl +``` + +Linux 默认使用 `gcc@15.1.0-musl`; macOS 默认使用 `llvm@20.1.7`。 + +后续构建不再触发该流程。 + +> [!TIP] +> 在 CI 或离线环境中,可通过设置 `MCPP_NO_AUTO_INSTALL=1` 关闭自动 +> 安装行为。此时若未安装工具链,`mcpp build` 将直接报错而不会发起 +> 网络请求。 + +## 手动安装 + +```bash +mcpp toolchain install gcc 16.1.0 # GNU libc,适用于动态链接默认场景 +mcpp toolchain install gcc 15.1.0-musl # musl libc,适用于全静态构建 +mcpp toolchain install musl-gcc 15.1.0 # 等价于上一条 +mcpp toolchain install llvm 20.1.7 # LLVM/Clang,macOS 默认工具链 +``` + +版本号支持部分匹配: + +```bash +mcpp toolchain install gcc 15 # 安装 15.x.y 中的最高版本(15.1.0) +mcpp toolchain install gcc@16 # 同样支持 @ 形式 +``` + +## 切换默认工具链 + +```bash +mcpp toolchain default gcc@16.1.0 +mcpp toolchain default gcc 15 # 部分版本时,从已安装的版本中选择最高 +``` + +## 查看工具链状态 + +```bash +mcpp toolchain list +``` + +输出形式如下: + +``` +Installed: + TOOLCHAIN BINARY + gcc 15.1.0-musl @mcpp/registry/data/xpkgs/xim-x-musl-gcc/15.1.0/bin/x86_64-linux-musl-g++ + * gcc 16.1.0 @mcpp/registry/data/xpkgs/xim-x-gcc/16.1.0/bin/g++ + +Available (run `mcpp toolchain install `): + TOOLCHAIN + gcc 13.3.0 + gcc 11.5.0 + ... +``` + +带有 `*` 标记的条目为当前默认工具链。`@mcpp/...` 是 `~/.mcpp/...` +的简写形式,用于减少输出宽度。 + +## 项目级版本锁定 + +若项目需固定特定版本而不依赖全局默认,可在项目的 `mcpp.toml` 中声明: + +```toml +[toolchain] +default = "gcc@16.1.0" + +# 也可按平台分发 +[toolchain] +linux = "gcc@15.1.0-musl" +macos = "llvm@20" +``` + +项目级声明优先于全局默认配置。 + +## 跨工具链构建 + +```bash +mcpp build --target x86_64-linux-musl +``` + +mcpp 将读取 `mcpp.toml` 中 `[target.x86_64-linux-musl]` 节,覆盖默认的 +工具链与 linkage 设置。该机制配合 `mcpp pack --mode static` 可生成 +全静态发布包,完整示例参见 +[`examples/03-pack-static`](../../examples/03-pack-static/)。 + +## 卸载 + +```bash +mcpp toolchain remove gcc@16.1.0 +``` + +## 重置沙盒 + +```bash +rm -rf ~/.mcpp # 删除整个沙盒 +mcpp build # 后续构建将再次触发首次安装 +``` + +## 环境变量 + +mcpp 的运行行为可通过以下环境变量调整: + +| 变量 | 用途 | +|---|---| +| `MCPP_HOME` | 覆盖沙盒位置(默认 `~/.mcpp/`),绝对路径优先级最高 | +| `MCPP_NO_AUTO_INSTALL=1` | 禁用工具链自动安装,适用于 CI 与离线环境 | +| `MCPP_NO_COLOR=1` / `NO_COLOR=1` | 禁用彩色输出 | +| `MCPP_LOG=trace\|debug\|info\|warn\|error` | 日志级别 | + +未显式设置 `MCPP_HOME` 时,mcpp 将基于二进制所在目录的上一级路径 +自动定位沙盒位置(release tarball 解压至 `~/.mcpp/` 后,`~/.mcpp/` +即为 home),因此 release 版本无需任何环境变量配置即可运行。 + + +## ABI 能力强制 + +依赖可声明 `abi:` 能力(如 `compat.glfw` 声明 `abi:glibc`)。解析出的 +工具链 ABI 不满足任一依赖的 abi 要求时,构建会**尽早失败**并给出修复建议 +(例如 musl-static 工具链遇到 abi:glibc 依赖),取代深层的链接/头文件报错。 +查看:`mcpp why toolchain`。 diff --git a/docs/zh/04-build-from-source.md b/docs/zh/04-build-from-source.md new file mode 100644 index 00000000..56f35957 --- /dev/null +++ b/docs/zh/04-build-from-source.md @@ -0,0 +1,104 @@ +# 04 — 从源码构建 & 参与贡献 + +> mcpp 采用自托管模式 —— 通过 mcpp 自身从源码构建 mcpp。 +> 任何已具备可运行 mcpp 二进制的环境均可完成源码构建。 + +## 准备 + +参照 [00 — 快速开始](00-getting-started.md) 安装一份现成的 mcpp, +然后克隆仓库: + +```bash +git clone https://github.com/mcpp-community/mcpp +cd mcpp +``` + +## 构建与测试 + +```bash +mcpp build # 使用现成 mcpp 编译当前源码 → ./target/.../bin/mcpp +mcpp run -- --version # 运行刚构建出的产物 +mcpp test # 执行 tests/unit 与 tests/e2e +``` + +首次构建会自动拉取默认工具链,详见 +[03 — 工具链管理](03-toolchains.md)。 + +如需生成与 release 一致的全静态二进制(对应 `release.yml` 走的路径): + +```bash +mcpp build --target x86_64-linux-musl +# → target/x86_64-linux-musl/.../bin/mcpp 为全静态 ELF +``` + +## 源码结构 + +``` +src/ +├── main.cpp 入口 +├── cli.cppm 命令分发与参数解析 +├── manifest.cppm mcpp.toml 解析 +├── lockfile.cppm mcpp.lock +├── version_req.cppm SemVer 约束 +├── fetcher.cppm 依赖下载(git / index / path) +├── config.cppm ~/.mcpp/config.toml +├── bmi_cache.cppm 跨项目 BMI 缓存 +├── dyndep.cppm ninja dyndep 生成 +├── ui.cppm 进度条与输出格式 +├── build/ 构建编排与 ninja 后端 +├── modgraph/ P1689 模块扫描与依赖图 +├── toolchain/ 工具链探测、指纹与 std 模块 +├── pack/ mcpp pack 实现 +├── publish/ mcpp publish 与 xpkg 生成 +└── libs/ 第三方依赖(toml 解析等) + +tests/ +├── unit/ 各 .cppm 模块的 gtest 单元测试 +└── e2e/ 端到端 shell 脚本(run_all.sh 为 CI 入口) +``` + +## 测试组织 + +测试分为两层: + +- **单元测试** 位于 `tests/unit/test_.cpp`,与 `src/.cppm` + 按模块一一对应。 +- **e2e 测试** 位于 `tests/e2e/NN_.sh`,通过执行真实的 `mcpp` + 二进制覆盖端到端行为;`run_all.sh` 为 CI 调用入口。 + +修改 `src/` 下任意 `.cppm` 模块时,应同步检查对应单元测试是否覆盖了 +变更点;新增功能优先补充 e2e 用例。 + +执行单个 e2e 脚本: + +```bash +cd tests/e2e +MCPP=$(realpath ../../target/x86_64-linux-musl/*/bin/mcpp) ./02_new_build_run.sh +``` + +## Issue 与 PR 提交规范 + +### Issue + +提交至 [github.com/mcpp-community/mcpp/issues](https://github.com/mcpp-community/mcpp/issues), +建议附带以下信息: + +- `mcpp self env` 的完整输出 +- 失败命令的完整输出(配合 `MCPP_LOG=debug` 可获得更详细信息) +- 操作系统、发行版、glibc 版本(可通过 `ldd --version` 查看) + +### Pull Request + +mcpp 处于早期迭代阶段,接口可能调整,提交 PR 前请注意: + +1. 涉及 CLI 或 `mcpp.toml` schema 的改动,建议先开 issue 对齐方向。 +2. 单个 PR 聚焦单一改动;commit 标题使用英文 imperative 形式 + (`fix: ...` / `feat: ...`)。 +3. 提交前确认 `mcpp test` 全部通过。 + +## 社区资源 + +- [社区论坛](https://forum.d2learn.org/category/20) +- 交流群 QQ: 1067245099 +- [mcpp-index](https://github.com/mcpp-community/mcpp-index) — 默认包索引 +- [mcpplibs](https://github.com/mcpplibs) — 配套的模块化 C++ 库集合 diff --git a/docs/zh/05-mcpp-toml.md b/docs/zh/05-mcpp-toml.md new file mode 100644 index 00000000..d22b4770 --- /dev/null +++ b/docs/zh/05-mcpp-toml.md @@ -0,0 +1,449 @@ +# mcpp.toml 工程文件指南 + +`mcpp.toml` 是 mcpp 构建工具的项目配置文件,类似 Cargo 的 `Cargo.toml` 或 Node 的 `package.json`。放在项目根目录下,`mcpp build` 会自动发现并读取它。 + +## 1. 最小化示例 + +mcpp 的设计原则是 **约定优于配置** —— 大多数字段都有合理默认值,最简单的 `mcpp.toml` 只需几行: + +### 1.1 可执行程序(最简) + +```toml +[package] +name = "hello" +version = "0.1.0" +``` + +mcpp 自动推断: +- 源文件: `src/**/*.{cppm,cpp,cc,c}` +- 入口: `src/main.cpp` → 生成 `hello` 二进制 +- 标准: C++23 +- 模块: 扫描 `export module ...` 声明自动建立依赖图 + +### 1.2 库项目(最简) + +```toml +[package] +name = "mylib" +version = "0.1.0" + +[targets.mylib] +kind = "lib" +``` + +lib-root 约定:主模块接口默认在 `src/mylib.cppm`(包名的最后一段)。 + +## 2. 完整字段参考 + +### 2.1 `[package]` — 包元数据 + +```toml +[package] +name = "myapp" # 包名(必填) +version = "0.1.0" # 语义化版本(必填) +standard = "c++23" # C++ 标准(默认 c++23; 可设 c++26) +description = "My awesome app" # 简介(可选) +license = "MIT" # 许可证(可选) +authors = ["Alice", "Bob"] # 作者列表(可选) +repo = "https://github.com/user/myapp" # 仓库地址(可选) +``` + +`standard` 是 C++ 语言标准的一等配置。推荐值: + +- `c++23`:默认值,适合当前模块化默认模板。 +- `c++26`:需要 C++26 语言特性时使用。 +- `c++2c`:兼容别名,解析后归一为 `c++26`。 +- `gnu++23` / `gnu++26`:需要 GNU dialect 时使用,会进入 fingerprint 和 std BMI cache key。 +- `c++latest`:跟随当前 mcpp 支持的最新标准,适合本地试验,不推荐要求可复现的发布包使用。 + +### 2.2 `[targets.]` — 构建目标 + +```toml +# 可执行程序(默认,有 src/main.cpp 时自动推断) +[targets.myapp] +kind = "bin" +main = "src/main.cpp" # 可选,默认 src/main.cpp + +# 静态库 +[targets.mylib] +kind = "lib" + +# 共享库 +[targets.mylib] +kind = "shared" +soname = "libmylib.so.1" # 可选: ELF/Mach-O ABI 名称,运行时会生成同名 alias +``` + +`soname` 用于共享库的 ABI 名称,类似 Autotools/CMake 中的 +`SOVERSION`/`SONAME`。在 Linux 上,mcpp 会向链接器传递 +`-Wl,-soname,`,并在输出目录生成 ` -> lib.so` alias, +让下游程序可通过标准 ABI 名称 `DT_NEEDED` 或 `dlopen()` 加载该库。 +该字段只对 `kind = "shared"` 有效,值必须是文件名 basename。 + +### 2.3 `[build]` — 构建配置 + +```toml +[build] +sources = ["src/**/*.cppm", "src/**/*.cpp"] # 源文件 glob(默认: src/**/*.{cppm,cpp,cc,c}) +include_dirs = ["include", "third_party/include"] # 头文件搜索路径 +c_standard = "c11" # C 源文件的标准(默认 c11) +cflags = ["-DFOO=1"] # 额外 C 编译参数 +cxxflags = ["-DBAR=2"] # 额外 C++ 编译参数(不要放 -std=...) +ldflags = ["-lfoo"] # 额外链接参数 +static_stdlib = true # 静态链接 libstdc++(默认 true) +macos_deployment_target = "14.0" # macOS 产物的最低支持系统版本(仅 macOS 生效) +``` + +`macos_deployment_target` 设定产物 Mach-O 头里的最低系统版本 +(`LC_BUILD_VERSION minos`),即二进制能运行的最老 macOS。优先级与各生态 +惯例一致:环境变量 `MACOSX_DEPLOYMENT_TARGET`(单次调用的显式覆盖, +cargo/rustc、cc 等同样尊重该变量)> 本字段(项目默认,类似 SwiftPM 的 +`platforms:`)> **内建默认 `14.0`**(rustc 风格——每个 target 都有基线, +14.0 即 LLVM 官方静态库自身的下限)。该值会进入 BMI 指纹——切换 target +会自动重建模块缓存。 + +**默认即静态运行时(portable by default)**:`static_stdlib = true` +(默认)时,macOS 链接会静态链入 LLVM 自带的 libc++/libc++abi —— +系统 libc++ 会把实际可运行版本钉死在构建机的 OS(老系统缺新符号, +如 `std::print` 的支撑符号),静态化才能真正兑现 floor。因此默认构建的 +产物在任何 macOS ≥ 14 上开箱即用。设 `static_stdlib = false` 退回动态 +系统 libc++(产物只保证在构建机同版本及以上运行)。更低 floor(11–13) +需自建 libc++ 归档(已验证可行,数据级切换,按需提供)。 + +C++ 标准不要通过 `build.cxxflags = ["-std=..."]` 配置。请使用: + +```toml +[package] +standard = "c++26" +``` + +mcpp 会把同一个标准用于普通 C++ 编译、模块扫描、`compile_commands.json` 和 `import std` 的标准库 BMI 构建。 + +**glob 排除**(`!` 前缀,mcpp 0.0.4+): + +```toml +[build] +sources = [ + "src/**/*.cpp", + "!src/**/*_test.cpp", # 排除测试文件 + "!src/**/*_fuzzer.cpp", # 排除 fuzzer +] +``` + +### 2.4 `[lib]` — 库根模块约定 + +```toml +[lib] +path = "src/capi/lua.cppm" # 覆盖默认的 lib-root 位置 +``` + +默认约定:`src/<包名最后一段>.cppm`(如包名 `mcpplibs.cmdline` → `src/cmdline.cppm`)。 + +### 2.5 `[dependencies]` — 运行时依赖 + +```toml +# 默认包空间(mcpplibs)下的包 +[dependencies] +gtest = "1.15.2" # 精确版本 +mbedtls = "3.6.1" +ftxui = "6.1.9" + +# dotted selector: 先匹配 mcpplibs., 找不到再匹配同级 peer root。 +# 例如 imgui.core 会按顺序尝试 mcpplibs.imgui/core, imgui/core。 +[dependencies] +capi.lua = "0.0.3" +compat.gtest = "1.15.2" +imgui.core = "0.0.1" +imgui.backend.glfw_opengl3 = "0.0.1" + +# 命名空间子表写法 +[dependencies.mcpplibs] +cmdline = "0.0.2" +tinyhttps = "0.2.2" +llmapi = "0.2.5" + +[dependencies.compat] +glfw = "3.4" # 显式 namespace, 不走 mcpplibs 优先候选 + +# 路径依赖(本地开发) +[dependencies] +mylib = { path = "../mylib" } + +# Git 依赖 +[dependencies] +mylib = { git = "https://github.com/user/mylib.git", tag = "v1.0.0" } + +# 长式 dep spec:features 与 backend 旋钮 +[dependencies] +imgui = { version = "0.0.3", features = ["docking"] } # 请求该依赖的 feature +widget = { version = "1.0", backend = "glfw_opengl3" } # 糖:= features=["backend-glfw_opengl3"] +``` + +`backend = ""` 是**通用约定糖**:1:1 脱糖为请求该依赖的 `backend-` +feature(库若支持该旋钮,应在自己的 `[features]` 中声明 `backend-*` 系列)。 +若目标包声明了 `[features]` 但不含所请求的 feature(含 backend 脱糖结果), +默认给出 warning,`mcpp build --strict` 下报错。 + +**SemVer 约束**: + +```toml +[dependencies] +foo = "^1.2.3" # >= 1.2.3, < 2.0.0 (caret,默认) +bar = "~1.2.3" # >= 1.2.3, < 1.3.0 (tilde) +baz = "=1.2.3" # 精确匹配 +qux = ">=1.0, <2.0" # 范围组合 +``` + +### 2.6 `[dev-dependencies]` — 测试依赖 + +```toml +[dev-dependencies] +gtest = "1.15.2" +``` + +`mcpp build` 忽略这些;`mcpp test` 解析并使用。`mcpp test` 会自动发现 `tests/**/*.cpp` 并编译为测试二进制。 + +### 2.7 `[toolchain]` — 工具链配置 + +```toml +[toolchain] +default = "gcc@16.1.0" + +# 跨编译目标覆盖 +[target.x86_64-linux-musl] +toolchain = "gcc@15.1.0-musl" +linkage = "static" +``` + +### 2.8 `[features]` — 特性(Cargo 式,加性) + +```toml +[features] +default = ["base"] # 默认激活集 +base = [] +docking = ["extra"] # 激活 docking 时隐含激活 extra(传递闭包) +extra = [] +``` + +- 激活来源:包自身 `default` 集 ∪ 显式请求(根包 `mcpp build --features a,b`; + 依赖经长式 dep spec `features = [...]` / `backend = "..."` 糖)。 +- 每个激活的 feature 在该包的编译中得到宏 `-DMCPP_FEATURE_` + (名字转大写,非字母数字转 `_`,如 `backend-a` → `MCPP_FEATURE_BACKEND_A`)。 +- **strict 校验**:目标包声明了 `[features]` 表时,请求未声明的 feature 给出 + warning;`--strict` 下报错。未声明 `[features]` 的包接受任意请求(纯宏用法)。 + +### 2.9 `[profile.]` — 构建档案 + +```toml +[profile.dist] +opt = 3 # -O 级别(数字或 "s"/"z" 字符串) +debug = false # -g +lto = true # -flto(注意:部分打包 gcc 未启用 LTO 插件) +strip = true # 链接期 -s +# passthrough 逃生口(固定键、开放值): +cflags = ["-fno-plt"] +cxxflags = ["-fno-plt"] +ldflags = [] +``` + +- 选择:`mcpp build --profile `,默认 `release`。 +- 内置档案:`release`(-O2)/ `dev`、`debug`(-O0 -g)/ `dist`(-O3 + strip; + **不默认开 lto**)。`[profile.<内置名>]` 可整体覆盖内置定义。 + +### 2.10 `[runtime]` — 主机运行时能力 + +```toml +[runtime] +library_dirs = ["vendor/lib"] # 烤进产物 RUNPATH 的目录(相对包根) +dlopen_libs = ["libGL.so.1"] # 运行期 dlopen 的 soname(doctor 校验) +capabilities = ["opengl.glx.driver"] # 需要的主机能力(开放命名空间) +provides = ["opengl.glx.driver"] # 显式声明本包兑现的能力(强 provider) + +# 显式 provider 覆盖(三档旋钮的"显式"档) +[runtime."opengl.glx.driver"] +provider = "compat.glx-runtime" +``` + +- **provider 选择**:声明 `provides` 的包(强)优先于仅在 `capabilities` 列出 + 能力的包(弱,向后兼容);`[runtime.] provider=` 显式覆盖最优先, + 指向依赖图中不存在的 provider 时给出 warning。 +- 解析结果可经 `mcpp why runtime`、`mcpp self doctor` 与构建产物 + `target///resolution.json` 查看(默认不是魔法)。 +- 能力命名约定:分层小写 `domain.sub.role`(如 `opengl.glx.driver`、 + `x11.display`)与前缀类 `abi:`(如 `abi:glibc`,参与工具链 ABI 强制)。 + +### 2.11 `[package] platforms` — 平台声明 + +```toml +[package] +platforms = ["linux", "macos", "windows"] +``` + +声明包支持的平台(CI 矩阵提示,经 `mcpp why` 展示)。词表由 mcpp 固定 +(它拥有 target/triple 体系):`linux | macos | windows`;未知值 warning, +`--strict` 下报错。 + +## 附录 A. Schema 所有权原则(新字段准入标准) + +> **语法封闭,词汇开放**:谁拥有解析语义谁定义键;谁拥有领域知识谁定义值。 + +- mcpp 只定义**机制**(features 并集/闭包、capability require/provide/override、 + profile→编译器旗标、platform→triple),键与形状固定;feature 名、能力名、 + 后端名等**领域词汇只出现在值里**,不进 mcpp 代码。 +- **不支持包自定义 toml 键**:键合法性不得依赖"先解析目标包",否则 manifest + 失去静态可解析性(lockfile/LSP/审计的前提)。包的扩展点 = 固定机制内的开放值域。 +- 包级旋钮统一收敛进 features;糖键(如 `backend=`)进入核心语法须满足: + ① 领域中立(跨生态通用模式)② 1:1 脱糖、零新增解析语义。 +- 字段归属总表与定型决策见 + `.agents/docs/2026-06-04-manifest-schema-ownership.md`。 + +## 3. 实战示例 + +### 3.1 简单 Hello World + +```toml +[package] +name = "hello" +version = "0.1.0" +``` + +```cpp +// src/main.cpp +import std; +int main() { std::println("Hello, mcpp!"); } +``` + +```bash +mcpp build && mcpp run +``` + +### 3.2 模块化库 + 测试 + +```toml +[package] +name = "mymath" +version = "1.0.0" + +[targets.mymath] +kind = "lib" + +[dev-dependencies] +gtest = "1.15.2" +``` + +```cpp +// src/mymath.cppm +export module mymath; +export int add(int a, int b) { return a + b; } +``` + +```cpp +// tests/test_add.cpp +#include +import mymath; +TEST(Math, Add) { EXPECT_EQ(add(1, 2), 3); } +``` + +```bash +mcpp build # 编译库 +mcpp test # 编译 + 跑测试 +``` + +### 3.3 依赖其他包的应用 + +```toml +[package] +name = "myapp" +version = "0.1.0" + +[dependencies] +ftxui = "6.1.9" + +[dependencies.mcpplibs] +cmdline = "0.0.2" +llmapi = "0.2.5" +``` + +mcpp 自动: +1. 从 mcpp-index 下载源码 tarball +2. 按 `[build].include_dirs` 传播头文件路径 +3. 传递依赖自动入图(llmapi → tinyhttps → mbedtls 全自动) + +### 3.4 纯 C 库 + +```toml +[package] +name = "myc" +version = "0.1.0" + +[build] +c_standard = "c99" +include_dirs = ["include"] +sources = ["src/**/*.c"] + +[targets.myc] +kind = "lib" +``` + +### 3.5 混合 C / C++23 模块项目 + +```toml +[package] +name = "hybrid" +version = "0.1.0" + +[build] +include_dirs = ["include"] +c_standard = "c11" + +[dependencies] +lua = "5.4.7" # 纯 C 库,mcpp 自动用 C 编译器编译 .c 文件 + +[targets.hybrid] +kind = "bin" +``` + +### 3.6 跨编译静态发布 + +```toml +[package] +name = "mytool" +version = "1.0.0" + +[toolchain] +default = "gcc@16.1.0" + +[target.x86_64-linux-musl] +toolchain = "gcc@15.1.0-musl" +linkage = "static" +``` + +```bash +mcpp build --target x86_64-linux-musl +# → 产出完全静态链接的二进制,可直接 scp 到任意 Linux x86_64 机器运行 +``` + +## 4. 约定与默认值速查 + +| 项目 | 默认值 | 说明 | +|---|---|---| +| 源文件 | `src/**/*.{cppm,cpp,cc,c}` | 自动递归扫描 | +| 入口 | `src/main.cpp` | 有这个文件就推断为 `bin` 目标 | +| 库根 | `src/.cppm` | 可用 `[lib].path` 覆盖 | +| C++ 标准 | `c++23` | 用 `[package].standard` 配置; 支持 `c++26` / `c++2c` | +| C 标准 | `c11` | `.c` 文件自动走 C 编译器 | +| 静态 stdlib | `true` | 便携二进制 | +| 头文件 | `include/`(如果存在) | 自动加到 `-I` | +| 测试 | `tests/**/*.cpp` | `mcpp test` 自动发现 | +| 依赖命名空间 | `mcpp`(默认) | 平铺写法走默认 ns | + +### 4.1 旧 `[language]` 兼容层 + +旧配置仍可读取: + +```toml +[language] +standard = "c++26" +``` + +新项目请使用 `[package].standard`。如果两个位置都出现,`[package].standard` 是权威配置。 diff --git a/docs/zh/06-workspace.md b/docs/zh/06-workspace.md new file mode 100644 index 00000000..8c0a4525 --- /dev/null +++ b/docs/zh/06-workspace.md @@ -0,0 +1,218 @@ +# 工作空间 (Workspace) + +工作空间允许在同一个仓库中组织和管理多个相关的 mcpp 包(库或应用程序)。各成员包共享统一的依赖版本配置和工具链设置,同时保持独立的 `mcpp.toml` 工程文件。 + +## 1. 概述 + +工作空间解决以下问题: + +- **依赖版本统一管理** — 多个子包使用相同版本的第三方依赖,避免重复声明和版本不一致 +- **工具链配置共享** — 在工作空间根目录统一声明工具链,各成员继承或覆盖 +- **多包协同开发** — 库与应用在同一仓库中开发,通过 `path` 依赖相互引用 + +工作空间不改变依赖声明方式。成员之间通过已有的 `path = "..."` 机制声明依赖关系,与非工作空间项目的用法完全一致。 + +## 2. 工程文件结构 + +### 2.1 工作空间根 + +在仓库根目录的 `mcpp.toml` 中声明 `[workspace]`: + +```toml +[workspace] +members = [ + "libs/core", + "libs/http", + "apps/server", +] +``` + +`members` 列出各成员包的相对路径,每个路径下须包含独立的 `mcpp.toml`。 + +可选 `exclude` 字段排除特定路径: + +```toml +[workspace] +members = ["libs/*"] +exclude = ["libs/experimental"] +``` + +### 2.2 虚拟工作空间与根包工作空间 + +**虚拟工作空间**:根 `mcpp.toml` 仅包含 `[workspace]`,不包含 `[package]`。根目录不产出构建产物,仅作为管理节点。 + +```toml +# 虚拟工作空间 — 只有 [workspace] +[workspace] +members = ["libs/core", "apps/server"] +``` + +**根包工作空间**:根 `mcpp.toml` 同时包含 `[package]` 和 `[workspace]`。根目录本身也是一个可构建的包。 + +```toml +[workspace] +members = ["libs/core"] + +[package] +name = "myapp" +version = "0.1.0" + +[dependencies] +core = { path = "libs/core" } +``` + +### 2.3 成员工程文件 + +各成员维护独立的 `mcpp.toml`,结构与普通项目一致: + +```toml +# libs/core/mcpp.toml +[package] +namespace = "myproject" +name = "core" +version = "0.1.0" + +[targets.core] +kind = "lib" +``` + +成员之间通过 `path` 依赖引用: + +```toml +# libs/http/mcpp.toml +[package] +namespace = "myproject" +name = "http" +version = "0.1.0" + +[dependencies] +core = { path = "../core" } + +[dependencies.compat] +mbedtls.workspace = true +``` + +## 3. 依赖版本继承 + +在 `[workspace.dependencies]` 中集中声明依赖版本,成员通过 `.workspace = true` 继承: + +```toml +# 根 mcpp.toml +[workspace.dependencies] +cmdline = "0.0.2" +capi.lua = "0.0.3" # dotted selector: mcpplibs.capi/lua, then capi/lua + +[workspace.dependencies.compat] +mbedtls = "3.6.1" +gtest = "1.15.2" +``` + +```toml +# 成员 mcpp.toml +[dependencies.compat] +mbedtls.workspace = true # 继承版本 → "3.6.1" + +[dev-dependencies.compat] +gtest.workspace = true # 继承版本 → "1.15.2" +``` + +成员可以覆盖继承的版本: + +```toml +[dependencies.compat] +mbedtls = "4.0.0" # 覆盖,不使用 workspace 版本 +``` + +## 4. 工具链与构建配置继承 + +工作空间根的 `[toolchain]` 和 `[target.]` 配置自动继承到所有成员。成员可在自身的工程文件中覆盖。 + +配置优先级(从高到低): + +1. 命令行参数(`--target`、`--static`) +2. 成员 `mcpp.toml` 中的声明 +3. 工作空间根 `mcpp.toml` 中的声明 +4. 全局配置(`~/.mcpp/config.toml`) +5. 内置默认值 + +```toml +# 工作空间根 +[toolchain] +default = "gcc@16.1.0" + +[target.x86_64-linux-musl] +toolchain = "gcc@15.1.0-musl" +linkage = "static" +``` + +```toml +# 某成员覆盖工具链 +[toolchain] +default = "clang@19.0" +``` + +## 5. 构建命令 + +### 5.1 从工作空间根目录构建 + +```bash +mcpp build # 构建默认目标(自动选择含二进制目标的成员) +mcpp build -p server # 构建指定成员及其依赖 +mcpp build -p core # 构建指定库成员 +``` + +### 5.2 从成员子目录构建 + +```bash +cd libs/http +mcpp build # 自动检测工作空间,构建当前成员 +``` + +mcpp 从当前目录向上搜索,若发现包含 `[workspace]` 的 `mcpp.toml` 且当前目录在 `members` 列表中,则自动进入工作空间模式,继承工作空间配置。 + +### 5.3 `-p, --package` 选项 + +`-p` 可用于 `build`、`test`、`run` 等命令,指定构建的目标成员。参数值为成员路径的最后一段目录名或完整相对路径: + +```bash +mcpp build -p server # 匹配 apps/server +mcpp test -p core # 匹配 libs/core +mcpp run -p server -- --port 8080 +``` + +## 6. 目录布局 + +工作空间推荐的目录布局: + +``` +myproject/ +├── mcpp.toml # [workspace] 声明 +├── libs/ +│ ├── core/ +│ │ ├── mcpp.toml # [package] namespace="myproject" name="core" +│ │ └── src/ +│ │ └── core.cppm # export module myproject.core; +│ └── http/ +│ ├── mcpp.toml +│ └── src/ +│ └── http.cppm # export module myproject.http; +└── apps/ + └── server/ + ├── mcpp.toml + └── src/ + └── main.cpp # import myproject.http; +``` + +各成员的构建产物位于各自的 `target/` 子目录下。 + +## 7. 与 C++ 模块的关系 + +工作空间与 C++23 模块机制协同工作: + +- **接口可见性由语言控制** — `export module` 和 `import` 语句决定模块的公开接口,工作空间不做额外的可见性限制 +- **模块名由库作者决定** — 工作空间不强制模块名与包名或命名空间一致 +- **partition 用于内部组织** — `import :internal;`(不带 `export`)的 partition 对消费者不可见,无需构建工具介入 + +## 8. 完整示例 + +参见 [`examples/04-workspace/`](../../examples/04-workspace/),包含一个三成员工作空间的完整可运行示例。 diff --git a/docs/zh/README.md b/docs/zh/README.md new file mode 100644 index 00000000..b8d2e2df --- /dev/null +++ b/docs/zh/README.md @@ -0,0 +1,11 @@ +# 用户文档目录 + +[English](../README.md) | **简体中文** + +- [00 - 快速开始](00-getting-started.md) +- [01 - 示例项目](01-examples.md) +- [02 - 发布打包](02-pack-and-release.md) +- [03 - 工具链管理](03-toolchains.md) +- [04 - 从源码构建 & 参与贡献](04-build-from-source.md) +- [05 - mcpp.toml 工程文件指南](05-mcpp-toml.md) +- [06 - 工作空间](06-workspace.md)