Makefile语法


前言

  本文只讲LInux环境下的Makefile基础语法,环境搭建见下链接:
https://blog.csdn.net/weixin_44567668/article/details/125189852


一、概述

  学过C语言都知道需要编译才能运行,其实运行的是可执行文件,可能是.obj或者.o文件,而将源文件.c变成可执行文件的过程就是编译,实际上GCC整个编译流程是:预处理、编译、汇编和链接,如使用下面命令进行编译:

gcc main.c -o main

  那有人好奇Makefile有什么用?上面知道计算机系统运行需要一个可执行文件,我们只有一个main.c文件只需要一个命令,但是如果有很多个源文件和头文件的时候一个个敲命令,特别是在修改了其中某个文件后,一行行敲命令很显然不现实。而Makefile可以有效的解决这个问题,Makefile本质上相当于一个shell脚本文件,那样你将所有编译命令集中在一起,最后只需要输入make命令就可以自动化编译,make与Makefile关系如下图:
在这里插入图片描述
  这就是 make 的执行过程,make 工具就是在 Makefile 中一层一层的查找依赖关系,并执行相应的命令运行gcc编译器,编译出最终的可执行文件

二、示例引用

  首先新建一个main.c的源文件,内容如下:

#include "stdio.h"

int main()
{
	printf("hello, world! This is a C program.\n");
	return 0;
}

  然后新建名为Makefile的文件,内容如下:

main:main.o
	gcc -o main main.o

main.o:main.c
	gcc -c main.c

clean:
	rm *.o
	rm main

  先不管语法后面会讲,然后在命令行里输入make命令即可执行Makefile,注意main.c、Makefile与终端当前路径是一致的,然后输入./main运行代码看效果
在这里插入图片描述
  可以看出就3步:编辑工程代码->编辑Makefile文件->输入make执行编译
在这里插入图片描述

三、Makefile规则与运行

3.1 书写格式

  1. Makefile的语法规则
[目标]:[依赖]
	[命令]

  由上一小节的例子可以看出就是目标文件指向对应的依赖文件,然后下面就是具体的转换命令。注意:Makefile文件命令行的首行缩进用Tab键,不能使用空格

  1. 通配符
      make支持3种通配符:*?[]。通配符代替了一系列文件,如“ *.c ”代表后缀为.c的文件

  2. 模式规则
      模式规则中,至少在规则的目标定定义中要包涵%,否则就是一般规则,目标中的“%”表示对文件名的匹配,“%”表示长度任意的非空字符串,比如“%.c”就是所有的以.c 结尾的文件,类似与通配符:

%.o : %.c
	命令
  1. 注释
      在Makefile里使用#添加注释,可以用反斜框进行转义,如\#

3.2 命令格式

  1. 显示命令
  • 通常,make会把其要执行的命令行在命令执行前输出到屏幕上。当我们用@字符在命令行前,那么,这个命令将不被make显示出来
  • 如果make执行时,带入make参数-n--just-print,那么其只是显示命令,但不会执行命令,这个功能很有利于我们调试我们的 Makefile
  • 而make参数-s--slient则是全面禁止命令的显示
  1. 命令执行
      当依赖目标新于目标时,也就是当规则的目标需要被更新时,make 会一条一条的执行其后的命令。需要注意的是,如果你要让上一条命令的结果应用在下一条命令时,你应该使用分号;分隔这两条命令,如:
exec: 
	cd /home/hchen;pwd
  1. 命令出错
      有些时候,命令的出错并不表示就是错误的。为了做到这一点,忽略命令的出错,我们可以在 Makefile 的命令行前加一个减号-
clean: 
	-rm -f *.o

  还有一个全局的办法是,给 make 加上-i或是--ignore-errors参数,那么,Makefile 中所有命令都会忽略错误。而如果一个规则是以.IGNORE作为目标的,那么这个规则中的所有命令将会忽略错误。
  还有一个要提一下的 make 的参数的是-k或是--keep-going,这个参数的意思是,如果某规则中的命令出错了,那么就终目该规则的执行,但继续执行其它规则

  1. 定义命令包
      如果 Makefile 中出现一些相同命令序列,那么我们可以为这些相同的命令序列定义一个变量。定义这种命令序列的语法以define开始,以endef结束,如:
define run-yacc 
	yacc $(firstword $^) 
	mv y.tab.c $@ 
