1- -- chriskohlhoff.asio -- Asio 1.38.1 暴露为 C++23 模块 `asio` (Form B inline)
1+ -- asio -- 将独立版 Asio 1.38.1 暴露为 C++23 模块 `asio`
2+ -- (Form B inline descriptor, separate-compilation mode)。
23--
3- -- 消费者引入:
4- -- mcpp add chriskohlhoff.asio@1.38.1
4+ -- 注意事项
5+ -- * 使用 `mcpp add chriskohlhoff.asio@1.38.1` 引入;消费者需显式写
6+ -- `import std; import asio;`,因为本包设置 import_std = false。
7+ -- * 本包只支持模块方式消费。同一 translation unit 不要混用
8+ -- `#include <asio.hpp>` 和 `import asio;`,避免 inline 定义与模块 BMI
9+ -- 的 separate-compilation 定义产生 ODR 差异。
10+ -- * 默认 feature 显式传播 ASIO_STANDALONE、ASIO_SEPARATE_COMPILATION、
11+ -- ASIO_DISABLE_BOOST_CONTEXT_FIBER 和 ASIO_HAS_THREADS。Asio 头文件内部
12+ -- 自动检测的其他 ASIO_HAS_* 宏不会由 `import asio;` 导出。
513--
6- -- 注意: 不要使用简写 mcpp add asio@1.38.1。
7- -- 简写 "asio" 已在默认注册表中匹配多个包 (compat.asio, mcpplibs.asio 等),
8- -- 会导致解析冲突或解析到错误的包。
14+ -- 与 header-only Asio 的区别/限制
15+ -- * 上游 1.38.x 没有模块接口单元。本描述生成 `asio.cppm`,并只编译一次
16+ -- `*/src/asio.cpp` 中的非模板实现;首次构建需生成 BMI,增量构建可避免
17+ -- 每个消费者 translation unit 重复解析整组 Asio 头文件。
18+ -- * 模块只暴露 wrapper 中明确 export 的声明,不等同于
19+ -- `#include <asio.hpp>` 的完整 API 表面。
20+ -- * asio::error_code 是 std::error_code 的别名;wrapper 导出
21+ -- asio::use_future 变量,但未导出 asio::use_future_t<Alloc> 类模板。
22+ -- * 依赖未导出 ASIO_HAS_* 宏、平台专用头文件或 Boost 扩展的代码,需要
23+ -- 改用标准/操作系统能力检测或另行扩展模块 wrapper。
924--
10- -- 本包是 compat.asio (header-only: #include <asio.hpp>) 的模块伴侣包。
11- -- 采用 ASIO_SEPARATE_COMPILATION 模式 (编译 */src/asio.cpp),
12- -- 上层叠加生成的模块接口单元 (.cppm wrapper), 使用者只需:
13- -- import std; import asio;
14- --
15- -- 为何用 generated_files: upstream 1.38.x 未提供模块接口单元,
16- -- wrapper 在 mcpp-index 内手工编写, 先以 docs/asio.lua 本地验证。
17- --
18- -- ========== 基本用法 ==========
19- -- import std; -- 必须, 模块版不会自动拉入标准库
20- -- import asio;
21- --
22- -- using namespace std::chrono_literals;
23- -- asio::io_context io;
24- -- auto strand = asio::make_strand(io);
25- -- asio::steady_timer timer(io, 100ms);
26- -- asio::co_spawn(io, my_coro(), asio::detached);
27- --
28- -- ========== 必须写 import std; ==========
29- -- 与 header-only 的 compat.asio 不同, 本模块不会隐式拉入任何标准库头文件。
30- -- 要使用 std::vector, std::error_code, std::thread, std::mutex,
31- -- std::chrono 等, 必须写 `import std;`。省略则标准库不可见。
32- --
33- -- ========== 与 compat.asio(header-only) 的主要差异 ==========
34- --
35- -- 1. 构建模型 (HEADER_ONLY -> SEPARATE_COMPILATION)
36- -- compat.asio: ASIO_HEADER_ONLY -- asio 模板在每个消费者 TU 中实例化,
37- -- 编译系统只需一个锚定 .c 文件。
38- -- chriskohlhoff.asio: ASIO_SEPARATE_COMPILATION -- 每次构建只编译一次
39- -- */src/asio.cpp; BMI (模块) 缓存模板实例化。
40- -- 首次构建较慢 (编译 asio 实现), 增量构建更快
41- -- (消费者 TU 变更时无需重解析 asio 头文件)。
42- --
43- -- 2. 宏 (宏定义) 不可见
44- -- `import asio;` 后, 模块边界隔离了预处理状态。使用者不能写:
45- -- #ifdef ASIO_HAS_THREADS -- 不可见
46- -- #ifndef ASIO_HEADER_ONLY -- 不可见
47- -- #ifdef ASIO_HAS_PTHREADS -- 不可见
48- -- #ifdef ASIO_HAS_PIPE -- 不可见
49- -- #ifdef ASIO_HAS_FILE -- 不可见
50- -- #ifdef ASIO_HAS_SERIAL_PORT -- 不可见
51- -- #ifdef ASIO_HAS_BOOST_* -- 不可见
52- -- 只有 ASIO_STANDALONE 和 ASIO_SEPARATE_COMPILATION 通过 feature defines
53- -- 暴露 (见下方 "features" 块)。需要平台检测时, 请使用 C++ 标准宏或
54- -- 操作系统级宏 (#ifdef __linux__ 等)。
55- --
56- -- 3. error_code 类型一致性
57- -- asio::error_code = std::error_code。模块导出了类型别名, 两者可互换。
58- -- 定时器回调签名 (const std::error_code&) 和 asio::error::* 枚举值
59- -- 均正常工作。
60- --
61- -- 4. 完成令牌 (Completion Token) 的模板类型
62- -- 模块使用者可以写 asio::detached / asio::detached_t / asio::deferred /
63- -- asio::deferred_t 作为类型。但 asio::use_future_t<Alloc> 是类模板,
64- -- 未导出。请直接使用 asio::use_future 变量, 无需命名其类型。
65- --
66- -- 5. 禁止混合 #include 和 import
67- -- 不要在同一个 TU 中混用 #include <asio.hpp> 和 import asio; --
68- -- 头文件的 inline 实例化与模块 BMI 之间可能存在 ODR 差异。选一种。
69- -- 需要 #include 方式时, 请依赖 compat.asio。同理, 不要在同一 TU 中
70- -- 混合 #include <vector> 和 import std;。
71- --
72- -- 6. import_std = false
73- -- mcpp schema "0.1" 要求自身提供模块接口的包必须设置 import_std = false
74- -- (由使用者显式写 `import std; import asio;`)。chriskohlhoff.asio 不会
75- -- 在包级别自动引入 import std;。
76- --
77- -- ========== 本模块不可用的 API 组件 ==========
78- --
79- -- 以下组件在 compat.asio (header-only) 中可用, 但本模块未导出:
80- --
81- -- 组件 头文件 / 路径 原因 / 替代方案
82- -- ------------------------+----------------------------+----------------------
83- -- SSL/TLS asio/ssl/*.hpp 需 OpenSSL/wolfSSL
84- -- (ssl::context, (外部依赖), 本包不包含
85- -- ssl::stream,
86- -- ssl::host_name_verify)
87- -- Unix 域套接字 asio/local/*.hpp 未导出。改用 TCP loopback,
88- -- (local::stream_protocol, 或在你的代码中 #include
89- -- local::datagram_proto)
90- -- POSIX 流描述符 asio/posix/*.hpp 未导出。
91- -- (posix::stream_descriptor,
92- -- posix::descriptor_base)
93- -- Windows 句柄 asio/windows/*.hpp Windows 专用, 未导出。
94- -- (stream_handle, object_handle,
95- -- overlapped_ptr)
96- -- 串口 asio/serial_port.hpp 平台相关
97- -- (ASIO_HAS_SERIAL_PORT)。
98- -- 未导出。
99- -- Pipe (管道) asio/*able_pipe.hpp 需 ASIO_HAS_PIPE。
100- -- (readable_pipe, writable_pipe) 未导出。
101- -- 文件 I/O asio/stream_file.hpp 需 ASIO_HAS_FILE。
102- -- asio/random_access_file 未导出。
103- -- spawn() 有栈协程 asio/spawn.hpp 需 Boost.Context
104- -- (spawn, yield_context) (ASIO_HAS_BOOST_CONTEXT
105- -- _FIBER)。我们定义了
106- -- ASIO_DISABLE_BOOST_
107- -- CONTEXT_FIBER, 因此
108- -- spawn() 给出编译期
109- -- #error。
110- -- -> 改用 co_spawn +
111- -- awaitable (C++20
112- -- 无栈协程)
113- -- Boost.Date_Time 定时器 asio/deadline_timer.hpp 已废弃。改用
114- -- steady_timer /
115- -- system_timer
116- -- (使用 std::chrono)
117- -- 通用套接字协议 asio/generic/*.hpp 较少使用, 未导出。
118- -- 执行器属性框架 asio/execution/*.hpp 高级执行器框架, 暂未导出。
119- -- 自定义点检测特质 asio/traits/*.hpp 检测特质, 最终用户
120- -- 价值较低, 未导出。
121- -- 遗留宏式协程 <asio/yield.hpp> 已过时。改用 awaitable。
122- -- <asio/coroutine.hpp>
123- -- asio::streambuf asio/streambuf.hpp 改用 mutable_buffer +
124- -- asio::buffer()。
125- --
126- -- ========== Boost 淘汰说明 ==========
127- --
128- -- 独立版 asio (定义了 ASIO_STANDALONE) 已从所有核心和网络 API 中移除
129- -- Boost 依赖:
130- --
131- -- * Boost.DateTime -- 已完全移除。ASIO_STANDALONE 在 config.hpp 中设置
132- -- ASIO_DISABLE_BOOST_DATE_TIME, 导致 deadline_timer (依赖
133- -- boost::posix_time) 完全不可编译。所有现代 asio 定时器
134- -- (steady_timer, system_timer, high_resolution_timer) 直接使用
135- -- std::chrono。
136- --
137- -- * Boost.Context -- 已从核心库移除, 但 spawn() 仍需要。
138- -- spawn() / basic_yield_context API 使用 boost::context::fiber 实现
139- -- 有栈协程。由于我们定义了 ASIO_DISABLE_BOOST_CONTEXT_FIBER,
140- -- 任何使用 spawn() 的代码都会产生编译期 #error。
141- -- -> 改用 C++20 无栈协程, 功能完全等价:
142- -- // 之前 (Boost.Context 有栈):
143- -- asio::spawn(io, [](asio::yield_context yield) {
144- -- timer.async_wait(yield);
145- -- });
146- -- // 之后 (C++20 无栈, 零 Boost):
147- -- asio::co_spawn(io, coro(), asio::detached);
148- -- asio::awaitable<void> coro() {
149- -- co_await timer.async_wait(asio::use_awaitable);
150- -- }
151- --
152- -- * Boost.Regex -- ASIO_STANDALONE 禁用了 ASIO_HAS_BOOST_REGEX。
153- -- * Boost.Config, Boost.Array, Boost.Bind, Boost.Limits, Boost.Chrono,
154- -- Boost.ThrowException 等 -- 全部已禁用。
155- --
156- -- * 陷阱提示: ASIO_HAS_BOOST_CONTEXT_FIBER 会针对任意 C++11 兼容编译器
157- -- (clang/GCC/MSVC) 自动检测并设置自身, 即使你从未要求过 Boost。
158- -- 如果 Boost 头文件碰巧在 include path 中, spawn() 看起来能编译,
159- -- 但会在链接时报错 (除非链接了 libboost_context)。
160- -- ASIO_DISABLE_BOOST_CONTEXT_FIBER 防护了这一点: 我们主动抑制自动检测,
161- -- 使结果是明确的编译期错误, 而非运行时崩溃。
162- --
163- -- ========== 迁移指南 (header-only -> 模块) ==========
164- --
165- -- 将项目从 compat.asio (#include <asio.hpp>) 切换到
166- -- chriskohlhoff.asio (import asio;) 时, 请检查以下断点:
167- --
168- -- [ ] 在每一个使用 asio 的 TU 顶部添加 import std;
169- -- (标准库类型不再隐式可用)
170- -- [ ] 删除所有 #include <asio/*.hpp> -- 替换为 import asio;
171- -- [ ] 删除 #include <asio.hpp> (如果有)
172- -- [ ] 检查 #ifdef ASIO_HAS_THREADS / ASIO_HAS_PIPE / 等
173- -- -> 替换为操作系统级宏或 if-constexpr 检测
174- -- [ ] 检查 asio::spawn() / yield_context 用法
175- -- -> 重写为 co_spawn + awaitable + use_awaitable
176- -- [ ] 检查 deadline_timer -> 替换为 steady_timer
177- -- [ ] 检查 asio::ssl::* -> 需要单独的 OpenSSL 集成包
178- -- [ ] 检查 asio::local::* / posix::* -> 如确实需要, 添加 #include
179- -- (但同一 TU 中混用 #include 和 import 有风险; 要么对这类文件
180- -- 继续使用 compat.asio, 要么在 .cppm 文件的模块前导区
181- -- 仅添加全局性 #include)
182- -- [ ] 构建时间: 首次构建较慢 (编译 asio.cpp), 增量构建更快
183- -- (BMI 缓存)。总体上更大的目标文件被跨 TU 更少的模板实例化抵消。
25+ -- 未导出的组件
26+ -- * SSL/TLS (`asio/ssl/*.hpp`):需要 OpenSSL/wolfSSL 等外部依赖。
27+ -- * Unix 域套接字、POSIX 描述符和 Windows 句柄:
28+ -- `asio/local/*.hpp`、`asio/posix/*.hpp`、`asio/windows/*.hpp`。
29+ -- * 串口、pipe 和文件 I/O:`asio/serial_port.hpp`、
30+ -- `asio/*able_pipe.hpp`、`asio/stream_file.hpp`、
31+ -- `asio/random_access_file.hpp`。
32+ -- * spawn()/yield_context 有栈协程:需要 Boost.Context;本包禁用其自动
33+ -- 检测,应改用 co_spawn + awaitable + use_awaitable。
34+ -- * deadline_timer、generic protocol、execution、traits、遗留宏式协程和
35+ -- streambuf:对应 `asio/deadline_timer.hpp`、`asio/generic/*.hpp`、
36+ -- `asio/execution/*.hpp`、`asio/traits/*.hpp`、`asio/yield.hpp`、
37+ -- `asio/coroutine.hpp`、`asio/streambuf.hpp`。
18438package = {
18539 spec = " 1" ,
18640 namespace = " chriskohlhoff" ,
187- name = " chriskohlhoff. asio" ,
41+ name = " asio" ,
18842 description = " Standalone asio exposed as the C++23 module `asio` (separate compilation)" ,
18943 licenses = {" BSL-1.0" },
19044 repo = " https://github.com/chriskohlhoff/asio" ,
@@ -210,10 +64,10 @@ package = {
21064 },
21165 },
21266 windows = {
213- -- Same symlink-free repack as compat.asio: upstream's tag archives
214- -- carry two POSIX symlinks (asio/include -> ../include,
215- -- asio/src -> ../src) that tar.exe cannot materialize on the
216- -- Windows runner. Provenance: xlings-res/asio README .
67+ -- Upstream tag archives carry two POSIX symlinks
68+ -- (asio/include -> ../include, asio/src -> ../src) that tar.exe
69+ -- cannot materialize on the Windows runner. This uses the existing
70+ -- symlink-free repack documented by xlings-res/asio.
21771 [" 1.38.1" ] = {
21872 url = {
21973 GLOBAL = " https://github.com/xlings-res/asio/releases/download/1.38.1/asio-1.38.1-nosymlinks.tar.gz" ,
@@ -390,12 +244,11 @@ using ::asio::this_coro::reset_cancellation_state;
390244 -- to every consumer TU (the module BMI and the consumer must agree on
391245 -- ASIO_SEPARATE_COMPILATION or the inline/extern split miscompiles).
392246 --
393- -- ASIO_HAS_THREADS: same rationale as compat.asio -- asio's thread
394- -- detection keys off CRT macros (_MT/_REENTRANT/_POSIX_THREADS) the
395- -- workspace's llvm-on-Windows toolchain does not define, silently
396- -- selecting null_thread; pin the detection result. asio only ever
397- -- tests defined(ASIO_HAS_THREADS), and on POSIX the pthread selection
398- -- beneath it still runs, so this is a no-op where detection works.
247+ -- ASIO_HAS_THREADS: asio's detection keys off CRT macros
248+ -- (_MT/_REENTRANT/_POSIX_THREADS) that the workspace's llvm-on-Windows
249+ -- toolchain does not define, otherwise silently selecting null_thread.
250+ -- Pin the known multithreaded package contract; POSIX pthread selection
251+ -- still runs beneath this define where applicable.
399252 features = {
400253 [" default" ] = { implies = { " separate-compilation" } },
401254 [" separate-compilation" ] = {
0 commit comments