一、GCC
//test.c
#include <stdio.h>
#include <stdlib.h>
void main()
{
printf("GCC is a strong tool ");
return;
}
程序编译过程如下图:
**
使用命令表示过程如下:
gcc -o test test.c
**
这条命令告诉GCC对源程序test.c进行编译和链接,并使用参数-o创建名为test的可执行程序。这条命令实际上可细分为三个步骤:
1) 预编译
在命令行键入命令。
gcc -o test1.c -E test.c
这条命令告诉GCC对源程序test.c进行预编译,预编译结果输出到test1.c文件中。
2) 编译
gcc -o test.o -c test1.c
这条命令告诉GCC对源程序test.c进行编译,但不链接,编译输出到test.o文件中。
3) 链接
gcc -o test test.o
这条命令告诉GCC对源程序test.o进行链接,生成可执行程序test。
GCC 编译选项
-o filename 输出文件名,如果没指定filename,默认为a.out
-c 只编译,不链接
-E 预编译
-g 包含调试信息
-l 链接指定的库文件
-O 优化编译后的代码
-w 关闭所有告警信息
-Wall 开启所有告警信息
GCC 辨识文件扩展名
c—->C语言源文件
cpp—-> C++源文件
s —->汇编语言源文件
o—-> 编译后的目标代码文件
a,so—-> 编译后的库文件
GCC 默认只链接C的标准库,并不链接C++标准库
gcc -o test test.cpp(编译报错)
gcc –lstdc++ -o test test.cpp
二、Make
为什么需要make指令?
1.任何一个商业项目都会包含多个源代码,这样需要的编译与链接指令就会很多。同时编译生成的中间目标文件也会太多,衔接过程会非常不方便。
2.make是一种控制编译或者重复编译软件的工具。
3.make可以自动管理软件的编译内容、方式和时机,从而使程序员把更多的精力集中在编写代码上。
注:在windows 下,.lib文件就是将这些中间文件打包而成的库文件,linux下,打包而成的库文件为.a文件。
make指令工作原理
makefile是一个文本形式的脚本文件,其中包含一些规则告诉make编译哪些文件,怎么样编译以及在什么条件下编译。
makefile文件规则遵循以下通用形式
target:dependency [dependency[…]]
command
command
[…]
每个command第一个字符必须是tab键,而不是空格键,不然make会报错并停止。
eg1:最简单的一个makefile文件
1.vi makefile
2.内容如下:
start:
gcc -o test test.c
3.输入make,makefile文件将会被执行
eg2:稍微复杂的makefile,内容如下:
start:test .o
gcc -o test test .o
test .o:
gcc -o test .o -c test .c
target start后面的test .o代表其下的command依赖与test .o这个target。所以make先执行了test .o这个target下的command
eg3:进一步完善的makefile,内容如下:
start:test.o
gcc -o test test .o
test .o:
gcc -o test .o -c test .c
clear:
rm -rf hello.o
增加了target clear。
输入make clear,make会直接执行clear其下的command
eg4:在makefile执行shell命令:
start:test.o
gcc -o test test.o
@echo '---------------success---------------'
test .o:
gcc -o test .o -c test .c
clear:
rm -rf test .o增加了target clear
注:前面加@符号,为了不将echo本身输出。
eg5:在makefile使用变量(约定大写表示),varname=some_text
引用变量:$(varname)
CC=gcc
start:test.o
$(CC) -o test test.o
@echo '---------------ok---------------'
test.o:
$(CC) -o test.o -c test.c
clear:
rm -rf test.o
eg6:在makefile使用变量(约定大写表示),varname=some_text
引用变量:$(varname)
CC=gcc
SRCS=test.c
OBJS=test.o
EXEC=test
start:$(OBJS)
$(CC) -o $(EXEC) $(OBJS)
@echo '---------------ok---------------'
$(OBJS):
$(CC) -o $(OBJS) -c $(SRCS)
clear:
rm -rf $(OBJS)
eg7: 使用模式规则
.SUFFIXES:.c .o 表示任何x.c文件与x.o关联
.c.o:表示make定义了一条规则,任何x.o文件都从 x.c编译而来
所以OBJS=
(SRCS:.c=.o),意思是将SRCS变量中的.c替换为.omakefile文件内容如下:CC=gccSRCS=test.cOBJS=
(SRCS:.c=.o)
EXEC=test
start:$(OBJS)
$(CC) -o $(EXEC) $(OBJS)
@echo '---------------ok---------------'
$(OBJS):
$(CC) -o $(OBJS) -c $(SRCS)
clear:
rm -rf $(OBJS)
eg8:使用自动变量与模式规则的makefile文件
make定义了一些有用的预定义变量
$@ 规则的目标所对应的文件名
$< 规则中的第一个相关文件名
makefile 文件如下:
.SUFFIXES:.c .o
CC=gcc
SRCS=test.c //这里可以添加其他.c文件
OBJS=$(SRCS:.c=.o)
EXEC=test
start:$(OBJS)
$(CC) -o $(EXEC) $(OBJS)
@echo '---------------ok---------------'
.c.o:
$(CC) -o $@ -c $<
clear:
rm -f $(OBJS)
三、GDB
gcc -g –o hello hello.c
-g选项就可以在生成的目标代码中添加调试信息。
启动gdb
gdb 程序名 [corefile]
corefile是可选的,但能增强gdb的调试能力。
Linux默认是不生成corefile的,需要手动操作
步骤1:cd //什么都不加,表示回到当前用户的宿主目录
步骤2:ls -al ,vi .bashrc,修改文件在文件的末尾处 添加 ulimit -c unlimited
步骤3:修改完.bashrc文件后记得 . .bashrc 让修改生效
调试方法一:通过gdb 查看core文件信息
gdb hello core //quit 退出gdb
如果你不喜欢一大堆的软件信息,可以通过-q参数关闭软件信息
gdb -q hello core
可以看到gdb通过core告诉你,程序哪条语句出现问题
调试方法二:通过gdb 运行程序1. gdb hello
2.run 命令查看出差信息