makefile中if then写法
Makefile文件语法

Makefile⽂件语法概述本⽂将介绍Makefile种注释、回显、通配符、变量、循环判断、函数注释Makefile中只有单⾏注释,没有多⾏注释,注释以 # 开头。
以下Makefile注释⽚段节选⾃的Makefile# Makefile for installing Lua# See doc/readme.html for installation and customization instructions.# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================# Your platform. See PLATS for possible values.PLAT= noneechoing(回显)通常,make在执⾏命令⾏之前会把要执⾏的命令⾏进⾏输出。
我们称之为“回显”,就好像我们输⼊命令执⾏⼀样。
@如果要执⾏的命令⾏以字符“@”开始,则make在执⾏时这个命令就不会被回显。
典型的⽤法是我们在使⽤“echo”命令输出⼀些信息时。
如:@echo 开始编译XXX模块......当make执⾏时,将输出“开始编译XXX模块......”这个信息。
如果在命令⾏之前没有字符“@”,那么,make的输出就是:echo编译XXX模块......编译XXX模块......“-n”或“--just-print”如果使⽤make的命令⾏参数“-n”或“--just-print”,那么make执⾏时只显⽰所要执⾏的命令,但不会真正的去执⾏这些命令。
只有在这种情况下make才会打印出所有make需要执⾏的命令,其中也包括了使⽤“@”字符开始的命令。
这个选项对于我们调试Makefile⾮常有⽤,使⽤这个选项我们可以按执⾏顺序打印出Makefile中所有需要执⾏的命令。
“-s”或“--slient”make参数“-s”或“--slient”则是禁⽌所有执⾏命令的显⽰,就好像所有的命令⾏均使⽤“@”开始⼀样。
makefile正则表达式

makefile正则表达式makefile是一种常用的工具,可以用于自动化构建和管理项目。
在makefile中,正则表达式是一个强大的工具,可以帮助我们更方便地匹配和处理文本内容。
makefile中常用的正则表达式包括:1. ^(起始符):匹配字符串的开头。
2. $(结束符):匹配字符串的结尾。
3. .(点号):匹配除了换行符外的任意一个字符。
4. *(星号):匹配前面的字符出现0个或多个。
5. +(加号):匹配前面的字符出现1个或多个。
6. ?(问号):匹配前面的字符出现0个或1个。
7. [ ](中括号):匹配中括号中任意一个字符。
8. [^ ](中括号取反):匹配不在中括号中的任意一个字符。
9. ( )(圆括号):将括号中的内容视为一个整体,可以和其他正则表达式一起使用。
除了这些常用的正则表达式外,还有一些特殊的符号和语法可以帮助我们更精确地匹配文本内容,比如:1. (反斜杠):转义符,可以将特殊字符转义为普通字符。
2. |(竖线):或运算符,可以匹配多个表达式中的一个。
3. { }(花括号):重复次数符号,可以指定一个字符或表达式的重复次数。
在使用正则表达式时,我们需要注意一些事项,比如:1. 正则表达式是区分大小写的。
2. 正则表达式中的空格和换行符也会被匹配。
3. 正则表达式可能会匹配到我们不需要的内容,因此需要通过进一步筛选和处理来达到我们的目的。
总之,正则表达式在makefile中的应用非常广泛,可以帮助我们更方便地编写自动化构建和管理脚本。
熟练掌握正则表达式的使用方法,可以极大地提高我们的工作效率。
Makefile 语法分析

Makefile 语法分析第一部分VERSION = 2# 给变量VERSION赋值PATCHLEVEL = 6# 给变量PATCHLEVEL赋值SUBLEVEL = 22# 给变量SUBLEVEL赋值EXTRAVERSION = .6# 给变量EXTRAVERSION赋值NAME = Holy Dancing Manatees, Batman!# 给变量NAME赋值# *DOCUMENTATION*# To see a list of typical targets execute "make help"# More info can be located in ./README# Comments in this file are targeted only to the developer, do not# expect to learn how to build the kernel reading this file.# Do not:# o use make's built-in rules and variables# (this increases performance and avoid hard-to-debug behavour);# o print "Entering directory ...";MAKEFLAGS += -rR --no-print-directory# 操作符“+=”的作用是给变量(“+=”前面的MAKEFLAGS)追加值。
# 如果变量(“+=”前面的MAKEFLAGS)之前没有定义过,那么,“+=”会自动变成“=”;# 如果前面有变量(“+=”前面的MAKEFLAGS)定义,那么“+=”会继承于前次操作的赋值符;# 如果前一次的是“:=”,那么“+=”会以“:=”作为其赋值符# 在执行make时的命令行选项参数被通过变量“MAKEFLAGS”传递给子目录下的make程序。
Makefile变量使用条件及判断使用

Makefile变量使用条件及判断使用使用变量————在Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方。
其与C/C++所不同的是,你可以在Makefile中改变其值。
在Makefile中,变量可以使用在“目标”,“依赖目标”,“命令”或是Makefile的其它部分中。
变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有“:”、“#”、“=”或是空字符(空格、回车等)。
变量是大小写敏感的,“foo”、“Foo”和“FOO”是三个不同的变量名。
传统的Makefile的变量名是全大写的命名方式,但我推荐使用大小写搭配的变量名,如:MakeFlags。
这样可以避免和系统的变量冲突,而发生意外的事情。
有一些变量是很奇怪字串,如“$<”、“$@”等,这些是自动化变量,我会在后面介绍。
一、变量的基础变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号,但最好用小括号“()”或是大括号“{}”把变量给包括起来。
如果你要使用真实的“$”字符,那么你需要用“$$”来表示。
变量可以使用在许多地方,如规则中的“目标”、“依赖”、“命令”以及新的变量中。
先看一个例子:objects = program.o foo.o utils.oprogram : $(objects)cc -o program $(objects)$(objects) : defs.h变量会在使用它的地方精确地展开,就像C/C++中的宏一样,例如:foo = cprog.o : prog.$(foo)$(foo)$(foo) -$(foo) prog.$(foo)展开后得到:prog.o : prog.ccc -c prog.c当然,千万不要在你的Makefile中这样干,这里只是举个例子来表明Makefile中的变量在使用处展开的真实样子。
手把手教你如何写Makefile

