什么是* .o文件?


69

我正在编译自己的项目。它因此错误而停止运行:

LINK ||致命错误LNK1181:无法打开输入文件'obj \ win \ release \ src \ lua \ bindings.o'|

在Win7下使用Code :: Blocks与VS 2005/2008编译器进行编译。还有很多其他空目录,其中* .o文件丢失。

他们在做什么?


3
首先,“。o”文件是编译和链接之间的中间阶段。如果存在编译错误,VS 2008将不会生成“ .o”文件,但仍会继续尝试构建应用程序,在链接阶段之后失败。当心慌时,您可以随时尝试“全部重建”;但是,我建议研究错误日志以查找缺少的目标文件。
Thomas Matthews'2

Answers:


98

以.o结尾的文件是目标文件。在将每个源文件链接到最终可执行文件之前,编译器会为每个源文件创建一个目标文件。


1
嗯,这可能是什么原因?为什么编译器没有为所有需要的源制作目标文件?
Max Frai

1
编译器无法为没有的源创建目标文件。
Liz Albin

可能有很多原因。您很可能弄乱了一些内含物或弄乱了模板。也可能是某些链接器设置有误,但我对此表示怀疑:)
cwap 2010年

对于ocktonal:如果出现问题,管理较小的文件而不是一个巨大的目标文件可能更容易。
最多

@Ockonal,查看编译器的整个输出日志。当存在较早的编译错误导致文件无法转换为“ .o”(对象)文件时,Visual Studio 2008习惯于链接文件并尝试构建可执行文件。
Thomas Matthews'2

47

您已经得到了一些答案,并且大多数答案都是正确的,但是错过了(我认为)这可能是重点。

我的猜测是您有一个要用来创建可执行文件的makefile。如果您不熟悉它们,makefile会列出文件之间的依赖关系。对于一个非常简单的情况,它可能类似于:

myprogram.exe: myprogram.o
    $(CC) -o myprogram.exe myprogram.o

myprogram.o: myprogram.cpp
    $(CC) -c myprogram.cpp

第一行说myprogram.exe取决于myprogram.o。第二行告诉如何创建myprogram.exe myprogram.o。第三行和第四行分别myprogram.o取决于myprogram.cpp和如何myprogram.o从myprogram.cpp`创建。

我的猜测是,在您的情况下,您拥有一个类似于上面为gcc创建的makefile。您遇到的问题是您将其用于MS VC而不是gcc。碰巧,MS VC使用“ .obj”作为其目标文件的扩展名,而不是“ .o”。

这意味着,当make(或您的情况下,其等效功能内置到IDE中)尝试构建程序时,它将查看这些行以尝试确定如何构建myprogram.exe。为此,它认为需要构建myprogram.o,因此会寻找告诉它如何构建的规则myprogram.o。那就是说它应该编译.cpp文件,所以就可以了。

然后事情就崩溃了-VC ++编译器生成myprogram.obj而不是myprogram.o作为目标文件生成,因此,当它尝试进行下一步从中生成文件myprogram.exemyprogram.o,它发现创建创建的尝试myprogram.o只是失败了。它按照规则说的去做,但是没有实现myprogram.o承诺。它不知道该怎么办,因此它退出并给您一条错误消息。

解决该特定问题的方法可能非常简单:编辑make文件,使所有目标文件的扩展名为,.obj而不是.o。尽管这是否可以解决所有问题,但仍有很多疑问–这可能是您所需要的,或者仅仅是导致其他(可能更困难)的问题。


1
那么$(CC)是用于编译器的吗?
zygimantus

1
@zygimantus:是的。从理论上讲,它是C编译器,但至少在大多数情况下,C和C ++编译器是相同的二进制文件(根据要编译的文件的扩展名对语言进行排序)。
杰里·科芬

1
我将所有.o扩展名都替换为.obj,但现在发生了相同的错误:make (e=2): The system cannot find the file specified. make: *** [src/haproxy.obj] Error 2
doubleOrt

6

.o目标文件文件(在Windows上也是.obj)包含编译的目标代码(即,由C或C ++编译器生成的机器代码),以及文件包含的函数和其他对象的名称。目标文件由链接器处理以生成最终的可执行文件。如果您的构建过程未生成这些文件,则您的makefile / project文件可能存在问题。


2

重要的是要注意,目标文件可重定位的格式组装为二进制代码。这是一种格式,它允许将汇编的代码加载到内存中的任何位置,以供链接器与其他程序一起使用。

指向标签的说明尚未在.o文件中为这些标签分配地址。

这些标签将被写为“ 0”,并且汇编程序为这些未知地址创建一个重定位记录。当文件链接并输出到可执行文件时,未知地址将被解析,程序可以执行。

您可以在目标文件上使用nm工具列出.o文件中定义的符号。


0

喷墨是正确的。更具体地说,.o(.obj)或目标文件是编译为机器代码的单个源文件(我不确定“机器代码”是否与可执行机器代码相同或相似)。最终,它是可执行程序和纯文本源文件之间的中介。

链接器使用o文件来汇编文件可执行文件。

维基百科可能有更详细的信息。我不确定您想要或需要多少信息。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.