gcc是进行C程序开发不可或缺的编译工具。gcc是GUN C
Compile的缩写,它是在GUN/Linux系统下的标准C编译器
最常见的格式是:gcc -c filename.c,默认是生成一个
a.out的可执行文件名
gcc基本格式:gcc [options] [filenames]
option指定的操作对给定的文件filenames进行编译处
理
gcc常见的选项
-c 只对文件进行编译和汇编,但不进行连接
-S 只对文件进行编译,但不汇编和连接
-E 只对文件进行预处理,但不编译汇编和连接
-o 将文件编译成可执行文件
-l 用来指定所使用的库文件
-I 为include文件的搜索指定目录
-w 禁止警告信息
-Wall 显示附加的警告信息
-g 显示排错信息以便用于gdb
-O(-O1) 对编译出的代码进行优化
-O2 进行比-O高一级别的优化
-O3 产生更高级别的优化
-v 显示gcc版本
-c:gcc 只把源代码.c文件编译成目标代码.o文件,但跳
过了汇编和连接两步,生成.o的文件
-S:gcc 在为C 程序文件产生了汇编语言文件后停止编译
,产生的汇编语言文件,生成.s的文件
gcc -S file.c
-E:指示编译器只对输入的文件进行预处理不会存放在文
件里面,但是用下面的方式可以实现存取预处理文件
gcc -E file.c -o file.i
-g:生成可调试的目标代码,下面用例子告诉大家如何去
找到Segmentation fault出错的地方
demo1.c代码:
#include <stdio.h>
int main(void)
{
int a;
scanf(“%d”,a);
printf(“%d\n”,a);
return 0;
}
找错步骤:
1.gcc –Wall –o demo1 demo1.c
2../demo1
3.gcc –ggdb3 –Wall –o demo1 demo1.c
4.ulimit –c unlimited //编译允许使用存储信息
5../demo1
6.gdb demo1 core
7.run
8.bt
-I:gcc 将使用默认的路径,去查找和使用头文件和库文
件。如果出现特出情况不在指定目录下,这时可以使用
-I 和-L 选项
gcc –I/usr/include –o demo1 demo1.c
gcc –L/usr/X11R6/lib –Wall –o demo1 demo1.c
-l:程序中连接库可以使用-l 选项,这个库可以是静态
的,也可以是共享
gcc –Wall –o demo1 demo1.c –lm //m(makefile)
–pipe:gcc 能建立适当的管道
管道实现的是使管道前的输出成为管道后的输入。通过
使用管道,可以同时调用多个程序,一个程序的输出作
为输入直接送给另外一个程序,而且还可以一直连续下
去,不需要临时文件。
gcc编译流程
将源代码变成可执行文件的过程中,需要经过许多中间
步骤,包含预处理、编译、汇编和连接
预处理器 cpp
GUN汇编器 as
GUN连接器 ld
演示一个优化的 例子:
#include <stdio.h>
int main(void)
{
int counter;
int ending;
int temp;
int five;
for(counter=0;counter<2*100000000*9/18+5131;
cunnter+=(5-3)/2)
{
temp=counter/15302;
ending=counter;
five=5;
}
printf(“five=%d;ending=%d\n”,fivev,ending);
return 0;
}
gcc -o demo3 demo3.c
time ./demo3
gcc -o1 -o demo31 demo3.c
time ./demo31
gcc -o2 -o demo32 demo3.c
time ./demo32
gcc -o3 -o demo33 demo3.c
time ./demo33
动态链接库通常以.so结尾
静态链接库通常以.a结尾
两者的差别仅在于程序执行时所需的代码是在运行时动
态加载的,还是在编译时静态加载的。默认情况下,gcc
在链接时优先使用动态链接库,只有当动态链接库不存
在时才考虑使用静态链接库。如果需要的话可以在编译
时加上-static选项,强制使用静态链接库。
静态链接库:
ar:归档工具
有一些参数:
-r:插入一个新的模块到文件里面,或者替换现有的文
件
-v:用来显示执行操作的附加信息
-t:查看已经生成文件的信息
-d:删除库文件中的成员
-x:提取目标文件到当前目录
gcc -c demo1.c
ar -rv demo1.a demo1.o
ar -t demo1.a
ar -d demo1.a
gcc main.o -L. demo1.a -o demo1
//生成可执行的目标文件
rm demo1.a
动态链接库:
-shared:指定生成动态库
gcc -c addh.c
gcc -shared addh.o -o libaddh_2.so
gcc main.o -L. libaddh_2 -o addh_test
如何找到生成的动态库有2种方式:
1)把库拷贝到/usr/lib和/lib目录下。
(2)在LD_LIBRARY_PATH环境变量中加上库所在路径。
例如动态库libhello.so在/home/example/lib目录下:
$export
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/example/li
b
gdb调试器
gdb 是一个用来调试 C 和 C++程序的功能强大的调试器
,它能在程序运行时观察程序的内部结构和内存的使用
情况
gdb主要提供以下功能:
监视程序中变量的值的变化;
设置断点,使程序在指定的代码行上暂停执行,便于观察
单步执行代码;
分析崩溃程序产生的core文件
gdb filename
实例说明:
// test.c
#include <stdio.h>
int func(int n)
{
int sum=0,i;
for(i=0; i<n; i++)
{
sum+=i;
}
return sum;
}
main()
{
int i;
long result = 0;
for(i=1; i<=100; i++)
{
result += i;
}
printf("result[1-100] = %d \n", result );
printf("result[1-250] = %d \n", func(250) );
}
调试步骤:
1.编译生成执行文件
gcc –g test.c -o test
2.使用gdb调试
gdb test
3.键入 命令
(gdb) l//相当于list命令,列出代码
(gdb) break 16 //设置断点,在源程序第16行处。
(gdb) break func//设置断点,在函数func()入口处
(gdb) info break//查看断点信息。
(gdb) r //运行程序,run命令简写
(gdb) n //单条语句执行,next命令简写 ,step区
别
(gdb) c//继续运行程序,continue命令简写
(gdb) p i//印变量i的值,print命令简写。
(gdb) p sum
(gdb) bt//查看函数堆栈
(gdb) finish//退出函数。
(gdb) delete n//删除断点
(gdb) c//继续运行
(gdb) q//退出gdb。
(gdb) clear 要清除的断点所在的行号
使用 make
make是一个解释makefile文件中的指令的命令工具
makefile文件就像一个Shell脚本,其中也可以执行操作
系统的命令。makefile文件带来的好处是——“自动化编译
”,一旦写好,只需要一个make命令,就可自动编译整个
工程,极大地提高了软件开发的效率
makefile文件的操作规则是:
1.如果这个工程没有编译过,所有C文件都要编译并被连
接。
2.如果这个工程的某几个C文件被修改,只需编译被修改
的C文件,并连接目标程序。
3.如果这个工程的头文件被改变了,需要编译引用了这
几个头文件的C文件,并连接目标程序
格式:
target ... : prerequisites ...
command
...
...
target是一个目标文件,可以是Object 文件,也可以是
执行文件,还可以是一个标签(Label)
makefile实例:
makefile:
main:maintool.o mytool1.o mytool2.o
gcc -o main maintool.o mytool1.o mytool2.o
maintool.o:`maintool.c mytool1.h mytool2.h
gcc -c maintool.c
mytool1.o:mytool1.c mytool1.h
gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
gcc -c mytool2.c
make
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖
文件
main:maintool.o mytool1.o mytool2.o
gcc -o $@ $^
maintool.o:`maintool.c mytool1.h mytool2.h
gcc -c $<
mytool1.o:mytool1.c mytool1.h
gcc -c $<
mytool2.o:mytool2.c mytool2.h
gcc -c $<
注意:
1.第一行表示的是依赖关系。第二行是规则。
2.如果有多个文件需要换行就用反斜杠“\”
如:clean :
rm edit main.o kbd.o command.o
display.o \
insert.o search.o files.o utils.o
3.规则一定要以一个Tab键作为开头。
make如何执行自定义命令
clean :
rm edit main.o kbd.o command.o
display.o \
insert.o search.o files.o utils.o
make clean即可以执行上面的命令
在makefile文件中使用变量
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o
utils.o
gcc -o edit main.o kbd.o command.o
display.o \
insert.o search.o files.o
utils.o
通过上面的代码发现[.o]文件的字符串被重复了两次,
如果这个工程需要加入一个新的[.o]文件,需要在多个
位置插入,这样容易出错,为了解决此问题,可以用变
量,类似于c语言的宏定义。
上面的变量用变量表示后如下:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
gcc -o edit $(objects)