makeMakefile

news2024/12/29 9:40:30

一、 什么是make&Makefile ?

①make 是一条命令,makefile是一个文件,配合使用,通过依赖关系和依赖方法达到我们形成可执行程序的目的

②makefile好处就是可以进行 自动化编译 ,极大的提高软件开发的效率,一旦写好,只需要一个 make 命令,整个工程即可以完全自动编译
③make 是一个命令工具,是一个解释 makefile 中指令的命令工具

二、  实例代码

0x01 Makefile的编辑

[wh@localhost lesson7]$ touch test.c
[wh@localhost lesson7]$ touch Makefile //Makefile建议开头大写
[wh@localhost lesson7]$ vim test.c
[wh@localhost lesson7]$ vim Makefile
[wh@localhost lesson7]$ make
gcc test.c -o test -std=c99
[wh@localhost lesson7]$ ll
total 20
-rw-rw-r--. 1 wh wh   41 Oct  5 05:54 Makefile
-rwxrwxr-x. 1 wh wh 8512 Oct  5 05:54 test
-rw-rw-r--. 1 wh wh   73 Oct  5 05:54 test.c
[wh@localhost lesson7]$ ./test
hello world
[wh@localhost lesson7]$ cat Makefile
test:test.c    //test的形成依赖于test.c,也可以说目标文件依赖于依赖文件
	gcc test.c -o test -std=c99  //依赖方法

上述代码是对一个项目的形成,当然我们也要对其进行清理:

[wh@localhost lesson7]$ cat Makefile
test:test.c
	gcc test.c -o test -std=c99

.PHONY:clean
clean:
		rm -f test

.PHONY是对clean的一个修饰,可以说clean是一个伪目标,而clean只有依赖方法,没有依赖关系,并且目标可执行程序如果没有修改,不需要重复执行,而伪目标可以多次执行

0x02 上述代码中为什么只输入make就形成了可执行程序test,而必须输入make clean才能进行清理呢?

 make扫描makefile文件的时候,默认只会形成一个目标依赖关系,一般就是第一个

当然也可以用$@代替目标文件,$^代替源文件

  1 test:test.c
  2   //gcc test.c -o test -std=c99  
  3   gcc -o $@ $^   
  4 .PHONY:clean
  5 clean:
  6     rm -f test

上述的test:test.c依赖关系也可以细分为:

  1 test:test.o
  2   gcc  test.o -o test                                                                                        
  3 test.o:test.s
  4   gcc -c test.s -o test.o
  5 test.s:test.i
  6   gcc -S test.i -o test.s
  7 test.i:test.c
  8   gcc -E test.c -o test.i
  9 .PHONY:clean
 10 clean:
 11     rm -f test test.i test.s test.o

0x03 printf在sleep之前,为什么先进行6s之后,printf才输出呢?难道是sleep先于printf运行吗?

当然不是,是因为printf已经执行,但是数据没有被立即刷新到显示器当中
①没有\n,字符串会暂时保存起来,保存在用户C语言级别的缓冲区中
②显示器设备刷新策略就是行刷新,遇到\n即进行刷新
③如果想要立马刷新,则可以使用fflush(stdout);因为printf打印向stdout打印,则刷新即是向stdout刷新

C程序,默认会打开三个流:

stdin对应键盘,stdout对应显示器,stderr对应显示器
因为程序的运行需要数据的输入,结果的输出以及错误的输出

三、Linux 第一个小程序 --进度条

0x01 初步学习

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

① 此时,显示器中显示的是10,90,80,70,...,10,这是为什么呢?
凡是从键盘读取的内容都是字符和显示到显示器上面的内容都是字符,比如pirntf("%d\n",234);每次显示的是字符2,字符3,字符4,每次%r,都是只重置到首字母,但是不换行,fflush刷新的都是一个字符
②那如何解决这个问题呢?
可以预留一部分空间出来,printf("%2d\r");留出来俩个空间