endef

  这里,“run-yacc”是这个命令包的名字,其不要和 Makefile 中的变量重名。调用示例如下:

foo.c : foo.y 
	$(run-yacc)

3.3 make的运行

  1. make的工作方式
    ①读入所有的 Makefile。
    ②读入被 include 的其它 Makefile。
    ③初始化文件中的变量。
    ④推导隐晦规则,并分析所有规则。
    ⑤为所有的目标文件创建依赖关系链。
    ⑥根据依赖关系,决定哪些目标要重新生成。
    ⑦执行生成命令。

  2. Makefile的文件名
      默认的情况下,make 命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解释这个文件。在这三个文件名中,最好使用Makefile这个文件名
      当 然 , 你 可 以 使 用 别 的 文 件 名 来 书 写 Makefile , 比 如 : “Make.Linux” ,“Make.Solaris”,“Make.AIX”等,如果要指定特定的 Makefile,你可以使用 make 的“-f”和“–file”参数,如:

make -f Make.Linux
make --file Make.AIX
  1. 文件搜索
      正常情况下make只会在当前目录中去找依赖文件和目标文件。但是我们可以使用特殊变量VPATH就可以去指定路径搜索,如:
VPATH = src:../headers

  上面的的定义指定两个目录,“src”和“…/headers”,make 会按照这个顺序进行搜索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)

  另一个设置文件搜索路径的方法是使用 make 的vpath关键字(注意,它是全小写的),这不是变量,这是一个 make 的关键字,如:

#为符合模式<pattern>的文件指定搜索目录<directories>。
vpath <pattern> <directories> 
# vapth 使用方法中的<pattern>需要包含“%”字符,如:
vpath %.h ../headers

#清除符合模式<pattern>的文件的搜索目录。 
vpath <pattern> 

#清除所有已被设置好了的文件搜索目录。 
vpath 
  1. 引用其它的 Makefile
      在Makefile使用include关键字可以把别的Makefile包含进来,如:
include foo.make *.mk $(bar) 
# 等价于: 
include foo.make a.mk b.mk c.mk e.mk f.mk
  • 如果make执行时,有-I--include-dir参数,那么make就会在这个参数 所指定的目录下去寻找
  • 如果目录<prefix>/include(一般是:/usr/local/bin 或/usr/include)存在的话,make 也会去找。如果有文件没有找到的话,make 会生成一条警告信息,如果你想让make不理那些无法读取的文件,而继续执行,你可以在 include 前加一个减号-
  • 如果你的当前环境中定义了环境变量MAKEFILES,那么make 会把这个变量中的值做一个类似于 include 的动作。这个变量中的值是其它的 Makefile,用空格分隔。只是,它和 include不同的是,从这个环境变中引入的 Makefile 的“目标”不会起作用,如果环境变量中定义的文件发现错误,make 也会不理。所以建议不要使用这个环境变量
  1. 变量传递
# 如果你要传递变量到下级 Makefile 中,那么你可以使用这样的声明: 
export <variable ...> 
 
#如果你不想让某些变量传递到下级 Makefile 中,那么你可以这样声明: 
unexport <variable ...>

  如果你要传递所有的变量,那么,只要一个 export 就行了。后面什么也不用跟,表示传递所有的变量。 需要注意的是,有两个变量,一个是 SHELL,一个是 MAKEFLAGS,这两个变量不管你是否 export,其总是要传递到下层 Makefile 中,特别是 MAKEFILES 变量,其中包含了 make的参数信息

  1. 嵌套执行make
      在一些大的工程中,我们会把我们不同模块或是不同功能的源文件放在不同的目录中,我们可以在每个目录中都书写一个该目录的 Makefile。如:
subsystem: 
	cd subdir && $(MAKE) 
 
#其等价于: 
subsystem: 
	$(MAKE) -C subdir

  定义$(MAKE)宏变量的意思是,也许我们的 make 需要一些参数,所以定义成一个变量比较利于维护。这两个例子的意思都是先进入“subdir”目录,然后执行 make 命令

  1. 伪目标
      一般的目标名都是要生成的文件,而伪目标不代表真正的目标名,在执行make命令的时候通过指定这个伪目标来执行其所在规则的定义的命令,如:
clean: 
	rm *.o temp

  此时输入命令make clean就会执行删除工作。其他伪目标:

