Makefile实战

news2024/11/17 4:33:31

文章目录

  • 1、准备环境
    • 1.2、规则
    • 1.3、假目标
    • 1.4、变量
    • 1.5、自动变量
    • 1.6、函数
    • addprefix 函数
    • filter函数
    • filter-out函数
    • patsubst函数
    • strip函数
    • wildcard函数

1、准备环境

准备一台Linux机器,验证环境中是否呗正确安装了,使用make -v命令进行验证

在这里插入图片描述

1.2、规则

在这里插入图片描述
在这里插入图片描述

最简单的例子输出hello world,创建一个makefile文件,文件输入一下文件内容
运行:make

# 加上@的意思是不希望他把这条命令打出来
all:
	@echo "hello world"

总结:
1、一个Makefile中可以定义多个目标。
2、调用make可以通过附加参数告诉他要做什么。
3、当Makefile得到目标后,先找到定义目标的规则,然后运行规则中的命令达到构建目标的目的,现在所示例的Makefile中,没一个规则中都只有一条命令,而实际的Makefile,每一个规则可以包含很多条命令。

1、例1

all: test 
	@echo "Hello World" 
test: 
	@echo "Just for test!"

这里应用了makefile中的依赖概念,all ⽬标后⾯的 test 是告诉 make,all ⽬标依赖 test ⽬标,这⼀依赖⽬标在 Makefile 中⼜被称之为先决条件。出现这种⽬标依赖关系时,make⼯具会按 从左到右的先后顺序先构建规则中所依赖的每⼀个⽬标。如果希望构建 all ⽬标,那么make 会在构建它之 前得先构建 test ⽬标,这就是为什么我们称之为先决条件的原因。

2、例2
foo.c

#include <stdio.h> 
void foo () 
{ 
	printf ("This is foo ()!\n"); 
}

main.c

extern void foo(); 
int main () 
{ 
	foo(); 
	return 0; 
}

Makefile

all: main.o foo.o 
	gcc -o simple main.o foo.o 

main.o: main.c 
	gcc -o main.o -c main.c 

foo.o: foo.c 
	gcc -o foo.o -c foo.c 

clean: 
	rm simple main.o foo.o

在这里插入图片描述

1.3、假目标

在前⾯的 sample 项⽬中,现在假设在程序所在的⽬录下⾯有⼀个 clean ⽂件,这个⽂件也可以通过 touch 命令来创建。创建以后,运⾏ make clean 命令,你会发现 make 总是提示 clean ⽂件是最新 的,⽽不是按我们所期望的那样进⾏⽂件删除操作,从原理上我们还是可以理解的,这是 因为 make 将 clean 当作⽂件,且在当前⽬录找到了这个⽂件,加上 clean ⽬标没有任何先决条件,所 以,当我们要求 make 为我们构建 clean ⽬标时,它就会认为 clean 是最新的。那对于这种情况,在现实中也难免存在所定义的⽬标与所存在的⽂件是同名的,采⽤ Makefile如何处理这 种情况呢?Makefile 中的假⽬标(phony target)可以解决这个问题。假⽬标可以采⽤.PHONY 关键字,来定义,需要注意的是其必须是⼤写字⺟。

.PHONY: clean
all: main.o foo.o 
	gcc -o simple main.o foo.o 

main.o: main.c 
	gcc -o main.o -c main.c 

foo.o: foo.c 
	gcc -o foo.o -c foo.c 

clean: 
	rm simple main.o foo.o

1.4、变量

.PHONY: clean 
CC = gcc 
RM = rm 
EXE = simple 
OBJS = main.o foo.o 
$(EXE): $(OBJS) 
	$(CC) -o $(EXE) $(OBJS) 
main.o: main.c 
	$(CC) -o main.o -c main.c 
foo.o: foo.c 
	$(CC) -o foo.o -c foo.c 
clean:$(RM) 
	$(EXE) $(OBJS)

1.5、自动变量

@ ⽤于表示⼀个规则中的⽬标。当我们的⼀个规则中有多个⽬标时, @⽤于表示⼀个规则中的⽬标。当我们的⼀个规则中有多个⽬标时, @⽤于表示个规则中的标。当我们的个规则中有多个标时,@所指的是其中任何造成命令 被运⾏的⽬标。
$^则表示的是规则中的所有先择条件。
$<表示的是规则中的第⼀个先决条件。

