shell脚本编程Makefile的编写,让你的代码编译链接更加快速_CAccept的博客-程序员ITS301

技术标签: c++  Shell脚本语言  Linux  shell  linux  

为什么要使用Makefile

简单来说,当我们写一个稍微大一些项目的时候,如果我们要执行一个程序那得编译很多个文件并且还得链接起来,如果没有Makefile我们就得一个一个编译一个一个链接那真的是又臭又长(而且还会经常写错),而Makefile就能够很好的解决这个问题,所以说掌握好Makefile的编写是很有必要的


Makefile的编写

程序的编译和链接

  • 使用C、C++编写可执行程序,首先要把源文件编译成中间代码文件,Linux下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。

  • 一个项目,拥有成百上千的源程序文件,编译链接这些源文件都是由规则的,Makefile闪亮登场!Makefile确定整个工程的编译规则,只需要一个make命令,就可以实现“自动化编译”。make是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。


Make 工作原理

通常在一个项目里,我们的规则是:
1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

其实就是智能的识别哪些编译链接需要做,哪些不用做避免不必要的时间消耗

只要我们的Makefile写得够好,我们只用一个make命令就可以完成,make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。


Makefile的规则

target … : prerequisites …

command


target:也就是一个目标文件,可以是ObjectFile,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,暂不叙述。

prerequisites:要生成那个target所需要的文件或是目标。

command:也就是make需要执行的命令。(任意的Shell命令)

这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

一个范例:

hello_demo : hellospeak.o speak.o   //由hellospeak.o speak.o链接成目标hello_demo                                  
        gcc -o hello_demo hellospeak.o speak.o  //执行下面的命令                               

hellospeak.o : hellospeak.c speak.h  //如果一些hellospeak.c的函数声明是在头文件speak.h中那么也得在这后面加上                                         
        gcc -c hellospeak.c                                                
speak.o : speak.c  speak.h                                                  
        gcc -c speak.c                                                    
clean :                                                                  
        rm hello_demo speak.o  hellospeak.o  //当执行make clean时就会执行这个语句 

下面是我写的整体例子

//speak.h
#include<stdio.h>
#include<stdlib.h>
void helloSpeak();
--------------------------------------------------------------




//speak.c
#include"speak.h"
void helloSpeak()
{
    
 printf("Hello Makefile\n");
}
--------------------------------------------------------------




//main.c
#include"speak.h"
int main()
{
    
  helloSpeak();
  return 0;
}



--------------------------------------------------------------
//Makefile
Hello: main.o speak.o
        gcc -o Hello  main.o speak.o
main.o: main.c speak.h
        gcc -c main.c
speak.o: speak.c speak.h
        gcc -c speak.c
clean:
        rm Hello speak.o main.o

~

运行效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Jacksqh/article/details/123299614

智能推荐

SPI协议(参考野火stm32教程)_SunBo__CSDN的博客-程序员ITS301_野火spi 总线协议介绍

协议简介SPI(Serial Peripheral interface),是一种常用的串行外围设备接口。由Motorola首先在其MC68HCXX系列处理器上定义的。主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方...

easyUI pagination分页控件点击下一页后跳转到最后一页_weixin_30781775的博客-程序员ITS301

