我正在使用带有g ++的 -c 选项来创建一堆目标文件,它只允许我为每个目标文件指定一个源文件。我想让其中一些文件进入其中。有没有办法做到这一点?
答案 0 :(得分:11)
其他人提到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.cpp
和file2.cpp
使用的标头只被解析一次)。但是,如果你将太多文件放在一个统一中,那么你会发现你需要重建比你想要的更多的资源,所以你需要尝试取得平衡。
答案 1 :(得分:6)
您可以使用ld -r
组合对象,同时保留重定位信息并使构造函数保持未解析状态:
ld -r -o everything.o object1.o object2.o ...
答案 2 :(得分:4)
答案 3 :(得分:2)
您可以使用ar命令创建供程序使用的存档。
答案 4 :(得分:1)
使用Peter Alexander中的解决方案是我想到的主要解决方案。
但是,请记住,通过使用此方法,您每次都必须编译整个源文件。当你的项目变大时,编译时间会变得很痛苦。
此外,自行编译多个文件可以在现代CPU上使用各种内核:每个源文件都将在其自己的进程中全速编译。不要低估多核的功率。
答案 5 :(得分:1)
我知道你在询问如何将.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
在。
答案 6 :(得分:0)
我所知道的唯一解决方案是创建一个单独的C ++文件,其中包含您要编译的所有文件,并进行编译。在我看来,一个非常糟糕的解决方案;通常,您希望增加目标文件的粒度,而不是减少它。
我想,真正的问题是你想要实现的目标。为什么只需要一个目标文件?
答案 7 :(得分:0)
从某种意义上讲,你做不到。编译器一次只编译一个文件。当您使用-c
为其提供文件列表时,或者变成单个可执行文件或共享库时,它实际上会使用一些临时输出文件(通常在/tmp
或其他文件中)多次调用编译器。类似),然后在事实之后将它们链接起来。
那么,解决方案是只要求它编译一个文件。已经提到正在编写要编译的文件
tocompile.cpp
--------------------
#include "file1.cpp"
#include "file2.cpp"
您甚至可以在Makefile中自动生成此文件,但事实证明,无需这样做,因为编译器非常乐意从-
(标准输入)中读取内容。
这意味着您可以简单地运行
printf '#include "%s"\n' ./*.cpp | $CXX $CXXFLAGS -o combined.o -x c++ -
请注意,-x
告诉编译器输入的语言,通常会根据称为{gcc
与g++
或类似名称的编译器以及文件名进行猜测,但是由于文件名是-
,我们必须指定。
在执行此操作时,假设您要包含整个项目,则-fwhole-program
中的gcc
是减小生成的输出大小的一种好方法,请注意,要使其正常工作,还需要列出所有需要的库。
答案 8 :(得分:-4)
我们使用-o选项来创建一个目标文件......默认情况下,当我们使用gcc或g ++编译文件时,我们得到一个名为a.out的对象文件,但我们可以更改它的名称....使用以下编译文件
gcc Filename.c -o NewFilename.out
然后运行文件,你可以使用./NewFilename.out