Makefile语法

本文详细介绍了Makefile的基础概念,包括变量定义、特殊字符的作用、规则的使用等,并通过具体实例展示了如何利用Makefile进行项目的编译管理和目录遍历。
1. 批注:以 # 开头的即为批注。
2.变量宣告:(有人称之为宏)
注意在,在变量=前后必须要加上空白,而变量名称为大小写相异。利用 MACRO = 来取消该变数。

3 := 语法

注意到,make 会将整个 Makefile 展开后,再决定变数的值。也就是说,变量的值将会是整个 Mackfile 中最后被指定的值。例:

x = foo
y = $(x) bar
x = xyz
# y 的值为 xyz bar

在上例中,y 的值将会是 xyz bar,而不是 foo bar。

您可以利用 := 来避开这个问题。:= 表示变量的值决定于它在 Makefile 中的位置,而不是整个 Makefile 展开后最终的值。

一些常见的自动化变量说明如下:
(1) $@ ——目标文件的名称;
(2) $^ ——所有的依赖文件,以空格分开,不包含重复的依赖文件;
(3) $< ——第一个依赖文件的名称。

(4)$* :代表 tragets 所指定的档案,但不包含扩展名。



示例:
main:main.c sort.o
gcc main.c sort.o -o main
表示为简洁的就是:
main:main.c sort.o
gcc $^ -o $@

 

子目录:

如果该项目有多个目录,且每一个目录中都有 Makefile,则利用以下指令来进入子目录并进行编译:

cd dir;$(MAKE)

例:

SUBDIRS = dir1 dir2 dir3
all:
        for i in $(SUBDIRS); do
                (cd $$i; make);
        done
clean:
        for i in $(SUBDIRS); do
                (cd $$i; make clean);
        done
install:
        for i in $(SUBDIRS); do
                (cd $$i; make install);
        done

 

特别字符:

@:不要显示执行的指令。

-:表示即使该行指令出错,也不会中断执行。

例:

.PHONY: clean
clean:
    @echo "Clean..."
    -rm *.o

因为 make 会一行一行将正在执行的 Commands 显示在屏幕上,但您可以利用 @ 来暂时关闭这个功能。

而 make 只要遇到任何错误就会中断执行。但像是在进行 clean 时,也许根本没有任何档案可以 clean,因而 rm 会传回错误值,因而导致 make 中断执行。我们可以利用 - 来关闭错误中断功能,让 make 不会因而中断。

规则:(Rule)

指示 make 如何进行编译。

主要语法:

target: dependencies
<Tab>Commands

target: dependencies; Commands
<Tab>Commands

Rule 指示了 make 如何建立 target;及何时要重新建立 target。

target:所要建立的档案
dependencies:相依项目。make 会据此决定是否要重新编译 target。
Commands:建立 target 的指令。

在 Makefile 里并没有限定 Rule 的先后顺序。但默认上,make 会参考 all 这个目标项目,并依据它的 dependencies 来决定要建立哪些项目。若没有 all 项目,则会采用 Makefile 里的第一个项目。

target:(目标项目)

这个项目所要建立的档案,必须以 : 结尾。例:

foo.o: common.h
    gcc -c foo.c

其中,foo.o 是这个项目要建立的档案;common.h 是相依性的项目/档案;而 gcc -c foo.c 则为要产生这个项目所要执行的指令。
make 在编译时,若发现 target 比较新,也就是 dependencies 都比 target 旧,那么将不会重新建立 target,如此可以避免不必要的编译动作。
若该项目并非档案,则为 fake 项目。如此一来将不会建立 target 档案。但为了避免 make 有时会无去判断 target 是否为档案或 fake 项目,建议利用 .PHONY 来指定该项目为 fake 项目。例:

.PHONY: clean
clean:
    rm *.o

在上例中,若不使用 .PHONY 来指定 clean 为 fake 项目的话,若目录中同时存在了一个名为 clean 的档案,则 clean 这个项目将被视为要建立 clean 这个档案,但 clean 这个项目却又没有任何的 dependencies,也因此,clean 项目将永远被视为 up-to-date,永远不会被执行

因为利用了 .PHONY 来指定 clean 为 fake 项目,所以 make 不会去检查目录中是否存在了一个名为 clean 的档案。如此也可以提升 make 的执行效率。

其它类以 .PHONY 的语法请参考:

GNU `make': 4.9 Special Built-in Target Names

另外,如果某个非 fake 项目里的 dependencies 包含了 fake 项目的话,因为 make 一定会执行 fake 项目,这样一来,这个非 fake 项目一定也会被执行。这可能不是理想的做法。

dependencies:(相依性项目,以空白间隔)

dependencies 是指定在建立 target 之前,必须先检查的项目。可以不指定。例:

foo.o: common.h
    gcc -c foo.c

上例中是指:检查 common.h。如果它的建立日期比 foo.o 新,就执行 gcc -c foo.c 来重新产生 foo.o。也就是说,可以依需求建立 dependencies,即使它和 target 一点关系也没有。

相依性项目可以是 Makefile 中其它的 target。也因此,在建立该 target 之前,它会先检查在 dependencies 里所指定的所有 target。

Commands:(即为要执行的 Shell 指令)

必须以 <Tab> 开头。使用 Shell Script 语法。在 Makefile 里,只要以 <Tab> 开头都将会被视为 Shell Script 执行。

每条法则必须写在同一行。每条 Command 会启动一个新的 Shell,预设为 /bin/sh。若执行完某条 Command 但传回了错误值,make 就会中断执行。

因为每条 Command 会启动一个新的 Shell,所以有时执行的指令必须写在同一行,像是使用 if 来进行条件判断,此时可以用 ; 来分隔指令。例:

all:
    if [ -f foo ];
        then rm foo;
    fi

而以下是错误示范:

all:
    cd subdir; $(MAKE)

这时因为 make 只会检查最后一个指令的传回值,所以在以上指令中,即使 subdir 不存在,但 make 并不会因而中断执行,并会继续执行 $(MAKE) 指令,而产生了不可预期的结果。
为了避免这个问题,可以利用 && 来检查其中某个指令是否成功执行,再决定是否执行下个指令。例:

all:
    cd subdir && $(MAKE)

转载于:https://www.cnblogs.com/cheng07045406/p/3521273.html

### 回答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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值