手把手教你如何写Makefile陈皓 2005.04.01一、Makefile的规则在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
target ... : prerequisites ...commandtarget也就是一个目标文件,可以是Object File,也可以是执行文件。
还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。
(任意的Shell命令)这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites 中的文件,其生成规则定义在command中。
说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。
这就是Makefile的规则。
也就是Makefile中最核心的内容。
说到底,Makefile的东西就是这样一点,好像我的这篇文档也该结束了。
呵呵。
还不尽然,这是Makefile的主线和核心,但要写好一个Makefile还不够,我会以后面一点一点地结合我的工作经验给你慢慢到来。
内容还多着呢。
:)二、一个示例正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。
edit : main.o kbd.o command.o display.o \insert.o search.o files.o utils.occ -o edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.omain.o : main.c defs.hcc -c main.ckbd.o : kbd.c defs.h command.hcc -c kbd.ccommand.o : command.c defs.h command.hcc -c command.cdisplay.o : display.c defs.h buffer.hcc -c display.cinsert.o : insert.c defs.h buffer.hcc -c insert.csearch.o : search.c defs.h buffer.hcc -c search.cfiles.o : files.c defs.h buffer.h command.hcc -c files.cutils.o : utils.c defs.hcc -c utils.cclean :rm edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.o反斜杠(\)是换行符的意思。
多目录的MAKEFILE

由于涉及到多目录下makefile文件的编写,每个目录下makefile 文件都不相同。
现在简单说下我的多目录下makefile文件的编写。
我把所需要的目录都放在src里面,如图所示其中libs存放库文件,bin存放可执行文件,app存放源文件目录,include存放所要包含的头文件makefile编写如下:TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)export TOPDIRLIBPATH := $(TOPDIR)/libsexport LIBPATH######################################################################### sub directoriesSUBDIRS = app.PHONY : $(SUBDIRS)########################################################################all: depend $(SUBDIRS)depend dep:@for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir .depend ; done$(SUBDIRS):$(MAKE) -C $@ allclean:@for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir clean ; done在app下有自己的源文件目录,如图:里面有一个项目叫ebook,当然还可以放更多的项目进来,ebook里面放的就是源文件了,makefile如下:SUBDIRS = ebook #项目是什么,就改什么.PHONY : $(SUBDIRS)all: .depend $(SUBDIRS)$(SUBDIRS):$(MAKE) -C $@ all.depend dep:@for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir .depend ; doneclean:@for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir clean ; done同样在ebook中也要写makefile,也是最后一个makefile了INCLUDEDIRS += -I. -I/usr/include/microwin -I/$(TOPDIR)/includeCC = gccCFLAGS = -O4 $(INCLUDEDIRS)ELF = ../../bin/ebook #相对于可执行文件AOBJS = $(patsubst %.s, %.o, $(wildcard *.s))COBJS = $(patsubst %.c, %.o, $(wildcard *.c))CPPOBJS = $(patsubst %.cpp, %.o, $(wildcard *.cpp))OBJS = $(AOBJS) $(COBJS) $(CPPOBJS)all: .depend $(OBJS)$(CC) $(CFLAGS) $(OBJS) \-L $(LIBPATH) -lini\-L /usr/lib -ljpeg -lnano-X -lfreetype -lttf -lz -lpthread\-L /usr/X11R6/lib -lX11\-o $(ELF)chmod 755 $(ELF)########################################################################.depend: Makefile $(AOBJS:.o=.S) $(COBJS:.o=.c) $(CPPOBJS:.o=.cpp)$(CC) -M $(CFLAGS) $(AOBJS:.o=.S) $(COBJS:.o=.c) $(CPPOBJS:.o=.cpp) > $@sinclude .depend########################################################################clean:rm -f *.o .dependrm -f $(ELF)好了,现在就可以在src下敲写make了。
Makefile经典教程(最掌握这部分足够---因为汇集全部精华)!!!!!!!!!!

Makefile经典教程0 Makefile概述什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。
这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。
特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
因为,makefile关系到了整个工程的编译规则。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。
可见,makefile都成为了一种在工程方面的编译方法。
现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。
当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。
必竟,这个make是应用最为广泛的,也是用得最多的。
而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。
在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。
makefile中的curdir函数

makefile中的curdir函数Makefile中的curdir函数是一个内建函数,它用于获取当前Makefile文件所在的目录路径。
在本文中,我将逐步回答有关curdir函数的问题,包括它的作用、语法和使用方法。
1. curdir函数的作用是什么?curdir函数可以帮助我们获取当前Makefile文件所在的目录路径。
这在构建复杂的项目时非常有用,因为有时我们需要根据当前目录的位置来执行特定的命令或设置相应的变量。
2. curdir函数的语法是什么?curdir函数的语法非常简单,只需使用(curdir)即可。
与其他Makefile函数一样,它需要用美元符号和括号来引用。
3. 如何使用curdir函数?使用curdir函数非常简单。
只需在需要获取当前目录路径的位置使用(curdir),它将被替换为当前Makefile文件所在的目录路径。
以下是一个示例,展示了如何使用curdir函数来获取当前目录路径:# 当前目录路径CUR_DIR := (curdir)all:echo "当前目录路径: (CUR_DIR)"在以上示例中,(CUR_DIR)将被替换为当前Makefile文件所在的目录路径,并输出到终端。
4. curdir函数示例下面是一个更详细的示例,展示了如何使用curdir函数进行条件判断和设置路径变量:# 当前目录路径CUR_DIR := (curdir)# 设置目录路径变量TARGET_DIR := (CUR_DIR)/buildall: create_direcho "目录已创建: (TARGET_DIR)"create_dir:# 如果目录不存在,则创建目录if [ ! -d "(TARGET_DIR)" ]; then \mkdir -p "(TARGET_DIR)"; \fi在以上示例中,我们首先使用curdir函数获取当前Makefile文件的目录路径,并将其存储在CUR_DIR变量中。
Makefile使用总结

