Makefile – 其他功能
在本章中,我们将研究Makefile的各种其他特性。
递归使用make
递归使用 make 是指将 make 作为makefile中的一个命令。当你想为组成一个大系统的各个子系统单独编写makefile时,这种技术非常有用。例如,假设你有一个名为 “subdir “的子目录,它有自己的makefile,而你希望包含目录的makefile能在子目录上运行 make 。你可以通过编写下面的代码来实现 —
subsystem:
cd subdir && (MAKE)
or, equivalently:
subsystem:(MAKE) -C subdir
你可以通过复制这个例子来编写递归的 make 命令。然而,你需要了解它们是如何工作的,为什么,以及子 make 与顶级 make 的关系。
向子 make 传递变量
顶层 make 的变量值可以通过明确的请求,通过环境传递给子make。这些变量在子制造中被定义为默认值。除非你使用`-e’开关,否则你不能覆盖子make makefile所使用的makefile中的指定内容。
要传递或导出一个变量, make 会将该变量及其值添加到运行每个命令的环境中。反过来,子make使用环境来初始化其变量值表。
特殊变量SHELL和MAKEFLAGS总是被导出(除非你取消导出)。如果你将MAKEFILES设置为任何内容,它就会被导出。
如果你想把特定的变量导出到一个子制作中,请使用导出指令,如下图所示
export variable ...
如果你想阻止一个变量被导出,使用unexport指令,如下图所示
unexport variable ...
变量MAKEFILES
如果定义了环境变量MAKEFILES, make 会把它的值看作是一个额外的makefile的名字列表(用空格隔开),这些文件将在其他文件之前被读取。这与include指令的工作原理很相似:不同的目录会被搜索到这些文件。
MAKEFILES的主要用途是在 make . NET的递归调用之间进行通信 。
包括不同目录下的头文件
如果你把头文件放在不同的目录下,并且你在不同的目录下运行 make ,那么就需要提供头文件的路径。这可以通过makefile中的-I选项来完成。假设 functions.h 文件在 /home/tutorialspoint/header 文件夹中,其余文件在 /home/tutorialspoint/src/ 文件夹中,那么 makefile 将被写成以下样子
INCLUDES = -I "/home/tutorialspoint/header"
CC = gcc
LIBS = -lm
CFLAGS = -g -Wall
OBJ = main.o factorial.o hello.o
hello: {OBJ}{CC} {CFLAGS}{INCLUDES} -o @{OBJS} {LIBS}
.cpp.o:{CC} {CFLAGS}{INCLUDES} -c $<
为变量添加更多文本
通常情况下,在已经定义的变量的值上添加更多的文本是很有用的。你可以用包含 “+=”的一行来做这件事,如图所示。
objects += another.o
它接收变量objects的值,并在其上添加文字`another.o’,前面有一个空格,如下图所示。
objects = main.o hello.o factorial.o
objects += another.o
上述代码将对象设置为`main.o hello.o factorial.o another.o’。
使用`+=’类似于:
objects = main.o hello.o factorial.o
objects := $(objects) another.o
Makefile中的续行
如果你不喜欢你的Makefile里有太大的行,那么你可以用反斜杠”/”来中断你的行,如下图所示。
OBJ = main.o factorial.o \
hello.o
is equivalent to
OBJ = main.o factorial.o hello.o
从命令提示符运行Makefile
如果你已经准备了名称为 “Makefile “的Makefile,那么只要在命令提示符下写make,它就会运行Makefile文件。但如果你给Makefile起了其他名字,那么请使用以下命令
make -f your-makefile-name