示例程序如下:
//test.c
#include
int main(void)
{
printf("hello word!\n");
return 0;
}
一步到位的编译指令是:
gcc test.c -o test
运行结果如下:
实质上,上述编译过程分位四个阶段进行,既预处理,编译,汇编,连接
gcc -E test.c -o test.i
gcc -c test.s -o test.o
gcc -c test.s -o test.o
gcc test.o -o test
运行代码
./test
通常程序是由多个源文件组成的,相应的也就形成了多个编译单元,使用gcc能够很好的管理这些编译单元。
假设有一个由main1.c 和sub1.c 两个源文件组成的程序,,为了对它们进行编译,并最终生成可执行程序main1,可以使用下面这条命令:
gcc main1.c sub1.c -o main1
深究起来,上面这条命令大致相当于依次执行如下三条命令:
gcc -c main1.c -o main1.o
gcc -c sub1.c -o sub1.o
gcc main1.o sub1.o -o main1
gcc -pedantic illcode.c -o illcode
除了-padantic之外,gcc还有一些其他编译选项也能够产生有用的警告信息,这些选项大多以-W开头,其中最有用的当数-Wall ,它能够使gcc产生尽可能多的警告信息。
gcc -Wall illcode.c -o illcode
在编译程序时带上-Werror 选项,那么gcc会在使用产生警告的地方停止编译,如下:
gcc -Werror test.c -o test
gcc -c -I /usr/dev/mysql/include test.c -o test.o
gcc -L /usr/dev/mysql/lib -lmysqlclient test.o -o test
gcc -L /usr/dev/mysql/lib -static -lmysqlclient test.o -o test
C运行库
C语言标准主要由两部分组成,一部分描述c的语法,另一部分描述c标准库。
c标准库定义了一组标准头文件,每个头文件中包含一些相关的函数,变量,类型声明和宏定义,譬如常见的printf函数便是一个c标准库函数,其原型定义在stdio头文件中。
C语言标准仅仅定义了c标准库函数原型,并没有提供实现。因此,C语言编译器通常需要一个c运行时库的支持。c运行时库又常常简称为c运行库。与c语言类似,c++也定义了自己的标准,同时提供相关支持库,称为c++运行时库。
//test.c
#include
int main(void)
{
printf("hello word!\n");
return 0;
}
1、预处理
gcc -E hello.c -o hello.i
2、编译
gcc -S hello.i -o helo.s
3、汇编
gcc -c hello.s -o hello.o
4、链接
生成可执行文件
gcc hello.c -o hello
size hello //使用size查看大小
ldd hello //可以看出该可执行文件链接了很多其他动态库,主要是Linux的glibc动态库
如果使用命令
gcc -static hello.c hello
则会使用静态库进行连接,生成的ELF可执行文件的大小和链接动态库的对比如下所示:
size hello
ldd hello
说明没有链接动态库
readelf -S hello
2.反汇编ELF
objdump -D hello
使用objdump 将其反汇编并将其C语言源代码混合显示出来:
gcc -o hello -g hello.c
objdump -S hello