首页 > 其他分享 >makefile文件详解

makefile文件详解

时间:2024-01-23 19:00:25浏览次数:26  
标签:echo 文件 make makefile 目标 详解 构建 txt

1. make

  • 编译:将源代码文件翻译成处理器可执行的二进制文件的过程,这个过程的时间区间称为编译时
  • 构建:指定多个编译过程的先后顺序

make命令是常用的构建工具,诞生于1977年,主要用于C/C++项目工程的构建,make命令的适用场景:只要某一个或多个文件发生变动,就要重新构建项目

2. Makefile

make的语义是制作,制作出某样工件,工件可以是各种可执行文件、中间文件、镜像等,通过Makefile文件描叙构建工件的过程,构建过程由一个或多个规则组成

  • make 命令默认使用工程项目目录下的Makefile文件,可以通过 -f --file 选项指定其位置的Makefile文件

  • 规则(rules)

<target>: <precondition> ...
|table|<command>
...
规则文法:
1. 冒号前面的 <target> 是构建的目标,可以是所构建对象的文件名,或者构建过程达成的目标名
2. 冒号后面的 <precondition> ... 是前置条件,判断目标是否重新构建,重新构建的条件为:只要有一个前置文件不存在或者有过更新(前置文件的mtime比目标的mtime新),跳过已经编译但未修改的文件,降低总编译时间
3. |table| 是一个缩进,必须以该字符起首
4. <command> 是命令,达成该目标需要执行的子命令
5. |table| <command> 可以有多个,是具体的执行过程,<prerequest> |table|<command> 至少存在一个
2.1 目标 -- target

一个目标构成一条规则

  • 目标可以是文件名
# 会在目录下创建 a.txt b.txt文件,b.txt文件先于a.txt文件创建,若b.txt文件的mtime时间戳比a.txt文件的时间戳新则重新执行a.txt的构建过程
# 通过判断当前工程目录下的文件是否存在,判断是否重新执行目标的构建过程
a.txt: b.txt
	cat b.txt > a.txt

b.txt:
	echo "make comand" > b.txt
  • 目标可以是某个操作名,若工程目录存在与操作同名的文件,就会跳过该目标的执行过程,可以通过 .PHONY声明为伪目标,不会检查目标名对应的文件是否存在
# 若当前工程目录下已存在clean文件,则跳过,可以通过 .PHONY指定该目标是一个非文件目标
.PHONY: clean 
clean:
	rm a.txt b.txt
2.2 前置条件 -- precondition

一组以空格隔开的文件名,用于判断目标是否重新构建,如果至少有一个文件不存在或者文件的最后修改时间比目标文件的最后修改时间新,则重新构建该目录

# 会首先依次构建前置条件中的目标文件,最后构建目标文件,反复构建,只要前置条件中的文件最后修改时间戳比目标文件小则跳过目标文件的构建过程
result.txt: file1.txt file2.txt file3.txt
	cat file1.txt file2.txt file3.txt > result.txt

file1.txt:
	echo "file1" > file1.txt

file2.txt:
	echo "file2" > file2.txt

file3.txt:
	echo "file3" > file3.txt
2. 3 命令 -- command

描叙目标是如何创建出来的,由一个或多个shell命令描叙,是构建目标的具体指令,每一行命令在一个进程中并行执行

  • 每个构建命令在各自的shell进程中执行,通过 .ONESHELL指定目标的命令集合都在同一个shell进程中串行
# 看不到变量NAME的值,需要使用$进行$符号的转义,输出不了变量的值
var-get:
	export NAME=cloud
	echo $$NAME
# 写在一行的方式,以分号隔开shell指令
var-get:
	export NAME=cloud;echo $$NAME
# export 与 echo 指令都在同一个shell进程中运行
.ONESHELL:
var-get:
	export NAME=cloud
	echo $$NAME

  • 可以通过 .RECIPEPREFIX 修改命令的前缀,默认为Table字符
result.txt: file1.txt file2.txt file3.txt
	cat file1.txt file2.txt file3.txt > result.txt

# 之后的构建目标的指令列表由 > 开头
.RECIPEPREFIX = >
file1.txt:
> echo "file1" > file1.txt

file2.txt:
> echo "file2" > file2.txt

