我在 debian 系统中使用 gcc 编译 C 代码。通常,我会使用 gcc file.c -o file.out。但我错误地输入了 gcc file.c -o file.o 。
当,运行 ./file.o 它仍然有效!
这个.o文件是什么,和.out一样吗?
Pau*_*mer 11
按照惯例,.o后缀是object代码。GCC等编译器在编译的时候,其实要经过几个步骤。在高层次上,它看起来像这样**:
#define和#include以及其他#...宏。这一步很少输出到文件 - 它几乎普遍直接传递到下一步。** 是的,这是一个简化的视图,省略了优化、调试符号、剥离、库链接和其他一些步骤,但这些也可以被视为编译过程中的子步骤。
按照惯例:
.c和.h .cpp和.hpp或.c++和.h++.o. .f. .as。.a位于 UNIX 和.libWindows 上.so位于 UNIX 和.dllWindows 上.exeWindows上通常没有扩展名,但对于a.out未指定输出名称的链接 C 和 C++ 程序有一个默认值。以上没有任何理由或要求,除了这是自 70 年代以来所做的事情以及程序员所期望的。
.o文件是由编译器从源代码编译的目标文件。这些是原始二进制文件,尚未与任何平台相关库链接。你不能只.o在你的系统上运行一个文件。
gcc -c program.c
Run Code Online (Sandbox Code Playgroud)
(注意-c flag是告诉编译器只编译。)
将生成一个二进制文件program.o,您不能立即在您的平台上运行。您需要将它与crt objects, 和dynamic libraries平台链接。
对于我的 linux 系统。
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o program.o -lc /usr/lib/x86_64-linux-gnu/crtn.o
Run Code Online (Sandbox Code Playgroud)
现在这将创建一个可执行文件a.out,您可以直接从控制台执行该文件。
但是当你跑步时
gcc program.c
Run Code Online (Sandbox Code Playgroud)
编译器为您执行链接部分并吐出一个a.out可执行文件。
结论:编译器.o通过编译源代码生成目标文件,然后需要与平台的目标文件和库链接以生成该.out平台的可执行目标文件,这个过程称为链接。
一些参考资料:[1] https://en.wikipedia.org/wiki/A.out
[2] https://en.wikipedia.org/wiki/Crt0
[3] https://en.wikipedia.org/ wiki/Object_file
[4] http://man7.org/linux/man-pages/man8/ld.so.8.html
编辑: -o 标志用于将编译器的输出放在指定的文件中。这是手册的摘录。
-o文件
将输出放在文件file 中。这适用于正在生成的任何类型的输出,无论是可执行文件、目标文件、汇编程序文件还是预处理的 C 代码。
Run Code Online (Sandbox Code Playgroud)If -o is not specified, the default is to put an executable file in a.out, the object file for source.suffix in source.o, its assembler file in source.s, a precompiled header file in source.suffix.gch, and all preprocessed C source on standard output.
扩展名在这里并不重要。
类 UNIX 操作系统的文件系统不会将扩展元数据与文件名的其余部分分开。点字符只是主文件名中的另一个字符。它主要面向人类用户。更常见的是,尤其是在二进制文件中,文件本身包含描述其内容的内部元数据。
如果 .o 和 .out 或任何扩展文件来自相同的编译操作,它们都将包含相同的二进制输出。