伪目标功能
all所有目标的目标,其功能一般是编译所有的目标
clean删除所有被 make 创建的文件
install安装已编译好的程序,其实就是把目标执行文件拷贝到指定的 目标中去
print例出改变过的源文件
tar把源程序打包备份
dist创建一个压缩文件,一般是把 tar 文件压成 Z 文件
TAGS更新所有的目标,以备完整地重编译使用
check和test用来测试 makefile 的流程

  但是如果目录下有一个同名的clean文件,此时输入命令并不会执行删除工作,因此我们可以使用标记.PHONY来指明目标是伪目标,如:

.PHONY:clean

四、变量

  1. 变量基础
      变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有“:”、“#”、“=”或是空字符(空格、回车等)。变量是大小写敏感的,“foo”、“Foo”和“FOO”是三个不同的变量名。
      变量在声明时需要给予初值,而在调用时需要给在变量名前加上$符号,但最好用小括号()或是大括号{}把变量给包括起来。如果你要使用真实的$字符,那么你需要用$$来表示。
      定义变量的方式有以下四种:
操作符作用
=延迟赋值,该变量只有在调用的时候,才会被赋值
:=直接赋值,延迟赋值相反,使用直接赋值的话,变量的值定义时就已经确定了。
?=若变量值为空,则进行赋值,通常用于设置默认值
+=追加赋值,可以往变量后面增加新的内容

  示例如下:

objects = program.o foo.o utils.o 	#定义变量
program : $(objects) 	#调用变量
	cc -o program $(objects)
  1. 自动化变量
      所谓自动化变量,就是这种变量会把模式中所定义的一系列的文件自动地挨个取出,直至所有的符合模式的文件都取完了。这种自动化变量只应出现在规则的命令中。自动化变量需要配合模式规则%。常用的自动化变量如表:
自动化变量描述
$@规则中的目标集合,在模式规则中,如果有多个目标的话,“$@”表示匹配模式中定义的目标集合。
$%当目标是函数库的时候表示规则中的目标成员名,如果目标不是函数库文件,那么其值为空。
$<依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么“$<”就是符合模式的一系列的文件集合。
$?所有比目标新的依赖目标集合,以空格分开。
$^所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,“$^”会去除重复的依赖文件,值保留一份。
$+和“$^”类似,但是当依赖文件存在重复的话不会去除重复的依赖文件。
$*这个变量表示目标模式中"%"及其之前的部分,如果目标是 test/a.test.c,目标模式为 a.%.c,那么“$*”就是 test/a.test。
%.o : %.c
	gcc -c $<
  1. 多行变量定义
      还有一种设置变量值的方法是使用define关键字。使用 define 关键字设置变量的值可以有换行,define指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以endef关键字结束。如:
define two-lines 
	echo foo 
	echo $(bar) 
endef
  1. 环境变量
      make 运行时的系统环境变量可以在 make 开始运行时被载入到 Makefile 文件中,但是如果 Makefile 中已定义了这个变量,或是这个变量由 make 命令行带入,那么系统的环境变量的值将被覆盖。(如果 make 指定了“-e”参数,那么,系统环境变量将覆盖 Makefile 中定义的变量)。因此,如果我们在环境变量中设置了CFLAGS环境变量,那么我们就可以在所有的Makefile 中使用这个变量了。

  2. 变量高级用法

  • 第一种是变量值的替换:我们可以替换变量中的共有的部分,其格式是$(var:a=b)或是${var:a=b},其意思是,把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾”意思是“空格”或是“结束符”。
  • 第二种是“把变量的值再当成变量”,如:
x = y 
y = z 
a := $($(x))

五、条件判断

  格式如下:

<条件关键字>
	<条件为真时执行的语句>
else
	<条件为假时执行的语句>
endif

  其中条件关键字有 4 个:ifeqifneqifdefifndef

  1. ifeq用来判断是否相等,格式如下
ifeq (<arg1>, <arg2>) 
ifeq '<arg1>' '<arg2>' 
ifeq "<arg1>" "<arg2>" 
ifeq "<arg1>" '<arg2>' 
ifeq '<arg1>' "<arg2>"
  1. ifneq就是判断是否不相等,格式类似ifeq
  2. ifdef表示如果“变量名”的值非空,那么表示表达式为真,否则表达式为假
ifdef <变量名>
  1. ifndef 用法类似,但是含义用户 ifdef 相反

六、函数

  1. 函数的调用
