GCC编译过程

GCC编译过程
-------------------------------------
    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 <stdio.h>
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
(将可执行二进制代码反汇编成汇编代码)
  网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)