将C++文件合并为一个源文件

29

我有一个包含多个源文件和头文件的 C++ 项目。我想要将我的项目提交到一个需要单个源文件的编程竞赛中。是否有自动化的方式将所有文件合并成单个 .cpp 文件?

例如,如果我有 a.cpp、a.h、b.cpp、b.h 等文件,我希望得到一个可以成功编译和运行的 main.cpp 文件。如果我手动合并这些文件,我是否只需将头文件合并并将源文件追加到彼此后面即可?在 externs、include 依赖和前向声明方面是否有需要注意的地方?


3
对于所有“回避”这个问题的答案,我无法将我的项目压缩,因为在线评测器期望只有一个cpp文件进行编译和运行。 - aramadia
解决方案在于更改判断条件。判断条件应该关注查找makefile以及从makefile中期望的输出(比如可执行文件的名称)。但当然,这对您来说并没有什么帮助。 - wilhelmtell
6
我的建议:使用类似于VC 2015的/E编译选项,只执行预处理器。它的工作原理是:生成一个 .cpp 文件,将项目中的所有 .cpp 文件(不包括 .h 文件!)包含在内,例如: #include "a.cpp" #include "b.cpp" ... 然后使用 /E 选项编译这个单独的 .cpp 文件。结果(stdout)是一个包含整个项目的单个 .cpp 文件。虽然不太方便且输出结果并不美观,但却有效。 - mdew
这个问题看起来像是 https://dev59.com/k3RB5IYBdhLWcg3wtZIV 的重复。 - starball
这个回答解决了你的问题吗?#将所有.cpp文件包含到单个编译单元中? - starball
8个回答

12
我也需要这个代码来参加编程比赛,确切地说是Codingame。所以我写了一个快速的JavaScript脚本来完成这个技巧。你可以在这里找到它: https://www.npmjs.com/package/codingame-cpp-merge 我在一次现场比赛和一次离线游戏中使用它,从未产生错误结果。欢迎提出建议或在Github上提交拉取请求!

1
通常情况下,您不能这样做。虽然您可以将头文件的内容粘贴到相应的#include位置,但通常情况下,您不能简单地连接源文件。首先,您可能会在具有文件作用域的事物之间遇到命名冲突。而且,考虑到您将每个头文件(包括类定义等)复制粘贴到每个源文件中,您最终会得到多次定义的类。
有更好的解决方案。正如已经提到的那样,为什么不在清除自动生成的对象文件等之后压缩整个项目目录呢?如果您真的必须要一个单独的源文件,那就写一个单独的源文件吧!

1

CIL 实用程序能够做到这一点:

$TIGRESS_HOME/cilly --merge -c x1.c -o x1.o
$TIGRESS_HOME/cilly --merge -c x2.c -o x2.o
$TIGRESS_HOME/cilly --merge -c x3.c -o x4.o
$TIGRESS_HOME/cilly --merge  --keepmerged x1.o x2.o x3.o -o merged --mergedout=merged.c

此处使用示例取自这里。请阅读有关CIL及其缺点的文档这里Tigress中提供了适用于Mac OS XLinux的二进制分发


1

嗯,这是可能的,我见过很多项目将源文件合并为单个.h和.c/.cpp文件,比如sqlite。

但是代码必须有一些限制,例如您不应该在其中一个源代码中具有静态全局变量。

可能没有通用的工具来合并源代码。您应该根据自己的代码编写一个。

以下是一些示例:

gaclib源包工具


0

我刚找到了一个非常适合我的 npm 包,它正好符合我的需求:cpp-merge

我提供链接: https://www.npmjs.com/package/cpp-merge

安装方法: npm install -g cpp-merge

使用方法: cpp-merge file.cpp

这将创建一个包含在 file.cpp 的所有指定文件#include "library.cpp"的合并文件。

此外,值得一提的是,它默认输出到标准输出。如果要将其写入文件,可以执行以下操作:

cpp-merge --output output.cpp

欲了解更多详细信息,请查看文档!


0

我认为带有头文件和源文件的项目比只有一个主文件的项目更好。不仅更容易处理和阅读,而且它们表明您在分离程序模块方面做得很好。

由于你的解决方案,我提供了这个格式,我认为你需要手工完成:

// STL headers


// --- prototype
// monster.h

// prince.h

// --- implementation

int main() { 
// your main function
return 0;
}

我同意,cpp文件仅用于提交。我有多个文件的原因是因为这样更容易理解和编辑,但最终输出必须是一个单独的cpp文件。 - aramadia

-2

我不知道有没有一个工具可以将.cpp文件合并在一起,但是我会把所有的文件压缩成一个gzip文件然后发送。


编程比赛不是这样运作的。 - xigoi

-3

如果您选择发送单个文件而不是压缩存档(例如tarball或zip文件),则可能需要考虑一些事情。

首先,像Thomas Matthews已经提到的那样将文件串联在一起。通过一些修改,您通常可以编译一个文件。删除不存在的#include语句,例如现在已包含的头文件。

您还必须按照它们各自的依赖关系顺序将这些文件连接在一起。也就是说,如果a.cpp需要在b.hpp中声明的类,则您很可能需要按照Thomas Matthews列出的顺序串联。

话虽如此,我认为共享代码的最佳方式是通过公共存储库,例如GitHub.comcompressed archive


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接