$(函数名 参数) 
#或者
${函数名 参数}
  1. 字符串处理函数
格式功能
$(subst from,to,text)把字串text中的from字符串替换成to
$(patsubst pattern,replacement,text)查找text中的单词是否符合模式pattern,如果匹配的话,则以replacement替换
$(strip string)去掉string字串中开头和结尾的空字符
$(findstring find,in)在字串in中查找find字串
$(filter pattern,text)以pattern模式过滤text字符串中的单词,保留符合模式pattern的单词
$(filter-out pattern,text)以pattern模式过滤text字符串中的单词,去除符合模式pattern的单词
$(sort list)给字符串list>中的单词排序(升序)
$(word n,text)取字符串text中第n个单词。(从一开始)
$(wordlist s,e,text)从字符串text中取从s开始到e的单词串
$(words text)统计text中字符串中的单词个数
$(firstword text)取字符串text中的第一个单词
  1. 文件名操作函数
函数名格式功能
dir$(dir <names…>)从文件名序列names中取出目录部分
notdir$(notdir <names…>)从文件名序列names中取出非目录部分
suffix$(suffix <names…>)从文件名序列names中取出各个文件名的后缀
basename$(basename <names…>)从文件名序列names中取出各个文件名的前缀部分
addsuffix$(addsuffix <suffix…>,<names…>)把后缀suffix加到names中的每个单词后面
addprefix$(addprefix <prefix…>,<names…>)把前缀prefix加到names中的每个单词后面
join$(join <list1…>,<list2…>)把list2中的单词对应地加到list1的单词后面
  1. 循环函数
      Makefile中的foreach函数几乎是仿照于 Unix 标准 Shell(/bin/sh)中的 for 语句,或是 C-Shell(/bin/csh)中的 foreach 语句而构建的。它的语法是:
$(foreach <var>,<list>,<text>)

  这个函数的意思是,把参数list中的单词逐一取出放到参数var所指定的变量中,然后再执行text所包含的表达式。每一次text会返回一个字符串,循环过程中,text的所返回的每个字符串会以空格分隔,最后当整个循环结束时,text所返回的每个字符串所组成的整个字符串(以空格分隔)将会是 foreach 函数的返回值。

names := a b c d 
files := $(foreach n,$(names),$(n).o)
  1. 条件函数
      if函数很像 GNU 的 make 所支持的条件语句——ifeq,if 函数的语法是:
$(if <condition>,<then-part>)
#或者
$(if <condition>,<then-part>,<else-part>)

  可见,if 函数可以包含“else”部分,或是不含。即 if 函数的参数可以是两个,也可以是三个。condition参数是 if 的表达式,如果其返回的为非空字符串,那么这个表达式就相当于返回真,于是,then-part会被计算,否则else-part会被计算。
  而 if函数的返回值是,如果condition为真(非空字符串),那个then-part会是整个函数的返回值,如果condition为假(空字符串),那么else-part会是整个函数的返回值,此时如果else-part没有被定义,那么,整个函数返回空字串。

  1. 定义函数
      使用call函数来创建新的参数化的函数
$(call <expression>,<parm1>,<parm2>,<parm3>...)

  当 make 执行这个函数时,expression参数中的变量,会被参数parm1,parm2,parm3依次取代,而expression的返回值就是call函数的返回值。例如:

reverse = $(1) $(2) 
	foo = $(call reverse,a,b)
  1. 寻找函数
      使用origin函数来寻找函数出处,格式如下:
$(origin <variable>)

  返回值如下:

  • undefined:如果variable从来没有定义过
  • default:如果variable是一个默认的定义,比如“CC”这个变量
  • file:如果variable这个变量被定义在 Makefile 中
  • command line:如果variable这个变量是被命令行定义的
  • override:如果variable是被 override 指示符重新定义的
  • automatic: 如果variable是一个命令运行中的自动化变量
  1. 其他函数
函数名格式说明
shell$(shell 命令)把执行操作系统命令后的输出作为函数返回
error$(error <text …>)产生一个致命的错误,<text …>是错误信息
warning$(warning <text …>)只是输出一段警告信息,而 make继续执行