.PHONY: all 
all: first second third 
	@echo "\$$@ = $@" 
	@echo "$$^ = $^" 
	@echo "$$< = $<"

执⾏
make
@ = all
^ = first second third
< = first

重写的makefile

.PHONY: clean 
CC = gcc 
RM = rm 
EXE = simple 
OBJS = main.o foo.o 
$(EXE): $(OBJS) 
	$(CC) -o $@ $^ 
main.o: main.c 
	$(CC) -o $@ -c $^ 
foo.o: foo.c 
	$(CC) -o $@ -c $^ 

clean:
	$(RM) $(EXE) $(OBJS)

通配符:

.PHONY: clean 
CC = gcc
RM = rm 
EXE = simple 
OBJS = main.o foo.o 
$(EXE): $(OBJS) 
	$(CC) -o $@ $^ 
%.o: %.c 
	$(CC) -o $@ -c $^ 
clean: 
	$(RM) $(EXE) $(OBJS)

1.6、函数

采⽤了 wildcard 和 patsubst 两个函数后 simple 项⽬的 Makefile。

.PHONY: clean 
CC = gcc 
RM = rm 
EXE = simple 
SRCS = $(wildcard *.c) 
OBJS = $(patsubst %.c,%.o,$(SRCS)) -》把.c 替换为.o 
$(EXE): $(OBJS) 
	$(CC) -o $@ $^ 
	
%.o: %.c $(CC) -o $@ -c $^ 

clean: 
	$(RM) $(EXE) $(OBJS)

addprefix 函数

addprefix 函数是⽤来在给字符串中的每个⼦串前加上⼀个前缀,其形式是: $(addprefix prefix, names…)

.PHONY: all 
without_dir = foo.c bar.c main.o
with_dir := $( addprefix objs/, $(without_dir)) 
all: @echo $(with_dir)

执⾏
$make
objs/foo.c objs/bar.c objs/main.o

filter函数

filter 函数⽤于从⼀个字符串中,根据模式得到满⾜模式的字符串,其形式是: $(filter pattern…, text)

PHONY: all 
sources = foo.c bar.c baz.s ugh.h 
sources := $(filter %.c %.s, $(sources)) 
all: 
	@echo $(sources)

执⾏
$make
foo.c bar.c baz.s

filter-out函数

filter-out 函数⽤于从⼀个字符串中根据模式滤除⼀部分字符串,其形式是: $(filter-out pattern…, text),从 objects 变量中给滤除了。filter 与 filter-out 是互补的。

.PHONY: all 
objects = main1.o foo.o main2.o bar.o 
result = $(filter-out main%.o, $(objects)) 
all: 
	@echo $(result)

执⾏
$make
foo.o bar.o

patsubst函数

patsubst 函数是⽤来进⾏字符串替换的,其形式是: $(patsubst pattern, replacement, text)

.PHONY: all 
mixed = foo.c bar.c main.o 
objects := $(patsubst %.c, %.o, $(mixed)) 
all: 
	@echo $(objects)

执⾏
$make
foo.o bar.o main.o

strip函数

strip 函数⽤于去除变量中的多余的空格,其形式是: $(strip string)

.PHONY: all 
original = foo.c bar.c 
stripped := $(strip $(original)) 
all: 
	@echo "original = $(original)" 
	@echo "stripped = $(stripped)"

执⾏
$make
original = foo.c bar.c
stripped = foo.c bar.c

wildcard函数

wildcard 是通配符函数,通过它可以得到我们所需的⽂件,这个函数如果我们在 Windows 或是Linux 命 令⾏中的“*”。其形式是: $(wildcard pattern)

.PHONY: all 
SRCS = $(wildcard *.c) 
all: 
	@echo $(SRCS)

执⾏
$make
bar.c foo.c main.c

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

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

相关文章

React中useState的setState方法请求了好多次

