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
(将可执行二进制代码反汇编成汇编代码)
-------------------------------------
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
(将可执行二进制代码反汇编成汇编代码)