file3.txt:
> echo "file3" > file3.txt

3. 文法

向make命令描叙字符文字的语法与语义

3.1 注释

以 # 开头,到行尾结束,Bash 与 Python语言 的注释也一样

# export 与 echo 指令都在同一个shell进程中运行
.ONESHELL:
var-get:
	export NAME=cloud	# 设置一个环境变量
	echo $$NAME			# 输出环境变量的值
3. 2 回声

echo -- 执行make命令会打印出每个目标的命令然后再执行,在命令的最开头添加@关闭回声

# export 与 echo 指令都在同一个shell进程中运行
.ONESHELL:
var-get:
	@export NAME=cloud	
	echo $$NAME			

3.2 通配符

选定一组文件名符合通配符的文件,文法规则和bash一致

  • 单个字符
  • 任意长度任意字符*
  • 字符集中单个字符 []
# 删除所有以 .0 结尾的文件
clean:
	rm -f *.o	
3.3 模式匹配

选定文件名相同,但文件类型不同的文件

# 所有 .c 结尾的文件通过命令生成同名的.o文件
%.o: %.c
3. 4 变量与赋值符

声明变量并存储值,在之后代码中访问并引用变量中值

  • 赋值 = := ?= +=
VARIABLE = value
# 在执行时扩展,允许递归扩展。

VARIABLE := value
# 在定义时扩展。

VARIABLE ?= value
# 只有在该变量为空时才设置值。

VARIABLE += value
# 将值追加到变量的尾端。
  • 访问值

通过 $()访问,访问bash变量需要加上$进行转义

# 访问定义的变量与bash变量
name = dream_flish
get-variable:
	@echo $(name)
	@echo $$HOME
  • 内置变量

当前编辑器 CC ,当前使用的make工具 $(MAKE)

# 访问定义的变量与bash变量
name = dream_flish
get-variable:
	@echo "$(CC) $(MAKE)" 
	@echo $$HOME
  • 自动变量

变量的值与当前的规则的目标与前置条件相关

1. $@ 当前目标
2. $< 第一个前置条件
3. $? 比目标文件mtime时间戳更新的前置条件文件,多个以空格隔开
4. $^ 所有前置条件
5. $* 匹配 % 部分
6. $(@D) 目标当前目录名
7. $(@F) 目标当前文件名
8. $(<D) 第一个前置条件的目录名
9. $(<F) 第一个前置条件的文件名
a.txt: b.txt c.txt
	echo $@ # 等价 echo a.txt
	cat $^ > a.txt # 等价 cat b.txt c.txt > a.txt

b.txt:
	echo "b" > b.txt

c.txt:
	echo "c" > c.txt
3. 5 判断与循环

流程控制,满足条件时执行一段代码,不满足时执行另一段代码,利用Bash代码实现循环

BOY_NAMES = ALEX BEI XIXI
GIRL_NAMES = LANGLANG XUEXUE XIAOXIAO
CONDATION = BOY

# 等值判断
ifeq ($(CONDATION), BOY)
	NAMES=$(BOY_NAMES)
else
	NAMES=$(GIRL_NAMES)
endif

# 访问变量中的值
all:
	for name in $(NAMES); do echo $$name; done

4. 函数

完成某项功能的指令集合,调用文法: $(函数名, 参数 ... )

  • shell函数 -- 执行shell命令
files := $(shell seq 1 10)

all:
	echo $(files)
  • wildcard 通配符函数 -- 替换Bash的通配符
