#competitive-programming #source-file #cpp #programming #competitive #single-file #amalgamation

app cpp-amalgamate

cpp-amalgamate递归地将C++源文件及其包含的头文件合并为一个单独的输出文件

2个稳定版本

1.0.1 2022年6月7日
1.0.0 2021年11月17日

#1207 in 开发工具

MIT许可证

38KB
793

cpp-amalgamate

Build status License Crates.io

cpp-amalgamate递归地将C++源文件及其包含的头文件合并为一个单独的输出文件。它会跟踪哪些头文件已被包含,并跳过对它们的进一步引用。可以精确控制哪些包含是内联的,哪些保持原样。

它最初是一种自动化方式,在提交到像CodeforcesAtCoder这样的竞技编程网站时内联预写的代码片段。从那时起,它被推广到其他上下文中,也可能很有用。

特性 & 局限性

当提供一个或多个源文件以及伴随的搜索目录(用于包含),cpp-amalgamate将连接源文件,并递归地内联所有可解析的包含语句(使用给定的搜索目录或当前目录中的#include "...")。默认情况下,所有可解析的包含都会被内联,但可以使用--filter*选项系列进行控制。它还可以插入相应的#line num "file"指令,这使得编译器或调试器可以将合并文件中的行解析回其原始位置。

然而,cpp-amalgamate不会解释预处理器指令,超出#include。这特别意味着它不能理解使用#if指令的传统头文件保护。相反,cpp-amalgamate假定每个头文件最多只包含一次,就像它被头文件保护或#pragma once保护一样。它确实检测到#pragma once指令并删除它们,因为这些指令在某些编译器中编译合并文件时会引发警告或错误。

这种简化的行为也可能导致问题,如果 #include 语句本身位于 #if 块中。如果在两个不同的 #if 块内部引用了相同的头文件,它只会在前者中展开,而后者中的 #include 将会被移除。

用法

cpp-amalgamate 的基本调用方式为

cpp-amalgamate [options] source-files...

要指定搜索目录,请使用 -d/--dir。您也可以使用 --dir-quote--dir-system 来指定仅用于引号(即,#include "...")或系统包含(即,#include <...>)的搜索目录。请注意,cpp-amalgamate 默认不使用任何搜索目录!

过滤

使用 -f/--filter,您可以指定不应内联的包含文件的glob。与搜索目录一样,--filter-quote--filter-system 只适用于一种类型的包含。glob可以通过前面的 ! 进行反转,即使之前的glob排除了它们,匹配的头文件也会被内联。glob按顺序评估,最后一个匹配的glob确定是否包含头文件。默认情况下(即如果没有glob匹配),所有头文件都会被内联。

请注意,这些glob应用于已解析所有符号链接的头文件的绝对路径。这意味着通常需要一个 ** 片段,它匹配任意数量的路径条目。也就是说,

  • ** 匹配任何文件,
  • **/*.hpp 所有扩展名为 .hpp 的文件,
  • 以及 /usr/local/include/** /usr/local/include 中的所有文件。

有关支持的完整语法的详细信息,请参阅 globset 文档

杂项

cpp-amalgamate 支持的其他标志包括

  • -o/--output:将合并的源文件写入文件而不是标准输出。
  • --line-directives:向输出添加 #line num "file" 指令,允许编译器和调试器将行号解析为其原始文件。
  • -v/--verbose-q/--quiet:增加或减少显示的日志消息级别。默认情况下,只显示警告和错误。
  • --unresolvable-include:指定当无法解析包含文件时执行的操作。可能的值是 errorwarnignore,后者是默认值。这可以用来断言所有包含文件最终都会被内联。也作为 --unresolvable-quote-include--unresolvable-system-include 可用。
  • --cyclic-include:指定如何处理循环包含。支持与--unresolvable-include相同的值,但默认为error

安装

每个GitHub版本都包含大多数常见操作系统/架构的预编译二进制文件。或者,可以使用与Rust捆绑的cargo安装cpp-amalgamate。

cargo install cpp-amalgamate

依赖项

~9–22MB
~283K SLoC