Makefile 语法速查

本文是我在看南京大学NEMU项目 makefile 总结的看到的语法,非面相零基础人员学习。

make​ 是一个用于构建大型项目的命令工具,其通过预先定义的 Makefile 来构建可执行文件。Makefile 中定义了各文件之间的依赖关系,以及需要执行哪些相应的命令来完成项目构建。

make的基础参数:

  • -s​:构建过程中不输出命令
  • -C DIRECTORY​:在构建之前,切换工作目录

基础语法

注释:以#​开头的内容都讲别注释,make命令在识别时自动忽略。

目标构建语法:由目标文件依赖文件执行命令构成,具体结构如下。

.PHONY: clean all
.DEFAULT_GOAL: app	# 指定默认构建目标

targets = hello	# 变量

all: target
	@echo "all done"	# @ 可以标记不在终端输出命令的内容

target: prerequisites …
	recipe	# 注意,使用制表符缩进!!# %表示模式匹配
%.o: $*.c
	gcc $^ -o $@

# 双::可以独立定义构建语法,不受限于別引用方法
clean::
	rm -rf *.o

.PHONY​ 可以用于标记哪些目标方法属于伪目标,这样 Make 就不会去检查文件是否真实存在了,并且永远会执行这个命令。

注:make 命令依赖文件的时间戳来判定是否需要重新构建项目,若依赖文件的时间戳晚于目标文件,则 make 命令认为源码有更新,需要重新编译。

特殊符号

  • $@​:代表目标文件
  • $^​:代表所有的依赖文件
  • $<​:代表第一个依赖文件
  • $*​:代表在 % ​通配符中匹配到的部分
  • $?​:代表比目标文件的时间戳还要新的文件,这里可以理解为在构建完成之后被修改的部分文件

变量

makefile 中的变量类似于 C 语言中的宏,存储的还是文本内容。常用于存储目标文件、编译参数等内容。通过 $(VAR)​ 语法就可以引用变量了。使用override​修饰符可以强制对变量进行赋值操作。

对于变量有以下几种常见赋值操作。

  • =​ ​简单赋值:无论变量是否已存在都重新定义

  • ?=​ ​条件赋值:若变量已被定义过则不在定义

  • +=​ ​追加赋值:在原有值的基础上追加新的值

  • :=​展开赋值:变量不会受到后续行的影响而改变。这个方法较为特殊,以下将展开讲解。

    首先,我们需要知道,make在读取文件时做的第一件事情并不是直接构建,而是展开Makefile。特别是在变量赋值的过程中引用了其他变量,这就导致了=​和:=​在实际运行过程中展现出了不同的效果。

    x = foo
    y = $(x) bar
    x = xyz
    # y = xyz bar
    
    x := foo
    y := $(x) bar
    x := xyz
    # y = foo bar
    

默认变量

  • $(MAKE)​:make命令的路径
  • $(MAKECMDGOALS)​:本次构建的目标文件

特殊语法$(变量名:原后缀=新后缀)​,对变量进行文本替换操作。

高级语法

include语法:引用指定文件内容,也是 makefile 格式的文件,通常以 .mk ​结尾。若引用文件不存在,-include ​则会忽略错误并继续构建。

条件分支语法

ifeq (arg1, arg2)	# 若arg1与arg2相等则执行, 可以是变量、函数或留空
	recipe
endif

ifneq (arg1, arg2)	# 不相等则执行

函数

函数的基本格式是 $(函数名称 参数1, 参数2 ...)​,Makefile 内置了大量函数一般足够开发使用。

  • $(shell COMMAND)​:在 Makefile 中执行 Shell 命令
  • $(wildcard pattern)​:查找符合 pattern 的文件或目录
  • $(info text)​:输出普通信息
  • $(warning text)​:输出警告信息
  • $(error msg)​:输出错误信息并终止构建流程
  • $(patsubst pattern,replacement,text)​:将 text​ ​中符合 pattern​ ​模式的内容替换为 replacement​ ​所指定的内容
  • $(filter-out pattern,text)​:从 text​ ​文本中去除符合 pattern​ ​模式的内容,返回剩下的内容
  • $(addprefix text)​:为字符串添加前缀
  • $(call function_name,param1,param2,...)​:调用自定义函数,并传入相应参数

自定义函数

单行函数:replace_string = $(subst $(1),$(2),$(3))​,其中 $(1)​ 表示接受的第一个参数。

多命令函数

define call_fixdep
    @$(FIXDEP) $(1) $(2) unused > $(1).tmp
    @mv $(1).tmp $(1)
endef


本文经「原本」原创认证,作者乾坤盘,访问yuanben.io查询【1XECQIZS】获取授权信息。

posted @   乾坤盘  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 本地部署 DeepSeek:小白也能轻松搞定!
· 基于DeepSeek R1 满血版大模型的个人知识库,回答都源自对你专属文件的深度学习。
· 在缓慢中沉淀,在挑战中重生!2024个人总结!
· Tinyfox 简易教程-1:Hello World!
· 大人,时代变了! 赶快把自有业务的本地AI“模型”训练起来!
点击右上角即可分享
微信分享提示