# 列出 src目录下所有以.tst后缀结尾的文件
files := $(wildcard src/*.txt)
all:
	echo $(files)
  • subst函数 -- 文本替换
# 小写的i换成大写的I
result := $(subst i,I,i Love C++)
all:
	echo $(result)

5. 编译 C++代码

  1. 在工程目录创建src目录,再在src目录下创建main.cpp文件,写入以下内容
#include <iostream>

int main() {
    std::cout << "I Love C++\n";
}
  1. 在工程目录下创建Makefile文件,写入以下规则
TARGET_DIR = bin
all:
	[ ! -d $)TARGET_DIR ] && mkdir -p $(TARGET_DIR); \
	c++ src/main.cpp -o $(TARGET_DIR)/main


clean:
	rm -f bin/*
  1. 在工程目录执行构建命令并执行编译后的结果
# 编译,没有目标则默认找到的第一个目标
make

# 执行,会输出 I Love C++
./bin/main

# 清理,make命令中输出目标名,多个目标以空格隔开
make clean

标签:echo,文件,make,makefile,目标,详解,构建,txt
From: https://www.cnblogs.com/2bjiujiu/p/17983180

相关文章

  • 这一次,弄明白JS中的文件相关(二):HTTP请求头和响应头
    (一)前置知识开始前,我们先来复习一下HTTP的基础知识。HTTP请求分为:请求行、请求头、空行、请求体(也叫正文、请求实体、请求主体)。HTTP响应分为:状态行(也叫响应行)、响应头、空行、响应体(也叫正文、响应实体、响应主体)。在HTTP请求中,最常见的GET请求是没有请求体的(GET的查询字符串......
  • 详解avcodec_encode_video2 AVERROR(EAGAIN)
    详解avcodec_encode_video2AVERROR(EAGAIN)在视频编码过程中,可能会遇到错误码AVERROR(EAGAIN)。本篇技术博客将详细解释avcodec_encode_video2函数中的AVERROR(EAGAIN)错误码的含义,并讨论可能的原因和解决方案。什么是avcodec_encode_video2?avcodec_encode_video2是FFmpeg(一个流行......
  • Element ui文件下载
    实现步骤设置移入后展示的标签,绑定点击事件 handleDownload(file),file是文件的相关信息<spanclass="el-upload-list__item-actions"style="font-size:16px;padding:010px"><spanv-if="!disabled"class="el-upload-list__item-download"......
  • 使用 easyofd 解析ofd 文件
    使用easyofd解析ofd文件关于OFD格式OFD格式简单来说是PDF的国产替代。目前只有国内一定范围内在用,所以相对应的工具库还比较少。安装easyofdpip安装pipinstalleasyofdgithub源码地址gitclonehttps://github.com/renoyuan/easyofd.git使用easyofdofd转pfdi......
  • 玩转数据处理利器:学会使用 YAML 文件轻松处理数据
    霍格沃兹的测试管理班是专门面向测试与质量管理人员的一门课程,通过提升从业人员的团队管理、项目管理、绩效管理、沟通管理等方面的能力,使测试管理人员可以更好的带领团队、项目以及公司获得更快的成长。提供1v1私教指导,BAT级别的测试管理大咖量身打造职业规划。YAML文件处理什......
  • 死锁详解
    什么是死锁?死锁是指两个或多个进程在执行过程中,因争夺资源而造成的一种相互等待的现象,如果没有外力干涉,这些进程将永远无法继续执行死锁通常发生在多个进程试图同时访问同一资源而无法获取的情况下,例如,进程A需要访问资源C,进程B需要访问资源D,如果进程A获取了资源C的锁,......
  • a标签下载文件 带token
    constdownloadfile=(url,token)=>{constheaders=newHeaders();headers.append('Authorization',token);//设置token//发起Fetch请求fetch(url,{method:'GET',headers:headers,}).then(res=>res......
  • 使用jar命令替换jar包中指定文件
    一、jar命令用法`1. -c创建新的归档文件3.-t列出归档目录和文件5.-x解压缩已归档的指定(或所有)文件7.-u更新现有的归档文件9.-v在标准输出中生成详细输出/提供更详细输出信息11.-f指定归档文件名/为压缩包指定名字13.-m包含......
  • vscode的配置文件
    vscode的配置文件总述:vscode中一般会在项目文件夹下自动生成.vscode文件夹,其中存放若干配置文件(.json),一般有如下文件:下面将解释每个文件的用途与表现。1.c_cpp_propertries.json这个文件是使用vscode进行C++开发时会产生的文件,非C++用户可以直接跳过。其内容大致如下:{......
  • git 查看某一文件的修改记录
    要查看某一文件的修改记录,可以使用以下命令: ```gitlog<文件路径>``` 例如,要查看文件`index.html`的修改记录,可以使用以下命令: ```gitlogindex.html```  这将显示该文件的所有提交记录,包括提交的作者、日期和提交消息。你可以使用上下箭头浏览记录,并按......