Makefile使⽤总结1. Makefile 简介Makefile 是和 make 命令⼀起配合使⽤的.很多⼤型项⽬的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项⽬中各种库和代码之间的依赖关系不知会多复杂. Makefile的组织流程的能⼒如此之强, 不仅可以⽤来编译项⽬, 还可以⽤来组织我们平时的⼀些⽇常操作. 这个需要⼤家发挥⾃⼰的想象⼒.本篇博客是基于⽽整理的, 有些删减, 追加了⼀些⽰例.⾮常感谢 gunguymadman_cu 提供如此详尽的Makefile介绍, 这正是我⼀直寻找的Makefile中⽂⽂档.1.1 Makefile 主要的 5个部分 (显⽰规则, 隐晦规则, 变量定义, ⽂件指⽰, 注释)Makefile基本格式如下:target ... : prerequisites ...command......其中,target - ⽬标⽂件, 可以是 Object File, 也可以是可执⾏⽂件prerequisites - ⽣成 target 所需要的⽂件或者⽬标command - make需要执⾏的命令 (任意的shell命令), Makefile中的命令必须以 [tab] 开头1. 显⽰规则 :: 说明如何⽣成⼀个或多个⽬标⽂件(包括⽣成的⽂件, ⽂件的依赖⽂件, ⽣成的命令)2. 隐晦规则 :: make的⾃动推导功能所执⾏的规则3. 变量定义 :: Makefile中定义的变量4. ⽂件指⽰ :: Makefile中引⽤其他Makefile; 指定Makefile中有效部分; 定义⼀个多⾏命令5. 注释 :: Makefile只有⾏注释 "#", 如果要使⽤或者输出"#"字符, 需要进⾏转义, "\#"1.2 GNU make 的⼯作⽅式1. 读⼊主Makefile (主Makefile中可以引⽤其他Makefile)2. 读⼊被include的其他Makefile3. 初始化⽂件中的变量4. 推导隐晦规则, 并分析所有规则5. 为所有的⽬标⽂件创建依赖关系链6. 根据依赖关系, 决定哪些⽬标要重新⽣成7. 执⾏⽣成命令2. Makefile 初级语法2.1 Makefile 规则2.1.1 规则语法规则主要有2部分: 依赖关系和⽣成⽬标的⽅法.语法有以下2种:target ... : prerequisites ...command...或者target ... : prerequisites ; commandcommand...*注* command太长, 可以⽤ "\" 作为换⾏符2.1.2 规则中的通配符* :: 表⽰任意⼀个或多个字符:: 表⽰任意⼀个字符[...] :: ex. [abcd] 表⽰a,b,c,d中任意⼀个字符, [^abcd]表⽰除a,b,c,d以外的字符, [0-9]表⽰ 0~9中任意⼀个数字~ :: 表⽰⽤户的home⽬录2.1.3 路径搜索当⼀个Makefile中涉及到⼤量源⽂件时(这些源⽂件和Makefile极有可能不在同⼀个⽬录中),这时, 最好将源⽂件的路径明确在Makefile中, 便于编译时查找. Makefile中有个特殊的变量VPATH就是完成这个功能的.指定了VPATH之后, 如果当前⽬录中没有找到相应⽂件或依赖的⽂件, Makefile 回到VPATH指定的路径中再去查找.. VPATH使⽤⽅法:vpath <directories> :: 当前⽬录中找不到⽂件时, 就从<directories>中搜索vpath <pattern> <directories> :: 符合<pattern>格式的⽂件, 就从<directories>中搜索vpath <pattern> :: 清除符合<pattern>格式的⽂件搜索路径vpath :: 清除所有已经设置好的⽂件路径# ⽰例1 - 当前⽬录中找不到⽂件时, 按顺序从 src⽬录 ../parent-dir⽬录中查找⽂件VPATH src:../parent-dir# ⽰例2 - .h结尾的⽂件都从 ./header ⽬录中查找VPATH %.h ./header# ⽰例3 - 清除⽰例2中设置的规则VPATH %.h# ⽰例4 - 清除所有VPATH的设置VPATH2.2 Makefile 中的变量2.2.1 变量定义 ( = or := )OBJS = programA.o programB.oOBJS-ADD = $(OBJS) programC.o# 或者OBJS := programA.o programB.oOBJS-ADD := $(OBJS) programC.o其中 = 和 := 的区别在于, := 只能使⽤前⾯定义好的变量, = 可以使⽤后⾯定义的变量测试 =# Makefile内容OBJS2 = $(OBJS1) programC.oOBJS1 = programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出虽然 OBJS1 是在 OBJS2 之后定义的, 但在 OBJS2中可以提前使⽤$ makeprogramA.o programB.o programC.o测试 :=# Makefile内容OBJS2 := $(OBJS1) programC.oOBJS1 := programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出 OBJS2 中的 $(OBJS1) 为空$ makeprogramC.o2.2.2 变量替换# Makefile内容SRCS := programA.c programB.c programC.cOBJS := $(SRCS:%.c=%.o)all:@echo "SRCS: " $(SRCS)@echo "OBJS: " $(OBJS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.cOBJS: programA.o programB.o programC.o2.2.3 变量追加值 +=# Makefile内容SRCS := programA.c programB.c programC.cSRCS += programD.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.c programD.c2.2.4 变量覆盖 override作⽤是使 Makefile中定义的变量能够覆盖 make 命令参数中指定的变量语法:override <variable> = <value>override <variable> := <value>override <variable> += <value>下⾯通过⼀个例⼦体会 override 的作⽤:# Makefile内容 (没有⽤override)SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: nothing################################################## Makefile内容 (⽤override)override SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: programA.c programB.c programC.c2.2.5 ⽬标变量作⽤是使变量的作⽤域仅限于这个⽬标(target), ⽽不像之前例⼦中定义的变量, 对整个Makefile都有效.语法:<target ...> :: <variable-assignment><target ...> :: override <variable-assignment> (override作⽤参见变量覆盖的介绍)⽰例:# Makefile 内容SRCS := programA.c programB.c programC.ctarget1: TARGET1-SRCS := programD.ctarget1:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)target2:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)# bash中执⾏make$ make target1SRCS: programA.c programB.c programC.cSRCS: programD.c$ make target2 <-- target2中显⽰不了 $(TARGET1-SRCS)SRCS: programA.c programB.c programC.cSRCS:2.3 Makefile 命令前缀Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不⽤前缀.3种格式的shell命令区别如下:不⽤前缀 :: 输出执⾏的命令以及命令执⾏的结果, 出错的话停⽌执⾏前缀 @ :: 只输出命令执⾏的结果, 出错的话停⽌执⾏前缀 - :: 命令执⾏有错的话, 忽略错误, 继续执⾏⽰例:# Makefile 内容 (不⽤前缀)all:echo"没有前缀"cat this_file_not_existecho"错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 @)all:@echo "没有前缀"@cat this_file_not_exist@echo "错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ make没有前缀 <-- 只有命令执⾏的结果, 不显⽰命令本⾝cat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 -)all:-echo"没有前缀"-cat this_file_not_exist-echo"错误之后的命令" <-- 这条命令会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: [all] Error 1 (ignored)echo"错误之后的命令" <-- 出错之后的命令也会显⽰错误之后的命令 <-- 出错之后的命令也会执⾏2.4 伪⽬标伪⽬标并不是⼀个"⽬标(target)", 不像真正的⽬标那样会⽣成⼀个⽬标⽂件.典型的伪⽬标是 Makefile 中⽤来清理编译过程中中间⽂件的 clean 伪⽬标, ⼀般格式如下: .PHONY: clean <-- 这句没有也⾏, 但是最好加上clean:-rm -f *.o2.5 引⽤其他的 Makefile语法: include <filename> (filename 可以包含通配符和路径)⽰例:# Makefile 内容all:@echo "主 Makefile begin"@make other-all@echo "主 Makefile end"include ./other/Makefile# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 20K-rw-r--r-- 1 wangyubin wangyubin 125 Sep 2316:13 Makefile-rw-r--r-- 1 wangyubin wangyubin 11K Sep 2316:15 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2316:11 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile'主 Makefile end2.6 查看C⽂件的依赖关系写 Makefile 的时候, 需要确定每个⽬标的依赖关系.GNU提供⼀个机制可以查看C代码⽂件依赖那些⽂件, 这样我们在写 Makefile ⽬标的时候就不⽤打开C源码来看其依赖那些⽂件了.⽐如, 下⾯命令显⽰内核源码中 virt/kvm/kvm_main.c 中的依赖关系$ cd virt/kvm/$ gcc -MM kvm_main.ckvm_main.o: kvm_main.c iodev.h coalesced_mmio.h async_pf.h <-- 这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系2.7 make 退出码Makefile的退出码有以下3种:0 :: 表⽰成功执⾏1 :: 表⽰make命令出现了错误2 :: 使⽤了 "-q" 选项, 并且make使得⼀些⽬标不需要更新2.8 指定 Makefile,指定特定⽬标默认执⾏ make 命令时, GNU make在当前⽬录下依次搜索下⾯3个⽂件 "GNUmakefile", "makefile", "Makefile",找到对应⽂件之后, 就开始执⾏此⽂件中的第⼀个⽬标(target). 如果找不到这3个⽂件就报错.⾮默认情况下, 可以在 make 命令中指定特定的 Makefile 和特定的⽬标.⽰例:# Makefile⽂件名改为 MyMake, 内容target1:@echo "target [1] begin"@echo "target [1] end"target2:@echo "target [2] begin"@echo "target [2] end"# bash 中执⾏make$ lsMakefile$ mv Makefile MyMake$ lsMyMake$ make <-- 找不到默认的 Makefilemake: *** No targets specified and no makefile found. Stop.$ make -f MyMake <-- 指定特定的Makefiletarget [1] begintarget [1] end$ make -f MyMake target2 <-- 指定特定的⽬标(target)target [2] begintarget [2] end2.9 make 参数介绍make 的参数有很多, 可以通过 make -h 去查看, 下⾯只介绍⼏个我认为⽐较有⽤的.参数含义--debug[=<options>]输出make的调试信息, options 可以是 a, b, v-j --jobs同时运⾏的命令的个数, 也就是多线程执⾏ Makefile-r --no-builtin-rules禁⽌使⽤任何隐含规则-R --no-builtin-variabes禁⽌使⽤任何作⽤于变量上的隐含规则-B --always-make假设所有⽬标都有更新, 即强制重编译2.10 Makefile 隐含规则这⾥只列⼀个和编译C相关的.编译C时,<n>.o 的⽬标会⾃动推导为 <n>.c# Makefile 中main : main.ogcc -o main main.o#会⾃动变为:main : main.ogcc -o main main.omain.o: main.c <-- main.o 这个⽬标是隐含⽣成的gcc -c main.c2.11 隐含规则中的命令变量和命令参数变量2.11.1 命令变量, 书写Makefile可以直接写 shell时⽤这些变量.下⾯只列出⼀些C相关的变量名含义RM rm -fAR arCC ccCXX g++⽰例:# Makefile 内容all:@echo $(RM)@echo $(AR)@echo $(CC)@echo $(CXX)# bash 中执⾏make, 显⽰各个变量的值$ makerm -farccg++2.11.2 命令参数变量变量名含义ARFLAGS AR命令的参数CFLAGS C语⾔编译器的参数CXXFLAGS C++语⾔编译器的参数⽰例: 下⾯以 CFLAGS 为例演⽰# test.c 内容#include <stdio.h>int main(int argc, char *argv[]){printf ("Hello Makefile\n");return 0;}# Makefile 内容test: test.o$(CC) -o test test.o# bash 中⽤make来测试$ lltotal 24K-rw-r--r-- 1 wangyubin wangyubin 69 Sep 2317:31 Makefile-rw-r--r-- 1 wangyubin wangyubin 14K Sep 2319:51 <-- 请忽略这个⽂件-rw-r--r-- 1 wangyubin wangyubin 392 Sep 2317:31 test.c$ makecc -c -o test.o test.ccc -o test test.o <-- 这个是⾃动推导的$ rm -f test test.o$ make CFLAGS=-Wall <-- 命令中加的编译器参数⾃动追加⼊下⾯的编译中了cc -Wall -c -o test.o test.ccc -o test test.o2.12 ⾃动变量Makefile 中很多时候通过⾃动变量来简化书写, 各个⾃动变量的含义如下:⾃动变量含义$@⽬标集合$%当⽬标是函数库⽂件时, 表⽰其中的⽬标⽂件名$<第⼀个依赖⽬标. 如果依赖⽬标是多个, 逐个表⽰依赖⽬标$?⽐⽬标新的依赖⽬标的集合$^所有依赖⽬标的集合, 会去除重复的依赖⽬标$+所有依赖⽬标的集合, 不会去除重复的依赖⽬标$*这个是GNU make特有的, 其它的make不⼀定⽀持3. Makefile ⾼级语法3.1 嵌套Makefile在 Makefile 初级语法中已经提到过引⽤其它 Makefile的⽅法. 这⾥有另⼀种写法, 并且可以向引⽤的其它 Makefile 传递参数.⽰例: (不传递参数, 只是调⽤⼦⽂件夹 other 中的Makefile)# Makefile 内容all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 28K-rw-r--r-- 1 wangyubin wangyubin 104 Sep 2320:43 Makefile-rw-r--r-- 1 wangyubin wangyubin 17K Sep 2320:44 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2320:42 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end⽰例: (⽤export传递参数)# Makefile 内容export VALUE1 := export.c <-- ⽤了 export, 此变量能够传递到 ./other/Makefile 中VALUE2 := no-export.c <-- 此变量不能传递到 ./other/Makefile 中all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "VALUE1: " $(VALUE1)@echo "VALUE2: " $(VALUE2)@echo "other makefile end"# bash中执⾏make$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginVALUE1: export.c <-- VALUE1 传递成功VALUE2: <-- VALUE2 传递失败other makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end*补充* export 语法格式如下:export variable = valueexport variable := valueexport variable += value3.2 定义命令包命令包有点像是个函数, 将连续的相同的命令合成⼀条, 减少 Makefile 中的代码量, 便于以后维护.语法:define <command-name>command...endef⽰例:# Makefile 内容define run-hello-makefile@echo -n "Hello"@echo " Makefile!"@echo "这⾥可以执⾏多条 Shell 命令!"endefall:$(run-hello-makefile)# bash 中运⾏make$ makeHello Makefile!这⾥可以执⾏多条 Shell 命令!3.3 条件判断条件判断的关键字主要有 ifeq ifneq ifdef ifndef语法:<conditional-directive><text-if-true>endif# 或者<conditional-directive><text-if-true>else<text-if-false>endif⽰例: ifeq的例⼦, ifneq和ifeq的使⽤⽅法类似, 就是取反# Makefile 内容all:ifeq ("aa", "bb")@echo "equal"else@echo "not equal"endif# bash 中执⾏make$ makenot equal⽰例: ifdef的例⼦, ifndef和ifdef的使⽤⽅法类似, 就是取反# Makefile 内容SRCS := program.call:ifdef SRCS@echo $(SRCS)else@echo "no SRCS"# bash 中执⾏make$ makeprogram.c3.4 Makefile 中的函数Makefile 中⾃带了⼀些函数, 利⽤这些函数可以简化 Makefile 的编写.函数调⽤语法如下:$(<function> <arguments>)# 或者${<function> <arguments>}<function> 是函数名<arguments> 是函数参数3.4.1 字符串函数字符串替换函数: $(subst <from>,<to>,<text>)功能: 把字符串<text> 中的 <from> 替换为 <to>返回: 替换过的字符串# Makefile 内容all:@echo $(subst t,e,maktfilt) <-- 将t替换为e# bash 中执⾏make$ makemakefile模式字符串替换函数: $(patsubst <pattern>,<replacement>,<text>)功能: 查找<text>中的单词(单词以"空格", "tab", "换⾏"来分割) 是否符合 <pattern>, 符合的话, ⽤ <replacement> 替代.返回: 替换过的字符串# Makefile 内容all:@echo $(patsubst %.c,%.o,programA.c programB.c)# bash 中执⾏make$ makeprogramA.o programB.o去空格函数: $(strip <string>)功能: 去掉 <string> 字符串中开头和结尾的空字符返回: 被去掉空格的字符串值# Makefile 内容VAL := " aa bb cc "all:@echo "去除空格前: " $(VAL)@echo "去除空格后: " $(strip $(VAL))# bash 中执⾏make去除空格前: aa bb cc去除空格后: aa bb cc查找字符串函数: $(findstring <find>,<in>)功能: 在字符串 <in> 中查找 <find> 字符串返回: 如果找到, 返回 <find> 字符串, 否则返回空字符串# Makefile 内容VAL := " aa bb cc "all:@echo $(findstring aa,$(VAL))@echo $(findstring ab,$(VAL))# bash 中执⾏make$ makeaa过滤函数: $(filter <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *保留* 符合模式 <pattern> 的单词, 可以有多个模式返回: 符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.o program.a反过滤函数: $(filter-out <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *去除* 符合模式 <pattern> 的单词, 可以有多个模式返回: 不符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter-out %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.c排序函数: $(sort <list>)功能: 给字符串 <list> 中的单词排序 (升序)返回: 排序后的字符串# Makefile 内容all:@echo $(sort bac abc acb cab)# bash 中执⾏make$ makeabc acb bac cab取单词函数: $(word <n>,<text>)功能: 取字符串 <text> 中的第<n>个单词 (n从1开始)返回: <text> 中的第<n>个单词, 如果<n> ⽐ <text> 中单词个数要⼤, 则返回空字符串# Makefile 内容all:@echo $(word 1,aa bb cc dd)@echo $(word 5,aa bb cc dd)@echo $(word 4,aa bb cc dd)# bash 中执⾏make$ makeaadd取单词串函数: $(wordlist <s>,<e>,<text>)功能: 从字符串<text>中取从<s>开始到<e>的单词串. <s>和<e>是⼀个数字.返回: 从<s>到<e>的字符串# Makefile 内容all:@echo $(wordlist 1,3,aa bb cc dd)@echo $(word 5,6,aa bb cc dd)@echo $(word 2,5,aa bb cc dd)# bash 中执⾏make$ makeaa bb ccbb单词个数统计函数: $(words <text>)功能: 统计字符串 <text> 中单词的个数返回: 单词个数# Makefile 内容all:@echo $(words aa bb cc dd)@echo $(words aabbccdd)@echo $(words )# bash 中执⾏make$ make41⾸单词函数: $(firstword <text>)功能: 取字符串 <text> 中的第⼀个单词返回: 字符串 <text> 中的第⼀个单词# Makefile 内容all:@echo $(firstword aa bb cc dd)@echo $(firstword aabbccdd)@echo $(firstword )# bash 中执⾏make$ makeaaaabbccdd3.4.2 ⽂件名函数取⽬录函数: $(dir <names...>)功能: 从⽂件名序列 <names> 中取出⽬录部分返回: ⽂件名序列 <names> 中的⽬录部分# Makefile 内容all:@echo $(dir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ make/home/ ./ ../ ./取⽂件函数: $(notdir <names...>)功能: 从⽂件名序列 <names> 中取出⾮⽬录部分返回: ⽂件名序列 <names> 中的⾮⽬录部分# Makefile 内容all:@echo $(notdir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ makea.c bb.cc.cd.c取后缀函数: $(suffix <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的后缀返回: ⽂件名序列 <names> 中各个⽂件名的后缀, 没有后缀则返回空字符串# Makefile 内容all:@echo $(suffix /home/a.c ./b.o ../c.a d)# bash 中执⾏make$ make.c .o .a取前缀函数: $(basename <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的前缀返回: ⽂件名序列 <names> 中各个⽂件名的前缀, 没有前缀则返回空字符串# Makefile 内容all:@echo $(basename /home/a.c ./b.o ../c.a /home/.d .e)# bash 中执⾏make$ make/home/a ./b ../c /home/加后缀函数: $(addsuffix <suffix>,<names...>)功能: 把后缀 <suffix> 加到 <names> 中的每个单词后⾯返回: 加过后缀的⽂件名序列# Makefile 内容all:@echo $(addsuffix .c,/home/a b ./c.o ../d.c)# bash 中执⾏make$ make/home/a.c b.c ./c.o.c ../d.c.c加前缀函数: $(addprefix <prefix>,<names...>)功能: 把前缀 <prefix> 加到 <names> 中的每个单词前⾯返回: 加过前缀的⽂件名序列# Makefile 内容all:@echo $(addprefix test_,/home/a.c b.c ./d.c)# bash 中执⾏make$ maketest_/home/a.c test_b.c test_./d.c连接函数: $(join <list1>,<list2>)功能: <list2> 中对应的单词加到 <list1> 后⾯返回: 连接后的字符串# Makefile 内容all:@echo $(join a b c d,1234)@echo $(join a b c d,12345)@echo $(join a b c d e,1234)# bash 中执⾏make$ makea1 b2 c3 d4a1 b2 c3 d4 5a1 b2 c3 d4 e3.4.3 foreach语法:$(foreach <var>,<list>,<text>)⽰例:# Makefile 内容targets := a b c dobjects := $(foreach i,$(targets),$(i).o)all:@echo $(targets)@echo $(objects)# bash 中执⾏make$ makea b c da.ob.oc.od.o3.4.4 if这⾥的if是个函数, 和前⾯的条件判断不⼀样, 前⾯的条件判断属于Makefile的关键字语法:$(if <condition>,<then-part>)$(if <condition>,<then-part>,<else-part>)⽰例:# Makefile 内容val := aobjects := $(if $(val),$(val).o,nothing)no-objects := $(if $(no-val),$(val).o,nothing)all:@echo $(objects)@echo $(no-objects)# bash 中执⾏make$ makea.onothing3.4.5 call - 创建新的参数化函数语法:$(call <expression>,<parm1>,<parm2>,<parm3>...)⽰例:# Makefile 内容log = "====debug====" $(1) "====end===="all:@echo $(call log,"正在 Make")# bash 中执⾏make$ make====debug==== 正在 Make ====end====3.4.6 origin - 判断变量的来源语法:$(origin <variable>)返回值有如下类型:类型含义undefined<variable> 没有定义过default<variable> 是个默认的定义, ⽐如 CC 变量environment<variable> 是个环境变量, 并且 make时没有使⽤ -e 参数file<variable> 定义在Makefile中command line<variable> 定义在命令⾏中override<variable> 被 override 重新定义过automatic<variable> 是⾃动化变量⽰例:# Makefile 内容val-in-file := test-fileoverride val-override := test-overrideall:@echo $(origin not-define) # not-define 没有定义@echo $(origin CC) # CC 是Makefile默认定义的变量@echo $(origin PATH) # PATH 是 bash 环境变量@echo $(origin val-in-file) # 此Makefile中定义的变量@echo $(origin val-in-cmd) # 这个变量会加在make的参数中@echo $(origin val-override) # 此Makefile中定义的override变量@echo $(origin @) # ⾃动变量, 具体前⾯的介绍# bash 中执⾏make$ make val-in-cmd=val-cmdundefineddefaultenvironmentfilecommand lineoverrideautomatic3.4.7 shell语法:$(shell <shell command>)它的作⽤就是执⾏⼀个shell命令, 并将shell命令的结果作为函数的返回.作⽤和 `<shell command>` ⼀样, ` 是反引号3.4.8 make 控制函数产⽣⼀个致命错误: $(error <text ...>)功能: 输出错误信息, 停⽌Makefile的运⾏# Makefile 内容all:$(error there is an error!)@echo "这⾥不会执⾏!"# bash 中执⾏make$ makeMakefile:2: *** there is an error!. Stop.输出警告: $(warning <text ...>)功能: 输出警告信息, Makefile继续运⾏# Makefile 内容all:$(warning there is an warning!)@echo "这⾥会执⾏!"# bash 中执⾏make$ makeMakefile:2: there is an warning!这⾥会执⾏!3.5 Makefile中⼀些GNU约定俗成的伪⽬标如果有过在Linux上, 从源码安装软件的经历的话, 就会对 make clean, make install ⽐较熟悉.像 clean, install 这些伪⽬标, ⼴为⼈知, 不⽤解释就⼤家知道是什么意思了.下⾯列举⼀些常⽤的伪⽬标, 如果在⾃⼰项⽬的Makefile合理使⽤这些伪⽬标的话, 可以让我们⾃⼰的Makefile看起来更专业, 呵呵 :)伪⽬标含义all所有⽬标的⽬标,其功能⼀般是编译所有的⽬标clean删除所有被make创建的⽂件install安装已编译好的程序,其实就是把⽬标可执⾏⽂件拷贝到指定的⽬录中去print列出改变过的源⽂件tar把源程序打包备份. 也就是⼀个tar⽂件dist创建⼀个压缩⽂件, ⼀般是把tar⽂件压成Z⽂件. 或是gz⽂件TAGS更新所有的⽬标, 以备完整地重编译使⽤check 或 test⼀般⽤来测试makefile的流程。
深入学习Make命令和Makefile(下)

