Makefile 语法分析
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”则是禁⽌所有执⾏命令的显⽰,就好像所有的命令⾏均使⽤“@”开始⼀样。
make用法总结

make用法总结Make是一个高级程序设计工具,通常用于源代码的自动化构建(编译、打包、测试、安装等)过程中。
它是在类Unix操作系统下使用的工具,因为所有的Unix遵循 POSIX 标准而支持make。
make被广泛用于各种编程语言,如C、C++、Java、Python等。
一、Make的基本语法在使用make前,我们需要先了解make语法中的一些基本概念:1. Target: 表示一个目标,可以是一个可执行文件、库文件、中间文件、目录等等。
2. Dependency: 表示一个目标所依赖的文件。
3. Rule: 表示如何从依赖生成目标的方法。
示例:```makefiletarget: dependency1 dependency2recipe```其中,“target”是一个目标,“dependency1”和“dependency2”是目标需要的依赖文件,“recipe”是构建目标的具体操作。
二、Makefile的生成make工具使用Makefile文件来指定构建目标及其依赖关系、构建规则和构建指令。
Makefile文件的一般格式为:```makefiletarget1: dependency1 dependency2 ...recipe1target2: dependency3 dependency4 ...recipe2...```在终端中执行make命令时,make工具会根据Makefile文件中的规则,自动分析所需的编译任务,并决定哪些任务需要重新编译。
三、Make的常见用法1. 编译make最常见的用法是编译C/C++源代码,将源代码编译为可执行文件。
下面是一个简单的Makefile,用于将main.c和io.c编译为可执行文件main:```makefileCC=gccCFLAGS=-Wall -pedantic -I./includeLDLIBS=-lmOBJ=main.o io.oEXEC=mainall: $(EXEC)$(EXEC): $(OBJ)$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@%.o: %.c$(CC) -c $(CFLAGS) $< -o $@```在Makefile中,我们首先定义了一些变量,比如CC表示编译器,CFLAGS表示编译选项,OBJ表示目标文件列表。
makefile--参数传递、条件判断、include(五)

makefile--参数传递、条件判断、include(五)在多个Makefile嵌套调⽤时,有时我们需要传递⼀些参数给下⼀层Makefile。
⽐如我们在顶层Makefile⾥⾯定义的打开调试信息变量DEBUG_SYMBOLS,我们希望在进⼊⼦⽬录执⾏⼦Makefile时该变量仍然有效,这是需要将该变量传递给⼦Makefile,那怎么传递呢?这⾥有两种⽅法:1. 在上层Makefile中使⽤”export”关键字对需要传递的变量进⾏声明。
⽐如:1 2DEBUG_SYMBOLS = TRUE export DEBUG_SYMBOLS当不希望将⼀个变量传递给⼦ make 时,可以使⽤指⽰符 “unexport”来声明这个变量。
export⼀般⽤法是在定义变量的同时对它进⾏声明。
如下:1export DEBUG_SYMBOLS = TRUE2. 在命令⾏上指定变量。
⽐如:1$(MAKE) -C xxx DEBUG_SYMBOLS = TRUE这样在进⼊⼦⽬录xxx执⾏make时该变量也有效。
像编程语⾔⼀样,Makefile也有⾃⼰的条件语句。
条件语句可以根据⼀个变量值来控制make的执⾏逻辑。
⽐较常⽤的条件语句是ifeq –else-endif、ifneq-else-endif、ifdef-else-endif。
ifeq关键字⽤来判断参数是否相等。
⽐如判断是否⽣成调试信息可以这么⽤:1 2 3 4 5 6ifeq ($(DEBUG_SYMBOLS), TRUE) >---CFLAGS += -g -Wall -Werror -O0 else>---CFLAGS += -Wall -Werror -O2 endifIfneq和ifeq作⽤相反,此关键字是⽤来判断参数是否不相等。
ifdef关键字⽤来判断⼀个变量是否已经定义。
后两个关键字⽤法和ifeq类似。
现在我们继续改进我们上⼀节的Makefile,上⼀节的Makefile完成Makefile的嵌套调⽤,每⼀个模块都有⾃⼰的Makefile。
window下makefile的使用

