如何避免 Makefile 目标中具有类似配方的重复?

Lon*_*ner 4 makefile dry

我有一个 Makefile,其中有很多目标,并且每个目标的配方非常相似。

foo:
    gcc foo.c -o foo
    mv foo ~/bin

bar:
    gcc bar.c -o bar
    mv bar ~/bin

baz:
    gcc baz.c -o baz
    mv baz ~/bin
Run Code Online (Sandbox Code Playgroud)

我想避免所有这些重复。我想要像下面这样的东西(这不是有效的语法;这只表达了我的意图)。

TARGET_NAME:
    gcc $(TARGET_NAME).c -o $(TARGET_NAME)
    mv $(TARGET_NAME) ~/bin
Run Code Online (Sandbox Code Playgroud)

可以做这样的事情吗?如果没有,我能编写的最好的 Makefile 是什么,可以最大限度地减少食谱中的重复?

Mad*_*ist 5

您的 makefile 是错误的,因为您的目标(foobar等)不依赖于它们的源文件(foo不依赖于foo.c等),因此,更改源代码不会导致目标被重建。

另外,你的 makefile 说你正在创建一个文件foo,但你的配方实际上创建了一个文件~/bin/foo,这不是一回事。

无论如何,这正是模式规则的用途:

EXES = foo bar baz

all: $(addprefix $(HOME)/bin/,$(EXES))

$(HOME)/bin/%:: %.c
        gcc $< -o $@
Run Code Online (Sandbox Code Playgroud)

(感谢Beta在原文中指出了我的想法)

  • 你没有违反[你自己的规则](http://make.mad-scientist.net/papers/rules-of-makefiles/)之一吗?准确地说,第 2 个(共 6 个):目标模式应该与正在构建的事物的实际名称相匹配 (`~/bin/%`)。 (2认同)