深入学习Make命令和Makefile(下)makefilemake是Linux下的一款程序自动维护工具,配合makefile的使用,就能够根据程序中模块的修改情况,自动判断应该对那些模块重新编译,从而保证软件是由最新的模块构成。
本文分为上下两部分,我们在上一篇文章中分别介绍了make和makefile的一些基本用法,在本文中,我们会对make和makefile的功能做进一步的介绍。
一、构建多个目标有时候,我们想要在一个makefile中生成多个单独的目标文件,或者将多个命令放在一起,比如,在下面的示例mymakefile3中我们将添加一个clean选项来清除不需要的目标文件,然后用install选项将生成的应用程序移动到另一个目录中去。
这个makefile跟前面的mymakefile较为相似,不同之处笔者用黑体加以标识:1.all: main2.# 使用的编译器 = gcc4.# 安装位置5.INSTDIR =/usr/local/bin6.# include文件所在位置7.INCLUDE =.8.# 开发过程中所用的选项9.CFLAGS =-g -Wall–ansi10.# 发行时用的选项11.# CFLAGS = -O -Wall –ansi12.main: main.o f1.o f2.o13.$(CC)-o main main.o f1.o f2.o14.main.o: main.c def1.h15.$(CC)-I$(INCLUDE) $(CFLAGS)-c main.c16.f1.o: f1.c def1.h def2.h17.$(CC)-I$(INCLUDE) $(CFLAGS)-c f1.c18.f2.o: f2.c def2.h def3.h19.$(CC)-I$(INCLUDE) $(CFLAGS)-c f2.c20.clean:21.-rm main.o f1.o f2.o22.install: main23.@if[-d $(INSTDIR)]; \24.then \25.cp main $(INSTDIR);\26.chmod a+x $(INSTDIR)/main;\27.chmod og-w $(INSTDIR)/main;\28.echo ‚Installed in $(INSTDIR)‚;\29.else \30.echo ‚Sorry, $(INSTDIR) does not exist‛;\31.fi在这个makefile中需要注意的是,虽然这里有一个特殊的目标all,但是最终还是将main作为目标。
makefile符号说明

