第一部分
示例
简单源文件编译
这个简单c文件用于输出 hello world!
经过发展 有一步到位的指令
gcc test.c -o test
但其实该编译经过了4个阶段(预处理、编译、汇编、连接)
编译展示:
预处理得道 test.i 文件
编译得到 test.s 文件
汇编得到 test.o 文件
最后连接得到 test 文件
运行test文件 ./test 运行输出 hello world!
多个源文件编译
常整个程序是由多个源文件组成的,相应的也就形成了多个编译单元,使用GCC能够很好的管理这些编译单元。假设有一个由test1.c和test2.c两个源文件组成的程序,为了对它们进行编译并最终生成可执行文件可使用命令:
gcc test1.c test2.c –o test
但如果同时处理的文件不止一个,g cc仍然会按照预处理,编译和链接的过程依次进行,如果深究起来。上面这条命令相当于依次执行下面三条命令:
gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o test
检错
gcc -pedantic illcode.c -o illcode
-pedantic 选项能够帮助程序员发现一些不符合ANSI/ISO C标准的代码,但不是全部。
源文件连接
编译成可执行文件
编译test.c文件为目标文件,这个时候需要执行
gcc -c -I /usr/dev/mysql/include test.c -o teest.o
最后我们把所有目标文件连接成可执行文件:
gcc -L /usr/dev/mysql/lib -lmysqlclient test.o -o test
第二部分
先创建一个test0工作目录,然后用文本编辑器生成一个C语言编写一个简单地hello.c程序为示例:
预处理
命令 gcc -E hello.c -o hello.i
将源文件hello.c预处理生成hello.i
Gcc 的选项-E使得Gcc在进行预处理后停止
hello.i文件可以作为普通文本打开查看 如下:
此为代码片段。
编译
使用gcc进行编译
gcc -S hello.i -o hello.s
将预处理生成的hello.i文件编译成hello.s
Gcc的选项-S使得Gcc在执行完编译后停止,生成汇编程序
hello.s也能打开查看 如下:
此为全部代码。
汇编
使用Gcc命令
gcc -c hello.s -o hello.o
将编译生成的hello.s文件汇编生成目标文件hello.o
Gcc的选项-c使得Gcc在执行完汇编后停止,生成目标文件。
或者直接使用as进行汇编
as -c hello.s -o hello.o
连接
使用命令 gcc hello.c -o hello
使用动态库进行连接,生成的ELF可执行文件的大小和连接的动态库如下
可以使用 size hello
查看大小
Idd hello
可以看出该执行文件连接了很多其他的动态库,主要是看Linux的glibc动态库
如果使用gcc -statuc hello.c -o hello
则会使用静态库进行连接,生成的ELF可执行文件的大小和连接的动态库如下所示
分析ELF文件
使用readelf -S hello
查看各个section的信息如下:
反汇编ELF 可使用 objdump -D hello
对其进行反汇编。