1、问题描述 最近在写react的时候碰到了一个很奇怪的问题。 可以看到那个getXXX()的方法一直不断的被调用&#xff0c;网页一直请求&#xff0c;根本停不下来了。 2、产生原因 要弄明白这个原因&#xff0c;首先要先了解一下react生命周期。 react是组件式的编程&#xff0c;一…

青岛大学_王卓老师【数据结构与算法】Week04_01_循环链表_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c;另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础–…

GO SDK使用说明

简介 欢迎使用腾讯云开发者工具套件&#xff08;SDK&#xff09;3.0&#xff0c;SDK 3.0 是云 API 3.0 平台的配套工具。SDK 3.0 实现了统一化&#xff0c;各个语言版本的 SDK 具备使用方法相同、接口调用方式相同、错误码和返回包格式相同等优点。本文以 GO SDK 3.0 为例&…

chatgpt赋能python:用Python编写BMI计算器,实现身体指数(BMI)的快速计算和分析

用Python编写BMI计算器&#xff0c;实现身体指数&#xff08;BMI&#xff09;的快速计算和分析 在当今的健康意识逐渐增强的时代&#xff0c;身体指数&#xff08;BMI&#xff09;成为了一个非常重要的健康指标。BMI是根据身高和体重计算出来的数值&#xff0c;用于评估一个人…

java pdf2html 和html2pdf 两款插件

1 pdf2html docker 启动&#xff0c;java 调用服务即可转化 https://beltxman.com/2567.html docker run -ti --rm -v ~/pdf:/pdf -w /pdf docker.io/pdf2htmlex/pdf2htmlex:0.18.8.rc2-master-20200820-ubuntu-20.04-x86_64 test.pdf 2 html2pdf java .Runtime 类型调用命…

超详细讲解在Ubuntu 20.04上安装ROS Noetic Ninjemys并测试

文章目录 前言安装STEP-1: 配置Ubuntu软件仓库STEP-2: 设置sources.listSTEP-3: 设置密钥STEP-4: 更新Ubuntu软件包确保安装索引是最新的STEP-5: 执行安装命令STEP-6: 配置ROS环境 测试ROS 前言 ROS是Robot Operating System的缩写, 即机器人操作系统, ROS是一组软件库和工具&…

LR录制https协议脚本前配置

LR录制https安全协议脚本前的设置 在IE中添加安全证书 打开IE浏览器&#xff0c;选择“工具—Internet选项—内容”&#xff0c;点击“证书”导入相应的证书&#xff0c;如下图 在LR中配置证书 获取pem格式证书 因为loadrunner只支持pem格式的证书&#xff0c;所以要将证书…

uniapp监听手机侧滑返回事件。

这篇文章是应一个粉丝的需求更新的&#xff01;你们看我多宠粉&#xff01; 若在App首页&#xff0c;点击手机物理返回键&#xff0c;此时无返回页面可关闭&#xff0c;uni-app默认会提示“再按一次退出应用”&#xff1b;若想自定义退出信息&#xff0c;如修改为&#xff1a;…

Arthas (阿尔萨斯)arthas-boot 方式安装及使用教程

目录 一、软件介绍二、下载教程三、安装教程四、使用教程 一、软件介绍 Arthas 地址&#xff1a;https://github.com/alibaba/arthas 官方文档&#xff1a;https://alibaba.github.io/arthas Arthas 是Alibaba开源的Java诊断工具&#xff0c;深受开发者喜爱。 当你遇到以下类…

ProGuard 进阶系列(四)访问者模式

在进行后面的内容分析之前&#xff0c;不得不讲到访问者模式&#xff0c;这是 GOF 23 个设计模式中最难的几个模式之一。如果能够很好的理解访问者模式&#xff0c; 后续源码解读会相对容易一些。本文将结合 ProGuard 的部分源码&#xff0c;理解分析访问者模式的用途及使用场景…

单相逆变原理验证仿真

为了用全桥控制一个电感中的电流跟踪指令电流,simulink图如下图1&#xff1a; 图1 前向通道传递函数&#xff0c;闭环伯德图如下&#xff1a; s tf(s); %LC及并联电阻R的值 L1*10^-3; R10; %调制限号到占空比的传递函数&#xff0c;dVcont/Vramp -> d/Vcont 1/Vramp1Kcd …