自动化变量
自动化变量通常用来在依赖规则的命令行中表示规则的一部分。
通常依赖规则是
上面七个自动化变量可以加上D(Directory)或F(FileName)来分别表示路径和文件名部分。
例如,$(@F)表示"$@"的文件部分,如果"$@"值是
"dir/foo.o",那么"$(@F)"就是"foo.o","$(@F)"相当于函数"$(notdir $@)";$(@D)表示"$@"的目录部分(不以斜杠做为结尾),如果"$@"值是"dir/foo.o",那么"$(@D)"就是"dir",而如果"$@"中没有包含斜杠的话,其值就是"."(当前目录)。
Makefile函数
按功能字符串、函数名排序:。
makefile语法

# Do not:
# o use make's built-in rules and variables
#
(this increases performance and avoid hard-to-debug behavour);
# o print "Entering directory ...";
# -R disable the built-in variable setttings.
# --no-print-directory。
# We are using a recursive build, so we need to do a little thinking # to get the ordering right. # # Most importantly: sub-Makefiles should only ever modify files in # their own directory. If in some directory we have a dependency on # a file in another dir (which doesn't happen often, but it's often # unavoidable when linking the built-in.o targets which finally # turn into vmlinux), we will call a sub make in that other dir, and # after that we are sure that everything which is in that other dir # is now up to date. # # The only cases where we need to modify files which have global # effects are thus separated out and done before the recursive # descending is started. They are now explicitly listed as the # prepare rule.
makefile ifneq函数的用法

