makefile简单脚本编写和Linux调试器gdb的简单应用_linux make自动化测试脚本

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

mybin:main.c contact.c
  2   gcc main.c contact.c -o mybin
  3 
  4 .PHONY:clean
  5 clean:
  6   rm -rf mybin  

❤️脚本详解

❤️实操理解:

❤️脚本写好后,我们就用make和makefile共同来进行编译:

⭐️输入make我们调用makefile里面的脚本,直接就会生成mybin可执行文件;

⭐️输入make clean就会删除可执行文件mybin

🥏2.3 升级版编译

❤️对于上面我们虽然用的是make和makefile进行编译,但是还是直接调用的test.c直接生成mybin;但是我们在gcc编译器已经声明,最好使用.o目标文件去生成mybin;那么怎么实现呢?我们还是先给出脚本!

❤️脚本:

mybin:main.o contact.o
  2   gcc $^ -o $@
  3 
  4 %.o:%.c
  5   gcc -c $<
  6 
  7 .PHONY:clean
  8 clean:
  9   rm -rf *.o mybin 

❤️脚本详解

❤️这个脚本就没有上面那个好理解了,但是这样写的效果无疑是最好的,特别是.c文件越多越好;这里%.o代表任意文件,*.o代表所有文件;

⭐️(1) mybin:main.o contact.o;对于依赖关系不再是mybin依赖.c文件了;而是依赖.o文  件,main.o和contact.o文件

⭐️(2) gcc $^ -o @ ; @; @^表示依赖文件列表(.o文件),$@表示目标文件(mybin);

⭐️(3)%o.%c;%c表示当前目录下的所有的.c文件;%.o表示对应的.c文件形成.o

⭐️(4)gcc -c < ; <; <<表示把所有的.c文件一个个拿出来,用gcc进行编译生成同名的.o文件

⭐️(5)最后删除基本一样的,区别就是多删除生成.o文件;*.o就表示以.o结尾的所有文件;

🥏2.4 函数版编译

❤️这里相信大家也发现了,2.3版本的编译虽然好,还是有很大问题;对于一个大工程,如果有很多.c文件,我们需要把所有对应的.o文件都要写出来吗?当然不是,这里就给大家一个函数的版本,可以了解一下!

❤️脚本:

CC=gcc -g    
ELF=mybin    
src = $(wildcard *.c)    
object = $(src:%.c=%.o)    
$(ELF):$(object)    
  @$(CC) $^ -o $@     
$(object):    
.PHONY:clean    
clean:    
  @rm -rf $(object) $(ELF) 

❤️这里先给大家介绍三个函数:wildcard函数、patsubst函数、notdir函数!

⭐️wildcard函数:当前目录下匹配模式的文件,例如:src=KaTeX parse error: Undefined control sequence: \* at position 11: (wildcard \̲*̲.c),找到所有的.c文 件,…(shell find ‘*.c’),找到所有的.c文件。

⭐️patsubst函数 ( p a t s u b s t (patsubst%.c,%.o, (patsubstsrc),这个不理解比较难记;可以写成下面这种方式:object=$(src:.c=.o),作用是把所有的.c文件转换成.o文件。

⭐️notdir函数:如果是多级目录呢?那就需要加上$(notdir s r c ) ,作用是去除目录的限制;不懂的同学也可以用: src),作用是去除目录的限制;不懂的同学也可以用: src),作用是去除目录的限制;不懂的同学也可以用:(shell find -name ‘*.c’);这句话就可以代替1,3的功能。

❤️脚本详解

⭐️这里我没有写太复杂,只用了wildcard函数;感兴趣的小伙伴可以自己学习一下上述的三个函数,尝试一下全用函数实现!

🏀3. 第一个Linux程序—进度条

在写进度条之前我们先理解两个知识点!

1.缓冲区;

  1. \n换行和\r回车;

🥏3.1 缓冲区

我们就拿一段代码来提出问题:

❤️sleep(3)表示睡眠 3秒,需要的头文件是<unistd.h>,想要深度了解的不妨去man 3 sleep查看详情;

⭐️我们常见的就是后者带\n;它是先打印在睡眠3秒;然后结束程序;

⭐️对于前者不带\n是先睡眠3秒,然后直接打印结束;为什么呢?这就涉及到缓冲区的概念了!那么怎么不带\n也能带到带\n的效果呢?利用fflush刷新一下缓冲区!

