2个稳定版本
1.0.1 | 2022年6月7日 |
---|---|
1.0.0 | 2021年11月17日 |
#1207 in 开发工具
38KB
793 行
cpp-amalgamate递归地将C++源文件及其包含的头文件合并为一个单独的输出文件。它会跟踪哪些头文件已被包含,并跳过对它们的进一步引用。可以精确控制哪些包含是内联的,哪些保持原样。
它最初是一种自动化方式,在提交到像Codeforces或AtCoder这样的竞技编程网站时内联预写的代码片段。从那时起,它被推广到其他上下文中,也可能很有用。
特性 & 局限性
当提供一个或多个源文件以及伴随的搜索目录(用于包含),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
:指定当无法解析包含文件时执行的操作。可能的值是error
、warn
和ignore
,后者是默认值。这可以用来断言所有包含文件最终都会被内联。也作为--unresolvable-quote-include
和--unresolvable-system-include
可用。--cyclic-include
:指定如何处理循环包含。支持与--unresolvable-include
相同的值,但默认为error
。
安装
每个GitHub版本都包含大多数常见操作系统/架构的预编译二进制文件。或者,可以使用与Rust捆绑的cargo安装cpp-amalgamate。
cargo install cpp-amalgamate
依赖项
~9–22MB
~283K SLoC