makefile ifneq函数的用法1. 介绍在makefile中,ifneq函数用于在条件判断中比较字符串是否不相等。
该函数的语法如下:$(ifneq [condition], [value-if-true], [value-if-false])其中,[condition]为条件表达式,[value-if-true]为条件成立时返回的值,[value-if-false]为条件不成立时返回的值。
2. 基本语法和示例下面我们来看一个简单的makefile示例,以演示ifneq函数的基本语法和用法:TARGET = programifeq ($(TARGET), program)SOURCES = main.celseSOURCES = foo.c bar.cendif$(TARGET): $(SOURCES)gcc -o $(TARGET) $(SOURCES)上述示例中,根据TARGET变量的值来确定要编译的源文件。
若TARGET等于”program”,则将main.c赋给SOURCES变量;否则将foo.c和bar.c赋给SOURCES变量。
然后通过gcc命令编译生成目标程序。
3. 使用ifneq函数实现条件编译ifneq函数可以用于实现条件编译,根据不同的条件来选择性地编译特定的代码片段。
下面是一个示例,演示了如何使用ifneq函数实现条件编译:DEBUG = 1ifeq ($(DEBUG), 1)CFLAGS = -g -DDEBUGelseCFLAGS =endifprogram: main.cgcc $(CFLAGS) -o program main.c上述示例中,根据DEBUG变量的值来确定是否要添加调试选项(-g)和定义DEBUG宏(-DDEBUG)。
若DEBUG等于1,则将CFLAGS设置为”-g -DDEBUG”;否则将CFLAGS 设置为空字符串。
然后通过gcc命令编译生成目标程序。
【转】Android源代码编译命令mmmmmmmake分析--不错