JavaWeb 笔记——1

JavaWeb 笔记-1 初始JavaWeb什么是JavaWeb 一、JDBC1.1、JDBC简介1.2、API详解-DriverManager1.3、API详解-Connection1.4、API详解-Statement1.5、API详解-ResultSet1.6、API详解-PreparedStatement1.6.1、API详解-PreparedStatement-SQL注入演示1.6.2、API详解-PreparedState…

NR PDCP(二) format/parameters

这篇主要是PDCP PDU&#xff0c;PDCP Formats及其参数的含义&#xff0c; 收发过程中用到的变量&#xff0c;常量和定时器的总结&#xff0c;都是概念性描述。 PDU 和RLC 类似&#xff0c;PDCP PDU 也分为data pdu 和control PDU。PDCP data PDU 的data field对应的是user pla…

FPGA USB FX2 ov5640摄像头视频采集 驱动CY7C68013A实现 提供2套工程源码和技术支持

目录 1、前言2、我这儿已有的 FPGA USB 通信方案3、CY7C68013A芯片解读和硬件设计FX2 简介SlaveFIFO模式及其配置 4、工程详细设计方案5、vivado工程6、上板调试验证7、福利&#xff1a;工程代码的获取 1、前言 目前USB2.0的实现方案很多&#xff0c;但就简单好用的角度而言&a…

SpringBoot的缓存管理

缓存是分布式系统中的重要组件&#xff0c;主要解决数据库数据的高并发访问问题。在实际开发中&#xff0c;尤其是用户 访问量较大的网站&#xff0c;为了提高服务器访问性能、减少数据库的访问压力、提高用户体验&#xff0c;使用缓存显得 尤为重要。Spring Boot对缓存提供了良…

js将后台返回的数据转化为树形结构(扁平数组转树状结构)

前言 做项目使常遇到需要将后台返回的数据&#xff0c;转换为树状结构给用户展现&#xff0c;例如&#xff1a; 这也是前端面试常考的算法题&#xff0c;一起来检测一下吧。 步骤 准备一个空的树对象。遍历列表中的每个元素。对于每个元素&#xff0c;根据该元素的父级ID找到…

Linux常用命令——fdisk命令

在线Linux命令查询工具 fdisk 查看磁盘使用情况和磁盘分区 补充说明 fdisk命令用于观察硬盘实体使用情况&#xff0c;也可对硬盘分区。它采用传统的问答式界面&#xff0c;而非类似DOS fdisk的cfdisk互动式操作界面&#xff0c;因此在使用上较为不便&#xff0c;但功能却丝…

ERP重构-SLA子分类账-分布式实现方案

背景 ERP中的GL总账模块&#xff0c;明细数据来源于各个业务模块如库存、成本、应收、应付、费控、资产等&#xff0c;统称为子模块&#xff0c;生成的账叫做子分类账。然而记账的业务逻辑各式各样&#xff0c;但是最终输出都是来源、类型、期间、科目、借贷金额等等关键信息。…

Java-数据结构(二)-Map:HashMap、TreeMap、LinkedHashMap

目录 一、 引言二、问题2.1 什么是Map2.2 使用Map的好处2.3 Map的底层原理2.4 Key和Value的含义2.5 Key值为什么不能重复2.6 Key值和Hash的关系 三、 HashMap3.1 初始化HashMap3.2 添加和获取元素3.3 遍历HashMap3.4 删除元素3.5实现原理①HashMap的put()方法②HashMap的get()方…

【海量数据挖掘/数据分析】 之 贝叶斯分类算法(朴素贝叶斯分类、贝叶斯分类计算流程、拉普拉斯修正、贝叶斯分类实例计算)

【海量数据挖掘/数据分析】 之 贝叶斯分类算法&#xff08;朴素贝叶斯分类、贝叶斯分类计算流程、拉普拉斯修正、贝叶斯分类实例计算&#xff09; 目录 【海量数据挖掘/数据分析】 之 贝叶斯分类算法&#xff08;朴素贝叶斯分类、贝叶斯分类计算流程、拉普拉斯修正、贝叶斯分类…