第1.8章: fast_io
使用 fast_io(仅头文件)
在 第1.5章 中,我们克隆了 fast_io 仓库。
fast_io 是一个仅头文件的库,因此你不需要构建任何东西。
你只需把 include 目录加入编译器选项。
假设你把 fast_io 克隆到了:
$HOME/libraries/fast_io
那么你可以在程序中包含它:
#include <fast_io.h>
int main() {
print("Hello from fast_io!\n");
}
并通过添加以下选项来编译:
-I$HOME/libraries/fast_io/include
这会告诉编译器到哪里去找 fast_io.h。
两个必需的选项:-fherbceptions -lherbceptions
fast_io 把每一个错误都报告为 赫布异常, 而赫布异常是一项编译器特性。所以仅靠 include 目录是不够的:你还需要 赫布异常运行时,以及一个实现了该语言特性的编译器。
-
-fherbceptions—— 打开赫布异常。凡是包含 fast_io 的 翻译单元都必须传入它。 -
-lherbceptions—— 链接拥有错误域(error domain)的运行时库。
只有我们的 GCC 和 LLVM 构建支持赫布异常。原版编译器
和 MSVC 则不支持——没有办法用 cl.exe 编译 fast_io。
完整解释以及每一条错误报告规则见
第3.16章: 赫布异常。
不需要别的东西:赫布异常的头文件与库都是你所安装工具链的一部分,
所以 -lherbceptions 就是全部额外的添加。假设 fast_io 被克隆到
$HOME/libraries/fast_io:
FASTIO=$HOME/libraries/fast_io
用 Clang 编译
示例:使用 Clang 和 MSVC sysroot 构建一个 Windows MSVC 二进制文件:
clang++ --config=$HOME/cfgs/x86_64-windows-msvc.cfg \
-O3 -flto=thin -fherbceptions \
-I$FASTIO/include \
hello.cpp -lherbceptions -o hello.exe
赫布异常运行时位于 sysroot 中:
链接时是 lib/<triple>/herbceptions.lib,
运行时是 bin/<triple>/herbceptions.dll(Wine 通过
WINEPATH 找到它)。我们的 MinGW g++ 用自己的导入库
复用同一个 DLL,并且需要 -lntdll,因为 fast_io 直接与 NT 打交道:
x86_64-w64-mingw32-g++ -o hello.exe hello.cpp \
-std=c++26 -O3 -s \
-fherbceptions \
-I$FASTIO/include \
-lherbceptions -lntdll
wine ./hello.exe
要查看一个 Windows 二进制文件需要哪些 DLL,请使用 win-ldd:
wine $HOME/softwares/win-ldd/x86_64-windows-msvc/win-ldd.exe ./hello.exe
herbceptions.lib,
运行时用 herbceptions.dll),所以 --sysroot 就能找到它,
永远不需要写 -L。GCC/GNU 目标的构建还会额外传入 -s
来剥离二进制文件。
用 GCC 编译
GCC 的工作方式相同,前提是使用我们带赫布异常的 GCC 构建:
g++ -o hello hello.cpp \
-std=c++26 -O3 -s -fuse-ld=lld \
-fherbceptions \
-I$FASTIO/include \
-lherbceptions
不支持 MSVC(cl.exe)
对 fast_io 而言,MSVC 不是受支持的编译器。它没有
-fherbceptions,而 fast_io 通过赫布异常通道报告每一个错误,
因此本教程的错误契约无法用它表达。请使用我们的 GCC 或
LLVM 分支。
在 Windows 上,请使用我们面向 x86_64-windows-msvc 的 Clang(就是
上面那条命令——它产出一个普通的 Windows 二进制文件,用
lld 链接),或者我们的 MinGW GCC。cl.exe 和 Visual Studio 的
常规 C++ 工具集都不参与其中。
使用 fast_io 模块
fast_io 也提供 C++20 模块文件。 它们位于:
{fast_io_cloned_dir}/share/fast_io
示例目录:
/Users/username/libraries/fast_io/share/fast_io
内容:
fast_io.cppm
fast_io_crypto.cppm
fast_io_legacy.cppm
fast_io_inc/
如何导入模块
创建一个文件 hello.cpp:
import fast_io;
int main() {
using namespace ::fast_io::io;
print("Hello from fast_io module!\n");
}
用 Clang 编译 fast_io 模块
首先,编译模块接口:
clang++ --config=$HOME/cfgs/x86_64-linux-gnu-libcxx.cfg \
-O2 -fherbceptions -I$FASTIO/include \
-x c++-module $FASTIO/share/fast_io/fast_io_json.cppm \
-o fast_io.json.pcm --precompile
然后用该 PCM 编译你的程序:
clang++ --config=$HOME/cfgs/x86_64-linux-gnu-libcxx.cfg \
-O2 -fherbceptions -I$FASTIO/include \
-fmodule-file=fast_io.json=fast_io.json.pcm \
hello.cpp fast_io.json.pcm -lherbceptions \
-o hello
模块只需预编译一次,之后即可导入;导入处除了
#include <herbceptions/error>(当你想自己编写
catch throws 处理程序时)之外,不需要头文件里的任何东西。
fast_io_json.cppm 目前可以干净地预编译并导入,也是本示例所用的那个。
总括式的 fast_io.cppm 仍在追赶头文件,所以如果预编译它在失败,
请改用头文件接口(#include <fast_io.h>)——本教程其余部分
用的就是这个。
用 GCC 编译 fast_io 模块
GCC 的模块支持仍是实验性的,而且我们带赫布异常的 GCC 构建
在某些 fast_io 模块单元上已知会崩溃(ICE)——请用 Clang 编译
这组模块,或者用 GCC 时改用头文件接口。
g++ -std=c++26 -fmodules -fherbceptions -O3 -s -fuse-ld=lld \
-c $FASTIO/share/fast_io/fast_io_json.cppm \
-I$FASTIO/include \
-o fast_io.json.gcm
g++ -std=c++26 -fmodules -fherbceptions -O3 -s -fuse-ld=lld hello.cpp \
fast_io.json.gcm \
-I$FASTIO/include \
-lherbceptions \
-o hello
MSVC 无法编译该模块
MSVC 不是 fast_io 支持的编译器:它没有赫布异常,而库中的每个错误
都被报告为赫布异常。我们的 GCC 和 LLVM 分支是本教程唯一支持的编译器。
Windows 二进制文件是用我们面向 MSVC ABI 的 Clang(或我们的 MinGW GCC)构建的——
产出的可执行文件是普通的 Windows 二进制文件,只不过不是由
cl.exe 生成的而已。
要点
- fast_io 是仅头文件的——不需要构建步骤。
- 把
-I{fast_io}/include加入你的编译器选项。 - Clang、GCC 和 MSVC 都能与 fast_io 配合使用。
- fast_io 还在
share/fast_io中提供了模块。 - 模块需要一个单独的编译步骤来生成
.pcm、.gcm或.ifc。