当前位置: 首页 > news >正文

Makefile学习(二)- 语法(变量、伪目标)

一、简介

       上一章节,我们介绍了Makefile的基本规则,如果不了解的可以先看这篇文章:https://blog.csdn.net/qq_26226375/article/details/151828250?sharetype=blogdetail&sharerId=151828250&sharerefer=PC&sharesource=qq_26226375&spm=1011.2480.3001.8118

        Makefile语法是一套用于定义编译规则的特殊格式,核心是通过“规则”描述文件依赖关系和编译命令。下面我们来详细介绍下。

二、语法

%(通配符)

        %可以匹配任意字符串,用于批量定义规则。例如上一章节的Makefile文件。

a.o: a.cgcc -o a.o -c a.c

        利用通配符,可以修改为

%.o: %.cgcc -o %.o -c %.c

       %.o表示所有的.o文件,%.c表示所有的.c文件

        但是这样写歧义会非常的大,make执行是会直接报错。

自动变量

        简化命令中的文件引用,常用如下指令

  • $@当前规则的目标文件
  • $<当前规则的第一个依赖文件
  • $^当前规则的所有依赖文件(去重)
  • $+当前规则的所有依赖文件(保留重复)

        加入自动变量后,可以优化如下代码

test: a.o b.ogcc -o test a.o b.oa.o: a.cgcc -o a.o -c a.cb.o: b.cgcc -o b.o -c b.c

        加入变量

test: a.o b.ogcc -o $@ $^%.o: %.cgcc -o $@ -c $<

      $@为当前规则目标文件,则gcc -o test a.o b.o可以缩减为gcc -o $@ a.o b.o

        $^为当前规则依赖的所有文件,则gcc -o $@ a.o b.o可以缩减为gcc -o $@ $^

        $<为当前规则的第一个依赖文件,则gcc -o b.o -c b.c可以缩减为gcc -o b.o -c $<

变量

        变量用于简化重复内容,定义和引用方式。常见的表达方式有如下:

变量名 = 值       # 递归展开(可能有副作用)
变量名 := 值      # 简单展开(推荐)
变量名 ?= 值      # 若变量未定义则赋值
变量名 += 值      # 追加内容
$(变量名)         # 引用变量

        :=(立即赋值)

        变量在定义时立即展开后续修改依赖的变量不会影响当前变量

A := hello
B := $(A) world  # 定义时立即展开,B 的值固定为 "hello world"
A := hi          # 后续修改 A 不影响 Btest:@echo "B = $(B)"  

        =(递归赋值)

        变量在定义时不会展开,在使用时展开,后续变量修改会影响当前变量

SRC = a.c
OBJ = $(SRC:.c=.o)  # 用 = 定义,依赖 SRC# 后续修改 SRC
SRC += b.ctest:@echo "OBJ = $(OBJ)"  

        ?=(条件赋值)

        仅当变量未被定义过时才赋值,若变量已经存在,则不改变其值。

SRC = a.c
SRC ?= b.cSRC2 = a.c
SRC2 = b.ctest:@echo "SRC = $(SRC), SRC2 = $(SRC2)" 

        +=(追加赋值)

        向已定义的变量追加内容,自动在新内容前添加空格(分隔多个值)

SRC := a.c b.c
SRC += c.c  test:@echo "SRC = $(SRC)"  

        按照这个,如下代码可以进一步优化。

test: a.o b.ogcc -o $@ $^%.o: %.cgcc -o $@ -c $<

        引入变量

CC := gcc # 指定编译器
SRC := a.c b.c # 指定源文件
OBJ := $(SRC:.c=.o) # 指定目标文件test: $(OBJ)$(CC) -o $@ $^	# 也可以写为 $(CC) -o $@ $(OBJ)%.o: %.c$(CC) -o $@ -c $<

        这里$(SRC:.c=.o)是一种字符串替换语法,用于将变量SRC中所有以.c结尾的文件名替换为.o结尾的文件名,从而自动生成目标文件列表。

伪目标

        用于定义不生成文件的操作,避免与同名文件冲突

        例如,在文件夹中存在clean文件,此时执行make clean将会报错。

        修改代码,声明伪目标

