Makefile小结
Makefile最基本的规则:target....:prerequisites.....
command
或:target....:prerequisites.....;command
target:目标文件,prerequisites:依赖文件,command:要执行的操作。命令太长可以使用“\”来换行不断行,其中的命令使用UNIX的标准shell,/bin/sh来执行。
基本等同于直接在terminal中输入命令的效果。
伪目标一般指不需要依赖文件的一类目标,可以使用“.PHONY”来显式的指出。
Makefile中的注释以“#”开头,命令以“[Tab]键开头”。注意加注释时,不要直接加在变量定义后边,因为这是Makefile会将空格也计算在变量内。
Makefile默认会将第一个目标设置为最终的目标。
在命令行输入make命令时,默认会在当前目录按“GNUmakefile”,“makefile”,“Makefile”的文件来顺序搜索。如果需要指定特定的Makefile,可以使用make的参数
“-f”,"--file"。在Makefile中可以使用“include”关键字将别的Makefile包含进来。在include前加“-”号,可以让make继续执行,而不论文件是否能读取。
所有的make命令之前加-号,都是忽略函数返回值的。 -rm -rf ./
makefile中的include,有三种形式,
1) include, 2) -include,3) sinclude,sinclude与-include类似,但是兼容性好一些。
Makefile中调用include的方式:
1) 首先在当前或者指定的目录下寻找被调用文件;
2) 如果没有找到,从-I所指定的include目录中寻找,
3) 仍然没有找到,makefile试图寻找匹配规则来生成对应的文件,
常见的应用模式,生成dependence文件 .d文件:
sinclude $(SOURCE:.c = .d) #include .d文件:
%.d:%.c
@set -e;\
$(CC) -MM $(INC_FLAG) $(DEF_FLAG) $< > $@.$$$$;
环境变量MAKEFILES,make会把这个变量的值做成一个类似include的动作,其中有一个区别是,从这个环境变量引入的Makefile的目标不会被识别。这个变量中的值,
用空格分隔。
make中的命令执行时,如果需要之后的一条命令,在前一条的基础上执行,则这两条命令必须写在同一行上,并且用分号隔开。
exec:
cd /home/hchen; pwd;
在描述Makefile中的规则时,make支持三种通配符“*”,“?”,“[...]”
objects = *.o
当变量中定义了通配符时,makefile并不会展开,变量的值就是*.o
objects := $(wildcard *.o)
需要展开时,需要加入wildcard关键字,这时,变量中的值就是所有.o文件的集合
在寻找目标文件和依赖文件的时候,在当前文件中找不到的情况下,make命令会自动搜索“VPATH”所指定的路径。“VPATH”变量中的值用“冒号”分隔。
VPATH = src:../headers
makefile会按顺序,一次搜索./src文件夹和../headers文件夹;
Makefile还有一种关键字“vpath”,用来指定符合模式的文件的所搜路径。 Eg vpath %.c ../foo makefile会在../foo中搜索所有的.c文件
静态模式:<targets...>:<target-pattern>:<prereq-patterns....>
<command>
适用于使用“%”来定义一个目标集模式。prereq-patterns一般也是用“%”来表示某种依赖文件。
可以有两个target,相同的依赖关系以及操作;
bigoutput littleoutput : text.g
generate text.g -$(subst output, , $@) > $@
$@中有几个目标,便等同于几个target
-MM自动生成依赖关系,gcc -MM main.c文件
Makefile中的变量,是大小写敏感的,传统的Makefile的变量名全是大写的命名方式。变量在声明时需要给予初值,在使用时,需要在前边加上“$”符号。可以用“()”
和“{}”来括起变量。如果要表示真实的“$”字符,需要使用“$$”表示。
几种定义方式:A=1234
A:=1234 前边的变量不能使用后边才定义的变量,这样防止上一种定义方式可能发生的变量嵌套时的死锁。
A?=1234 如果A前边没有定义过,这条语句才会有效。
A+=1234 为变量A追加值,以空格隔开,如果变量之前有定义,“+=”会自动继承前次操作的赋值符。“=” “:=” "+="
如果有变量是通过命令行参数来定义的,同时Makefile内部也对它进行了定义,则默认忽略Makefile中的定义。除非加“override”关键字在变量定义时。
对变量列表中的变量可以直接进行替换: $(sources:.c = .d)将之前source中的.c文件都替换为.d文件。
Makefile中还有针对目标的变量和针对模式的变量。
从terminal中将变量传入makefile, 直接make var=2接口,makefile内部直接将var作为一个为赋值的变量就可以。该var的值也可以作为target,来从外部控制makefile流程。
Makefile中的条件判断:make是在读取Makefile时就计算表达式的值,并根据条件表达式的值来选择语句,所以不应该吧自动化变量如($@)放在条件表达式中。
1)ifeq, else, endif
2)ifneq
3)ifdef
4)ifndef
for循环:必须使用$$(),来调用循环变量。
rule1:
for i in $(SOURCE); do echo $$(i); done
Makefile默认会将要执行的命令,在执行前输出到屏幕,当我们用“@”字符在命令前时,这个命令就不会被显示出来了。用“-”在命令前,则该命令即使出现问题,make
也不会退出。
在Makefile中执行命令时,如果要让上一条命令的结果应用于下一条命令时,应该使用“分号”来分隔这两条命令。
Eg: cd /home/hchen cd /home/hchen;
pwd pwd
在Makefile间传递变量,直接在当前环境生成环境变量,在定义变量时,使用“export”关键字。只加一个export后没有变量,则传递所有变量。如果有从命令过来的变量,Makefile会自动在嵌套式的
Makefie中传递。也可以使用unexport来拒绝传递变量;
Makefile中的字符串处理函数:函数调用与变量的使用很像,也是使用“$”来标识。
1)$(subst <from>,<to>,<text>):字符串替换函数。
2)$(patsubst <%from>,<%to>,<text>):模式字符串替换函数。
3)$(strip <string>):去掉字符串的前后空格。
4)$(findstring <fing>,<in>):查找字符串并返回。
5)$(filter <pattern.....>, <text>):过滤函数,返回符合模式的单词。
6)$(filter-out <pattern.....>, <text>):反过滤函数,返回不符合模式的单词。
7)$(sort <list>):给字符串<list>中的单词排序,去除相同的单词。
8)$(word <n>, <text>):取单词函数。
9)$(wordlist <s>, <n>, <text>):取多个单词函数。
10)$(words <text>):统计单词个数函数。
11)$(firstword <text>):取首个单词函数。
Makefile中的文件名操作函数:
1)$(dir <name....>) 取目录函数,可以是多个数据的列表,返回多个。
2)$(notdir <name....>) 取文件函数,与上一函数相反。
3)$(suffix <name.....>) 取后缀函数,如文件后缀。
4)$(basename <name....>) 取前缀函数,除了文件后缀的其他部分。
5)$(addsuffix <suffix>, <name....>) 加后缀函数,加文件后缀。
6)$(addprefix <prefix>, <name....>) 加前缀函数,加除了文件后缀之外的部分。
7)$(join <list1>, <list2>) 连接函数,将<list2>的单词对应的加到<list1>的后边。
Makefile中的其他函数:
1)$(if <condition>, <then-part>, <else_part>)
2)$(origin <variable>) 返回变量的来历
返回值是固定的几个,undefined,default,file,command line,override,automatic,environment,
一般用在变量是否被重新定义,override太过暴力,可以在来自env的进行重定义;
ifeq “$(origin bletch)" "environment"
bletch = barf,
3)$(shell xxx) 引用UNIX的shell命令,与“反引号”作用相同。
contents := $(shell cat foo)
4)$(error <text...>) 表示出现错误,打出text,退出。
5)$(warning <text...>) 表示出现warning,打出text。
6) $(call <expression>, <param1>, <param2> ....)自定义一个参数化的函数
reverse = $(1) $(2) ##首先自定义一个复杂的表达式
foo = $(call reverse , a, b) ##直接调用
##返回a b。
Makefile中的参数“-w”或是“--print-directory”,在切换目录时,输出信息。
“-n”或是“--just-print",只打印出命令及其规则,但是不执行,适合调试。
“-C”或是“--directory”,指定读取makefile的目录。
"-s" make时的参数,全面禁止命令的显示。
“-i” 执行过程中,忽略所有的error;
“-k” 执行过程中,一个target执行错误之后,执行其他的target;
1)嵌套式的makefile,一般讲make和makefiag定义为变量,这样方便一些 make 参数的传递,
2)makefile中定义命令包,命名空间与变量相同,调用也相同;以define开头, endef结束;
define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef
自动化变量$@,表示规则中的目标文件集合,用于匹配目标模式中定义的集合;
$<,依赖目标中的第一个目标的名字,如果依赖目标是以%来定义的,那么$< 表示符合模式的一系列的文件集合,是一一取出来的。
$*,目标模式 %,及其之前的部分;
%.d : %.c
gcc $(INC_FLAG) -o $*.o //其中的$*表示.d文件名
$(shell pwd | sed 's///');来进行目录的操作。
Makefile小结的更多相关文章
- makefile 转载
http://blog.csdn.net/hongfuhaocomon/article/details/51523394 http://blog.csdn.net/lanmanck/article/d ...
- 20155326 2017-2018-1 《信息安全系统设计基础》第2周学习及课堂总结myod
20155326 2017-2018-1 <信息安全系统设计基础>第1次学习及课堂总结myod 虚拟机之前出了一些问题,然后我重新弄了一个新的虚拟机. 先在虚拟机里面安装了git. 安完以 ...
- 移植 Linux 内核
目录 更新记录 1.Linux 版本及特点 2.打补丁.编译.烧写.启动内核 3.内核源码文件结构 4.内核架构分析 4.1 内核配置 4.2 Makefile架构分析 4.3 Kconfig 架构文 ...
- makefile学习小结
=============2016/08/15================ 上午完成makefile的试验,缩短了代码量,现在make强大,有缺省的变量,能自己推导关系,不需要gcc –MM -M ...
- Makefile 使用小结
Makefile的基本格式 #目标:依赖(条件) # 命令 #all: add.c sub.c dive.c mul.c main.c # gcc add.c sub.c div.c mul.c ma ...
- Solaris 命令 小结
Solaris 命令 小结 prstat -a 系统进程监控 Solaris 10默认的shell是sh,可以改成bash #useradd -m -d /home/dave dave -s /bin ...
- 高通平台 lcd driver 调试小结
一.概述 1.1 简介 本文档主要包括LCD模块的驱动流程分析.Framebuffer相关知识.Gralloc等相关内容,以及LCD调试的一些经验和相关bug的分析和讲解. 1.2 开发环境 And ...
- 十天学Linux内核之第十天---总结篇(kconfig和Makefile & 讲不出再见)
原文:十天学Linux内核之第十天---总结篇(kconfig和Makefile & 讲不出再见) 非常开心能够和大家一起分享这些,让我受益匪浅,感激之情也溢于言表,,code monkey的 ...
- tiny210——uboot移植Makefile文章分析
这东西已经写,我们没有时间发布,如今,终于有时间稍微长送记录汇总uboot学习过程.具体了.以后忘了也能够再温习回来嘛有些特殊字符显示得乱掉了 Makefile追踪技巧: 技巧1:能够先从编译目标開始 ...
随机推荐
- 跟bWAPP学WEB安全(PHP代码)--SSL(Server-Side-Include)漏洞
什么是Server-Side-Include漏洞 服务端包含漏洞是指发送指令到服务器,服务器会将指令运行完,把运行结果包含在返回文件中发送给你.利用这种漏洞可以获取服务端的信息甚至执行命令,这样的指令 ...
- 开源网络抓包与分析框架学习-Packetbeat篇
开源简介packbeat是一个开源的实时网络抓包与分析框架,内置了很多常见的协议捕获及解析,如HTTP.MySQL.Redis等.在实际使用中,通常和Elasticsearch以及kibana联合使用 ...
- SQL已存在则更新不存在则插入
不废话,下代码. replace into T_Life_UMessage(message_id,account,isread,isdelete)values(?,?,1,1) 意思是若不存在则插入要 ...
- vue--axios发送请求
首先安装:axios $ npm install axios $ cnpm install axios //taobao源 $ bower install axios 或者使用cdn: <scr ...
- 爬虫之Scrapy详解
性能相关 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢. import requests def fetch_async(url): ...
- 8.17 一个博客demo
2018-8-17 18:13:27 明天周末准备整理一下看看我的博客!!! 说一下思路 1.先搭建框架 1.1 大体分成两块div 左右两部分 <div class="left&qu ...
- 把Asp.Net Core 2.0部署在Linux上,使用Nginx代理服务器,并且用Systemctl命令以服务的方式监听项目
在Linux上部署.net core 2.0程序: 第一步:配置Nginx代理 在/etc/nginx/sites-available/default 中添加 server { listen ; lo ...
- HUST 1605 Gene recombination(广搜,位运算)
题目描述 As a gene engineer of a gene engineering project, Enigma encountered a puzzle about gene recomb ...
- HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6278 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
- C++中的类成员指针
写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...