diff --git a/.agents/docs/2026-07-17-add-asio-plan.md b/.agents/docs/2026-07-17-add-asio-plan.md deleted file mode 100644 index 8087396..0000000 --- a/.agents/docs/2026-07-17-add-asio-plan.md +++ /dev/null @@ -1,183 +0,0 @@ -# Add standalone Asio 1.38.1 as a header-only package - -Date: 2026-07-17 - -This document defines the contribution scope for `compat.asio@1.38.1`. It is -based on the current `origin/main`, its active validation workflow, and mcpp -0.0.94. Dated repository guidance is treated as historical when it conflicts -with those live contracts. - -## 1. Scope - -This contribution adds only the upstream standalone, header-only Asio package. -Consumers use `#include ` and related upstream headers. - -The following work is intentionally excluded: - -- a native C++ module or `import asio;` interface; -- OpenSSL or wolfSSL integration; -- Boost.Context, Boost.Regex, or Boost.Date_Time integration; -- liburing integration; -- changes to repository contribution guidance or README content. - -Native module adaptation remains separate because it has a different build and -consumer contract and requires its own compatibility evidence. - -## 2. Upstream identity and archive evidence - -- Canonical repository: `https://github.com/chriskohlhoff/asio`. -- Release tag: `asio-1-38-1`, the latest numeric Asio tag observed on - 2026-07-17. -- Tag commit: `bbecff21a23b97c34641f0f1f08b28c91b9c77cf`. -- License: Boost Software License 1.0 (`BSL-1.0`), confirmed from upstream - `COPYING` and `LICENSE_1_0.txt` at the tag. -- Linux/macOS archive: tag tarball, SHA-256 - `2827b229972be80cdb14e5497962fa393d1adf036b5869e2b9c99f644daadacc`, - CN-mirrored byte-identically at - `https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1.tar.gz`. -- Windows archive: `asio-1.38.1-nosymlinks.tar.gz`, SHA-256 - `77f74094bb12cd867a6edbf5736bbed816c6ce0906e880de8573097a81714d89`, hosted at - `https://github.com/xlings-res/asio/releases/download/1.38.1/` (GLOBAL) and - `https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/` (CN). - -Two independent downloads of the upstream tarball produced the same SHA-256. -All archives are wrapped in `asio-asio-1-38-1/`, and their public entry header -is `asio-asio-1-38-1/include/asio.hpp`. Therefore `*/include` is the required -consumer include root. - -Both upstream tag archive encodings (tar.gz and zip) contain -`asio/include -> ../include` and `asio/src -> ../src` POSIX symlink entries. -The Windows extraction path (`tar.exe` via xlings) cannot materialize them, so -both encodings fail on the Windows runner, and upstream publishes no -symlink-free asset for 1.38.x (GitHub has no release assets; SourceForge stops -at 1.36.0). The Windows entry therefore uses a repackaged variant of the -upstream tag tarball with only those two symlink entries removed -(`tar --delete` + `gzip -n -9`); all 1544 regular files are byte-identical to -upstream. Provenance is documented in the `xlings-res/asio` repository README. - -The upstream tag is annotated but not cryptographically signed. Reproducibility -is enforced by the descriptor's pinned archive digest. - -## 3. Package shape and descriptor contract - -Asio is a third-party project without an mcpp manifest in the selected release, -so the package uses an inline Form B descriptor at -`pkgs/c/compat.asio.lua`: - -- namespace: `compat`; -- full package name: `compat.asio`; -- published version: bare version `1.38.1`; -- platforms: Linux and macOS use the tag tarball; Windows uses the repackaged - symlink-free tarball to avoid the POSIX symlink extraction failure; -- include root: `*/include`; -- build target: a generated C anchor provides the buildable library target - required by the current package resolver; -- Linux link interface: `-pthread`; -- `import_std = false` because this package is consumed through textual headers. - -The intended post-publication CLI token is `compat:asio@1.38.1`, which maps to -the consumer declaration `[dependencies.compat] asio = "1.38.1"`. Before the -replacement PR is opened, that token must be exercised with the current mcpp -CLI in an isolated project rather than inferred only from the descriptor name. - -The default `standalone` feature contributes these public preprocessor defines: - -- `ASIO_STANDALONE`; -- `ASIO_HEADER_ONLY`; -- `ASIO_DISABLE_BOOST_CONTEXT_FIBER`; -- `ASIO_HAS_THREADS` — asio's own thread detection keys off CRT macros - (`_MT`/`_REENTRANT`/`_POSIX_THREADS`) that the workspace's llvm-on-Windows - toolchain does not define. Without the pin asio silently selects - `null_thread` and every internal-thread operation (notably the - waitable-timer wait thread behind `steady_timer`) throws - `operation_not_supported` (10045) at runtime — observed as the core, - coroutine, and network consumer tests failing on the Windows runner while - the thread-free tests passed. asio only ever tests - `defined(ASIO_HAS_THREADS)`, and the POSIX pthread selection still runs - beneath it, so the pin is a no-op on platforms where detection already - works (re-verified by the Linux consumer suite). - -mcpp 0.0.94 accepts feature `defines` in the current xpkg parser and propagates -them to consumers. The Asio surface test rejects builds where any of these -defines is absent, and generated compile commands are inspected during local -verification to confirm that the flags reach every consumer translation unit. - -The descriptor uses grammar already accepted by the live index contract. This -contribution does not change `index.toml` (`min_mcpp = "0.0.87"`) or the active -workflow pin (`MCPP_VERSION = "0.0.94"`). - -## 4. URL and mirror decision - -Linux/macOS keep the canonical upstream GitHub tarball as GLOBAL; a -byte-identical copy of that tarball is uploaded to -`gitcode.com/mcpp-res/asio` as the CN mirror (same SHA-256, verified after -upload). - -Windows cannot use either upstream tag archive encoding (both carry the POSIX -symlinks), so its GLOBAL asset is the repackaged symlink-free tarball hosted -in the ecosystem's resource org `github.com/xlings-res/asio`, with a -byte-identical CN copy on `gitcode.com/mcpp-res/asio`. Both hosts were -sha256-verified after upload against the descriptor's pinned digest. - -## 5. Consumer and test design - -The consumer project is `tests/examples/asio`, registered in the root workspace -and resolved through the local `compat` index. The current repository workflow -uses `mcpp test --workspace`, so the example follows the active `tests/*.cpp` -layout instead of the historical `src/main.cpp` runner layout. - -Six executable tests provide failure-capable assertions: - -- `core`: timers, executor work, dispatch, defer, and post behavior; -- `coroutine`: `co_spawn`, `use_awaitable`, and completion behavior; -- `experimental`: experimental channel send/receive behavior; -- `network`: loopback TCP accept/connect/read/write behavior; -- `platform`: platform-specific public types guarded by target macros; -- `surface`: representative public headers, public types, and required package - defines. - -The tests do not include or exercise the separate native module adapter. - -## 6. Validation contract - -The active workflow pins mcpp 0.0.94. Before opening the replacement PR, the -branch must provide fresh evidence for all locally available checks: - -1. run the descriptor syntax and mirror lint with the available local Lua 5.5; -2. parse `pkgs/c/compat.asio.lua` with mcpp 0.0.94; -3. run the targeted Asio consumer tests from isolated build state with - `MCPP_INDEX_MIRROR=GLOBAL`; -4. inspect the generated compile commands for all three public defines; -5. exercise `mcpp add compat:asio@1.38.1` in an isolated consumer project; -6. run `git diff --check` and confirm README is identical to `origin/main`. - -The replacement PR must then pass every check instantiated by the live -workflow, including the Linux, macOS, and Windows workspace matrix. Local macOS -success is not evidence for the other declared platforms. - -## 7. Documentation and change boundary - -README remains byte-identical to `origin/main`. This package contribution does -not update historical contribution instructions, even where they describe old -CI job names or old feature limitations. Any correction to those documents -requires a separate, evidence-backed audit and a separately scoped change. - -The replacement PR is limited to: - -- this design record; -- `pkgs/c/compat.asio.lua`; -- the root workspace registration; -- `tests/examples/asio` consumer configuration and tests. - -## 8. Acceptance criteria - -- upstream version, license, layout, and repeated archive digest are recorded; -- local descriptor lint passes with Lua 5.5, and the workflow's Lua 5.4 lint - passes in GitHub Actions; -- the CLI dependency token is verified through an isolated `mcpp add`; -- the six targeted consumer tests pass from isolated build state; -- the Windows workspace job downloads the ZIP and completes the Asio tests; -- README has no diff; -- the replacement PR contains no native module adaptation; -- all required GitHub Actions jobs pass before maintainer merge; -- publication remains the repository's automatic post-merge responsibility. diff --git a/.agents/docs/2026-07-20-retire-compat-asio-and-bare-module-design.md b/.agents/docs/2026-07-20-retire-compat-asio-and-bare-module-design.md new file mode 100644 index 0000000..1832e66 --- /dev/null +++ b/.agents/docs/2026-07-20-retire-compat-asio-and-bare-module-design.md @@ -0,0 +1,266 @@ +# Retire `compat.asio` and make `asio@1.38.1` module-only + +Date: 2026-07-20 + +## 1. Decision + +Retire the transitional header-only Asio package introduced by +mcpplibs/mcpp-index PR #73. The index will publish one Asio 1.38.1 package, +consumed only as a C++23 module: + +```bash +mcpp add asio@1.38.1 +``` + +```cpp +import std; +import asio; +``` + +The current module recipe introduced by PR #80 remains the implementation, but +its package identity changes from `chriskohlhoff.asio@1.38.1` to the default +root package `asio@1.38.1`. + +The old qualified token `mcpp add chriskohlhoff.asio@1.38.1` is not retained as +an alias and is not part of the new compatibility contract. + +## 2. Goals and non-goals + +Goals: + +- remove `compat.asio@1.38.1` and all header-only consumer coverage; +- preserve the existing `import asio;` module implementation and behavior; +- make `asio@1.38.1` the only supported dependency identity and CLI token; +- keep one descriptor, one package identity, one lockfile identity, and one + module test member; +- preserve the existing archives, mirrors, hashes, platforms, generated module + wrapper, and separate-compilation build configuration. + +Non-goals: + +- supporting `#include ` through mcpp-index; +- selecting header-only/module behavior through `features`; +- retaining `chriskohlhoff.asio` through an alias, redirect, forwarding package, + or non-canonical filename fallback; +- changing mcpp core package resolution; +- publishing a new Asio upstream version or changing source bytes. + +## 3. Revert PR #73 + +PR #73 was squash-merged as the single-parent commit +`b3ebdd15bc3b56dc61cb91ab5b592200f713709f`. Revert it with: + +```bash +git revert b3ebdd15bc3b56dc61cb91ab5b592200f713709f +``` + +Do not use `git revert -m 1`; the commit is not a merge commit. + +The reverse patch removes: + +- `.agents/docs/2026-07-17-add-asio-plan.md`; +- `pkgs/c/compat.asio.lua`; +- `tests/examples/asio/mcpp.toml`; +- all six header-only tests under `tests/examples/asio/tests/`; +- `tests/examples/asio` from the root workspace. + +On the current `upstream/main`, the revert conflicts only in the root +`mcpp.toml`. Resolve it by removing only `tests/examples/asio`; retain +`tests/examples/asio-module` and every workspace member added after PR #73. + +Keep the resolved revert as its own commit so the removal remains traceable to +PR #73. + +## 4. Rename the module package identity + +Move the descriptor: + +```text +pkgs/c/chriskohlhoff.asio.lua + -> pkgs/a/asio.lua +``` + +Change its identity fields from: + +```lua +namespace = "chriskohlhoff" +name = "chriskohlhoff.asio" +``` + +to: + +```lua +namespace = "" +name = "asio" +``` + +This is a canonical default-root package shape already used by module packages +such as `imgui`, `ffmpeg`, and `opencv`. The descriptor filename, declared +identity, dependency key, install target, and lockfile identity all become the +same bare name. No package alias or compatibility fallback is involved. + +Do not change the following parts of the descriptor: + +- version `1.38.1`; +- Linux/macOS upstream archive and SHA-256; +- Windows symlink-free archive and SHA-256; +- GLOBAL/CN mirror tables; +- `generated_files` module wrapper; +- `modules = { "asio" }`; +- `*/src/asio.cpp` separate-compilation source; +- `ASIO_STANDALONE`, `ASIO_SEPARATE_COMPILATION`, + `ASIO_DISABLE_BOOST_CONTEXT_FIBER`, and `ASIO_HAS_THREADS`; +- platform link settings. + +## 5. Consumer contract + +Update `tests/examples/asio-module/mcpp.toml` from the qualified local index: + +```toml +[indices] +chriskohlhoff = { path = "../../.." } + +[dependencies.chriskohlhoff] +asio = "1.38.1" +``` + +to the default-root local index: + +```toml +[indices] +default = { path = "../../.." } + +[dependencies] +asio = "1.38.1" +``` + +Keep the existing five module consumer tests. They already cover core runtime +behavior, coroutines, networking, experimental APIs, and the exported surface. +No second alias-specific member is needed because there is only one supported +package token. + +The resulting lockfile contract is: + +```toml +[package."asio"] +version = "1.38.1" +``` + +It must not contain `namespace = "compat"` or +`namespace = "chriskohlhoff"` for Asio. + +## 6. Documentation cleanup + +The module descriptor currently describes `compat.asio` as a header-only +companion and tells users to select it for APIs outside the wrapper. Remove or +rewrite those statements. + +The retained documentation must state: + +- installation: `mcpp add asio@1.38.1`; +- consumption: `import std; import asio;`; +- the package is module-only; +- APIs not exported by the wrapper are unavailable through this package; +- textual inclusion with `#include ` is outside the supported + mcpp-index contract; +- `chriskohlhoff.asio@1.38.1` was the retired pre-rename package token and is + not a supported alias. + +Remove comparison comments in `tests/examples/asio-module` that refer to the +deleted `tests/examples/asio` member. Do not rewrite unrelated package docs. + +## 7. Compatibility impact + +This is an intentional package-identity replacement: + +| Old dependency | New state | +| --- | --- | +| `compat.asio@1.38.1` | removed; header-only consumption unsupported | +| `chriskohlhoff.asio@1.38.1` | removed; no alias retained | +| `asio@1.38.1` | canonical module package | + +Existing module consumers migrate with: + +```bash +mcpp remove chriskohlhoff.asio +mcpp add asio@1.38.1 +``` + +Their C++ source remains `import std; import asio;`. They must regenerate the +lockfile/build state so the retired namespace does not remain pinned. + +Historical index artifacts remain historical; do not rewrite or manually +republish them. The new rolling index simply stops advertising the two retired +identities. + +## 8. Test-first implementation sequence + +1. Create a topic branch from the latest `upstream/main`. +2. Revert PR #73 and resolve only the root workspace conflict. +3. Change `tests/examples/asio-module` to the bare dependency while the module + descriptor still has the qualified identity. Run the targeted test and + record the expected package-not-found failure. +4. Move the descriptor to `pkgs/a/asio.lua` and change its declared identity to + root `asio`. +5. Update stale descriptor and test comments. +6. Run the targeted test again and inspect its generated lockfile. +7. Run descriptor, mirror, workspace, and diff validation. +8. Commit the module identity migration separately from the PR #73 revert. +9. Push a topic branch and open a focused PR only after explicit authorization. + +The Red/Green boundary is the dependency identity: the same module test must +fail before the descriptor rename and pass after it. Do not weaken the module +behavior assertions to make the migration pass. + +## 9. Validation + +Use the mcpp version pinned by the live `upstream/main` workflow. The descriptor +uses existing grammar, so this change does not raise `index.toml`'s client floor +or the workflow pin. + +Required local evidence, in order: + +1. `git diff --check`; +2. Lua syntax and repository descriptor lint for `pkgs/a/asio.lua`; +3. strict `mcpp xpkg parse pkgs/a/asio.lua`; +4. repository mirror validation, confirming the move did not alter URL/SHA + tables; +5. the recorded bare-dependency Red before the identity change; +6. `mcpp test -p asio-module` after the identity change; +7. inspection of `tests/examples/asio-module/mcpp.lock`, confirming root package + `asio` at version `1.38.1` and no retired namespace; +8. a search proving that no active descriptor, workspace dependency, or + consumer instruction still advertises `compat.asio` or + `chriskohlhoff.asio`; +9. the workspace scope selected by the current validation workflow. + +The implementation PR must pass every Linux, macOS, and Windows job created by +the live workflow. One local platform is not evidence for all declared +platforms. + +## 10. Risks and mitigations + +| Risk | Mitigation | +| --- | --- | +| The revert removes later workspace members | Resolve `mcpp.toml` manually and review the complete final member list | +| The recipe changes during the identity move | Review the move with whitespace-insensitive diff and compare archive/hash/build blocks | +| A stale qualified dependency survives | Search active manifests and inspect the generated lockfile | +| Header-only support is accidentally retained | Require both the descriptor and `tests/examples/asio` tree to be absent | +| Existing qualified-token consumers break unexpectedly | State the breaking migration explicitly in the PR and package comments | +| Module behavior regresses | Keep and run all five existing module tests on the three-platform CI matrix | + +## 11. Acceptance criteria + +- `pkgs/c/compat.asio.lua` and `tests/examples/asio` no longer exist; +- `pkgs/c/chriskohlhoff.asio.lua` no longer exists; +- exactly one Asio descriptor exists at `pkgs/a/asio.lua`; +- that descriptor declares root package `asio@1.38.1`; +- `mcpp add asio@1.38.1` followed by a build imports module `asio`; +- `mcpp add chriskohlhoff.asio@1.38.1` is not claimed or tested as supported; +- the generated lockfile contains only the root Asio identity; +- all five existing module tests pass without reduced assertions; +- all active `compat.asio` and qualified-token instructions are removed; +- archives, hashes, mirrors, platforms, module wrapper, and build defines are + unchanged; +- no mcpp core change, alias package, forwarding package, feature split, mirror + upload, or manual index publication is included. diff --git a/.agents/docs/2026-07-20-retire-compat-asio-and-bare-module-plan.md b/.agents/docs/2026-07-20-retire-compat-asio-and-bare-module-plan.md new file mode 100644 index 0000000..eeec534 --- /dev/null +++ b/.agents/docs/2026-07-20-retire-compat-asio-and-bare-module-plan.md @@ -0,0 +1,572 @@ +# Asio Module-Only Package Migration Implementation Plan + +> **Historical execution record — completed locally on 2026-07-20** +> +> This plan was executed locally on branch `refactor/asio-module`. After rebasing onto `upstream/main`, the implementation commits are `a65002d` (PR #73 revert) and `4ff03bd` (canonical root module migration). +> +> Do not rerun this plan against the completed branch. The commands and checklists below are retained as a historical execution record. +> +> Validation was narrowed by the user to Asio-only: isolated macOS arm64 with pinned mcpp 0.0.101 passed 5/5. Full workspace/OpenCV validation was intentionally stopped; Linux/Windows remain unverified. + +**Goal:** 删除 `compat.asio` header-only 包,将现有 Asio module recipe 改为唯一根包 `asio@1.38.1`,并通过 `mcpp add asio@1.38.1` 消费。 + +**Architecture:** 先精确 revert PR #73 的 squash commit,再把 PR #80 的 Form B descriptor 从 `chriskohlhoff.asio` 身份迁移为默认根身份 `asio`。保留原 module wrapper、archive、mirror、hash、三平台配置和五个 module 行为测试;不保留旧全名 alias,不修改 mcpp core。 + +**Tech Stack:** Git, Lua xpkg descriptor, workflow-pinned mcpp (currently 0.0.101), C++23 modules, GitHub Actions workspace validation. + +--- + +**Design reference:** `.agents/docs/2026-07-20-retire-compat-asio-and-bare-module-design.md` + +**Remote topology:** `origin` is the writable fork `wellwei/mcpp-index`; `upstream` is the canonical `mcpplibs/mcpp-index`. Refresh and diff against `upstream/main`; publish the topic branch to `origin` only after local approval. + +**External-action boundary:** 本计划实施阶段只产生本地提交。不要执行 `git push`、`gh pr create`、mirror 上传、tag、release 或手工 index 发布。完成后停止并等待用户审批;获批后才把 `refactor/asio-module` 推到 `origin`,并从 `wellwei:refactor/asio-module` 向 `mcpplibs:main` 创建 PR。 + +## File map + +| Path | Action | Responsibility | +| --- | --- | --- | +| `.agents/docs/2026-07-17-add-asio-plan.md` | Delete via revert | PR #73 的 header-only 设计记录 | +| `pkgs/c/compat.asio.lua` | Delete via revert | 退役的 header-only package | +| `tests/examples/asio/` | Delete via revert | 退役的六项 header-only consumer tests | +| `mcpp.toml` | Modify via revert conflict resolution | 删除 `tests/examples/asio`,保留 `asio-module` 和所有后续 members | +| `pkgs/c/chriskohlhoff.asio.lua` | Rename/delete | PR #80 的旧 namespaced module descriptor | +| `pkgs/a/asio.lua` | Create by `git mv`, then modify | 唯一 canonical `asio@1.38.1` module descriptor | +| `tests/examples/asio-module/mcpp.toml` | Modify | 使用 default local index 和 bare `asio` dependency | +| `tests/examples/asio-module/tests/experimental.cpp` | Modify comments only | 删除指向已退役 header test 的说明 | +| `tests/examples/asio-module/tests/network.cpp` | Modify comments only | 删除指向已退役 header test 的说明 | + +### Task 1: Refresh the baseline and prove the current module package is green + +**Files:** +- Read: `.github/workflows/validate.yml` +- Read: `index.toml` +- Test: `tests/examples/asio-module/` + +- [ ] **Step 1: Confirm branch and worktree state** + +Run: + +```bash +git branch --show-current +git status --short --branch +``` + +Expected: + +```text +refactor/asio-module +## refactor/asio-module...upstream/main [ahead 4] +``` + +The exact ahead count may increase only by approved plan/doc commits. There must be no unstaged or staged implementation files. + +- [ ] **Step 2: Refresh `upstream/main` and check for duplicate Asio work** + +Run: + +```bash +git fetch upstream main +git log --oneline HEAD..upstream/main +gh pr list --repo mcpplibs/mcpp-index --state open --search "asio in:title" --json number,title,headRefName,url +``` + +Expected: no unreviewed upstream Asio change and no duplicate open Asio PR. If `HEAD..upstream/main` contains only unrelated commits, rebase the unpushed branch with the one-shot repository identity: + +```bash +git -c user.name=wellwei \ + -c user.email=96378453+wellwei@users.noreply.github.com \ + -c core.editor=true \ + rebase upstream/main +``` + +If upstream changes any Asio path, `mcpp.toml`, `index.toml`, or the validation contract, stop and update this plan before implementation. + +- [ ] **Step 3: Obtain the exact workflow-pinned mcpp client** + +On the current macOS arm64 workspace, run: + +```bash +PIN=$(sed -n 's/^[[:space:]]*MCPP_VERSION: "\([^"]*\)"/\1/p' .github/workflows/validate.yml | head -1) +TOOLS="/private/tmp/mcpp-index-asio-tools-${PIN}" +mkdir -p "$TOOLS" +curl -L -fsS -o "$TOOLS/mcpp.tar.gz" \ + "https://github.com/mcpp-community/mcpp/releases/download/v${PIN}/mcpp-${PIN}-macosx-arm64.tar.gz" +tar -xzf "$TOOLS/mcpp.tar.gz" -C "$TOOLS" +MCPP="$TOOLS/mcpp-${PIN}-macosx-arm64/bin/mcpp" +"$MCPP" --version +``` + +Expected: the printed mcpp version exactly equals `PIN` (currently `0.0.101`). Do not use the host's older `mcpp 0.0.96` binary. + +- [ ] **Step 4: Run the current qualified-token baseline** + +Run: + +```bash +PIN=$(sed -n 's/^[[:space:]]*MCPP_VERSION: "\([^"]*\)"/\1/p' .github/workflows/validate.yml | head -1) +MCPP="/private/tmp/mcpp-index-asio-tools-${PIN}/mcpp-${PIN}-macosx-arm64/bin/mcpp" +git clean -fdX tests/examples/asio-module +MCPP_INDEX_MIRROR=GLOBAL "$MCPP" test -p asio-module +``` + +Expected: `5 passed; 0 failed`. The network test must remain enabled. If sandboxed loopback fails with `bind: Operation not permitted`, rerun this same command with local-network permission; do not weaken or remove the test. + +### Task 2: Revert the header-only package from PR #73 + +**Files:** +- Delete: `.agents/docs/2026-07-17-add-asio-plan.md` +- Delete: `pkgs/c/compat.asio.lua` +- Delete: `tests/examples/asio/mcpp.toml` +- Delete: `tests/examples/asio/tests/core.cpp` +- Delete: `tests/examples/asio/tests/coroutine.cpp` +- Delete: `tests/examples/asio/tests/experimental.cpp` +- Delete: `tests/examples/asio/tests/network.cpp` +- Delete: `tests/examples/asio/tests/platform.cpp` +- Delete: `tests/examples/asio/tests/surface.cpp` +- Modify: `mcpp.toml:9` + +- [ ] **Step 1: Verify the revert target is the single-parent squash commit** + +Run: + +```bash +git show -s --format='%H%n%P%n%s' b3ebdd15bc3b56dc61cb91ab5b592200f713709f +``` + +Expected: commit `b3ebdd15...`, exactly one parent, subject `feat(pkgs): add standalone asio 1.38.1 (#73)`. + +- [ ] **Step 2: Start the revert and confirm the only conflict** + +Run: + +```bash +git revert --no-edit b3ebdd15bc3b56dc61cb91ab5b592200f713709f +``` + +Expected: nonzero exit with one content conflict in `mcpp.toml`. + +Run: + +```bash +git diff --name-only --diff-filter=U +``` + +Expected: + +```text +mcpp.toml +``` + +If any other file conflicts, stop and re-evaluate the current upstream baseline. + +- [ ] **Step 3: Resolve `mcpp.toml` to the exact member list** + +Use `apply_patch` to replace the conflicted `[workspace]` block with: + +```toml +[workspace] +members = [ + "tests/examples/archive", + "tests/examples/asio-module", + "tests/examples/build-mcpp", + "tests/examples/cjson", + "tests/examples/core", + "tests/examples/eigen", + "tests/examples/ffmpeg", + "tests/examples/ffmpeg-module", + "tests/examples/fmtlib.fmt", + "tests/examples/gui-stack", + "tests/examples/imgui", + "tests/examples/imgui-module", + "tests/examples/imgui-window", + "tests/examples/marzer.tomlplusplus", + "tests/examples/nlohmann.json", + "tests/examples/openblas", + "tests/examples/opencv", + "tests/examples/opencv-win", + "tests/examples/opencv-unifont", + "tests/examples/opencv-dnn", + "tests/examples/opencv-module", + "tests/examples/opencv-module-dnn", + "tests/examples/opencv-module-unifont", + "tests/examples/spdlog", + "tests/examples/spdlog-compiled", + "tests/examples/tinyhttps", +] +``` + +Before continuing, compare this block with the latest `upstream/main:mcpp.toml`. The only removed member must be `tests/examples/asio`. + +- [ ] **Step 4: Complete the revert commit** + +Run: + +```bash +git add mcpp.toml +git -c user.name=wellwei \ + -c user.email=96378453+wellwei@users.noreply.github.com \ + -c core.editor=true \ + revert --continue +``` + +Expected: one new revert commit. + +- [ ] **Step 5: Verify the removal boundary** + +Run: + +```bash +test ! -e pkgs/c/compat.asio.lua +test ! -e tests/examples/asio +test ! -e .agents/docs/2026-07-17-add-asio-plan.md +test -e pkgs/c/chriskohlhoff.asio.lua +test -e tests/examples/asio-module/mcpp.toml +git show --stat --oneline HEAD +``` + +Expected: only PR #73 content is removed; PR #80 module files remain. + +### Task 3: Create the bare-token Red through the real `mcpp add` command + +**Files:** +- Modify: `tests/examples/asio-module/mcpp.toml` +- Test: `tests/examples/asio-module/tests/*.cpp` + +- [ ] **Step 1: Change only the local index routing and remove the old dependency** + +Use `apply_patch` to make `tests/examples/asio-module/mcpp.toml` exactly: + +```toml +# Asio C++23-module consumer test project: `import std; import asio;`. +# The public package is the default-root module-only `asio@1.38.1` package. +[package] +name = "asio-module-tests" +version = "0.1.0" + +[indices] +default = { path = "../../.." } +``` + +- [ ] **Step 2: Add the dependency through the requested CLI surface** + +Run: + +```bash +PIN=$(sed -n 's/^[[:space:]]*MCPP_VERSION: "\([^"]*\)"/\1/p' .github/workflows/validate.yml | head -1) +MCPP="/private/tmp/mcpp-index-asio-tools-${PIN}/mcpp-${PIN}-macosx-arm64/bin/mcpp" +cd tests/examples/asio-module +"$MCPP" add asio@1.38.1 +cd ../../.. +``` + +Expected: `mcpp add` reports `Adding asio v1.38.1 to dependencies`, and the manifest ends with: + +```toml +[dependencies] +asio = "1.38.1" +``` + +- [ ] **Step 3: Run the consumer test and verify the expected Red** + +Run: + +```bash +PIN=$(sed -n 's/^[[:space:]]*MCPP_VERSION: "\([^"]*\)"/\1/p' .github/workflows/validate.yml | head -1) +MCPP="/private/tmp/mcpp-index-asio-tools-${PIN}/mcpp-${PIN}-macosx-arm64/bin/mcpp" +git clean -fdX tests/examples/asio-module +set +e +MCPP_INDEX_MIRROR=GLOBAL "$MCPP" test -p asio-module \ + > /private/tmp/asio-module-bare-red.log 2>&1 +rc=$? +set -e +test "$rc" -ne 0 +rg -n "asio|not found" /private/tmp/asio-module-bare-red.log +``` + +Expected: failure because the local index has neither `pkgs/a/asio.lua` nor a remaining `compat.asio` fallback. Do not commit the failing state yet. + +### Task 4: Make the descriptor identity canonical and restore Green + +**Files:** +- Rename: `pkgs/c/chriskohlhoff.asio.lua` -> `pkgs/a/asio.lua` +- Modify: `pkgs/a/asio.lua:1` +- Modify: `tests/examples/asio-module/tests/experimental.cpp:1` +- Modify: `tests/examples/asio-module/tests/network.cpp:1` + +- [ ] **Step 1: Move the descriptor to its canonical root-package path** + +Run: + +```bash +git mv pkgs/c/chriskohlhoff.asio.lua pkgs/a/asio.lua +``` + +- [ ] **Step 2: Replace the stale descriptor preamble and package identity** + +Use `apply_patch` to replace everything before `package = {` with this exact preamble: + +```lua +-- asio -- standalone Asio 1.38.1 exposed as the C++23 module `asio` +-- (Form B inline descriptor, separate-compilation mode). +-- +-- Install and consume: +-- mcpp add asio@1.38.1 +-- import std; +-- import asio; +-- +-- The upstream 1.38.x release has no module interface unit. This descriptor +-- generates a reviewed `asio.cppm` wrapper and compiles upstream `src/asio.cpp` +-- with ASIO_SEPARATE_COMPILATION. `import std;` is required because this package +-- does not inject the standard library through the module boundary. +-- +-- This package is module-only. Textual `#include ` consumption and +-- APIs not exported by the wrapper are outside its mcpp-index contract. The +-- wrapper intentionally excludes SSL/TLS, local/POSIX/Windows handle APIs, +-- serial ports, pipes, file I/O, stackful spawn, and other surfaces listed by +-- headers that it does not include. +-- +-- ASIO_STANDALONE and ASIO_SEPARATE_COMPILATION are public build defines, but +-- preprocessor macros do not cross `import asio;`. Consumers should use C++ or +-- operating-system facilities instead of testing ASIO_HAS_* macros. +``` + +Then make the package table begin exactly: + +```lua +package = { + spec = "1", + namespace = "", + name = "asio", + description = "Standalone asio exposed as the C++23 module `asio` (separate compilation)", + licenses = {"BSL-1.0"}, + repo = "https://github.com/chriskohlhoff/asio", + type = "package", +``` + +Preserve the complete `xpm` and `mcpp` tables after this header. + +- [ ] **Step 3: Make the two remaining recipe comments self-contained** + +Replace the Windows archive comment with: + +```lua + -- Upstream tag archives carry two POSIX symlinks + -- (asio/include -> ../include, asio/src -> ../src) that tar.exe + -- cannot materialize on the Windows runner. This uses the existing + -- symlink-free repack documented by xlings-res/asio. +``` + +Replace the `ASIO_HAS_THREADS` comment with: + +```lua + -- ASIO_HAS_THREADS: asio's detection keys off CRT macros + -- (_MT/_REENTRANT/_POSIX_THREADS) that the workspace's llvm-on-Windows + -- toolchain does not define, otherwise silently selecting null_thread. + -- Pin the known multithreaded package contract; POSIX pthread selection + -- still runs beneath this define where applicable. +``` + +Do not change the associated URLs, hashes, sources, features, or flags. + +- [ ] **Step 4: Remove stale header-test comparisons from module tests** + +Make the opening of `tests/examples/asio-module/tests/experimental.cpp` exactly: + +```cpp +// Experimental channel/concurrent_channel/use_promise over the module surface. +import std; +import asio; +``` + +Make the opening of `tests/examples/asio-module/tests/network.cpp` exactly: + +```cpp +// TCP (acceptor/socket, async_read/async_write) and UDP (datagram send/receive) +// over the imported module surface. +import std; +import asio; +``` + +- [ ] **Step 5: Prove the recipe body did not change** + +Run both commands and compare the hashes: + +```bash +git show HEAD:pkgs/c/chriskohlhoff.asio.lua \ + | sed -E '/^[[:space:]]*--/d;/^[[:space:]]*$/d;/^[[:space:]]*namespace[[:space:]]*=/d;/^[[:space:]]*name[[:space:]]*=/d' \ + | shasum -a 256 +sed -E '/^[[:space:]]*--/d;/^[[:space:]]*$/d;/^[[:space:]]*namespace[[:space:]]*=/d;/^[[:space:]]*name[[:space:]]*=/d' pkgs/a/asio.lua \ + | shasum -a 256 +``` + +Expected: identical SHA-256 values. A mismatch means a non-comment recipe field changed; inspect and restore it before continuing. + +- [ ] **Step 6: Parse the descriptor and run the Green test** + +Run: + +```bash +PIN=$(sed -n 's/^[[:space:]]*MCPP_VERSION: "\([^"]*\)"/\1/p' .github/workflows/validate.yml | head -1) +MCPP="/private/tmp/mcpp-index-asio-tools-${PIN}/mcpp-${PIN}-macosx-arm64/bin/mcpp" +lua -e "assert(loadfile('pkgs/a/asio.lua', 't'))" +lua tests/check_mirror_urls.lua pkgs/a/asio.lua +"$MCPP" xpkg parse pkgs/a/asio.lua +git clean -fdX tests/examples/asio-module +MCPP_INDEX_MIRROR=GLOBAL "$MCPP" test -p asio-module +``` + +Expected: Lua syntax success, mirror check success, strict parse success, and `5 passed; 0 failed`. + +- [ ] **Step 7: Inspect the generated lock identity** + +Run: + +```bash +LOCK=tests/examples/asio-module/mcpp.lock +test -f "$LOCK" +rg -n '^\[package\."asio"\]$|^namespace[[:space:]]*=|^version[[:space:]]*=' "$LOCK" +``` + +Expected: `[package."asio"]` with version `1.38.1`; there must be no Asio namespace line for `compat` or `chriskohlhoff`. + +### Task 5: Validate the complete local change + +**Files:** +- Test: `pkgs/a/asio.lua` +- Test: `tests/examples/asio-module/` +- Test: root workspace + +- [ ] **Step 1: Verify the active-tree cleanup** + +Run: + +```bash +test ! -e pkgs/c/compat.asio.lua +test ! -e pkgs/c/chriskohlhoff.asio.lua +test ! -e tests/examples/asio +test -e pkgs/a/asio.lua +set +e +rg -n "compat\.asio|chriskohlhoff\.asio|tests/examples/asio([^\-]|$)" \ + mcpp.toml pkgs tests README.md +rc=$? +set -e +test "$rc" -eq 1 +``` + +Expected: the three absence checks pass and `rg` exits 1 because it finds no active package, workspace, test, or user-instruction references. The upstream repository URL `github.com/chriskohlhoff/asio` is allowed because it is not a package token. + +- [ ] **Step 2: Run whitespace, descriptor, and mirror checks** + +Run: + +```bash +PIN=$(sed -n 's/^[[:space:]]*MCPP_VERSION: "\([^"]*\)"/\1/p' .github/workflows/validate.yml | head -1) +MCPP="/private/tmp/mcpp-index-asio-tools-${PIN}/mcpp-${PIN}-macosx-arm64/bin/mcpp" +git diff --check +lua -e "assert(loadfile('pkgs/a/asio.lua', 't'))" +lua tests/check_mirror_urls.lua pkgs/a/asio.lua +"$MCPP" xpkg parse pkgs/a/asio.lua +``` + +Expected: all commands exit 0. + +- [ ] **Step 3: Re-run the targeted module suite from clean member state** + +Run: + +```bash +PIN=$(sed -n 's/^[[:space:]]*MCPP_VERSION: "\([^"]*\)"/\1/p' .github/workflows/validate.yml | head -1) +MCPP="/private/tmp/mcpp-index-asio-tools-${PIN}/mcpp-${PIN}-macosx-arm64/bin/mcpp" +git clean -fdX tests/examples/asio-module +MCPP_INDEX_MIRROR=GLOBAL "$MCPP" test -p asio-module +``` + +Expected: `5 passed; 0 failed`. + +- [ ] **Step 4: Run the full local workspace suite** + +Run: + +```bash +PIN=$(sed -n 's/^[[:space:]]*MCPP_VERSION: "\([^"]*\)"/\1/p' .github/workflows/validate.yml | head -1) +MCPP="/private/tmp/mcpp-index-asio-tools-${PIN}/mcpp-${PIN}-macosx-arm64/bin/mcpp" +MCPP_INDEX_MIRROR=GLOBAL "$MCPP" test --workspace +``` + +Expected: every member selected for macOS passes. Record the exact passed/failed totals. Linux and Windows matrix validation remains unverified until the user authorizes a push/PR; do not claim three-platform completion locally. + +### Task 6: Commit the module identity migration + +**Files:** +- Add: `pkgs/a/asio.lua` +- Delete: `pkgs/c/chriskohlhoff.asio.lua` +- Modify: `tests/examples/asio-module/mcpp.toml` +- Modify: `tests/examples/asio-module/tests/experimental.cpp` +- Modify: `tests/examples/asio-module/tests/network.cpp` + +- [ ] **Step 1: Review the exact implementation diff** + +Run: + +```bash +git status --short +git diff --find-renames --stat +git diff --find-renames -- \ + pkgs/a/asio.lua \ + pkgs/c/chriskohlhoff.asio.lua \ + tests/examples/asio-module +git diff --check +``` + +Expected: one descriptor rename with comment/identity changes, one manifest change, and two comment-only test changes. No archive, hash, generated wrapper, source, feature, or platform flag change. + +- [ ] **Step 2: Commit the Green implementation** + +Run: + +```bash +git add \ + pkgs/a/asio.lua \ + pkgs/c/chriskohlhoff.asio.lua \ + tests/examples/asio-module/mcpp.toml \ + tests/examples/asio-module/tests/experimental.cpp \ + tests/examples/asio-module/tests/network.cpp +git diff --cached --check +git -c user.name=wellwei \ + -c user.email=96378453+wellwei@users.noreply.github.com \ + commit -m "refactor(asio): make module package canonical" +``` + +Expected: one focused implementation commit after the separate PR #73 revert commit. + +### Task 7: Prepare the local approval handoff and stop + +**Files:** +- Read: all branch changes against `upstream/main` + +- [ ] **Step 1: Verify final repository state** + +Run: + +```bash +git status --short --branch +git log --oneline --decorate upstream/main..HEAD +git diff --stat upstream/main...HEAD +git diff upstream/main...HEAD --check +``` + +Expected: clean worktree; design/plan commits, one PR #73 revert commit, and one module migration commit. No uncommitted files. + +- [ ] **Step 2: Report evidence without external actions** + +Report to the user: + +- local branch name and commit list; +- deleted package/test paths; +- final descriptor identity and path; +- Red failure summary and Green targeted/full-workspace totals; +- descriptor/mirror/lockfile verification; +- Linux/Windows CI still pending because no PR was created. + +Stop here. Do not push the branch and do not create a PR until the user explicitly approves the reviewed local diff and verification evidence. After that approval, publish with `git push -u origin refactor/asio-module` and create the PR against `mcpplibs/mcpp-index:main`; required checks must pass before maintainers merge it. diff --git a/docs/superpowers/plans/2026-07-21-asio-adaptation-comments.md b/docs/superpowers/plans/2026-07-21-asio-adaptation-comments.md new file mode 100644 index 0000000..8ba1251 --- /dev/null +++ b/docs/superpowers/plans/2026-07-21-asio-adaptation-comments.md @@ -0,0 +1,75 @@ +# Asio Adaptation Comments Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add concise Asio module cautions, differences/limitations, and unexported-component notes without changing the descriptor table. + +**Architecture:** Replace only the leading comments in `pkgs/a/asio.lua`, compare the table from `package = {` byte-for-byte, and run only Asio validation. + +**Tech Stack:** Lua xpkg descriptor, C++23 modules, mcpp 0.0.101, Git. + +--- + +### Task 1: Replace The Leading Comment Block + +**Files:** +- Modify: `pkgs/a/asio.lua:1` + +- [ ] Save the current table beginning at `package = {` to `/tmp/asio-package-table.before`. +- [ ] Replace the leading comments with this exact block: + +```lua +-- asio -- 将独立版 Asio 1.38.1 暴露为 C++23 模块 `asio` +-- (Form B inline descriptor, separate-compilation mode)。 +-- +-- 注意事项 +-- * 使用 `mcpp add asio@1.38.1` 引入;消费者需显式写 +-- `import std; import asio;`,因为本包设置 import_std = false。 +-- * 本包只支持模块方式消费。同一 translation unit 不要混用 +-- `#include ` 和 `import asio;`,避免 inline 定义与模块 BMI +-- 的 separate-compilation 定义产生 ODR 差异。 +-- * 默认 feature 显式传播 ASIO_STANDALONE、ASIO_SEPARATE_COMPILATION、 +-- ASIO_DISABLE_BOOST_CONTEXT_FIBER 和 ASIO_HAS_THREADS。Asio 头文件内部 +-- 自动检测的其他 ASIO_HAS_* 宏不会由 `import asio;` 导出。 +-- +-- 与 header-only Asio 的区别/限制 +-- * 上游 1.38.x 没有模块接口单元。本描述生成 `asio.cppm`,并只编译一次 +-- `*/src/asio.cpp` 中的非模板实现;首次构建需生成 BMI,增量构建可避免 +-- 每个消费者 translation unit 重复解析整组 Asio 头文件。 +-- * 模块只暴露 wrapper 中明确 export 的声明,不等同于 +-- `#include ` 的完整 API 表面。 +-- * asio::error_code 是 std::error_code 的别名;wrapper 导出 +-- asio::use_future 变量,但未导出 asio::use_future_t 类模板。 +-- * 依赖未导出 ASIO_HAS_* 宏、平台专用头文件或 Boost 扩展的代码,需要 +-- 改用标准/操作系统能力检测或另行扩展模块 wrapper。 +-- +-- 未导出的组件 +-- * SSL/TLS (`asio/ssl/*.hpp`):需要 OpenSSL/wolfSSL 等外部依赖。 +-- * Unix 域套接字、POSIX 描述符和 Windows 句柄: +-- `asio/local/*.hpp`、`asio/posix/*.hpp`、`asio/windows/*.hpp`。 +-- * 串口、pipe 和文件 I/O:`asio/serial_port.hpp`、 +-- `asio/*able_pipe.hpp`、`asio/stream_file.hpp`、 +-- `asio/random_access_file.hpp`。 +-- * spawn()/yield_context 有栈协程:需要 Boost.Context;本包禁用其自动 +-- 检测,应改用 co_spawn + awaitable + use_awaitable。 +-- * deadline_timer、generic protocol、execution、traits、遗留宏式协程和 +-- streambuf:对应 `asio/deadline_timer.hpp`、`asio/generic/*.hpp`、 +-- `asio/execution/*.hpp`、`asio/traits/*.hpp`、`asio/yield.hpp`、 +-- `asio/coroutine.hpp`、`asio/streambuf.hpp`。 +``` + +- [ ] Compare the table after `package = {` with the saved baseline; expect no diff. +- [ ] Confirm the comment contains no `compat.asio`, `chriskohlhoff.asio`, or obsolete short-name warning. + +### Task 2: Validate And Commit + +**Files:** +- Validate: `pkgs/a/asio.lua` +- Test: `tests/examples/asio-module/**` + +- [ ] Run `lua -e "assert(loadfile('pkgs/a/asio.lua', 't'))"`. +- [ ] Run `lua tests/check_mirror_urls.lua pkgs/a/asio.lua`. +- [ ] Confirm `mcpp --version` reports `0.0.101` and run `mcpp xpkg parse pkgs/a/asio.lua`. +- [ ] Run `MCPP_HOME= MCPP_INDEX_MIRROR=GLOBAL mcpp test -p asio-module`; expect 5 passed and 0 failed. +- [ ] Run `git diff --check` and confirm only the leading `asio.lua` comments changed. +- [ ] Commit `pkgs/a/asio.lua` as `docs(asio): restore module adaptation notes`. diff --git a/docs/superpowers/specs/2026-07-21-asio-adaptation-comments-design.md b/docs/superpowers/specs/2026-07-21-asio-adaptation-comments-design.md new file mode 100644 index 0000000..2a39f12 --- /dev/null +++ b/docs/superpowers/specs/2026-07-21-asio-adaptation-comments-design.md @@ -0,0 +1,24 @@ +# Asio Adaptation Comments Design + +## Goal + +Merge the useful notes from the retired `chriskohlhoff.asio@1.38.1` +descriptor into canonical `pkgs/a/asio.lua` without changing package behavior. + +## Scope + +Replace only the comment block before `package = {`. Keep three concise +sections: + +- usage cautions for `mcpp add`, `import std`, module-only consumption, and + propagated build defines; +- differences and limitations compared with header-only Asio; +- API component groups not exported by the generated wrapper. + +Do not include a tutorial, detailed Boost history, or a migration checklist. +Do not restore `compat.asio` or `chriskohlhoff.asio` as usable package names. + +## Validation + +Prove the executable Lua table is unchanged, then run Lua syntax, mirror, +workflow-pinned parser, whitespace, and targeted `asio-module` checks only. diff --git a/mcpp.toml b/mcpp.toml index 0ed6250..6ca8a67 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -9,7 +9,6 @@ [workspace] members = [ "tests/examples/archive", - "tests/examples/asio", "tests/examples/asio-module", "tests/examples/build-mcpp", "tests/examples/cjson", diff --git a/pkgs/a/asio.lua b/pkgs/a/asio.lua new file mode 100644 index 0000000..b4671de --- /dev/null +++ b/pkgs/a/asio.lua @@ -0,0 +1,272 @@ +-- asio -- 将独立版 Asio 1.38.1 暴露为 C++23 模块 `asio` +-- (Form B inline descriptor, separate-compilation mode)。 +-- +-- 注意事项 +-- * 使用 `mcpp add asio@1.38.1` 引入;消费者需显式写 +-- `import std; import asio;`,因为本包设置 import_std = false。 +-- * 本包只支持模块方式消费。同一 translation unit 不要混用 +-- `#include ` 和 `import asio;`,避免 inline 定义与模块 BMI +-- 的 separate-compilation 定义产生 ODR 差异。 +-- * 默认 feature 显式传播 ASIO_STANDALONE、ASIO_SEPARATE_COMPILATION、 +-- ASIO_DISABLE_BOOST_CONTEXT_FIBER 和 ASIO_HAS_THREADS。Asio 头文件内部 +-- 自动检测的其他 ASIO_HAS_* 宏不会由 `import asio;` 导出。 +-- +-- 与 header-only Asio 的区别/限制 +-- * 上游 1.38.x 没有模块接口单元。本描述生成 `asio.cppm`,并只编译一次 +-- `*/src/asio.cpp` 中的非模板实现;首次构建需生成 BMI,增量构建可避免 +-- 每个消费者 translation unit 重复解析整组 Asio 头文件。 +-- * 模块只暴露 wrapper 中明确 export 的声明,不等同于 +-- `#include ` 的完整 API 表面。 +-- * asio::error_code 是 std::error_code 的别名;wrapper 导出 +-- asio::use_future 变量,但未导出 asio::use_future_t 类模板。 +-- * 依赖未导出 ASIO_HAS_* 宏、平台专用头文件或 Boost 扩展的代码,需要 +-- 改用标准/操作系统能力检测或另行扩展模块 wrapper。 +-- +-- 未导出的组件 +-- * SSL/TLS (`asio/ssl/*.hpp`):需要 OpenSSL/wolfSSL 等外部依赖。 +-- * Unix 域套接字、POSIX 描述符和 Windows 句柄: +-- `asio/local/*.hpp`、`asio/posix/*.hpp`、`asio/windows/*.hpp`。 +-- * 串口、pipe 和文件 I/O:`asio/serial_port.hpp`、 +-- `asio/*able_pipe.hpp`、`asio/stream_file.hpp`、 +-- `asio/random_access_file.hpp`。 +-- * spawn()/yield_context 有栈协程:需要 Boost.Context;本包禁用其自动 +-- 检测,应改用 co_spawn + awaitable + use_awaitable。 +-- * deadline_timer、generic protocol、execution、traits、遗留宏式协程和 +-- streambuf:对应 `asio/deadline_timer.hpp`、`asio/generic/*.hpp`、 +-- `asio/execution/*.hpp`、`asio/traits/*.hpp`、`asio/yield.hpp`、 +-- `asio/coroutine.hpp`、`asio/streambuf.hpp`。 +package = { + spec = "1", + namespace = "", + name = "asio", + description = "Standalone asio exposed as the C++23 module `asio` (separate compilation)", + licenses = {"BSL-1.0"}, + repo = "https://github.com/chriskohlhoff/asio", + type = "package", + + xpm = { + linux = { + ["1.38.1"] = { + url = { + GLOBAL = "https://github.com/chriskohlhoff/asio/archive/refs/tags/asio-1-38-1.tar.gz", + CN = "https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1.tar.gz", + }, + sha256 = "2827b229972be80cdb14e5497962fa393d1adf036b5869e2b9c99f644daadacc", + }, + }, + macosx = { + ["1.38.1"] = { + url = { + GLOBAL = "https://github.com/chriskohlhoff/asio/archive/refs/tags/asio-1-38-1.tar.gz", + CN = "https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1.tar.gz", + }, + sha256 = "2827b229972be80cdb14e5497962fa393d1adf036b5869e2b9c99f644daadacc", + }, + }, + windows = { + -- Upstream tag archives carry two POSIX symlinks + -- (asio/include -> ../include, asio/src -> ../src) that tar.exe + -- cannot materialize on the Windows runner. This uses the existing + -- symlink-free repack documented by xlings-res/asio. + ["1.38.1"] = { + url = { + GLOBAL = "https://github.com/xlings-res/asio/releases/download/1.38.1/asio-1.38.1-nosymlinks.tar.gz", + CN = "https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1-nosymlinks.tar.gz", + }, + sha256 = "77f74094bb12cd867a6edbf5736bbed816c6ce0906e880de8573097a81714d89", + }, + }, + }, + + mcpp = { + schema = "0.1", + language = "c++23", + import_std = false, + modules = { "asio" }, + -- GitHub wraps the tag as asio-asio-1-38-1/; expose its include root + -- so the wrapper's `#include ` resolve. + include_dirs = { "*/include" }, + generated_files = { + ["mcpp_generated/asio.cppm"] = [==[ +module; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +export module asio; + +export namespace asio::detail { +using ::std::chrono::operator==; +using ::std::chrono::operator<; +using ::std::chrono::operator>=; +using ::std::chrono::operator+; +using ::std::chrono::operator-; +using ::std::coroutine_traits; +} + +export namespace asio::error { +using ::asio::error::make_error_code; +using ::asio::error::operation_aborted; +} + +export namespace asio { +using ::asio::io_context; +using ::asio::post; +using ::asio::make_work_guard; +using ::asio::dispatch; +using ::asio::defer; +using ::asio::steady_timer; +using ::asio::thread_pool; +using ::asio::make_strand; +using ::asio::mutable_buffer; +using ::asio::const_buffer; +using ::asio::buffer; +using ::asio::awaitable; +using ::asio::use_awaitable; +using ::asio::co_spawn; +using ::asio::cancellation_signal; +using ::asio::cancellation_type; +using ::asio::bind_cancellation_slot; +using ::asio::execution_context; +using ::asio::any_io_executor; +using ::asio::system_executor; +using ::asio::system_context; +using ::asio::associated_executor; +using ::asio::associated_allocator; +using ::asio::associated_cancellation_slot; +using ::asio::error_code; +using ::asio::detached; +using ::asio::detached_t; +using ::asio::use_future; +using ::asio::deferred; +using ::asio::deferred_t; +using ::asio::redirect_error; +using ::asio::bind_executor; +using ::asio::signal_set; +using ::asio::system_timer; +using ::asio::bind_allocator; +using ::asio::append; +using ::asio::prepend; +using ::asio::consign; +using ::asio::as_tuple; +using ::asio::socket_base; +using ::asio::connect; +using ::asio::async_read; +using ::asio::async_write; +using ::asio::read; +using ::asio::write; +using ::asio::read_until; +} + +export namespace asio::experimental { +using ::asio::experimental::channel; +using ::asio::experimental::concurrent_channel; +using ::asio::experimental::use_promise; +} + +export namespace asio::experimental::error { +using ::asio::experimental::error::make_error_code; +} + +export namespace asio::ip { +using ::asio::ip::tcp; +using ::asio::ip::udp; +using ::asio::ip::address; +using ::asio::ip::address_v4; +using ::asio::ip::address_v6; +} + +export namespace asio::this_coro { +using ::asio::this_coro::executor; +using ::asio::this_coro::cancellation_state; +using ::asio::this_coro::throw_if_cancelled; +using ::asio::this_coro::reset_cancellation_state; +} + +]==], + }, + sources = { + "mcpp_generated/asio.cppm", + "*/src/asio.cpp", + }, + targets = { ["asio"] = { kind = "lib" } }, + -- `separate-compilation` is a default feature so its defines propagate + -- to every consumer TU (the module BMI and the consumer must agree on + -- ASIO_SEPARATE_COMPILATION or the inline/extern split miscompiles). + -- + -- ASIO_HAS_THREADS: asio's detection keys off CRT macros + -- (_MT/_REENTRANT/_POSIX_THREADS) that the workspace's llvm-on-Windows + -- toolchain does not define, otherwise silently selecting null_thread. + -- Pin the known multithreaded package contract; POSIX pthread selection + -- still runs beneath this define where applicable. + features = { + ["default"] = { implies = { "separate-compilation" } }, + ["separate-compilation"] = { + defines = { + "ASIO_STANDALONE", + "ASIO_SEPARATE_COMPILATION", + "ASIO_DISABLE_BOOST_CONTEXT_FIBER", + "ASIO_HAS_THREADS", + }, + }, + }, + deps = {}, + -- POSIX threading is detected by asio from unistd.h feature macros; + -- retain the portable driver-level thread link contract on Linux. + linux = { + ldflags = { "-pthread" }, + }, + -- On the supported desktop MSVC-ABI route, asio autolinks ws2_32.lib + -- and mswsock.lib. Do not inject GNU -l flags into native link.exe. + }, +} diff --git a/pkgs/c/chriskohlhoff.asio.lua b/pkgs/c/chriskohlhoff.asio.lua deleted file mode 100644 index ad183a8..0000000 --- a/pkgs/c/chriskohlhoff.asio.lua +++ /dev/null @@ -1,419 +0,0 @@ --- chriskohlhoff.asio -- Asio 1.38.1 暴露为 C++23 模块 `asio` (Form B inline) --- --- 消费者引入: --- mcpp add chriskohlhoff.asio@1.38.1 --- --- 注意: 不要使用简写 mcpp add asio@1.38.1。 --- 简写 "asio" 已在默认注册表中匹配多个包 (compat.asio, mcpplibs.asio 等), --- 会导致解析冲突或解析到错误的包。 --- --- 本包是 compat.asio (header-only: #include ) 的模块伴侣包。 --- 采用 ASIO_SEPARATE_COMPILATION 模式 (编译 */src/asio.cpp), --- 上层叠加生成的模块接口单元 (.cppm wrapper), 使用者只需: --- import std; import asio; --- --- 为何用 generated_files: upstream 1.38.x 未提供模块接口单元, --- wrapper 在 mcpp-index 内手工编写, 先以 docs/asio.lua 本地验证。 --- --- ========== 基本用法 ========== --- import std; -- 必须, 模块版不会自动拉入标准库 --- import asio; --- --- using namespace std::chrono_literals; --- asio::io_context io; --- auto strand = asio::make_strand(io); --- asio::steady_timer timer(io, 100ms); --- asio::co_spawn(io, my_coro(), asio::detached); --- --- ========== 必须写 import std; ========== --- 与 header-only 的 compat.asio 不同, 本模块不会隐式拉入任何标准库头文件。 --- 要使用 std::vector, std::error_code, std::thread, std::mutex, --- std::chrono 等, 必须写 `import std;`。省略则标准库不可见。 --- --- ========== 与 compat.asio(header-only) 的主要差异 ========== --- --- 1. 构建模型 (HEADER_ONLY -> SEPARATE_COMPILATION) --- compat.asio: ASIO_HEADER_ONLY -- asio 模板在每个消费者 TU 中实例化, --- 编译系统只需一个锚定 .c 文件。 --- chriskohlhoff.asio: ASIO_SEPARATE_COMPILATION -- 每次构建只编译一次 --- */src/asio.cpp; BMI (模块) 缓存模板实例化。 --- 首次构建较慢 (编译 asio 实现), 增量构建更快 --- (消费者 TU 变更时无需重解析 asio 头文件)。 --- --- 2. 宏 (宏定义) 不可见 --- `import asio;` 后, 模块边界隔离了预处理状态。使用者不能写: --- #ifdef ASIO_HAS_THREADS -- 不可见 --- #ifndef ASIO_HEADER_ONLY -- 不可见 --- #ifdef ASIO_HAS_PTHREADS -- 不可见 --- #ifdef ASIO_HAS_PIPE -- 不可见 --- #ifdef ASIO_HAS_FILE -- 不可见 --- #ifdef ASIO_HAS_SERIAL_PORT -- 不可见 --- #ifdef ASIO_HAS_BOOST_* -- 不可见 --- 只有 ASIO_STANDALONE 和 ASIO_SEPARATE_COMPILATION 通过 feature defines --- 暴露 (见下方 "features" 块)。需要平台检测时, 请使用 C++ 标准宏或 --- 操作系统级宏 (#ifdef __linux__ 等)。 --- --- 3. error_code 类型一致性 --- asio::error_code = std::error_code。模块导出了类型别名, 两者可互换。 --- 定时器回调签名 (const std::error_code&) 和 asio::error::* 枚举值 --- 均正常工作。 --- --- 4. 完成令牌 (Completion Token) 的模板类型 --- 模块使用者可以写 asio::detached / asio::detached_t / asio::deferred / --- asio::deferred_t 作为类型。但 asio::use_future_t 是类模板, --- 未导出。请直接使用 asio::use_future 变量, 无需命名其类型。 --- --- 5. 禁止混合 #include 和 import --- 不要在同一个 TU 中混用 #include 和 import asio; -- --- 头文件的 inline 实例化与模块 BMI 之间可能存在 ODR 差异。选一种。 --- 需要 #include 方式时, 请依赖 compat.asio。同理, 不要在同一 TU 中 --- 混合 #include 和 import std;。 --- --- 6. import_std = false --- mcpp schema "0.1" 要求自身提供模块接口的包必须设置 import_std = false --- (由使用者显式写 `import std; import asio;`)。chriskohlhoff.asio 不会 --- 在包级别自动引入 import std;。 --- --- ========== 本模块不可用的 API 组件 ========== --- --- 以下组件在 compat.asio (header-only) 中可用, 但本模块未导出: --- --- 组件 头文件 / 路径 原因 / 替代方案 --- ------------------------+----------------------------+---------------------- --- SSL/TLS asio/ssl/*.hpp 需 OpenSSL/wolfSSL --- (ssl::context, (外部依赖), 本包不包含 --- ssl::stream, --- ssl::host_name_verify) --- Unix 域套接字 asio/local/*.hpp 未导出。改用 TCP loopback, --- (local::stream_protocol, 或在你的代码中 #include --- local::datagram_proto) --- POSIX 流描述符 asio/posix/*.hpp 未导出。 --- (posix::stream_descriptor, --- posix::descriptor_base) --- Windows 句柄 asio/windows/*.hpp Windows 专用, 未导出。 --- (stream_handle, object_handle, --- overlapped_ptr) --- 串口 asio/serial_port.hpp 平台相关 --- (ASIO_HAS_SERIAL_PORT)。 --- 未导出。 --- Pipe (管道) asio/*able_pipe.hpp 需 ASIO_HAS_PIPE。 --- (readable_pipe, writable_pipe) 未导出。 --- 文件 I/O asio/stream_file.hpp 需 ASIO_HAS_FILE。 --- asio/random_access_file 未导出。 --- spawn() 有栈协程 asio/spawn.hpp 需 Boost.Context --- (spawn, yield_context) (ASIO_HAS_BOOST_CONTEXT --- _FIBER)。我们定义了 --- ASIO_DISABLE_BOOST_ --- CONTEXT_FIBER, 因此 --- spawn() 给出编译期 --- #error。 --- -> 改用 co_spawn + --- awaitable (C++20 --- 无栈协程) --- Boost.Date_Time 定时器 asio/deadline_timer.hpp 已废弃。改用 --- steady_timer / --- system_timer --- (使用 std::chrono) --- 通用套接字协议 asio/generic/*.hpp 较少使用, 未导出。 --- 执行器属性框架 asio/execution/*.hpp 高级执行器框架, 暂未导出。 --- 自定义点检测特质 asio/traits/*.hpp 检测特质, 最终用户 --- 价值较低, 未导出。 --- 遗留宏式协程 已过时。改用 awaitable。 --- --- asio::streambuf asio/streambuf.hpp 改用 mutable_buffer + --- asio::buffer()。 --- --- ========== Boost 淘汰说明 ========== --- --- 独立版 asio (定义了 ASIO_STANDALONE) 已从所有核心和网络 API 中移除 --- Boost 依赖: --- --- * Boost.DateTime -- 已完全移除。ASIO_STANDALONE 在 config.hpp 中设置 --- ASIO_DISABLE_BOOST_DATE_TIME, 导致 deadline_timer (依赖 --- boost::posix_time) 完全不可编译。所有现代 asio 定时器 --- (steady_timer, system_timer, high_resolution_timer) 直接使用 --- std::chrono。 --- --- * Boost.Context -- 已从核心库移除, 但 spawn() 仍需要。 --- spawn() / basic_yield_context API 使用 boost::context::fiber 实现 --- 有栈协程。由于我们定义了 ASIO_DISABLE_BOOST_CONTEXT_FIBER, --- 任何使用 spawn() 的代码都会产生编译期 #error。 --- -> 改用 C++20 无栈协程, 功能完全等价: --- // 之前 (Boost.Context 有栈): --- asio::spawn(io, [](asio::yield_context yield) { --- timer.async_wait(yield); --- }); --- // 之后 (C++20 无栈, 零 Boost): --- asio::co_spawn(io, coro(), asio::detached); --- asio::awaitable coro() { --- co_await timer.async_wait(asio::use_awaitable); --- } --- --- * Boost.Regex -- ASIO_STANDALONE 禁用了 ASIO_HAS_BOOST_REGEX。 --- * Boost.Config, Boost.Array, Boost.Bind, Boost.Limits, Boost.Chrono, --- Boost.ThrowException 等 -- 全部已禁用。 --- --- * 陷阱提示: ASIO_HAS_BOOST_CONTEXT_FIBER 会针对任意 C++11 兼容编译器 --- (clang/GCC/MSVC) 自动检测并设置自身, 即使你从未要求过 Boost。 --- 如果 Boost 头文件碰巧在 include path 中, spawn() 看起来能编译, --- 但会在链接时报错 (除非链接了 libboost_context)。 --- ASIO_DISABLE_BOOST_CONTEXT_FIBER 防护了这一点: 我们主动抑制自动检测, --- 使结果是明确的编译期错误, 而非运行时崩溃。 --- --- ========== 迁移指南 (header-only -> 模块) ========== --- --- 将项目从 compat.asio (#include ) 切换到 --- chriskohlhoff.asio (import asio;) 时, 请检查以下断点: --- --- [ ] 在每一个使用 asio 的 TU 顶部添加 import std; --- (标准库类型不再隐式可用) --- [ ] 删除所有 #include -- 替换为 import asio; --- [ ] 删除 #include (如果有) --- [ ] 检查 #ifdef ASIO_HAS_THREADS / ASIO_HAS_PIPE / 等 --- -> 替换为操作系统级宏或 if-constexpr 检测 --- [ ] 检查 asio::spawn() / yield_context 用法 --- -> 重写为 co_spawn + awaitable + use_awaitable --- [ ] 检查 deadline_timer -> 替换为 steady_timer --- [ ] 检查 asio::ssl::* -> 需要单独的 OpenSSL 集成包 --- [ ] 检查 asio::local::* / posix::* -> 如确实需要, 添加 #include --- (但同一 TU 中混用 #include 和 import 有风险; 要么对这类文件 --- 继续使用 compat.asio, 要么在 .cppm 文件的模块前导区 --- 仅添加全局性 #include) --- [ ] 构建时间: 首次构建较慢 (编译 asio.cpp), 增量构建更快 --- (BMI 缓存)。总体上更大的目标文件被跨 TU 更少的模板实例化抵消。 -package = { - spec = "1", - namespace = "chriskohlhoff", - name = "chriskohlhoff.asio", - description = "Standalone asio exposed as the C++23 module `asio` (separate compilation)", - licenses = {"BSL-1.0"}, - repo = "https://github.com/chriskohlhoff/asio", - type = "package", - - xpm = { - linux = { - ["1.38.1"] = { - url = { - GLOBAL = "https://github.com/chriskohlhoff/asio/archive/refs/tags/asio-1-38-1.tar.gz", - CN = "https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1.tar.gz", - }, - sha256 = "2827b229972be80cdb14e5497962fa393d1adf036b5869e2b9c99f644daadacc", - }, - }, - macosx = { - ["1.38.1"] = { - url = { - GLOBAL = "https://github.com/chriskohlhoff/asio/archive/refs/tags/asio-1-38-1.tar.gz", - CN = "https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1.tar.gz", - }, - sha256 = "2827b229972be80cdb14e5497962fa393d1adf036b5869e2b9c99f644daadacc", - }, - }, - windows = { - -- Same symlink-free repack as compat.asio: upstream's tag archives - -- carry two POSIX symlinks (asio/include -> ../include, - -- asio/src -> ../src) that tar.exe cannot materialize on the - -- Windows runner. Provenance: xlings-res/asio README. - ["1.38.1"] = { - url = { - GLOBAL = "https://github.com/xlings-res/asio/releases/download/1.38.1/asio-1.38.1-nosymlinks.tar.gz", - CN = "https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1-nosymlinks.tar.gz", - }, - sha256 = "77f74094bb12cd867a6edbf5736bbed816c6ce0906e880de8573097a81714d89", - }, - }, - }, - - mcpp = { - schema = "0.1", - language = "c++23", - import_std = false, - modules = { "asio" }, - -- GitHub wraps the tag as asio-asio-1-38-1/; expose its include root - -- so the wrapper's `#include ` resolve. - include_dirs = { "*/include" }, - generated_files = { - ["mcpp_generated/asio.cppm"] = [==[ -module; -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -export module asio; - -export namespace asio::detail { -using ::std::chrono::operator==; -using ::std::chrono::operator<; -using ::std::chrono::operator>=; -using ::std::chrono::operator+; -using ::std::chrono::operator-; -using ::std::coroutine_traits; -} - -export namespace asio::error { -using ::asio::error::make_error_code; -using ::asio::error::operation_aborted; -} - -export namespace asio { -using ::asio::io_context; -using ::asio::post; -using ::asio::make_work_guard; -using ::asio::dispatch; -using ::asio::defer; -using ::asio::steady_timer; -using ::asio::thread_pool; -using ::asio::make_strand; -using ::asio::mutable_buffer; -using ::asio::const_buffer; -using ::asio::buffer; -using ::asio::awaitable; -using ::asio::use_awaitable; -using ::asio::co_spawn; -using ::asio::cancellation_signal; -using ::asio::cancellation_type; -using ::asio::bind_cancellation_slot; -using ::asio::execution_context; -using ::asio::any_io_executor; -using ::asio::system_executor; -using ::asio::system_context; -using ::asio::associated_executor; -using ::asio::associated_allocator; -using ::asio::associated_cancellation_slot; -using ::asio::error_code; -using ::asio::detached; -using ::asio::detached_t; -using ::asio::use_future; -using ::asio::deferred; -using ::asio::deferred_t; -using ::asio::redirect_error; -using ::asio::bind_executor; -using ::asio::signal_set; -using ::asio::system_timer; -using ::asio::bind_allocator; -using ::asio::append; -using ::asio::prepend; -using ::asio::consign; -using ::asio::as_tuple; -using ::asio::socket_base; -using ::asio::connect; -using ::asio::async_read; -using ::asio::async_write; -using ::asio::read; -using ::asio::write; -using ::asio::read_until; -} - -export namespace asio::experimental { -using ::asio::experimental::channel; -using ::asio::experimental::concurrent_channel; -using ::asio::experimental::use_promise; -} - -export namespace asio::experimental::error { -using ::asio::experimental::error::make_error_code; -} - -export namespace asio::ip { -using ::asio::ip::tcp; -using ::asio::ip::udp; -using ::asio::ip::address; -using ::asio::ip::address_v4; -using ::asio::ip::address_v6; -} - -export namespace asio::this_coro { -using ::asio::this_coro::executor; -using ::asio::this_coro::cancellation_state; -using ::asio::this_coro::throw_if_cancelled; -using ::asio::this_coro::reset_cancellation_state; -} - -]==], - }, - sources = { - "mcpp_generated/asio.cppm", - "*/src/asio.cpp", - }, - targets = { ["asio"] = { kind = "lib" } }, - -- `separate-compilation` is a default feature so its defines propagate - -- to every consumer TU (the module BMI and the consumer must agree on - -- ASIO_SEPARATE_COMPILATION or the inline/extern split miscompiles). - -- - -- ASIO_HAS_THREADS: same rationale as compat.asio -- asio's thread - -- detection keys off CRT macros (_MT/_REENTRANT/_POSIX_THREADS) the - -- workspace's llvm-on-Windows toolchain does not define, silently - -- selecting null_thread; pin the detection result. asio only ever - -- tests defined(ASIO_HAS_THREADS), and on POSIX the pthread selection - -- beneath it still runs, so this is a no-op where detection works. - features = { - ["default"] = { implies = { "separate-compilation" } }, - ["separate-compilation"] = { - defines = { - "ASIO_STANDALONE", - "ASIO_SEPARATE_COMPILATION", - "ASIO_DISABLE_BOOST_CONTEXT_FIBER", - "ASIO_HAS_THREADS", - }, - }, - }, - deps = {}, - -- POSIX threading is detected by asio from unistd.h feature macros; - -- retain the portable driver-level thread link contract on Linux. - linux = { - ldflags = { "-pthread" }, - }, - -- On the supported desktop MSVC-ABI route, asio autolinks ws2_32.lib - -- and mswsock.lib. Do not inject GNU -l flags into native link.exe. - }, -} diff --git a/pkgs/c/compat.asio.lua b/pkgs/c/compat.asio.lua deleted file mode 100644 index 1f0bc63..0000000 --- a/pkgs/c/compat.asio.lua +++ /dev/null @@ -1,95 +0,0 @@ --- compat.asio — standalone Asio 1.38.1, exposed in upstream's default --- header-only mode. The package intentionally does not provide optional --- OpenSSL/wolfSSL, Boost.Context/Regex/Date_Time, or liburing dependencies. -package = { - spec = "1", - namespace = "compat", - name = "compat.asio", - description = "Standalone asynchronous I/O and networking library (header-only)", - licenses = {"BSL-1.0"}, - repo = "https://github.com/chriskohlhoff/asio", - type = "package", - - xpm = { - linux = { - ["1.38.1"] = { - url = { - GLOBAL = "https://github.com/chriskohlhoff/asio/archive/refs/tags/asio-1-38-1.tar.gz", - CN = "https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1.tar.gz", - }, - sha256 = "2827b229972be80cdb14e5497962fa393d1adf036b5869e2b9c99f644daadacc", - }, - }, - macosx = { - ["1.38.1"] = { - url = { - GLOBAL = "https://github.com/chriskohlhoff/asio/archive/refs/tags/asio-1-38-1.tar.gz", - CN = "https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1.tar.gz", - }, - sha256 = "2827b229972be80cdb14e5497962fa393d1adf036b5869e2b9c99f644daadacc", - }, - }, - windows = { - ["1.38.1"] = { - -- Upstream's tag archives (tar.gz AND zip) both carry two POSIX - -- symlinks (asio/include -> ../include, asio/src -> ../src) that - -- tar.exe cannot materialize on the Windows runner, and upstream - -- publishes no symlink-free asset for 1.38.x. This asset is the - -- upstream tag tarball with only those two symlink entries - -- removed (tar --delete); all 1544 regular files are - -- byte-identical to upstream. Provenance: xlings-res/asio README. - url = { - GLOBAL = "https://github.com/xlings-res/asio/releases/download/1.38.1/asio-1.38.1-nosymlinks.tar.gz", - CN = "https://gitcode.com/mcpp-res/asio/releases/download/1.38.1/asio-1.38.1-nosymlinks.tar.gz", - }, - sha256 = "77f74094bb12cd867a6edbf5736bbed816c6ce0906e880de8573097a81714d89", - }, - }, - }, - - mcpp = { - language = "c++23", - import_std = false, - c_standard = "c11", - -- GitHub wraps the tag as asio-asio-1-38-1/; expose its public include root. - include_dirs = { "*/include" }, - -- Header-only packages still need a buildable target in mcpp. - generated_files = { - ["mcpp_generated/asio_anchor.c"] = [==[ -int mcpp_compat_asio_headers_anchor(void) { return 0; } -]==], - }, - sources = { "mcpp_generated/asio_anchor.c" }, - targets = { ["asio"] = { kind = "lib" } }, - -- Explicitly pin the package's public configuration. `standalone` is a - -- default feature so its defines propagate to every consumer TU. - -- - -- ASIO_HAS_THREADS: asio's own thread detection keys off CRT macros - -- (_MT/_REENTRANT/_POSIX_THREADS) that the workspace's llvm-on-Windows - -- toolchain does not define, so asio silently selects null_thread and - -- every internal-thread operation (e.g. the waitable-timer wait thread) - -- throws operation_not_supported (10045) at runtime. All supported - -- targets are multithreaded; pin the detection result. asio only ever - -- tests defined(ASIO_HAS_THREADS), and on POSIX the pthread selection - -- below it still runs, so this is a no-op where detection already works. - features = { - ["default"] = { implies = { "standalone" } }, - ["standalone"] = { - defines = { - "ASIO_STANDALONE", - "ASIO_HEADER_ONLY", - "ASIO_DISABLE_BOOST_CONTEXT_FIBER", - "ASIO_HAS_THREADS", - }, - }, - }, - deps = {}, - -- POSIX threading is detected by Asio from unistd.h feature macros; - -- retain the portable driver-level thread link contract on Linux. - linux = { - ldflags = { "-pthread" }, - }, - -- On the supported desktop MSVC-ABI route, Asio autolinks ws2_32.lib - -- and mswsock.lib. Do not inject GNU -l flags into native link.exe. - }, -} diff --git a/tests/examples/asio-module/mcpp.toml b/tests/examples/asio-module/mcpp.toml index 75e359f..cc13ac3 100644 --- a/tests/examples/asio-module/mcpp.toml +++ b/tests/examples/asio-module/mcpp.toml @@ -1,13 +1,11 @@ -# Asio C++23-module consumer test project: `import asio;` (chriskohlhoff.asio, -# Form B inline descriptor, separate-compilation mode). Complements -# tests/examples/asio, which exercises the same upstream in header-only -# `#include ` form. +# Asio C++23-module consumer test project: `import std; import asio;`. +# The public package is the default-root module-only `asio@1.38.1` package. [package] name = "asio-module-tests" version = "0.1.0" [indices] -chriskohlhoff = { path = "../../.." } +default = { path = "../../.." } -[dependencies.chriskohlhoff] +[dependencies] asio = "1.38.1" diff --git a/tests/examples/asio-module/tests/experimental.cpp b/tests/examples/asio-module/tests/experimental.cpp index c7d66fd..aa1480b 100644 --- a/tests/examples/asio-module/tests/experimental.cpp +++ b/tests/examples/asio-module/tests/experimental.cpp @@ -1,5 +1,4 @@ // Experimental channel/concurrent_channel/use_promise over the module surface. -// Mirrors tests/examples/asio/tests/experimental.cpp. import std; import asio; diff --git a/tests/examples/asio-module/tests/network.cpp b/tests/examples/asio-module/tests/network.cpp index 381fd3a..c8d72f2 100644 --- a/tests/examples/asio-module/tests/network.cpp +++ b/tests/examples/asio-module/tests/network.cpp @@ -1,5 +1,5 @@ // TCP (acceptor/socket, async_read/async_write) and UDP (datagram send/receive) -// over the module surface. Mirrors tests/examples/asio/tests/network.cpp. +// over the imported module surface. import std; import asio; diff --git a/tests/examples/asio/mcpp.toml b/tests/examples/asio/mcpp.toml deleted file mode 100644 index ba10afc..0000000 --- a/tests/examples/asio/mcpp.toml +++ /dev/null @@ -1,10 +0,0 @@ -# Asio consumer test project: standalone, header-only, cross-platform behavior. -[package] -name = "asio-tests" -version = "0.1.0" - -[indices] -compat = { path = "../../.." } - -[dependencies.compat] -asio = "1.38.1" diff --git a/tests/examples/asio/tests/core.cpp b/tests/examples/asio/tests/core.cpp deleted file mode 100644 index 21f11fd..0000000 --- a/tests/examples/asio/tests/core.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include - -#include -#include -#include -#include - -#if !defined(_WIN32) -#ifndef ASIO_HAS_THREADS -#error "Asio must detect POSIX thread support" -#endif -#ifndef ASIO_HAS_PTHREADS -#error "Asio must select its pthread implementation on POSIX" -#endif -#endif - -int main() { - using namespace std::chrono_literals; - - asio::io_context io; - auto guard = asio::make_work_guard(io); - auto serial = asio::make_strand(io); - asio::steady_timer timer(io, 2ms); - - std::atomic posted{0}; - std::mutex order_mutex; - std::vector order; - bool timer_called = false; - - asio::post(serial, [&] { - std::lock_guard lock(order_mutex); - order.push_back(1); - ++posted; - }); - asio::post(serial, [&] { - std::lock_guard lock(order_mutex); - order.push_back(2); - ++posted; - }); - timer.async_wait([&](const asio::error_code& ec) { - timer_called = !ec; - guard.reset(); - }); - - asio::thread worker([&] { io.run(); }); - worker.join(); - - if (posted != 2 || !timer_called || order != std::vector{1, 2}) return 1; - - asio::thread_pool pool(2); - std::atomic pooled{0}; - asio::post(pool, [&] { ++pooled; }); - asio::post(pool, [&] { ++pooled; }); - pool.join(); - if (pooled != 2) return 2; - - asio::io_context cancel_io; - asio::steady_timer cancelled(cancel_io, 1h); - asio::cancellation_signal cancellation; - asio::error_code cancelled_ec; - bool cancelled_called = false; - cancelled.async_wait(asio::bind_cancellation_slot( - cancellation.slot(), - [&](const asio::error_code& ec) { - cancelled_ec = ec; - cancelled_called = true; - })); - cancellation.emit(asio::cancellation_type::all); - cancel_io.run(); - - return cancelled_called && cancelled_ec == asio::error::operation_aborted ? 0 : 3; -} diff --git a/tests/examples/asio/tests/coroutine.cpp b/tests/examples/asio/tests/coroutine.cpp deleted file mode 100644 index eb39ad4..0000000 --- a/tests/examples/asio/tests/coroutine.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include - -#include - -#ifndef ASIO_HAS_CO_AWAIT -#error "C++23 compat.asio consumers must have co_await support" -#endif -#ifndef ASIO_HAS_STD_COROUTINE -#error "C++23 compat.asio consumers must use the standard coroutine library" -#endif - -asio::awaitable timer_value() { - asio::steady_timer timer(co_await asio::this_coro::executor); - timer.expires_after(std::chrono::milliseconds(1)); - co_await timer.async_wait(asio::use_awaitable); - co_return 42; -} - -int main() { - asio::io_context io; - int result = 0; - bool completed = false; - - asio::co_spawn(io, timer_value(), - [&](std::exception_ptr error, int value) { - if (!error) { - result = value; - completed = true; - } - }); - - io.run(); - return completed && result == 42 ? 0 : 1; -} diff --git a/tests/examples/asio/tests/experimental.cpp b/tests/examples/asio/tests/experimental.cpp deleted file mode 100644 index 816f857..0000000 --- a/tests/examples/asio/tests/experimental.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -int main() { - asio::io_context io; - - asio::experimental::channel channel(io, 1); - if (!channel.try_send(asio::error_code{}, "channel")) return 1; - std::string channel_value; - asio::error_code channel_error; - channel.async_receive([&](asio::error_code ec, std::string value) { - channel_error = ec; - channel_value = std::move(value); - }); - - asio::experimental::concurrent_channel concurrent(io, 1); - if (!concurrent.try_send(asio::error_code{}, 42)) return 2; - int concurrent_value = 0; - asio::error_code concurrent_error; - concurrent.async_receive([&](asio::error_code ec, int value) { - concurrent_error = ec; - concurrent_value = value; - }); - - auto promised = asio::post(io, asio::experimental::use_promise); - bool promise_completed = false; - promised([&] { promise_completed = true; }); - - io.run(); - - return !channel_error && channel_value == "channel" - && !concurrent_error && concurrent_value == 42 - && promise_completed ? 0 : 3; -} diff --git a/tests/examples/asio/tests/network.cpp b/tests/examples/asio/tests/network.cpp deleted file mode 100644 index 2494945..0000000 --- a/tests/examples/asio/tests/network.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include - -#include -#include -#include - -int main() { - using asio::ip::tcp; - using asio::ip::udp; - using namespace std::chrono_literals; - - asio::io_context io; - tcp::acceptor acceptor(io, {asio::ip::address_v4::loopback(), 0}); - tcp::socket server(io); - tcp::socket client(io); - asio::steady_timer deadline(io, 5s); - - const std::string ping = "ping"; - const std::string pong = "pong"; - std::array server_data{}; - std::array client_data{}; - bool accepted = false; - bool connected = false; - bool tcp_done = false; - bool timed_out = false; - int failure = 0; - - auto fail = [&](int code) { - if (failure == 0) failure = code; - asio::error_code ignored; - acceptor.close(ignored); - server.close(ignored); - client.close(ignored); - deadline.cancel(); - }; - - deadline.async_wait([&](const asio::error_code& ec) { - if (!ec) { - timed_out = true; - fail(90); - } - }); - - acceptor.async_accept(server, [&](const asio::error_code& ec) { - if (ec) return fail(1); - accepted = true; - asio::async_read(server, asio::buffer(server_data), - [&](const asio::error_code& read_ec, std::size_t n) { - if (read_ec || n != ping.size() - || std::string(server_data.data(), n) != ping) return fail(2); - asio::async_write(server, asio::buffer(pong), - [&](const asio::error_code& write_ec, std::size_t written) { - if (write_ec || written != pong.size()) fail(3); - }); - }); - }); - - client.async_connect( - {asio::ip::address_v4::loopback(), acceptor.local_endpoint().port()}, - [&](const asio::error_code& ec) { - if (ec) return fail(4); - connected = true; - asio::async_write(client, asio::buffer(ping), - [&](const asio::error_code& write_ec, std::size_t written) { - if (write_ec || written != ping.size()) return fail(5); - asio::async_read(client, asio::buffer(client_data), - [&](const asio::error_code& read_ec, std::size_t n) { - if (read_ec || n != pong.size() - || std::string(client_data.data(), n) != pong) return fail(6); - tcp_done = true; - deadline.cancel(); - }); - }); - }); - - io.run(); - if (failure || timed_out || !accepted || !connected || !tcp_done) return failure ? failure : 7; - - asio::io_context udp_io; - udp::socket receiver(udp_io, {asio::ip::address_v4::loopback(), 0}); - udp::socket sender(udp_io, {asio::ip::address_v4::loopback(), 0}); - const std::string datagram = "asio-udp"; - std::array received{}; - udp::endpoint remote; - bool receive_done = false; - bool send_done = false; - asio::error_code udp_failure; - - receiver.async_receive_from(asio::buffer(received), remote, - [&](const asio::error_code& ec, std::size_t n) { - udp_failure = ec; - receive_done = !ec && n == datagram.size() - && std::string(received.data(), n) == datagram; - }); - sender.async_send_to(asio::buffer(datagram), receiver.local_endpoint(), - [&](const asio::error_code& ec, std::size_t n) { - if (ec) udp_failure = ec; - send_done = !ec && n == datagram.size(); - }); - - udp_io.run(); - return !udp_failure && receive_done && send_done ? 0 : 8; -} diff --git a/tests/examples/asio/tests/platform.cpp b/tests/examples/asio/tests/platform.cpp deleted file mode 100644 index eadbcd9..0000000 --- a/tests/examples/asio/tests/platform.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include - -#include -#include - -int main() { -#if defined(ASIO_HAS_PIPE) - asio::io_context io; - asio::readable_pipe reader(io); - asio::writable_pipe writer(io); - asio::error_code ec; - asio::connect_pipe(reader, writer, ec); - if (ec) return 1; - - const std::string sent = "pipe"; - std::array received{}; - if (asio::write(writer, asio::buffer(sent), ec) != sent.size() || ec) return 2; - if (asio::read(reader, asio::buffer(received), ec) != sent.size() || ec) return 3; - if (std::string(received.data(), received.size()) != sent) return 4; -#endif - -#if defined(ASIO_HAS_LOCAL_SOCKETS) - static_assert(sizeof(asio::local::stream_protocol::endpoint) > 0); -#endif -#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) - static_assert(sizeof(asio::posix::stream_descriptor::native_handle_type) > 0); -#endif -#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) - static_assert(sizeof(asio::windows::stream_handle::native_handle_type) > 0); -#endif -#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) - static_assert(sizeof(asio::windows::object_handle::native_handle_type) > 0); -#endif -#if defined(ASIO_HAS_FILE) - static_assert(sizeof(asio::random_access_file::native_handle_type) > 0); -#endif -#if defined(ASIO_HAS_SERIAL_PORT) - static_assert(sizeof(asio::serial_port::native_handle_type) > 0); -#endif - - return 0; -} diff --git a/tests/examples/asio/tests/surface.cpp b/tests/examples/asio/tests/surface.cpp deleted file mode 100644 index ca8e927..0000000 --- a/tests/examples/asio/tests/surface.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef ASIO_STANDALONE -#error "compat.asio must expose standalone Asio to consumers" -#endif -#ifndef ASIO_HEADER_ONLY -#error "compat.asio must expose Asio's header-only configuration" -#endif -#ifndef ASIO_DISABLE_BOOST_CONTEXT_FIBER -#error "compat.asio must make the excluded Boost.Context spawn path explicit" -#endif -#ifdef ASIO_ENABLE_BOOST -#error "compat.asio must not enable Boost.Asio mode" -#endif -#ifdef ASIO_HAS_BOOST_CONFIG -#error "standalone Asio must not depend on Boost.Config" -#endif -#ifdef ASIO_HAS_BOOST_REGEX -#error "standalone Asio must not expose Boost.Regex overloads" -#endif -#ifdef ASIO_HAS_BOOST_DATE_TIME -#error "standalone Asio must not expose legacy Boost.Date_Time timers" -#endif -#ifdef ASIO_HAS_IO_URING -#error "compat.asio base package must not require liburing" -#endif - -#include - -int main() { - static_assert(std::is_class_v); - static_assert(std::is_class_v); - static_assert(std::is_class_v); - static_assert(std::is_class_v); - static_assert(std::is_class_v); - static_assert(std::is_class_v); - static_assert(std::is_class_v>); - static_assert(std::is_class_v>); - -#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) - static_assert(std::is_class_v); -#endif -#if defined(ASIO_HAS_LOCAL_SOCKETS) - static_assert(std::is_class_v); -#endif -#if defined(ASIO_HAS_PIPE) - static_assert(std::is_class_v); - static_assert(std::is_class_v); -#endif -#if defined(ASIO_HAS_SERIAL_PORT) - static_assert(std::is_class_v); -#endif -#if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) - static_assert(std::is_class_v); -#endif -#if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) - static_assert(std::is_class_v); -#endif -#if defined(ASIO_HAS_FILE) - static_assert(std::is_class_v); -#endif - - return 0; -}