七、隐含规则

  “隐含规则”也就是一种惯例,make 会按照这种“惯例”心照不喧地来运行,那怕我们的 Makefile 中没有书写这样的规则。例如,把[.c]文件编译成[.o]文件这一规则,你根本就不用写出来,make会自动推导出这种规则,并生成我们需要的[.o]文件。
  “隐含规则”会使用一些我们系统变量,我们可以改变这些系统变量的值来定制隐含规则的运行时的参数。如系统变量“CFLAGS”可以控制编译时的编译器参数。当然,你也可以利用 make 的-R--no–builtin-variables参数来取消你所定义的变量对隐含规则的作用。

  1. 关于命令的变量
变量默认命令
AR函数库打包程序。默认命令是“ar”
AS汇编语言编译程序。默认命令是“as”。
CCC 语言编译程序。默认命令是“cc”。
CXXC++语言编译程序。默认命令是“g++”。
CO从 RCS 文件中扩展文件程序。默认命令是“co”。
CPPC 程序的预处理器(输出是标准输出设备)。默认命令是“$(CC) –E”。
FCFortran 和 Ratfor 的编译器和预处理程序。默认命令是“f77”。
GET从 SCCS 文件中扩展文件的程序。默认命令是“get”。
LEXLex 方法分析器程序(针对于 C 或 Ratfor)。默认命令是“lex”。
PCPascal 语言编译程序。默认命令是“pc”。
YACCYacc 文法分析器(针对于 C 程序)。默认命令是“yacc”。
YACCRYacc 文法分析器(针对于 Ratfor 程序)。默认命令是“yacc –r”。
MAKEINFO转换 Texinfo 源文件(.texi)到 Info 文件程序。默认命令是“makeinfo”。
TEX从 TeX 源文件创建 TeX DVI 文件的程序。默认命令是“tex”。
TEXI2DVI从 Texinfo 源文件创建军 TeX DVI 文件的程序。默认命令是“texi2dvi”。
WEAVE转换 Web 到 TeX 的程序。默认命令是“weave”。
CWEAVE转换 C Web 到 TeX 的程序。默认命令是“cweave”。
TANGLE转换 Web 到 Pascal 语言的程序。默认命令是“tangle”。
CTANGLE转换 C Web 到 C。默认命令是“ctangle”。
RM删除文件命令。默认命令是“rm –f”
  1. 关于命令参数的变量
      下面的这些变量都是相关上面的命令的参数。如果没有指明其默认值,那么其默认值都是空
参数含义
ARFLAGS函数库打包程序 AR 命令的参数。默认值是“rv”。
ASFLAGS汇编语言编译器参数。(当明显地调用“.s”或“.S”文件时)。
CFLAGSC 语言编译器参数。
CXXFLAGSC++语言编译器参数。
COFLAGSRCS 命令参数。
CPPFLAGSC 预处理器参数。( C 和 Fortran 编译器也会用到)。
FFLAGSFortran 语言编译器参数。
GFLAGSSCCS “get”程序参数。
LDFLAGS链接器参数。(如:“ld”)
LFLAGSLex 文法分析器参数。
PFLAGSPascal 语言编译器参数。
RFLAGSRatfor 程序的 Fortran 编译器参数。
YFLAGSYacc 文法分析器参数。

八、GCC命令补充

  1. 调用数学库用“-L”指定库所在的目录
LIBPATH := -lgcc -L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.4
  1. -Wall选项意思是编译后显示所有警告
  2. -nostdlib 不连接系统标准启动文件和标准库文件.只把指定的文件传递给连接器
  3. 加入选项“-fno-builtin”表示不使用内建函数
  4. 添加了选项“-Wa,-mimplicit-it=thumb”,避免报错thumb(拇指?) 条件指令应该在IT(?)块中
$(CC) -Wall -Wa,-mimplicit-it=thumb -nostdlib -fno-builtin -c -O2 $(INCLUDE) -o $@ $<
  1. 加入了“-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard”指令,这些指令用于
    指定编译浮点运算的时候使用硬件 FPU
 $(CC) -Wall -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -Wa,-mimplicit-it=thumb -nostdlib -fno-builtin -c -O2 $(INCLUDE) -o $@ $<
  1. 自动生成依赖性
      大多数的C/C++编译器都支持一个“-M”的选项,即自动找寻源文件中包含的头文件,并生成一个依赖关系,如:
