如何使用gcc使用多个源文件创建单个对象文件

How to use multiple source files to create a single object file with gcc

本文关键字:文件创建 单个 对象 文件 何使用 gcc      更新时间:2023-10-16

我使用g++的-c选项来创建一组对象文件,它只允许我为每个对象文件指定一个源文件。我想将多个文件放入其中一些文件中。有办法做到这一点吗?

其他人提到了归档,但另一个选择是Unity构建。

代替:

g++ -c file1.cpp file2.cpp

创建一个单独的"统一文件"

// This is the entire file (unity.cpp)
#include "file1.cpp"
#include "file2.cpp"
// more if you want...

然后

g++ -c unity.cpp

在许多情况下,这还具有更快的编译和链接的优点(因为file1.cppfile2.cpp使用的头只解析一次)。然而,如果你在一个统一中放置了太多的文件,那么你会发现你需要重建比你想要的更多的源,所以你需要尝试并取得平衡。

您可以使用ld -r组合对象,同时保留重新定位信息并使构造函数未解析:

ld -r -o everything.o object1.o object2.o ...

您可以创建archive,它是一组对象文件。

ar mylib.a file1.o file2.o

如此有效地将file1.cppfile2.cpp组合为mylib.a

您可以使用ar命令创建供程序使用的归档文件。

使用Peter Alexander的解决方案是我想到的主要问题。

但是,请记住,通过使用此方法,每次都必须编译整个源文件。当您的项目越来越大时,编译时间可能会变得很痛苦。

此外,单独编译几个文件可以使用现代CPU上的各种内核:每个源文件都将在自己的进程中全速编译。请勿过度使用多芯电源。

我知道您正在询问如何将.cpp文件合并为一个对象文件。我假设您这样做的目标是在以后将组合对象与其他单独的对象文件链接起来。如果是这种情况,您可以使用静态或动态库。为了您的目标,我建议使用动态库,因为您可以跳过对象文件的生成,只需执行一个编译和链接步骤。使用g++ -shared -fpic file1.cpp file2.cpp file3.cpp -o libtest.so之类的命令,可以将需要合并的.cpp文件合并到库中。要使用单独的对象文件编译库,请使用g++ -ltest individual1.o individual2.o individual3.o -o myexecutable等命令。在最后的链接步骤中,我假设libtest.so在您当前的目录中。如果它不在当前目录中,则添加-L标志,并且目录libtest.so在.

从某种意义上说,你做不到。编译器一次只编译一个文件。当你给它一个文件列表,或者用-c,或者变成一个单独的可执行文件或共享库时,它实际上会用一些临时输出文件(通常用/tmp或类似的文件)多次调用编译器,然后在事后链接它们。

因此,解决方案是只要求它编译一个文件。已经提到的是编写一个文件来编译

tocompile.cpp
--------------------
#include "file1.cpp"
#include "file2.cpp"

您甚至可以在Makefile中自动生成这个文件,但事实证明没有必要这样做,因为编译器很乐意从-(标准输入)中读取。

这意味着您可以简单地运行

printf '#include "%s"n' ./*.cpp | $CXX $CXXFLAGS -o combined.o -x c++ -

请注意,-x告诉编译器输入的语言是什么,通常它会根据调用的编译器(gccg++或类似)和文件名进行猜测,但由于文件名是-,因此我们必须指定。

在执行此操作时,假设您包含了整个项目,gcc中的-fwhole-program是减少生成的输出大小的好方法,请注意,要做到这一点,还需要列出所需的所有库。

我所知道的唯一解决方案是创建一个单独的C++文件,其中包括您想要编译的所有文件,并对其进行编译。在我看来,这是一个相当糟糕的解决方案;通常,您希望增加而不是减少对象文件的粒度。

我想,真正的问题是你想达到什么目的。为什么只想要一个对象文件?

我们使用-o选项来创建一个对象文件。。。。。。默认情况下,当我们使用gcc或g++编译文件时,我们会得到名为a.out的对象文件,但我们可以更改其名称。。。。使用以下内容编译文件

gcc Filename.c-o NewFilename.out

然后运行您可以使用的文件/新文件名.退出