Windows下的makefile1. windows下nmake的使用为nmake、cl、link运行设置环境变量:把VS安装目录下的VC/bin设置到环境变量path 中。
2. windows下使用makefile的问题解决2.1 Fatal error U1052: ‘win32.mak’ not found stop在执行构建(nmake)命令时有时会出现如下错误:Fatal error U1052: ‘win32.mak’ not found stop解决方法:运行visual studio中的VC\bin\vcvars32.bat不要关闭命令窗口,然后在同一窗口中执行命令就不会出错。
3. nmake的命令行语法NMAKE的命令行语法语法:NMAKE [options] [macros] [targets]其中,options是NMAKE的选项,macros是在命令行中的宏定义,targets是NMAKE的目标文件列表。
选项(忽略大小写):1)/A强制重新构件所有与NMAKE的target相关的dependents,即使这些dependents 并没有过期;2)/B即使dependent与target有相同的time stamp,也重建该target。
大部分的OS中的time stamp是以2秒为单位的,如果一个2秒之内被修改,那么它的time stamp将不会有任何变化。
在这种情况下,你就需要使用该选项让NMAKE重建之。
为了预防万一,总是应该使用该选项,尽管可能会导致不必要的重建操作。
3)/C屏蔽掉大部分的NMAKE输出信息,包括:非致命错误信息,警告信息,time stamp和版权信息。
如果/C和/K选项同时存在,则/K发出的警告信息也会被干掉。
4)/D在NMAKE执行期间显示相关的信息。
包括每个文件的time stamp,依赖关系,以及类似于“文件不存在”之类的提示信息。
用于对makefile除错;5)/E使环境变量可以覆盖预定义宏;6)/F filename指定makefile的名字。
makefile循环语句