⭐️缓冲区就是一块内存区域;刷新策略主要有三种:
         a.无缓冲(立即)
         b.行缓冲(\n)
         c.全缓冲(缓冲区满了才缓冲)
   ⭐️程序退出,也会自动刷新!
❤️我们的进度条肯定是在同一行打印的,肯定不能用\n进行换行;那么我们怎么让不带\n达到带\n的效果?这就需要fflush刷新缓冲区;fflush(stdout);刷新到显示器!

🥏3.2 \n和\r的区别

❤️对于\n是换行,\r是回车;我们都是知道的,但是你深入理解过这两个吗?其实这两个是和光标的位置有关系的!

❤️对于\n(换行)

⭐️对于换行;我们写完一句话,写完了需要换行,它是对应着当前光标的位置另起一行!但是不从头开始,而是衔接着上一行的位置;比如:

但是C语言里的\n实际上有两个功能换行和回车!

❤️对于\r(回车)

⭐️对于回车,并不会新起一行,而是在当前行回退到起始位置,原来的内容会被新的内容覆盖,比如:

我们目前就记住一句话:\n既回车又换行,\r只回车不换行!

🥏3.3 倒时游戏

既然我们理解了前两个,不妨就写一个好玩的倒时小游戏,就利用\n和\r看看有什么区别!

❤️(1)用\n

#include <stdio.h>
  2 #include <unistd.h>                                                                                                                                                                    
  3 int main()
  4 {
  5   int i = 10;
  6   while(i)
  7   {
  8      printf("%d\n",i);
  9      sleep(1);
 10      i--;
 11   }
 12 
 13   return 0;
 14 }

⭐️运行效果动图如下:

❤️(2)用\r

#include <stdio.h>
  2 #include <unistd.h>
  3 int main()
  4 {
  5   int i = 9;                                                                                                                                                                           
  6   while(i)
  7   {
  8      printf("%d\r",i);
  9      fflush(stdout); //刷新缓存
 10      sleep(1);
 11      i--;
 12   }
 13 
 14   return 0;
 15 }

⭐️运行效果动图如下:

🥏3.4 进度条的编写

有了前面的一整套学习,我们就可以写我们的第一个Linux正式小程序了,进度条的编写!

🥅3.4.1 程序的编写

❤️我们还是分成三个部分:ProcBar.h头文件的包含等、ProcBar.c具体函数的实现、Main功能的测试!

❤️**(1)Main.c**

#include "ProcBar.h"
  2 int main()
  3 {
  4   process_bar();                                                                                                                                                                       
  5   return 0;
  6 }

⭐️主要包括函数的调用,用来测试功能!注意需要引头文件“ProcBar.h”

❤️(2)ProcBar.h

 #pragma once
 #include <stdio.h>
 #include <unistd.h>//sleep的头文件
 #include <string.h>//memset的头文件
 #define M 101
 void process_bar();

⭐️主要包括头文件的包含、宏的定义、函数的声名!

❤️**(3)ProcBar.h**

#include "ProcBar.h"    
void process_bar()    
{    
  char arr[M];    
  memset(arr,0,sizeof(arr));//初始化    
  const char* p = "|/-\\";    
  int i = 0;    
  while(i<=100)    
  {    
    printf("[%-100s][%-3d%%][%c]\r",arr,i,p[i%4]);    
    fflush(stdout);    
    arr[i++] = '#';    
    usleep(50000);//1s = 1000ms 1ms = 1000um                                                                                                                                               
  }    
  printf("\n");    
    
}    

⭐️主要包括具体函数的实现!注意需要引头文件“ProcBar.h”

🥅3.4.2 脚本的编写

❤️我么还用前面学过的知识点,利用make和makefile进行编译链接!

❤️makefile脚本的编写

procbar:Main.o ProcBar.o    
  @gcc $^ -o $@    
    
%.o:%.c    
  @gcc -c $<    

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

e脚本的编写**

procbar:Main.o ProcBar.o    
  @gcc $^ -o $@    
    
%.o:%.c    
  @gcc -c $<    

[外链图片转存中…(img-oILQRNQJ-1715276690147)]
[外链图片转存中…(img-KQ0j6VVM-1715276690147)]
[外链图片转存中…(img-EQwGknhq-1715276690148)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值