赞
踩
1.熟练使用规则编写简单的makefile文件
2.熟练使用makefile中的变量
3.熟练使用makefile中的函数
4.熟练掌握gdb相关调试命令的使用
5.了解概念:pcd和文件描述符,虚拟地址空间
6.熟练掌握Linux系统IO函数的使用
open
read
write
lseek
7.了解阻塞和非阻塞的概念
一次编写,终身受益
目标:依赖
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
如果更改其中一个文件,所有的源码都重新编译。
可以考虑编译过程分解,先生成.o文件,然后使用.o文件得到结果
规则是递推的:
依赖文件如果比目标文件新,则重新生成目标。
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
main.o:main.c
gcc -c main.c -I ./include
sub.o:sub.c
gcc -c sub.c -I ./include
div.o:div.c
gcc -c div.c -I ./include
add.o:add.c
gcc -c add.c -I ./include
mul.o:mul.c
gcc -c mul.c -I ./include
第二版本makefile
可以定义变量ObjFiles=main.o add.o sub.o div.o …
变量的使用:$ ( ObjFiles ),$ (变量名)
ObjFiles = main.o add.o sub.o div.o mul.o
app:$(ObjFiles)
gcc -o app -I ./include main.o add.o sub.o div.o mul.o
main.o:main.c
gcc -c main.c -I ./include
sub.o:sub.c
gcc -c sub.c -I ./include
div.o:div.c
gcc -c div.c -I ./include
add.o:add.c
gcc -c add.c -I ./include
mul.o:mul.c
gcc -c mul.c -I ./include
makefile的隐含规则:默认处理第一个目标
函数:
wildcard 可以进行文件匹配
patsubst 内容的替换
makefile的变量
第三版本makefile,使用函数wildcard,patsubst
# get all -c files
SrcFiles=$(wildcard *.c)
# all .c files --> .o files
ObjFiles=$(patsubst %.c,%.o,$(SrcFiles))
#目标文件用法:$(var)
app:$(ObjFiles)
gcc -o app -I ./include $(ObjFiles)
#模式匹配规则,S@,S<,这些变量,只能在规则中出现
%.o:%.c
gcc -c $< -I ./include -o $@
@在规则前代表不输出该条规则的命令
规则前的“-”,代表该条规则报错,仍然继续执行
第四版本makefile
可以指定编译目标make test
增加清理目标:clean
使用make clean清理工程
@在规则前代表不输出该条规则的命令
规则前的“-”,代表该条规则报错,仍然继续执行
# get all -c files SrcFiles=$(wildcard *.c) # all .c files --> .o files ObjFiles=$(patsubst %.c,%.o,$(SrcFiles)) #目标文件用法:$(var) app:$(ObjFiles) gcc -o app -I ./include $(ObjFiles) #模式匹配规则,S@,S<,这些变量,只能在规则中出现 %.o:%.c gcc -c $< -I ./include -o $@ test: echo $(SrcFiles) echo $(ObjFiles) clean: @rm -f *.o rm -f app
最终版makefile
定义伪目标:all
使用.PHONY,防止目标有歧义
# get all -c files SrcFiles=$(wildcard *.c) # all .c files --> .o files ObjFiles=$(patsubst %.c,%.o,$(SrcFiles)) all:app app1 #目标文件用法:$(var) app:$(ObjFiles) gcc -o app -I ./include $(ObjFiles) app1:$(ObjFiles) gcc -o app -I ./include $(ObjFiles) #模式匹配规则,S@,S<,这些变量,只能在规则中出现 %.o:%.c gcc -c $< -I ./include -o $@ test: echo $(SrcFiles) echo $(ObjFiles) .PHONY clean all clean: @rm -f *.o rm -f app
执行指定的makefile
1.使用gdb:编译的时候加-g参数
gcc func.c main.c -o app -I ./ -g
2.启动gdb:gdb app(对应可执行程序名)
3.在gdb启动程序
r(un) 启动
start 启动 -停留在main函数,分步调试
n(ext) 下一条指令
s(tep) 下一条指令,可以进入函数内部,库函数不能进
q(uit) 退出gdb
设置启动参数 set args 10 6
设置断点
b 行号----主函数所在文件的行
b 函数名
b 文件名:行号
l(ist)查看代码,默认显示10行
– l – 显示主函数对应的文件
– I 文件名:行号
删除断点,d(el)编号
查看断点i(nfo) b,得到编号
c(ontinue) 跳到下一断点
p(rint) 打印变量的值
ptype 打印变量的类型
set 设置变量的值
– set argc=4
– set argv[1]=“12”
– set argv[2]=“7”
display 显示变量的值,用于追踪,查看变量具体什么时候变化
undisplay 删除显示变量,查看编号
设置条件断点 b line if i == 1
4.gdb跟踪core
设置生成:core:ulimit -c unlimited
取消生成:core:ulimit -c 0
设置core文件格式:
系统函数调用:
文件描述符表:
查看 man 2 open
int open(const char *pathname,int flags);
int open(const char *pathname,int flags,mode_t mode);
pathname 文件名
flags
必选项:
O_RDONLY 只读
O_WRONLY只写
O_RDWR 读写
可选项:
O_APPEND 追加
O_CREAT 创建文件
– O_EXCL 与O_CREAT一起使用,如果文件存在,则报错
– mode权限位,最终(mode& ~umask)
O_NONBLOCK 非阻塞
返回值:返回最小的可用文件描述符,失败返回-1,设置errno
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include<fcnt1.h> #include<unistd.h> int main(int argc,char *argv[]) { if(argc!=2) { printf("./a.out filename\n"); return -1; } int fd = open(argv[1],O_RDONLY|O_CREAT,0666); close(fd); return 0; }
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include<fcnt1.h> #include<unistd.h> int main(int argc,char *argv[]) { if(argc!=2) { printf(“./a.out filename\n”); return -1; } int fd=open(argv[1],O_RDONLY); //读,输出到屏幕 char buf[256]; int ret = read(fd,buf,sizeof(buf)); write(STDOUT_FILENO,buf,ret); //改进:循环读取,读到0结束 close(fd); return 0; }
需求:打开一个文件,写入内容:helloworld,然后读取一下该文件的内容,输出
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include<fcnt1.h> #include<unistd.h> int main(int argc,char *argv[]) { if(argc!=2) { printf(“./a.out filename\n”); return -1; } int fd=open(argv[1],O_RDWR|O_CREAT,0666); write(fd,"helloworld",11); //文件读写位置此时到末尾 //需要移动读写位置 lseek(fd,0,SEEK_SET); char buf[256]={0}; int ret = read(fd,buf,sizeof(buf)); if(ret) { write(STDOUT_FILENO,buf,ret); //STDIN_FILEND,STDERR_FILEEND } close(fd); return 0; }
lseek的作用:
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include<fcnt1.h> #include<unistd.h> int main(int argc,char *argv[]) { if(argc!=2) { printf(“./a.out filename\n”); return -1; } //1.open int fd=open(argv[1],O_RDONLY); //2.lseek,得到返回值 int ret = lseek(fd,0,SEEK_END); printf("file size is %d\n",ret); //3.close(fd); close(fd); return 0; }
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include<fcnt1.h> #include<unistd.h> int main(int argc,char *argv[]) { if(argc!=2) { printf(“./a.out filename\n”); return -1; } //1.open int fd=open(argv[1],O_WRONLY|O_CREAT,0666); //2.lseek,拓展文件 int ret = lseek(fd,1024,SEEK_END); //需要至少写一次,否则不能保存 write(fd,"a",1); //3.close(fd); close(fd); return 0; }
阻塞的概念:
read函数在读设备或者读管道,或者读网路的时候
输入输出设备对应/dev/tty
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<fcnt1.h> #include<string.h> #include<sys/types.h> int main(int argc,char *argv[]) { //O_NONBLOC将设备的阻塞状态改成非阻塞 int fd = open("/dev/tty",O_RDWR|O_NONBLOCK); char buf[256]; int ret = 0; while(1) { ret = read(fd,buf,sizeof(buf)); if(ret<0) { perror("read err:"); printf("ret is %d\n",ret); } if(ret) { printf("buf id %s\n",buf); } printf("haha\n"); sleep(1); } close(fd); return 0; }
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<fcnt1.h> #include<string.h> #include<sys/types.h> int main(int argc,char *argv[]) { //O_NONBLOC将设备的阻塞状态改成非阻塞 //int fd = open("/dev/tty",O_RDWR|O_NONBLOCK); int fd = open("/dev/tty",O_RDWR); //fcnt1()函数,设置非阻塞 int flags = fcnt1(fd,F_GETFL); flags|=O_NONBLOCK; fcnt1(fd,F_SETFL,flags); char buf[256]; int ret = 0; while(1) { ret = read(fd,buf,sizeof(buf)); if(ret<0) { perror("read err:"); printf("ret is %d\n",ret); } if(ret) { printf("buf id %s\n",buf); } printf("haha\n"); sleep(1); } close(fd); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。