easyui-pagination点击下一页直接跳转到最后一页的可能原因今天做到聊天记录展示页面的时候发现一个bug:初次进入页面加载出第一页的数据,点击下一页的时候不是到第二页而是到最后一页。 如下图所示:这个bug确实让我很郁闷,最初以为是后台的问题,调试了一会儿发现跟后台没关系。随后检查了下js代码,我的pagination js是这样写的: Js代码$('#...

设计模式 考试题+答案_披风秃头侠的博客-程序员ITS301_设计模式考试题

一、选择题1.( A )模式的关键是将一个对象定义为原型,并为其提供复制自己的方法。A.原型 B.创建者 C.工厂方法 D.迭代2.下面的类图表示的是哪个设计模式?(B ) A装饰模式(Decorator) B策略模式(Strategy)C桥接模式(Bridge) D观察者模式(Observer)转存失败重..._1671465600

微机原理程序“大小写转换”问题详细讲解_乔洪涛的博客-程序员ITS301_微机原理大小写转换程序

&gt; 大小写转换问题,先看一下大小写字母的ASCII码值A 十六进制 41H 十进制65B 十六进制 42H 十进制66C 十六进制 43H 十进制67D 十六进制 44H 十进制68E 十六进制 45H 十进制69F 十六进制 46H 十进制70a 十六进制 6..._1671465600

input upload 问题归纳_Lucy酱的博客-程序员ITS301

DOM:&lt;inputid="uniqueId" type="file" accept=".txt,.ppt"onChange={fileChange} multiple/&gt;注意:1、当一个页面多个upload input,id必须唯一,不然fileChange后set值会错乱2、fileChange上传的file temp,不能将file temp转换成String再转换回Object。如: (1)例子:fileChange后得到的变量为data,JSO...

离骚_mseaspring的博客-程序员ITS301

帝高阳之苗裔(yì)兮,朕皇考曰伯庸。高阳:颛顼之号。苗裔:苗,初生的禾本植物。裔,衣服的末边。此苗裔连用,喻指子孙后代。朕:我。皇考:对亡父的尊称。摄提贞于孟陬(zōu)兮,惟庚(gē...

随便推点

遍历数组和对象的方法_天下1281的博客-程序员ITS301_手滑又来遍历数组。但是他对于这个简单类型的数组和对于引用类型也就是对象数

一般的我们遍历数组是用for遍历的var arr = [2,3,1,5];for( var i=0;i<arr.length;i++){ console.log(arr[i]);}我们可以使用内置的forEach方法: 此方法用于调用数组中的每个元素,并将元素传递给回调函数。 注意:forEach对于空数组是不会执行回调函数的。forEach不能return,map可以,下文有例子。

docker安装容器搭建go环境_answer_yym的博客-程序员ITS301

1、简介IaaS(Infrastructure as a Service)PaaS(Platform)SaaS(Software)Docker daemon,docker守护进程,root权限

Linux安装jdk的详细步骤_苍煜的博客-程序员ITS301

linux的使用过程中,总是要使用jdk的,有的linux系统自带的openjdk,总是不太好用;本文以centos7为例,安装jdk1.8版本。

NOIP2015 跳石头_INGg__的博客-程序员ITS301

最近一直在刷二分答案的题,先来总结一下lyd大佬对于二分答案的解释借助二分,我们把求最优解的问题,转化为给定一个值mid,判定是否存在一个可行的方案评分达到mid的问题。对于跳石头这个题来说,我们可能枚举去掉哪几个石头来构成方案的问题很难,但是我们可以通过二分出来它最后跳跃的最短距离可能是多少来进行选择从而本质上二分答案讲问题转化为判定问题最终本题解题思路就是,看看在某一个最短距离的情况下,能不能去掉小于等于m块石头的方案如果某个距离答案满足了去掉的小于等于m的方案个数,那么我就看看比它小

华为研发工程师编程题(一)_念殊15的博客-程序员ITS301

题一 汽水瓶解法(贪心)贪心算法,每次使用已有的空瓶数,得到最多数量可以喝的水,接着记录已有的空瓶数,继续算import java.util.*;public class Main{ // 要写在主方法中 public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = 0; int sum = 0;

netcore - MVC的ActionFilter的使用_weixin_34388207的博客-程序员ITS301

经过一周的时间没有分享文章了,主要是在使用.netcore做一个小的项目,项目面向大众用户的增删改查都做的差不多了,打算本周在云服务器上部署试试,很期待,也希望上线后大家多多支持;以上纯属个人废话,来一起看看今天的正篇环节:.继承IActionFilter来定义个验证登录的流程例子.ActionFilter中怎么使用依赖注入下面一步一个脚印的来...

推荐文章

热门文章

相关标签