GCC、GDB、makefile


GCC

  • -I 用于指定包含文件的路径(比如头文件)
  • -L 包含库的路径
  • -l 指定库名
  • -o 生成目标文件
  • -c 编译成.o文件
  • -g 在目标文件中加入源码,不加-g无法进行调试
  • -Wall 显示更过警告
  • -D 指定宏编译
  • -lstdc++ 编译C++代码
  • -O 优化选项 1-3越高,优先级越高
gcc -Wall hello.c -o hello
gcc -c hello.s -o hello.o
gcc add.c -I ./include/
gcc add.c -D DEBUG -o app -g
gcc hello.cpp -lstdc++ -o helloapp
gcc add.c -D DEBUG -o app -g -Wall -O2

静态库

静态库文件命名:libxxx.a

  1. 先编译成.o文件
  2. 将.o文件打包: ar rcs libxxx.a xxx.o xxx2.o
  3. 将头文件与库文件一起发布
gcc -c add.c sub.c -I ./Include/ 
# gcc -c *.c -I ./Include/
ar rcs libCalc.a *.o
nm libCalc.a			#nm查看文件内容
gcc main.c -o app -I ./Include/ -L lib/ -lCalc		#使用静态库

动态库

  1. 编译与位置无关的代码(加一个-fPIC参数),生成.o文件
  2. 将.o文件打包:关键参数-shared
  3. 将头文件与库文件一起发布
gcc -fPIC -c *.c -I ./Include/
gcc -shared -o libCalc.so *.o
gcc main.c -o app -I Include/ -L lib/ -lCalc
ldd app			#检查链接
#配置/etc/ld.so.conf文件,在该文件中添加动态库的绝对路径
sudo vim /etc/ld.so.conf
sudo ldconfig -v		#使配置文件生效

GDB

编译的时候加-g参数才可以使用gdb

  • 启动 gdb: ***gdb app [-p 进程号] *** #加上-p 进程号,可以调试正在运行的程序
  • gdb中执行程序:run 12 7 #直接执行一遍,12 7是两个参数
  • gdb中启动程序:start #在main上暂停,按n进行下一步
  • 单步调试:next(n) #不会进入函数内部
  • 单步调试:step(s) #和start类似,但是可以进入到函数内部
  • 退出gdb:quit(q)
  • 设置启动参数: set args 10 6 #10 6 是两个参数
  • 设置变量的值:set var 变量名 = 值
  • 显示主函数文件的代码:list(l) #func.c:1 #默认显示10行,按回车显示下10行,func.c:1表示显示func.c文件,从第一行开始显示
  • 设置断点:break(b)17 #17代表行号, break sum #在sum函数处设置断点,break func.c:6 #在func.c文件的第6行设置断点
  • 查看断点:info(i) break(b)
  • 删除断点:delete(d) 3 #3表示断点编号
  • 跳到下一个断点:continuing©
  • 打印变量或者数据结构的值:print§ argc #argc是变量
  • 查看变量类型:ptype argc
  • 跟踪变量的值:display argc #每执行一步,就打印一遍argc的值
  • 放弃跟踪变量:undisplay 3 #3是编号
  • 显示源码和汇编代码:layout split
  • 查看函数调用栈:bt
  • 程序挂掉时,系统缺省不会生成core文件,使用:ulimit -a 系统(非gdb)命令查看系统参数,使用:ulimit -c unlimit 把core文件的大小设置为无限制。
  • 调试core文件:gdb [可执行程序名] [core文件名]
  • 调试子进程:set follow-fork-mode child,默认调试父进程。
  • 设置调试模式:set detach-on-fork [on|off] 缺省是on表示调试当前进程的时候,其他的进程继续运行,如果使用off,调试当前进程的时候,其他的进程被gdb挂起。
  • 查看调试的进程:info inferiors
  • 切换当前调试的进程:inferior 进程id
  • 查看当前运行的线程 ps -aL | grep book
  • 查看主线程和子线程的关系:pstree -p 主线程id
  • 查看当前线程gdb:info threads
  • 切换线程:*** thread 线程id***
  • 只运行当前线程/全部的线程:set scheduler-locking on|off
  • 指定某线程/全部线程执行某gdb命令:thread apply 线程id/all cmd

makefile

命名规则

makefile或者Makefile

三要素

目标
依赖
规则命令

写法

目标:依赖
tab键 规则命令
makefile文件书写
app:main.c add.c sub.c div.c mul.c
		gcc -o app -I ./include main.c add.c sub.c div.c mul.c  #include文件夹中有头文件,终端执行:make 生成app文件

缺点如果更改其中一个文件,所有的源码都重新编译

第一次改进

如果依赖文件比目标文件新,则重新生成目标文件。

app:main.o add.o sub.o div.o mul.o
	gcc -o app -I ./include main.o add.o sub.o div.o mul.o  #include文件夹中有头文件

main.o:main.c	#依赖是可以递推的,app依赖main.0,main.o依赖main.c
	gcc -c main.c -I ./include
add.o:add.c	
	gcc -c add.c -I ./include
sub.o:sub.c	
	gcc -c sub.c -I ./include
mul.o:mul.c	
	gcc -c mul.c -I ./include
div.o:div.c	
	gcc -c div.c -I ./include

第二次改进

objFiles=main.o add.o sub.o div.o mul.o #定义objFiles变量为依赖文件

app:$(objFile) #变量用法
	gcc -o app -I ./include main.o add.o sub.o div.o mul.o  #include文件夹中有头文件

main.o:main.c	#依赖是可以递推的,test依赖main.0,main.o依赖main.c
	gcc -c main.c -I ./include
add.o:add.c	
	gcc -c add.c -I ./include
sub.o:sub.c	
	gcc -c sub.c -I ./include
mul.o:mul.c	
	gcc -c mul.c -I ./include
div.o:div.c	
	gcc -c div.c -I ./include

makefile的隐含规则默认处理第一个目标

第三次改进

函数:
	wildcard 可以进行文件匹配
    patsubst 内容替换

变量(=变量替换,:=常量,+=追加):
	$@ 代表目标
    $^ 代表全部依赖
    $< 代表第一个依赖
    $? 代表第一个变化的依赖
SrcFiles=$(wildcard *.c)				#获取当前目录所有的.c文件
objFiles=$(patsubst %.c,%.o,$(SrcFilies)) #把.c文件换成.o文件
cc:=gcc

 #定义伪目标,防止有歧义
.PHONY:clean all
all:app

app:$(objFiles) #变量用法
	$(cc) -o $@ -I ./include $(objFiles)  #include文件夹中有头文件
	
#模式匹配规则,$@,$<等只能在规则中出现,%代表任意一个,*代表所有
%.o:%.c
	$(cc) -o $@ -c $< -I ./include	
	
test:	#依赖和规则可以不写,目标必须写
	echo $(SrcFiles)
	
clean:
  	-@rm -f *.o  #@在规则前代表不输出该条规则的命令,-在规则前代表该条规则报错任然执行
  	rm -f app

终端输入 make默认编译第一个目标,make test 编译指定的test目标

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值