• 2007-12-23

    gcc 做了些什么...

      可能大家都习惯了之间gcc -o hello hello.c 来生成hello,现在我要来说说gcc 到底给我们做了什么。

    1.  首先 gcc 会调用预处理器 cpp 来处理源程序 生成 hello.i,接着会调用编译器来生成hello.s

      接下去会条用 汇编器 as 来生成 hello.o ,最后调用连接器 ld 来生成可执行文件。

       以上就是gcc在处理一个源程序的时候流程

       hello.c-->hello.i-->hello.s-->hello.o-->hello 

     2.  不过如果你自己按照上面一步一步走,也许生成不了最后的hello,即使生成了可能也是不能执行的。因为gcc在这之中又为你做了很多,比如参数的调用,很多你可能都不知掉。不过你可以通过-v选现来打印出来。

       # gcc -v -o hello hello.c

       Using built-in specs.
    Target: i486-linux-gnu
    Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
    Thread model: posix
    gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
     /usr/lib/gcc/i486-linux-gnu/4.1.2/cc1 -quiet -v hello.c -quiet -dumpbase testobjectm.c -mtune=i686 -auxbase hello -version -o /tmp/cc6TFVwb.s
    ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
    ignoring nonexistent directory "/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../i486-linux-gnu/include"
    ignoring nonexistent directory "/usr/include/i486-linux-gnu"
    #include "..." search starts here:
    #include <...> search starts here:
     /usr/local/include
     /usr/lib/gcc/i486-linux-gnu/4.1.2/include
     /usr/include
    End of search list.
    GNU C version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) (i486-linux-gnu)
        compiled by GNU C version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21).
    GGC heuristics: --param ggc-min-expand=54 --param ggc-min-heapsize=46326
    Compiler executable checksum: 60ce5af9fc7eaad04f44a3c8fd96f438
     as -V -Qy -o /tmp/ccAZpP6e.o /tmp/cc6TFVwb.s
    GNU assembler version 2.17 (i486-linux-gnu) using BFD version 2.17 Debian GNU/Linux
     /usr/lib/gcc/i486-linux-gnu/4.1.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o hello /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.1.2/crtbegin.o -L/usr/lib/gcc/i486-linux-gnu/4.1.2 -L/usr/lib/gcc/i486-linux-gnu/4.1.2 -L/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib -L/lib/../lib -L/usr/lib/../lib /tmp/ccAZpP6e.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i486-linux-gnu/4.1.2/crtend.o /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../lib/crtn.o

     大家可以看到,gcc整个过程,生成临时文件,还有最后一个  /usr/lib/gcc/i486-linux-gnu/4.1.2/collect2 

     具体用途可以看gcc文档,有一点就是它会自动寻找ld,按照一定的优先顺序。

     3. 另外说几点参数

        gcc 可以通过 -Wl,option和 -Xlinker 来给linker传递参数。比如 -Wl --warn-common ,-Xlinker -z defs

      


    收藏到:Del.icio.us