cc -M main.c
  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Makefile 是用于自动化编译程序的工具,它使用一种名为“规则”的方式来描述源文件和目标文件之间的依赖关系,然后根据这些规则自动编译程序。 Makefile 通常包括以下几个部分: 1. 变量定义:定义需要的变量,如编译器、编译选项等。 2. 目标文件:定义需要编译的目标文件、依赖文件和编译规则。 3. 伪目标:定义一些伪目标,如 clean、install 等。 下面是 Makefile语法: 1. 变量定义: 变量定义的语法格式为: ``` 变量名 = 变量值 ``` 例如: ``` CC = gcc CFLAGS = -Wall -O2 ``` 2. 目标文件: 目标文件的格式为: ``` 目标文件: 依赖文件 编译规则 ``` 例如: ``` main.o: main.c $(CC) $(CFLAGS) -c main.c -o main.o ``` 其中: - 目标文件是 main.o。 - 依赖文件是 main.c。 - 编译规则是 $(CC) $(CFLAGS) -c main.c -o main.o,表示使用 gcc 编译器和编译选项将 main.c 编译成 main.o。 3. 伪目标: 伪目标的格式为: ``` 伪目标: 命令 ``` 例如: ``` clean: rm -rf *.o ``` 其中: - 伪目标是 clean。 - 命令是 rm -rf *.o,表示删除所有的 .o 文件。 这些是 Makefile 的基本语法,你可以根据需要添加更多的规则来实现自动化编译。 ### 回答2: Makefile是用于自动化构建和管理软件项目的一种脚本语言,它描述了软件项目中的文件依赖关系和构建规则。Makefile文件通常包含一系列规则和命令。 Makefile的基本语法包括: 1.目标(Target):由一组规则组成,表示一个或多个文件的生成或操作。目标的命名可以是任意合法的文件名。 2.依赖(Prerequisites):目标所依赖的文件或目标。依赖可以是文件、目录或其他目标。当依赖发生变化时,相应的目标将重新生成。 3.命令(Command):规则中执行的命令。命令必须以Tab键开头,并且可以有多条。 4.规则(Rule):目标、依赖和命令的组合。规则表示了如何生成目标文件或执行一系列操作。 5.变量(Variables):用于存储常用的值或字符串,以便在Makefile中重复使用。变量以$符号开头,并用括号括起来。 6.条件判断(Conditionals):用于根据特定条件选择不同的规则或命令执行路径。条件判断以ifeq、ifneq等关键字开头。 7.循环(Loops):可以在Makefile中使用循环语句,例如foreach、while等,用于重复执行特定的操作。 Makefile的执行过程是根据文件的依赖关系来决定哪些目标需要重新生成。当执行make命令时,Makefile会被解析,并根据依赖关系构建目标文件,如果目标文件已经存在且依赖没有发生变化,则不会重新生成。 Makefile的优点是可以自动化构建过程、减少重复操作、提高项目的可维护性和可靠性。它可以根据项目的需要灵活定义构建规则,并自动处理文件间的依赖关系,大大简化了项目的管理工作和构建过程。 ### 回答3: makefile是一种用于构建和管理软件项目的工具,它使用明确的规则来指导编译和链接操作。它通常用于编译C/C++等编程语言的项目。 makefile的基本语法包含了规则、变量和命令。 规则是makefile的核心,它由目标、依赖和命令组成。目标是需要生成的文件,依赖是生成目标所依赖的文件或其他目标,命令是生成目标的具体操作。规则的格式如下: ``` 目标: 依赖 [tab] 命令 ``` 变量在makefile中用于保存常用的路径、编译选项等信息。可以通过变量的引用来简化makefile的书写和维护。变量的定义使用等号(=)来完成,如: ``` 变量名 = 值 ``` 命令是makefile中的具体操作步骤,用于生成目标。每条命令都必须以一个制表符(tab)开头,否则会被当作普通文本处理。 makefile还有一些常用的指令,如clean、all等。clean指令用于清理编译生成的目标文件和可执行文件,all指令用于编译所有文件。 makefile的优势在于可以自动判断哪些文件需要重新编译,从而提高了构建效率。它可以根据文件的修改时间和依赖关系来确定需要重新编译的文件,并只编译这些文件,避免了不必要的重复操作。 总之,makefile是一种强大的构建工具,它以简洁的语法和智能的依赖关系判断,能够实现高效的软件构建和管理。但需要注意的是,makefile语法在不同的平台和编译器上可能会有一些差异,需要根据具体情况进行调整和学习。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别问,问就是全会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值