如何使用多个源文件通过gcc创建单个目标文件

问题描述 投票:11回答:9

我在g ++中使用-c选项来创建一堆目标文件,这只允许我为每个目标文件指定一个源文件。我希望其中有多个文件。有什么办法吗?

c++ object gcc g++
9个回答
12
投票

其他人提到archive,但另一个选择是Unity builds

而不是:

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所使用的标头仅被解析一次)。但是,如果将太多文件放在一个单元中,那么您将发现需要重建比所需数量更多的源,因此您需要尝试保持平衡。


6
投票

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

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

4
投票

您可以创建archive,它是一组目标文件。

archive

因此,有效地将ar mylib.a file1.o file2.o file1.cpp合并为file2.cpp


2
投票

您可以利用mylib.a命令创建供程序使用的存档。


1
投票

使用ar中的解决方案是我想到的主要解决方案。

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

此外,自行编译多个文件可以在现代CPU上使用各种内核:每个源文件将在其自己的进程中全速编译。不要滥用多核的功能。


1
投票

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


0
投票

我知道的唯一解决方案是创建一个单独的C ++文件,其中包括您要编译的所有文件,然后进行编译。我认为这是一个非常糟糕的解决方案;通常,您要增加目标文件的粒度,而不是减小粒度。

我想,真正的问题是您要实现什么。为什么只需要一个目标文件?


0
投票

从某种意义上讲,你不能。编译器一次只编译一个文件。当使用libtest.so或一个单个可执行文件或共享库为它提供文件列表时,它实际上会用一些临时输出文件(通常在-c或类似文件中)多次调用编译器,并且然后在事实之后将它们链接起来。

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

/tmp

您甚至可以在Makefile中自动生成此文件,但事实证明没有必要这样做,因为编译器非常乐意从tocompile.cpp -------------------- #include "file1.cpp" #include "file2.cpp" (标准输入)中读取。

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

-

[请注意,printf '#include "%s"\n' ./*.cpp | $CXX $CXXFLAGS -o combined.o -x c++ - 会告诉编译器输入的语言,通常会根据称为-xgcc或类似名称的编译器和文件名进行猜测,但是由于文件名是g++,我们必须指定。


-4
投票

我们使用-o选项来创建目标文件……默认情况下,当我们使用gcc或g ++编译文件时,我们得到的目标文件名为a.out,但是我们可以更改其名称...。使用以下命令编译文件

gcc Filename.c -o NewFilename.out

然后运行文件,您可以使用./NewFilename.out

© www.soinside.com 2019 - 2024. All rights reserved.