CC := gcc # 指定编译器
SRC := a.c b.c # 指定源文件
OBJ := $(SRC:.c=.o) # 指定目标文件
.PHONY: cleantest: $(OBJ)$(CC) -o $@ $^	# 也可以写为 $(CC) -o $@ $(OBJ)%.o: %.c$(CC) -o $@ -c $<clean:rm -f $(OBJ) test

       all

        这里需要介绍一个特殊的伪目标“all”

        在Makefile中,all是一个特殊的伪目标,通常用于定义默认执行的任务,即当在命令行直接输入make而不指定目标时,make会执行all所定义的操作。例如下面的代码:

CC := gcc # 指定编译器
SRC := a.c b.c # 指定源文件
OBJ := $(SRC:.c=.o) # 指定目标文件
.PHONY: clean allall: test cleanecho "所有目标构建完成"test: $(OBJ)$(CC) -o $@ $^%.o: %.c$(CC) -o $@ -c $<clean:rm -f $(OBJ) test

        运行make等价于make all,会依次构建test和clean,最后输出提示信息。若不定义all,make会默认执行第一个目标test,而忽略clean

        可以看到运行Make后,程序执行了make test 和make clean,导致最终并没有生成.o和test程序。

        而all后面跟的目标文件的顺序也决定了程序运行的顺序,例如将all test clean更换为all clean test,在执行make

CC := gcc # 指定编译器
SRC := a.c b.c # 指定源文件
OBJ := $(SRC:.c=.o) # 指定目标文件
.PHONY: clean allall: clean test echo "所有目标构建完成"test: $(OBJ)$(CC) -o $@ $^	%.o: %.c$(CC) -o $@ -c $<clean:rm -f $(OBJ) test

        可以看到,执行make后,先执行了make clean,再执行了make test。

@

         运行make时,系统会打印执行的命令,如果不希望显示这些命令,可以在命令前加上@。

CC := gcc # 指定编译器
SRC := a.c b.c # 指定源文件
OBJ := $(SRC:.c=.o) # 指定目标文件
.PHONY: allall: clean test @echo "所有目标构建完成"test: $(OBJ)@$(CC) -o $@ $^	%.o: %.c@$(CC) -o $@ -c $<clean:@rm -f $(OBJ) test

        可以看到,所有执行的命令都没有在窗口上回显出来。

http://www.dtcms.com/a/389734.html

相关文章:

  • Winform自定义无边框窗体
  • 文献综述是什么?怎么写好一篇综述?
  • CLIP:开启多模态AI新时代的密钥(上)
  • @[TOC](位运算) # 常见位运算总结
  • 【Block总结】sMLP,全新的“稀疏MLP”模块|即插即用|原模型改进
  • TDengine IDMP 基本功能——数据可视化(4. 仪表盘)
  • 亚信安全与中国联通共同打造的联通联信一体化安全检测与响应平台亮相网安周
  • 短脉冲计数
  • 铝厂天车PLC远程调试解决方案:御控物联网网关赋能工业智造新生态
  • CPU-GPU预处理流程的核心和优化关键 格式流转
  • 混元开源之力:spring-ai-hunyuan 项目功能升级与实战体验
  • 基于开源AI大模型、AI智能名片与S2B2C商城小程序的社群入群仪式设计研究
  • HookConsumerWidget 深入理解
  • Django多数据库实战:Mysql从逻辑隔离到跨库外键问题的解决方案
  • SQL Server索引优化:从原理到实战的完整指南
  • 前端-Vue自定义指令
  • 深度学习调参核心:PyTorch学习率调整策略全解析(一)(附系列PPT关键要点)
  • 如何在保证质量的前提下,快速完成一份 PPT?
  • AssemblyScript 入门教程(3)AssemblyScript 项目搭建与实战入门
  • React 实战进阶视频教程
  • 运维安全08 - 日志检测和 tcpdump (抓包) 的介绍以及使用
  • 感烟火灾探测器工程量计算
  • 数学真题分类刷题(前两章)
  • 基于文本与声学特征的渐冻症言语障碍严重程度分类研究
  • 基于语音合成的数据增强在独立说话人构音障碍严重程度分类中的应用
  • vscode 设置
  • vscode关闭coplit功能
  • ICML 2025|GAPrompt:用于3D视觉模型的几何感知点云提示
  • OCCI使用
  • 如何在命令列将.brd转成.siw