Makfile总结
Makfile总结
在前面的三篇文章彻底掌握Makefile(一)、彻底掌握Makefile(二)和彻底掌握Makeifle(三)当中我们仔细介绍了Makefile各种使用方法,在本篇文章当中主要是对前面三篇关于makefile的文章做一个总结,方便大家快速查阅和检查。
Makefile基础以及小技巧
Make命令的工作流程
当我们在命令行当中输入make
的时候他的执行流程如下:
- make命令首先会在当前目录下面寻找makefile或者Makefile文件。
- 寻找到makefile文件之后,他会在文件当中寻找到一个编译目标,比如在上面的makefile文件当中他会找到
demo
这个编译目标,而不是clean
这个目标,因为clean
是第二个编译目标。 - 然后make会解析编译目标的依赖,如果这个依赖是其他的编译目标A的话,那么make会先完成它依赖的编译目标A的命令,如果它依赖的编译目标A也存在依赖B的话,make就会去执行依赖的B的编译命令,如此的递归下去,知道有所得依赖目标都存在了,才会完成第一个编译目标的编译,这个也很好理解,只有依赖文件都存在了我们才能够完成正确的编译过程。
Makefile当中的小技巧
- makefile基本规则
编译目标:依赖文件
编译命令
- 一个最基本的makefile
main: demo.o myprint.o
gcc demo.o myprint.o -o out
echo make 解析编译完成
demo.o: demo.c
gcc -c demo.c -o demo.o
myprint.o: myprint.c
gcc -c myprint.c -o myprint.o
clean:
rm myprint.o demo.o out
- 在makefile当中使用变量
cflags=-c
main: demo.o myprint.o
gcc demo.o myprint.o -o out
demo.o: demo.c
gcc $(cflags) demo.c -o demo.o
myprint.o: myprint.c
gcc $(cflags) myprint.c -o myprint.o
clean:
rm myprint.o demo.o out
- 在makefile当中使用include
include submakefile
demo.o: demo.c
gcc $(cflags) demo.c -o demo.o
myprint.o: myprint.c
gcc $(cflags) myprint.c -o myprint.o
clean:
rm myprint.o demo.o out
- 在makefile当中使用PHONY
cflags=-c
main: demo.o myprint.o
gcc demo.o myprint.o -o main
demo.o: demo.c
gcc $(cflags) demo.c -o demo.o
myprint.o: myprint.c
gcc $(cflags) myprint.c -o myprint.o
clean:
rm myprint.o demo.o main
.PHONY: clean # 增加这一行
- 在makefile当中使用通配符
cflags=-c
main: demo.o myprint.o
gcc demo.o myprint.o -o main
%.o: %.c
gcc $(cflags) $<
clean:
rm myprint.o demo.o main
.PHONY: clean
- 在makefile当中使用VPATH自动搜索
cflags=-c
VPATH=./files
main: demo.o myprint.o a.o b.o
gcc demo.o myprint.o a.o b.o -o main
demo.o:demo.c
gcc $(cflags) demo.c
myprint.o:myprint.c
gcc $(cflags) myprint.c
a.o: a.c
gcc $(cflags) $<
b.o: b.c
gcc $(cflags) $<
clean:
rm myprint.o demo.o main
.PHONY: clean
- @符号
有时候在makefile当中我们不想输出某些命令(如果不进行设置makefile会输出每一条我们执行过的命令),我们就可以使用@符号进行修饰。
main: demo.c
@echo hello world
- override覆盖命令行的赋值,让makefile文件当中的变量覆盖命令行当中的变量。
Makefile当中进行if判断
ifeq 和 ifneq
主要是用于判断字符是否相等。
cc=g++
main: demo.c
echo $(cc)
ifeq ($(cc), gcc)
echo $(cc) = 相等的语句执行了
else
echo $(cc) != 不相等的语句执行了
endif
cc=g++
main: demo.c
echo $(cc)
ifneq ($(cc), gcc)
echo $(cc) != gcc
else
echo $(cc) = gcc
endif
ifdef 和 ifndef
判断变量是否被定义或者为空
foo = 1
main: demo.c
echo demo
ifdef foo
echo define foo
else
echo not define foo
endif
main: demo.c
echo demo
ifdef foo
echo define foo
else
echo not define foo
endif
Makefile当中的函数
在makefile当中除了能够使用条件表达式之外我们还可以使用函数,在makefile当中函数的使用规则如下:
$(<函数名> <函数参数>)
或者
将()替换为{}
函数的调用规则如上图所示,函数参数用.隔开。
字符串函数
subst
$(subst <from>,<to>,<text>)
- 字符串替换函数。
- 表示文本,这个函数会将text当中是的字符串替换为。
s = ii am learning makefile
ss = $(subst ii, you, $(s))
main: demo.c
echo demo
echo $(s)
echo $(ss)
patsubst
$(patsubst <pattern>,<replacement>,<text>)
- pattern 表示第一个参数,用于表示如何对 text 进行匹配。
- replacement 表示第二个参数 表示如何对匹配的字符进行重写。
- patsubst在进行匹配替换的时候,会先将字符串text根据空格或者tab键或者回车换行符进行分割,然后一一的进行替换和匹配。
s = a.c b.c d.c abc.c abo.c
ss = $(patsubst %.c, %.o, $(s))
main: demo.c
echo demo
echo $(s)
echo $(ss)
Strip
$(strip <string>)
主要功能去掉字符串 string 首尾的空格。
findstring
$(findstring <find>,<text>)
这个函数的作用是从字符串当中寻找字符串,如果找到了字符串就返回字符串,否则返回空。
filter
$(filter <pattern...>,<text>)
这是一个过滤函数,这个函数执行时,首先会根据空格或者tab键或者回车换行符进行分割,然后一一的进行filter函数的操作。然后遍历每一个被分割出来的字符,如果不满足pattern的规则的话对应的字符就会被过滤掉。
s = a.c abo.c s.o s.y x.o x.y
ss = $(filter %.c %.o, $(s))
main: demo.c
echo $(ss)
filter-out
这个函数和filter的用法是一样的只不过,作用刚好相反,filter是保存符合条件的字符串,filter-out是保存不符合条件的字符串。
s = a.c abo.c s.o s.y x.o x.y
ss = $(filter-out %.c %.o, $(s))
main: demo.c
echo $(ss)
sort
这个函数主要是用于帮助字符串排序的,同时还会取出分割之后相同的字符串。
s = g a b c d e f a a a a
ss = $(sort $(s))
main: demo.c
echo $(ss)
word
$(word <n>,<text>)
这个功能很简单,返回当中第个字符。
s = g a b c d e f a a a a
ss = $(word 1, $(s)) # 取出第一个字符
main: demo.c
echo $(ss)
wordlist
$(wordlist <start>,<end>,<text>)
这个也是从字符串当中取出字符,是取出第个字符一直到第个字符。
s = g a b c d e f a a a a
ss = $(wordlist 1, 5, $(s))
main: demo.c
echo $(ss)
words
统计单词的个数。
s = 1 2 3 4 5
ss = $(words $(s))
main: demo.c
echo $(ss)
firstword
这个函数主要是用于返回第一个字符串的。
s = 1 2 3 4 5
ss = $(firstword $(s))
main: demo.c
echo $(ss)
文件函数
dir与notdir函数
dir函数主要书获取文件路径当中的目录部分,而notdir函数主要是获取文件路径当中文件名的部分
file = ./files/a.c
fdir = $(dir $(file))
nfdir = $(notdir $(file))
main: demo.c
echo $(fdir)
echo $(nfdir)
suffix函数
这个函数主要是用于获取文件的后缀名。
file = ./files/a.c
fdir = $(dir $(file))
nfdir = $(notdir $(file))
name = $(suffix $(file))
main: demo.c
echo $(fdir)
echo $(nfdir)
echo $(name)
basename
这个函数用于获取文件路径当中除去后缀名的部分。
file = ./files/a.c
base = $(basename $(file))
main: demo.c
echo $(base)
addsuffix
这个函数主要是给文件加上后缀的。
file = ./files/a.c
base = $(addsuffix .c, $(file))
main: demo.c
echo $(base)
addprefix
这个函数的主要作用就是在字符串的前面加上一串字符。
file = files/a.c
base = $(addprefix ./src/main/, $(file))
main: demo.c
echo $(base)
其他函数
循环函数foreach
foreach
函数的主要使用规则为:
$(foreach <var>,<list>,<text>)
我们直接使用一个例子来说明这个情况:
files = a.c b.c c.c d.c
new_files = $(foreach n, $(files), $(n)pp)
main: demo.c
echo $(new_files)
call函数
call函数在makefile当中可以用于调用我们自定义的一个表达式,他的语法个数如下面所示:
$(call <expression>,<parm1>,<parm2>,...,<parmn>)
- 表示定义的表达式的名字。
- 表示第n个参数,我们在当中可以使用
$(n)
进行引用。
a=a.c
b=b.c
c=$(a)-------$(b)
main: demo.c
echo $(c)
在makefile当中使用shell函数
我们在makefile的表达式当中可以使用shell的函数。
比如现在我们有一个文件叫做test.txt
,文件的内容如下所示:
a.c b.c c.c d.c
content=$(shell cat test.txt) # 将shell命令的输出内容赋给content
main: demo.c
echo $(content) # 输出content
origin函数
origin这个函数主要是返回变量的定义方式,使用格式如下:
$(origin <variable>) # 其中 variable 是变量名字 这里不需要使用 $ 符号去引用
error函数
在makefile当中我们可以使用error函数让makefie停止执行。当我们有需求:让在某种条件下让makefile停止编译
data=data
ifeq ($(data), data)
$(error "data == data")
endif
main: main.c
gcc main.c
除此之外还有个warning函数使用方法和error一样!
总结
在本篇文章当中主要给大家总结了一些常见的makefile的使用方法,方便大家查阅复习!
以上就是本篇文章的所有内容了,我是LeHung,我们下期再见!!!更多精彩内容合集可访问项目:https://github.com/Chang-LeHung/CSCore
关注公众号:一无是处的研究僧,了解更多计算机(Java、Python、计算机系统基础、算法与数据结构)知识。
Makfile总结的更多相关文章
- Gdb调试工具/ Makfile项目管理
gdb调试工具 gcc -g main.c -o main 常用命令 命令 简写 作用 help h 按模块列 ...
- makfile
1. Makefile 简介 Makefile 是和 make 命令一起配合使用的. 很多大型项目的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项目中各种库和代码之 ...
- libjpeg 编译makfile
一.准备 首先需要下载libjpeg库,网址在这里:http://www.ijg.org/ 如果不想编译就在这下载吧:http://pan.baidu.com/s/1hqeTDre 二.编译 1. 解 ...
- Makfile文件编写
一.make是什么 GNU make是一个工程管理器,专门负责管理.维护较多文件的处理,实现自动化编译.如果一个工程项目中,有成百上千个代码源文件,若其中一个或多个文件进过修改,make就需要能够自动 ...
- makfile.am 和makefile.in 的使用
参考 http://blog.csdn.net/vevenlcf/article/details/48134313 http://linux.chinaunix.net/techdoc/develop ...
- 如何在makfile中查看变量的值
在makefile中查看变量的取值是多少应该是一个比较麻烦的问题,但是本大神自己研究出一个十分方便的方法.这个方法十分简单.现在介绍如下 如果在一个十分复杂庞大的makefile文件中,有个地方用到一 ...
- Linux高级编程--03.make和makfile
Makefile语法基础 在Linux下,自动化编译工具是通过make命令来完成的(一些工具厂商也提供了它们自己的make命令,如gmake等),make命令的基本格式如下: make [-f mak ...
- Android中makfile的随记
什么是makefile?也许非常多Winodws的程序员都不知道这个东西,由于那些Windows的IDE都为你做了这个工作,但我认为要作一个好的Android底层程序员. makefile还是要懂. ...
- 多目录,多可执行文件的Makfile的编写
1.前言 在目前的工作中,我遇到这样的一个工作情景,可以认为我要开发一个库,这个库的有多个模块,每个模块的.c放到src中,.h放到include中,这应该是个标准做法. drwxr-xr-x. ro ...
随机推荐
- flv.js的追帧、断流重连及实时更新的直播优化方案
目录 1. 前言 2. 前端直播 2.1 常见直播协议 2.2 flv.js 的原理 2.3 flv.js 的简单使用 3. flv.js 的优化方案 3.1 追帧-解决延迟累积问题 3.2 断流重连 ...
- NOI / 2.1基本算法之枚举 1749:数字方格
描述: 如上图,有3个方格,每个方格里面都有一个整数a1,a2,a3.已知0 <= a1, a2, a3 <= n,而且a1 + a2是2的倍数,a2 + a3是3的倍数, a1 + a2 ...
- 枚举子集为什么是 O(3^n) 的
这是更新日志 \(2021/2/9\) 代数推导 \(2021/2/10\) 组合意义,构建 TOC 目录 枚举子集 复杂度证明 代数推导 组合意义 Summary 枚举子集 枚举子集为什么是 \(O ...
- css基础05
无关浏览器,只想对于原来的位置.而且下面的盒子也不会升上去. 没有父亲的时候就是以浏览器为标准的. 父亲没定位,爷爷有定位,就按照爷爷的,不管父亲了. 绝对定位飘起来比浮动还要高.飘起来了它的位置就会 ...
- 使用Hexo建立一个轻量、简易、高逼格的博客
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_93 在之前的一篇文章中,介绍了如何使用Hugo在三分钟之内建立一个简单的个人博客系统,它是基于go lang的,其实,市面上还有一 ...
- async...await在tcp通讯中的正确用法
引言 编程能力在不断的总结中进步以及成长,最近的半年里,对之前的开源项目代码进行回归,在重构的过程中进行了很多思考,很多次都想放弃重构,毕竟一个已经在使用的项目,重构基础代码就相当于重新开发了,不过最 ...
- 浅谈 Raft 分布式一致性协议|图解 Raft
前言 本篇文章将模拟一个KV数据读写服务,从提供单一节点读写服务,到结合分布式一致性协议(Raft)后,逐步扩展为一个分布式的,满足一致性读写需求的读写服务的过程. 其中将配合引入Raft协议的种种概 ...
- Vue3 Transition 过渡效果之基于 CSS 过渡
介绍 Transistion 路由组件的切换.动态组件的切换.v-if 条件渲染组件以及 v-show 显示组件原本是没有任何过渡(CSS 动画)效果的.然而,Vue 的内置组件<Transit ...
- which 和 that 在定语从句中作介词宾语的用法
关系代词在定语从句中作介词的宾语,且介词在关系代词之前时,关系代词应该用 which:介词在定语从句句末,关系代词可以用 that 或 which. (一)He teaches in a school ...
- Web 前端模块出现的原因,以及 Node.js 中的模块
模块出现原因 简单概述 随着 Web 2.0 时代的到来,JavaScript 不再是以前的小脚本程序了,它在前端担任了更多的职责,也逐渐地被广泛运用在了更加复杂的应用开发的级别上. 但是 JavaS ...