这么重要的东西以前自己既然没怎么注意, 就知道这样用就可以了,但好多好多的gcc功能我们基本没有使用。 今天来学习一部分。
GCC能够处理的后缀有:
a>. *.c *.C (C语言)
b>. *.cxx *.cc (C++语言)
c>. *.m (面向对象的C)
d>. *.i (预处理后的C语言源文件)
e>. *.ii (预处理后的C++语言源文件)
f>. *.s *.S (汇编语言)
h>. *.h (头文件)
编译器把编译生成目标代码的任务分为以下4步:
a>. 预处理,把预处理命令扫描处理完毕;
b>. 编译,把预处理后的结果编译成汇编或者目标模块;
c>. 汇编,把编译出来的结果汇编成具体CPU上的目标代码模块;
d>. 连接,把多个目标代码模块连接生成一个大的目标模块;
简单的事例:
a>. 预处理, gcc -E test.c -o test.i
b>. 编译, 编译后生成汇编语言文件*.s gcc -S test.i -o test.s
c>. 汇编, 将输入的汇编文件*.s转换成机器语言*.o gcc -c test.s -o test.o
d>. 连接, 在连接阶段将输入的机器代码文件*.o(与其它的机器代码文件和库文件)汇集成一个可执行的二进制代码文件
gcc test.o -o test
下面有一篇GCC编译过程学习一下:
http://hi.baidu.com/zengzhaonong/blog/item/8a887106d9ec8b780208819a.html-------------------------------------
Pre-Processing cpp 预处理
Compiling ccl 编译
Assembling as 汇编
Linking ld 链接
命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(#include)、预编译语句(如宏定义#define等)进行分析。
当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是链接。在链接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的库中链接到合适的地方。
ld -- The GNU linker
-l LIBNAME, --library LIBNAME Search for library LIBNAME(默认情况下会去链接动态共享库,如果有-static参数时将会去静态共享库进行静态链接)
-static Do not link against shared libraries(静态链接共享库).
.c 为后缀的文件,C语言源代码文件;
.a 为后缀的文件,是由目标文件构成的库文件;
.C、 .cc或.cxx为后缀的文件,是C++源代码文件;
.h 为后缀的文件,是程序所包含的头文件;
.i 为后缀的文件,是已经预处理过的C源代码文件;
.ii为后缀的文件,是已经预处理过的C++源代码文件;
.m 为后缀的文件,是Objective-C源代码文件;
.o 为后缀的文件,是编译后的目标文件;
.s 为后缀的文件,是汇编语言源代码文件;
.S 为后缀的文件,是经过预编译的汇编语言源代码文件。
# man gcc
-------------------------------------
If you only want some of the stages of compilation, you can use -x (or filename suffixes) to tell gcc where to start, and one of the options -c, -S, or -E to say where gcc is to stop. Note that some combinations (for example, -x cpp-output -E) instruct gcc to do nothing at all.
-E -Stop after the preprocessing stage; do not run the compiler proper. The
output is in the form of preprocessed source code, which is sent to the
standard output.
Input files which don’t require preprocessing are ignored.
-S -Stop after the stage of compilation proper; do not assemble. The output is in
the form of an assembler code file for each non-assembler input file
specified.
By default, the assembler file name for a source file is made by replacing
the suffix .c, .i, etc., with .s.
Input files that don’t require compilation are ignored.
-c -Compile or assemble the source files, but do not link. The linking stage
simply is not done. The ultimate output is in the form of an object file for
each source file.
By default, the object file name for a source file is made by replacing the
suffix .c, .i, .s, etc., with .o.
Unrecognized input files, not requiring compilation or assembly, are ignored.
例程
-------------------------------------
# vi hello.c
#include
int main(void)
{
printf ("Hello world, Linux programming!\n");
return 0;
}
编译
# gcc -E hello.c -o hello.i
# gcc -S hello.i
# gcc -c hello.s
# gcc hello.o -o hello
# ./hello
Hello world, Linux programming!
# gcc hello.o -o hello (动态链接)
# gcc -static hello.o -o hello.static (静态链接)
# ls -lh hello hello.static
-rwxr-xr-x 1 root root 6.6K 2007-10-31 14:03 hello
-rwxr-xr-x 1 root root 525K 2007-10-31 14:03 hello.static
# ldd hello
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e33000)
/lib/ld-linux.so.2 (0xb7f84000)
# ldd hello.static
not a dynamic executable
反汇编
# objdump -S hello > hello.s
(将可执行二进制代码反汇编成汇编代码)
阅读(2686) | 评论(0) | 转发(0) |