0x02 进一步编写

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<unistd.h>
  4                                                                                                              
  5 int main()
  6 {
  7 #define NUM 100
  8   char bar[NUM+1];//预留出'\0'的位置
  9   memset(bar,'\0',sizeof(bar));
 10 
 11   int i = 0;
 12   while(i <= 100)
 13   {
 14     printf("%s\r",bar);
 15     fflush(stdout);
 16     bar[i] = '#';
 17     i++;
 18     sleep(1);
 19   }
 20 }

0x03 增加[ ]和百分比和运行光标

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<unistd.h>
  4 
  5 int main()
  6 {
  7 #define NUM 100
  8   char bar[NUM+1];
  9   memset(bar,'\0',sizeof(bar));
 10   const char* label = '|/-\\'
 11   int i = 0;
 12   while(i <= 100)
 13   {
 14     printf("[%-100s][%d%%] %c\r",bar,i,label[i%4]);
        //预留100个空间,%是转义字符,%%表示一个%
        //因为默认格式控制是右对齐,所以是从右往左打印,加'-'则是左对齐,从左往右打印
 15     fflush(stdout);
 16     bar[i] = '#';
 17     i++;
 18     usleep(50000);
 19   }
 20   printf("\n");                                                                                              
 21 }

0x04 运行成果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1063644.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推荐一款在线的JDK17中文文档

spring6.0及springboot3.0最低版本要求都是java17&#xff0c;换上java17是迟早的事&#xff0c;所以虽然我现在做的是java8&#xff0c;但是后面我想从java8直接飞升到java17&#xff0c;先做个准备&#xff0c;找到一个JDK17的中文文档&#xff0c;是在线的&#xff0c;地址&…

数据结构刷题训练——二叉树篇(一)

&#x1f4d9;作者简介&#xff1a; 清水加冰&#xff0c;目前大二在读&#xff0c;正在学习C/C、Python、操作系统、数据库等。 &#x1f4d8;相关专栏&#xff1a;C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…

学习记忆——方法篇——整除特点

理解记忆法 对于数的整除特征大家都比较熟悉&#xff1a;比如4看后两位&#xff08;因为100是4的倍数&#xff09;&#xff0c;8看后三位&#xff08;因为1000是8的倍数&#xff09;&#xff0c;5末尾是0或5&#xff0c;3与9看各位数字和等等&#xff0c;今天重点研究一下3,9,…

创新家庭办公室:打造完美工作空间的秘诀

一个精心策划的家庭办公室有很多好处&#xff0c;何不把临时工作区升级改造为你的专属工作区呢&#xff0c;还能为这些至关重要的区域注入新的活力。 创造多用途的起居室&#xff1a;我们大多数人都不曾拥有一个可以完全根据工作需求设计的独立家庭办公室——所以有时候要找到…

目标检测算法改进系列之Backbone替换为RIFormer

RIFormer简介 Token Mixer是ViT骨干非常重要的组成成分&#xff0c;它用于对不同空域位置信息进行自适应聚合&#xff0c;但常规的自注意力往往存在高计算复杂度与高延迟问题。而直接移除Token Mixer又会导致不完备的结构先验&#xff0c;进而导致严重的性能下降。 原文地址&…

Pytorch之shuffleNet图像分类

&#x1f482; 个人主页:风间琉璃&#x1f91f; 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 前言 ShuffleNet是Face&#xff08;旷视&#xff09;在2017年发布的一个高效率…