【转】Android源代码编译命令mmmmmmmake分析--不错在前⽂中,我们分析了Android编译环境的初始化过程。
Android编译环境初始化完成后,我们就可以⽤m/mm/mmm/make命令编译源代码了。
当然,这要求每⼀个模块都有⼀个Android.mk⽂件。
Android.mk实际上是⼀个Makefile脚本,⽤来描述模块编译信息。
Android编译系统通过整合Android.mk⽂件完成编译过程。
本⽂就对Android源代码的编译过程进⾏详细分析。
从前⾯这篇⽂章可以知道,lunch命令其实是定义在build/envsetup.sh⽂件中的函数lunch提供的。
与lunch命令⼀样,m、mm和mmm命令也分别是由定义在build/envsetup.sh⽂件中的函数m、mm和mmm提供的,⽽这三个函数⼜都是通过make命令来对源代码进⾏编译的。
事实上,命令m就是对make命令的简单封装,并且是⽤来对整个Android源代码进⾏编译,⽽命令mm和mmm都是通过make命令来对Android源码中的指定模块进⾏编译。
接下来我们就先分别介绍⼀下函数m、mm和mmm的实现,然后进⼀步分析它们是如何通过make命令来编译代码的。
函数m的实现如下所⽰:[plain]1. function m()2. {3. T=$(gettop)4. if [ "$T" ]; then5. make -C $T $@6. else7. echo "Couldn't locate the top of the tree. Try setting TOP."8. fi9. }函数m调⽤函数gettop得到的是Android源代码根⽬录T。
在执⾏make命令的时候,先通过-C选项指定⼯作⽬录为T,即Android源代码根⽬录,接着⼜将执⾏命令m指定的参数$@作为命令make的参数。
shell遍历文件夹并执行命令

shell遍历⽂件夹并执⾏命令背景:有⼀个源码包⾥⾯包含很多⼦⽬录和makefile,打包后的压缩包太⼤,需要将make⽣成的所有⼆进制⽂件删除然后再打包。
需求:因此,要求在制定⽬录的所有递归⼦⽬录中执⾏make clean以清楚所有的⽬标⽂件。
代码:写了⼀段简单的shell脚本,有两个功能:1.遍历所有⼦⽬录,如果存在Makefile就执⾏make clean(当然也可以⼲更多的事);2.列出所有⼦⽬录下⼤于10M(当然也可以指定其他值)的⽂件。
话不多说上代码:#!/bin/bashrun_make(){#如果该⽬录下存在Makefileif [ -f "Makefile" ];thenecho""echo ===================== FOUND ===================pwd;echo ===============================================make clean;fi}run_ls(){pwd;#列出⼤于10M的⽂件#ls -l |awk'{if($5 > 10485760){print $5}}'ls -l |awk'{if($5 > 10485760){print "--",$9,$5}}'echo""}myfunc(){cd $1;#run_make;run_ls;for x in $(ls .)doif [ -d "$x" ];thenmyfunc $x;cd ..fidone}p=.if [ $1 ];thenp=$1fiecho $pmyfunc $p。
make file的if fi写法