makefile循环语句【最新版】目录1.Makefile 简介2.Makefile 循环语句的作用3.Makefile 循环语句的语法4.Makefile 循环语句的示例5.Makefile 循环语句的注意事项正文1.Makefile 简介Makefile 是一种用于自动构建和编译计算机程序的脚本文件。
它最初被用于 Unix 系统,但现在也广泛应用于其他操作系统,如 Linux 和macOS。
Makefile 通过定义一系列的规则和依赖关系,自动化了软件开发的构建和编译过程,从而提高了开发效率。
2.Makefile 循环语句的作用在 Makefile 中,循环语句用于遍历一个列表,并执行相应的操作。
这使得 Makefile 具有了更强的灵活性和可扩展性,可以适应不同的构建需求。
3.Makefile 循环语句的语法Makefile 循环语句的基本语法如下:```foreach 变量名 in (列表) {# 循环体```其中,`变量名`是一个用户自定义的变量,用于存储列表中的每个元素;`列表`是一个由空格分隔的元素序列,可以是文件名、目录名等。
4.Makefile 循环语句的示例以下是一个 Makefile 循环语句的示例:```all: main.o file1.o file2.omain.o: main.c$(CC) $(CFLAGS) -c main.cfile1.o: file1.c$(CC) $(CFLAGS) -c file1.cfile2.o: file2.c$(CC) $(CFLAGS) -c file2.cclean:rm -f *.o *.elfforeach target in ($@) {ifneq ($(wildcard $(target).o), *) {$(target).o: $(target).c$(CC) $(CFLAGS) -c $(target).cendif}在这个示例中,`foreach` 语句遍历了所有以“.o”结尾的目标文件(如“main.o”、“file1.o”和“file2.o”),并针对每个目标文件执行相应的编译操作。
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中⼀些特殊符号的意义在makefile中,有时会接触到⼀些以特殊字符打头的命令,⽐如@, -, +,如果之前没有接触过的话,会感觉⽐较奇怪,其实,多是⼀些为了实现特定⾏为模式⽽引⼊的标记符。
命令⾏以'@'打头的含义:在执⾏到的时候不回显相应的命令内容,只显⽰命令的输出。
命令⾏以'-'打头的含义:在执⾏到的时候如果发⽣错误(退出返回⾮零状态)时,不中断make过程。
命令⾏以'+'打头的含义: makefile中以+开头的命令的执⾏不受到 make的-n,-t,-q三个参数的影响。
我们知道,在make的时候,如果加上-n, -t, -q这样的参数,都是不执⾏相应命令的,⽽以'+'开头的命令,则⽆论make命令后⾯是否跟着三个参数,都会被执⾏。
附:make命令参数make的参数下⾯列举了所有GNU make 3.80版的参数定义。
其它版本和产商的make⼤同⼩异,不过其它产商的make的具体参数还是请参考各⾃的产品⽂档。
“-b”“-m”这两个参数的作⽤是忽略和其它版本make的兼容性。
“-B”“--always-make”认为所有的⽬标都需要更新(重编译)。
“-C <dir>;”“--directory=<dir>;”指定读取makefile的⽬录。
如果有多个“-C”参数,make的解释是后⾯的路径以前⾯的作为相对路径,并以最后的⽬录作为被指定⽬录。
如:“make –C ~hchen/test –C prog”等价于“make –C ~hchen/test/prog”。
“—debug[=<options>;]”输出make的调试信息。
它有⼏种不同的级别可供选择,如果没有参数,那就是输出最简单的调试信息。
下⾯是<options>;的取值:a —— 也就是all,输出所有的调试信息。
makefile编译流程

makefile编译流程Makefile是一种用于自动化编译的工具,它可以根据源代码文件的依赖关系自动编译出目标文件。
Makefile的编写需要遵循一定的规则和语法,下面将介绍Makefile的编译流程。
1. 编写Makefile文件Makefile文件是一个文本文件,其中包含了编译的规则和依赖关系。
在编写Makefile文件时,需要遵循一定的语法规则,如使用TAB键缩进、使用变量和函数等。
2. 执行make命令在Makefile文件所在的目录下执行make命令,make会自动读取Makefile文件,并根据其中的规则和依赖关系进行编译。
如果Makefile文件中没有指定目标,则默认编译第一个目标。
3. 分析依赖关系在执行make命令时,make会先分析Makefile文件中的依赖关系,确定哪些文件需要重新编译。
如果某个源文件被修改了,那么与之相关的目标文件也需要重新编译。
4. 编译源文件在确定需要重新编译的文件后,make会依次编译每个源文件,生成对应的目标文件。
编译过程中,make会根据Makefile文件中的规则和命令进行编译。
5. 链接目标文件在所有的源文件都编译完成后,make会将所有的目标文件链接起来,生成最终的可执行文件。
链接过程中,make会根据Makefile文件中的规则和命令进行链接。
6. 完成编译当所有的源文件都编译完成并链接成功后,make会输出编译成功的信息,并生成最终的可执行文件。
如果编译过程中出现错误,make会输出错误信息并停止编译。
总之,Makefile编译流程是一个自动化的过程,它可以大大提高编译的效率和准确性。
在编写Makefile文件时,需要注意语法规则和依赖关系,以确保编译过程的正确性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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程序。
# 对于这个变量除非使用指示符“unexport”对它们进行声明,它们在整个make的执行过程中始终被自动的传递给所有的子make。
# 还有个特殊变量SHELL与MAKEFLAGS一样,默认情况(没有用“unexport”声明)下在整个make的执行过程中被自动的传递给所有的子make。
## -rR --no-print-directory# -r disable the built-in impilict rules.# -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.# To put more focus on warnings, be less verbose as default# Use 'make V=1' to see the full commandsifdef Vifeq ("$(origin V)", "command line")KBUILD_VERBOSE = $(V)endifendififndef KBUILD_VERBOSEKBUILD_VERBOSE = 0endif# “ifdef”是条件关键字。
语法是ifdef <variable-name>;<text-if-true>; else <text-if-false>; endif # ifdef只检验一个变量是否被赋值,它并不会去推导这个变量,并不会把变量扩展到当前位置。
# “ifeq”与“ifdef”类似。
# “ifeq”语法是ifeq (<arg1>;, <arg2>;),功能是比较参数“arg1”和“arg2”的值是否相同。
## 函数origin并不操作变量的值,只是告诉你你的这个变量是哪里来的。
# 语法是:$(origin <variable>;)# origin函数的返回值有:# “undefined”从来没有定义过、“default”是一个默认的定义、“environment”是一个环境变量、# “file”这个变量被定义在Makefile中、“command line”这个变量是被命令行定义的、# “override”是被override指示符重新定义的、“automatic”是一个命令运行中的自动化变量## 应用变量的语法是:$(变量名)。
如KBUILD_VERBOSE = $(V)中的$(V)。
## KBUILD_VERBOSE的值根据在命令行中是否定义了变量V,# 当没有定义时,默认为V=O,输出为short version;可以用make V=1 来输出全部的命令。
## ifndef与ifdef语法类似,但功能恰好相反。
ifndef是判断变量是不是没有被赋值。
# Call a source code checker (by default, "sparse") as part of the# C compilation.## Use 'make C=1' to enable checking of only re-compiled files.# Use 'make C=2' to enable checking of *all* source files, regardless# of whether they are re-compiled or not.## See the file "Documentation/sparse.txt" for more details, including# where to get the "sparse" utility.ifdef Cifeq ("$(origin C)", "command line")KBUILD_CHECKSRC = $(C)endifendififndef KBUILD_CHECKSRCKBUILD_CHECKSRC = 0endif# ifdef是Makefile的条件关键字,其语法是:ifdef <variable-name>;# 如果变量<variable-name>;的值非空,那到表达式为真。
否则,表达式为假。
# ifndef也是Makefile的条将关键字,功能与ifdef相反,语法相似。
# Use make M=dir to specify directory of external module to build# Old syntax make ... SUBDIRS=$PWD is still supported# Setting the environment variable KBUILD_EXTMOD take precedenceifdef SUBDIRSKBUILD_EXTMOD ?= $(SUBDIRS)endififdef Mifeq ("$(origin M)", "command line")KBUILD_EXTMOD := $(M)endifendif# ifdef是Makefile的条件关键字,其语法是:ifdef <variable-name>;# 如果变量<variable-name>;的值非空,那到表达式为真。
否则,表达式为假。
## ifeq是Makefile的条件关键字,其语法是:ifeq (<arg1>;, <arg2>;),比较参数“arg1”和“arg2”的值是否相同。
## 操作符“:=”与操作符“+=”的功能相同,只是操作符“:=”后面的用来定义变量(KBUILD_EXTMOD)的变量M只能是前面定义好的,# 如果操作符“?=”前面的变量KBUILD_EXTMOD没有定义过,那么就将SUBDIRS赋给KBUILD_EXTMOD;# 如果定义过,则语句KBUILD_EXTMOD ?= $(SUBDIRS)什么也不做。
# kbuild supports saving output files in a separate directory.# To locate output files in a separate directory two syntaxes are supported.# In both cases the working directory must be the root of the kernel src.# 1) O=# Use "make O=dir/to/store/output/files/"## 2) Set KBUILD_OUTPUT# Set the environment variable KBUILD_OUTPUT to point to the directory# where the output files shall be placed.# export KBUILD_OUTPUT=dir/to/store/output/files/# make## The O= assignment takes precedence over the KBUILD_OUTPUT environment# variable.# KBUILD_SRC is set on invocation of make in OBJ directory# KBUILD_SRC is not intended to be used by the regular user (for now)ifeq ($(KBUILD_SRC),)# ifeq是Makefile的条件关键字,其语法是:ifeq (<arg1>;, <arg2>;),比较参数“arg1”和“arg2”的值是否相同。