【傅里叶梅林图像配准】用于图像配准的傅里叶梅林相位相关性的实现(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Python之元组

Python之元组 元组tuple 一个有序的元素组成的集合使用小括号 ( ) 表示元组是不可变对象 tuple(), (), type(()) # 空元组 ((), (), tuple)(1,), (1) # 元组中只有1必须加逗号&#xff0c;否则就是1了 # ((1,), 1)x 1, 2 # 以逗号分隔的内容会形成元组&#xff0c;封装元组x…

壁炉装饰:突破传统的创新趋势

壁炉&#xff0c;一直以来都是家庭温馨的象征&#xff0c;但它也是家居装饰中一个充满潜力的元素。如今&#xff0c;随着设计趋势的不断演变&#xff0c;壁炉装饰已经迈入了一个全新的时代&#xff0c;融合了美学、功能和可持续性&#xff0c;为家庭创造了更多可能性。 壁炉装饰…

强化学习环境 - robogym - 学习 - 3

强化学习环境 - robogym - 学习 - 3 文章目录 强化学习环境 - robogym - 学习 - 3项目地址为什么选择 robogymObservation - 观测信息Action - 动作信息Initialization - 初始状态设置 项目地址 https://github.com/openai/robogym 为什么选择 robogym 自己的项目需要做一些机…

04.数据解析之css选择器

1、常见数据类型 结构化的数据是指可以使用关系型数据库表示和存储&#xff0c;表现为二维形式的数据。一般特点是&#xff1a;数据以行为单位&#xff0c;一行数据表示一个实体的信息&#xff0c;每一行数据的属性是相同的。 1、1 结构化数据 ​ 结构化的数据是指可以使用关…

策略模式与模板方法结合案例

一、背景 上周在迁移项目MQ工程的时候&#xff0c;重新Review代码&#xff0c;发现有一段代码综合使用了策略模式和模板方法&#xff0c;下面讲解一下具体场景应用的思路。 二、模板方法 策略模式前段时间有一个关于库存具体案例&#xff0c;详见 库存管理与策略模式。 模板…

智能银行卡明细筛选与统计,轻松掌握账户总花销!

作为现代生活的重要组成部分&#xff0c;银行卡成为了我们日常消费和收入的主要途径。但是&#xff0c;当我们需要了解自己的银行卡账户的总花销时&#xff0c;繁琐的明细筛选和统计工作常常让人头疼。现在&#xff0c;让我们向您推荐一款智能银行卡明细筛选与统计工具&#xf…

基于SpringBoot的学生选课系统

基于SpringBoot的学生选课系统的设计与实现&#xff0c;前后端分离 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 前台主页 登录界面 管理员界面 教师界面 学生界面 摘要 学生选课系统…

halcon 数字识别

文章目录 素材交互选取区域阈值分割特征提取识别字符显示全部代码 素材 dev_get_window(WindowHandle) **读取图像 read_image(Image,C:/Users/Augustine/Desktop/1.png) **把图像转正&#xff0c;镜像方式 mirror_image(Image,ImageMirror,row) mirror_image(ImageMirror,Imag…

Python 无废话-基础知识面向对象编程详解

类定义 如何理解万物皆对象&#xff1f; 生活中一些事物&#xff0c;动物&#xff08;可爱的小狗、调皮的小猫&#xff09;、交通工具&#xff08;比亚迪U8汽车、飞机&#xff09;、人&#xff08;学生、教师&#xff09;…… 这些对象都有着独特或共性的属性和方法来描述其…

Android:实现Camera前后双摄

效果展示 一.概述 本博文讲解如何实现手机前后两颗摄像头同时预览并显示 我之前博文《OpenGLES&#xff1a;GLSurfaceView实现Android Camera预览》对单颗摄像头预览做过详细讲解&#xff0c;而前后双摄实现原理其实也并不复杂&#xff0c;粗糙点说就是把单摄像头预览流程写两…

Pytorch之MobileNetV3图像分类

&#x1f482; 个人主页:风间琉璃&#x1f91f; 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 前言 由于传统卷积神经网络&#xff0c; 内存需求大、 运算量大导致无法在移动…

多线程JUC

文章目录 多线程一.什么是多线程二.多线程的两个概念三.线程的实现方式四.常见的成员方法五.线程安全的问题六.死锁七.生产者和消费者 多线程 一.什么是多线程 进程:是程序的基本执行实体 理解:每一个运行的软件就是一个进程 线程:是操做系统能够进行运算调度的最小单位,它…

Halcon 从基础到精通-02- 开发基于HALCON的应用

HALCON的应用通过HDevelop应用来构建原型。HDevelop的开发主要有3种形式。 Start from Scratch: 手动通过脚本&#xff0c;把HDevelop的代码转化为一般的编程语言。如&#xff0c;上一节提到&#xff0c;其实&#xff0c;每个operators,也许并不一样&#xff0c;需要依据HALC…