一、make file的概念及作用make file是一种用来描述文件之间的依赖关系,以及如何通过执行特定命令来生成目标文件的工具。
它的作用在于帮助程序员自动化编译、信息和部署程序,提高开发效率和代码质量。
二、make file的语法及基本结构1. make file以一组规则的形式存在,每个规则包含了目标、依赖以及命令三部分。
2. 目标指定了规则要生成的文件名,可以是可执行文件、中间文件或者其他类型的文件。
3. 依赖指定了生成目标文件所需要依赖的文件或者其他目标文件。
4. 命令指定了生成目标文件的具体操作,可以是编译、信息、复制等操作。
三、make file的if/then/fi写法1. if/then/fi是make file中用来判断条件并执行相应操作的语法结构,类似于C语言中的if语句。
2. if后面跟着条件表达式,根据条件的真假来决定执行then后面的命令还是fi后面的命令。
3. then后面跟着要执行的命令,可以是单个命令,也可以是多个命令使用分号分隔。
4. fi表示if语句的结束,标志着条件判断部分的结束。
四、if/then/fi的使用场景1. if/then/fi结构可以用来根据特定条件执行不同的命令,比如根据评台的不同选择不同的编译选项。
2. 可以在make file中根据文件的存在与否来判断是否执行特定操作,比如判断依赖文件是否存在,如果不存在则生成。
3. 可以根据变量的取值来选择不同的操作,比如根据DEBUG变量的取值来选择是否生成调试信息。
五、if/then/fi的注意事项1. 在make file中使用if/then/fi时需要注意语法的正确性,要保证if、then和fi的配对和嵌套关系正确。
2. 条件表达式要保证逻辑上的正确性,避免出现歧义和错误。
3. 命令部分的书写要符合make file的语法规范,保证可以正确执行。
4. 对于复杂的条件判断,可以考虑使用shell脚本来处理,然后在make file中调用对应的shell脚本。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
makefile中if then写法
如何在Makefile 中使用if-then 写法
Makefile 是一种软件构建工具,广泛用于管理和构建软件项目。
它使用一系列规则和命令来指导构建过程。
其中,条件语句if-then 是Makefile 中常用的控制语句之一。
在本文中,我们将逐步介绍如何在Makefile 中使用if-then 写法,以及它的用途和常见示例。
一、if-then 写法的基本语法
在Makefile 中,if-then 语句的基本语法如下所示:
ifeq (条件, 值)
#条件为真时执行的命令
else
#条件为假时执行的命令
endif
在上述语法中,ifeq 是条件语句的关键字,用于判断一个条件是否为真。
条件是通过与指定的值进行比较来确定的。
若条件为真,则执行ifeq 和else 之间的命令块;若条件为假,则执行else 和endif 之间的命令块。
二、if-then 语句的使用场景
if-then 语句在Makefile 中具有广泛的应用场景。
它可以用于实现以下功能:
1. 根据不同的条件选择性地执行命令。
2. 根据环境变量的值选择性地执行命令。
3. 根据文件存在与否选择性地执行命令。
4. 根据命令执行结果选择性地执行不同的命令。
下面让我们逐步来看每个使用场景的示例。
三、根据不同的条件选择性地执行命令
首先,我们来看一个根据不同的条件选择性地执行命令的示例。
假设我们有一个变量MODE,它的值可以是release 或debug。
根据MODE 的不同,我们可以选择性地执行不同的命令。
makefile
MODE := release
ifeq ((MODE), release)
# release 模式下执行的命令
(info Building release version...)
gcc -O3 -o myprogram main.c
else
# debug 模式下执行的命令
(info Building debug version...)
gcc -g -o myprogram main.c
endif
在上述示例中,(info ...) 是一个内置函数,用于在Makefile 执行过程中打印文本消息。
当MODE 的值为release 时,将打印Building release version...;当MODE 的值为debug 时,将打印Building debug version...。
四、根据环境变量的值选择性地执行命令
其次,让我们看一个根据环境变量的值选择性地执行命令的示例。
假设我们有一个环境变量BUILD_TYPE,它的值可以是release 或debug。
根据BUILD_TYPE 的不同,我们可以选择性地执行不同的命令。
makefile
BUILD_TYPE := (shell echo BUILD_TYPE)
ifeq ((BUILD_TYPE), release)
# release 模式下执行的命令
(info Building release version...)
gcc -O3 -o myprogram main.c
else
# debug 模式下执行的命令
(info Building debug version...)
gcc -g -o myprogram main.c
endif
在上述示例中,(shell ...) 是一个内置函数,用于执行一个shell 命令,并将结果返回给变量。
这里使用(shell echo BUILD_TYPE) 的目的是获取BUILD_TYPE 环境变量的值。
五、根据文件存在与否选择性地执行命令
再次,让我们看一个根据文件存在与否选择性地执行命令的示例。
假设我们的项目中存在一个名为config.h 的头文件。
如果config.h 存在,我们执行一段特定的命令;反之,我们执行另一段命令。
makefile
ifeq ((wildcard config.h), )
# 当config.h 不存在时执行的命令
(info config.h doesn't exist. Creating one...)
touch config.h
else
# 当config.h 存在时执行的命令
(info config.h already exists.)
endif
在上述示例中,(wildcard ...) 是一个内置函数,用于检查文件是否存在。
当config.h 不存在时,(wildcard config.h) 返回一个空字符串,所以条件(wildcard config.h), ) 是真的,将执行if 块中的命令;反之,将执行else 块中的命令。
六、根据命令执行结果选择性地执行不同的命令
最后,让我们看一个根据命令执行结果选择性地执行不同的命令的示例。
假设我们有一个命令git rev-parse abbrev-ref HEAD,它用于获取当前git 分支的名称。
如果当前分支的名称为master,我们执行一段特定的命令;反之,我们执行另一段命令。
makefile
BRANCH := (shell git rev-parse abbrev-ref HEAD)
ifeq ((BRANCH), master)
# 当前分支为master 时执行的命令
(info Building from master branch...)
gcc -O3 -o myprogram main.c
else
# 当前分支不为master 时执行的命令
(info Building from non-master branch...)
gcc -g -o myprogram main.c
endif
在上述示例中,(shell ...) 内部的命令用于获取当前git 分支的名称,并将结果返回给变量BRANCH。
根据BRANCH 变量的值,我们可以选择性地执行不同的命令。
七、总结
在本文中,我们详细介绍了如何在Makefile 中使用if-then 写法,并提供了该写法的基本语法和常见应用场景的示例。
if-then 写法在Makefile 中是非常有用的,它可以根据不同的条件选择性地执行命令,从而更好地管理和构建软件项目。
希望本文对您理解和使用Makefile 中的if-then 写法有所帮助。