1.编译过程
程序的编译包括:预处理,编译,汇编,链接。
预处理:在C/C++源文件中,以#开头的的命令被称为预处理命令,例如#include包含的头文件,#define的宏定义,还有#ifdef条件编译,
预处理就是把include包含的文件插入到源文件中,将宏定义展开,根据条件编译命令选择要使用的代码,最后将这些代码输出到一个.i的文件中等待进一步处理。预处理一般使用gcc -E选项.
编译:把.i文件翻译成汇编代码。
汇编:汇编就是将汇编代码翻译成符合一定格式的机器代码,在linux系统上是elf格式的目标文件,hello.o中的.o其实就是object file的首写字母,一般成为obj文件。
链接:链接就是将前面生成的obj文件和系统库的obj文件、库文件链接起来,生成可执行文件。
crt1.o、crti.o、crtbegin.o、crtend.o、crtn.o是gcc加入的系统标准启动文件,
对于一般应用程序,这些启动是必需的。
gcc -v -nostdlib -o hello hello.o会提示因为没有链接系统标准启动文件和标准库文件,而链接失败。
这个-nostdlib选项常用于裸机/bootloader、linux内核等程序,因为它们不需要启动文件、标准库文件。
一般应用程序才需要系统标准启动文件和标准库文件。
裸机/bootloader、linux内核等程序不需要启动文件、标准库文件。
gcc -o hello_shared hello.o #生成动态库
gcc -static -o hello_static hello.o #生成静态库
小结:
- 输入文件的后缀和选项共同决定GCC到底执行哪些操作,
- 在编译过程中,除非使用了-E,-S,-c选项(或者编译出错,阻止了完整的编译过程),否则最后的步骤都是链接。
2.gcc常用命令选项
命令行中输入gcc --help 得到帮助信息,删掉不常用的选项,
Usage: gcc [options] file...
Options:
--help Display this information
-v Display the programs invoked by the compiler
-### Like -v but options quoted and commands not executed
-E Preprocess only; do not compile, assemble or link
-S Compile only; do not assemble or link
-c Compile and assemble, but do not link
-o <file> Place the output into <file>
gcc的使用方法是:gcc [选项] 文件名
gcc -v:用来查看gcc编译器的版本,显示gcc执行时的详细过程。
-o:指定输出文件的名字,例如gcc -o hello hello.c
-E:只预处理,不会编译、汇编、链接。例如gcc -E -o hello.i hello.c
-S:只编译,不汇编、链接。gcc -S -o hello.s hello.i
-c: 编译和汇编,不链接, gcc -c -o hello.o hello.s
3.三种编译方式
方式1:
gcc hello.c 输出一个a.out,然后./a.out来执行该应用程序。
gcc -o hello hello.c 输出hello,然后./hello来执行该应用程序。
方式2:
gcc -E -o hello.i hello.c
gcc -S -o hello.s hello.i
gcc -c -o hello.o hello.s
gcc -o hello hello.o
方式3:
gcc -c -o hello.o hello.c
gcc -o hello hello.o
gcc会对.c文件默认进行预处理操作,-c再来指明了编译、汇编,从而得到.o文件
再通过gcc -o hello hello.o将.o文件进行链接,得到可执行应用程序。