概述
如果您想在更新某些文件时运行或更新任务,该make
实用程序可以派上用场。该make
实用程序需要一个文件,Makefile
(或makefile
),它定义了要执行的任务集。您可能习惯于make
从源代码编译程序。大多数开源项目用于make
编译最终的可执行二进制文件,然后可以使用make install
.
在本文中,我们将探索make
和Makefile
使用基本和高级示例。在开始之前,请确保make
已安装在您的系统中。
基本示例
让我们从在终端上打印经典的“Hello World”开始。myproject
创建一个包含具有以下内容的文件的空目录Makefile
:
echo "Hello World"
make
现在通过在目录中键入来运行该文件myproject
。输出将是:
echo "Hello World"
你好世界
在上面的示例中,say_hello
与在任何编程语言中一样,它的行为类似于函数名称。这称为目标。先决条件或依赖项遵循目标。为了简单起见,我们没有在这个例子中定义任何先决条件。该命令echo "Hello World"
称为配方。配方使用先决条件来制作目标。目标、先决条件和配方一起构成规则。
总而言之,以下是典型规则的语法:
< TAB >配方
例如,目标可能是依赖于先决条件(源文件)的二进制文件。另一方面,先决条件也可以是依赖于其他依赖项的目标:
Recipe_to_create_final_target
sub_target: sub_target.c
配方_to_create_sub_target
目标不一定是文件;它可能只是食谱的名称,如我们的示例所示。我们称这些为“虚假目标”。
回到上面的例子,当被执行时,会显示make
整个命令,然后是实际的命令输出。echo "Hello World"
我们通常不希望这样。要抑制回显实际命令,我们需要echo
从以下内容开始@
:
@echo "Hello World"
现在尝试再次运行make
。输出应该只显示这个:
让我们添加一些更多的虚假目标:generate
并clean
添加到Makefile
:
@echo " Hello World" generate: @echo "Creating empty text files..." touch file- { 1 .. 10 } .txt clean : @echo "正在清理... " rm * .txt
make
如果我们尝试在更改后运行,则say_hello
只会执行目标。那是因为只有 makefile 中的第一个目标是默认目标。通常称为默认目标all
,这就是您在大多数项目中将其视为第一个目标的原因。all
调用其他目标是责任。我们可以使用一个名为.DEFAULT_GOAL
.
让我们将其包含在我们的 makefile 的开头:
.DEFAULT_GOAL := generate
generate
这将默认运行目标:
创建空文本文件...
touch file- { 1 .. 10 } .txt
顾名思义,假目标.DEFAULT_GOAL
一次只能运行一个目标。这就是为什么大多数 makefile 包含all
一个可以根据需要调用任意多个目标的目标。
让我们包含虚假目标all
并删除.DEFAULT_GOAL
:
:
@echo "Hello World" generate: @echo "Creating empty text files..." touch file- { 1 .. 10 } .txt clean: @echo "正在清理..." rm * .文本
在运行之前make
,让我们包含另一个特殊的虚假目标,.PHONY
我们在其中定义所有不是文件的目标。make
将运行其配方,而不管具有该名称的文件是否存在或其最后修改时间是什么。这是完整的生成文件:
say_hello generate
say_hello:
@echo "Hello World" generate: @echo " Creating empty text files..." touch file- { 1 .. 10 } .txt clean : @echo "清理中..." rm * .txt
应该make
调用say_hello
和generate
:
Hello World
创建空文本文件...
touch file- { 1 .. 10 } .txt
最好不要调用clean
或all
将其作为第一个目标。clean
当需要清洁作为第一个参数时,应该手动调用make
:
正在清理...
rm * .txt
现在您已经了解了基本 makefile 的工作原理以及如何编写简单的 makefile,让我们看一些更高级的示例。
进阶范例
变量
跳到内容
在上面的 示例中,大多数目标值和先决条件值是硬编码的,但在实际项目中,这些值被替换为变量和模式。在 makefile 中定义变量的最简单方法是使用=
运算符。例如,将命令分配gcc
给变量CC
:
CC = gcc
这也称为递归扩展变量,它在如下所示的规则中使用:
${CC} hello.c -o你好
正如您可能已经猜到的那样,配方在传递到终端时展开如下:
gcc hello.c -o hello
和${CC}
都是$(CC)
对 call 的有效引用gcc
。但是,如果有人试图将一个变量重新分配给自己,则会导致无限循环。让我们验证一下:
CC = ${CC}
all:
@echo $ {CC}
运行make
将导致:
Makefile: 8 : ***递归变量“CC”引用自身(最终)。停止。
为了避免这种情况,我们可以使用:=
运算符(也称为简单扩展变量)。运行下面的 makefile 应该没有问题:
:= ${CC}
all:
@echo ${CC}
模式和功能
下面的 makefile 可以通过使用变量、模式和函数来编译所有 C 程序。让我们逐行探索它:
# make # compile all binary
# make clean # remove ALL binaries and objects
.PHONY = all clean
CC = gcc # 编译器使用
LINKERFLAG = -lm
SRCS := $(wildcard *.c)
BINS := $(SRCS :%.c=%)
all: ${BINS}
%: %.o
@echo "Checking.."
${CC} ${LINKERFLAG} $< -o $@
%.o: %.c
@echo "Creating对象.."
${CC} -c $<
clean:
@echo "正在清理..."
rm -rvf *.o ${BINS}
-
以 开头的行
#
是注释。 -
行
.PHONY = all clean
定义虚假目标all
和clean
。 -
变量
LINKERFLAG
定义要在配方中使用的标志gcc
。 -
SRCS := $(wildcard *.c)
:是文件名的功能$(wildcard pattern)
之一。在这种情况下,所有具有扩展名的文件都将存储在一个变量中。.c
SRCS
-
BINS := $(SRCS:%.c=%)
:这称为替代参考。在这种情况下,如果SRCS
有值'foo.c bar.c'
,BINS
将有'foo bar'
。 -
行
all: ${BINS}
:虚假目标all
将值${BINS}
作为单独的目标调用。 -
规则:
% : % .o
@ echo "正在检查.."
${CC} ${LINKERFLAG} $ & lt; -o $ @让我们看一个例子来理解这个规则。假设
foo
是 中的值之一${BINS}
。然后%
将匹配foo
(%
可以匹配任何目标名称)。以下是扩展形式的规则:foo: foo.o
@ echo "正在检查.."
gcc -lm foo.o -o foo如图所示,
%
被替换为foo
。$<
替换为foo.o
.$<
被模式化以匹配先决条件并$@
匹配目标。将为中的每个值调用此规则${BINS}
-
规则:
% .o: % .c
@echo "创建对象.." ${CC} -c $ & lt ;
先前规则中的每个先决条件都被视为此规则的目标。以下是扩展形式的规则:
foo.o : foo.c
@echo "Creating object.." gcc -c foo.c
-
最后,我们删除 target 中的所有二进制文件和目标文件
clean
。
下面是上面的 makefile 的重写,假设它被放置在具有单个文件的目录中foo.c:
# make # compile all binary
# make clean # remove ALL binaries and objects
.PHONY = all clean
CC = gcc # 编译器使用
LINKERFLAG = -lm
SRCS := foo.c
BINS := foo
all: foo foo
: foo .o
@echo "正在检查.."
gcc -lm foo.o -o foo
foo.o: foo.c
@echo "正在创建对象.."
gcc -c foo.c
clean:
@echo "正在清理..."
rm -rvf foo.o foo
有关 makefile 的更多信息,请参阅GNU Make 手册,其中提供了完整的参考和示例。
您还可以阅读我们的GNU Autotools 简介,了解如何为您的编码项目自动生成 makefile。
最后
以上就是灵巧方盒为你收集整理的Makefile工具的工作原理的全部内容,希望文章能够帮你解决Makefile工具的工作原理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复