Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何避免类似配方的Makefile目标中的重复?_Makefile_Dry - Fatal编程技术网

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

如何避免类似配方的Makefile目标中的重复?,makefile,dry,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 我希望避免所有这些重复。我希望有如下内容(这不是有效的语法;这只表达了我的意图) 有可能这样做吗?如果没有,我能写的最好的Makefile是什么,可以最大限度地减少配方中

我有一个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
我希望避免所有这些重复。我希望有如下内容(这不是有效的语法;这只表达了我的意图)


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

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

另外,您的makefile表示您正在创建一个文件
foo
,但您的配方实际上创建了一个文件
~/bin/foo
,这与此不同

无论如何,这正是我们的目的:

EXES=foo-bar-baz
全部:$(addprefix$(HOME)/bin/,$(EXES))
$(HOME)/bin/%::%.c
gcc$<-o$@

(感谢Beta在原文中指出了我的think-o)

A
make
规则实际上可以匹配多个目标:

foo bar baz:
    gcc $@.c -o $@
    mv $@ ~/bin
但是,您应该在规则中明确依赖关系:

foo: foo.c
bar: bar.c
baz: baz.c

foo bar baz:
    gcc $< -o $@
    mv $@ ~/bin
foo:foo.c
酒吧:酒吧
baz:baz.c
福吧巴兹:
gcc$<-o$@
mv$@~/bin

前三行只指定依赖项,没有任何实际构建它们的操作。您可以在gcc的帮助下生成这些规则:
gcc-mmfoo.c
将为
foo.c

打印一条规则,您是否违反了其中一条规则?精确地说,第2个,共6个:目标模式应该与正在构建的对象的实际名称相匹配(
~/bin/%
)。您应该使用以避免使用。类似这样的:
foobarbaz:%:%.c
你说得对。我想这是一个
cp
而不是
mv
。我会更新的。关于“静态模式规则”:我一直看到这个建议,您“应该”使用它们。我几乎从不使用它们。事实上,我总是使用普通模式规则,只有当我有一个子集的目标应该以不同的方式构建时,才使用静态模式规则。我认为这是一种风格/观点;我不会在没有任何理由的情况下告诉人们他们“应该”使用它们。正如@beta在其他地方指出的那样,你的
Makefile
被破坏了,因为你移动了你制作的文件,所以无论是否有必要,每次都会重新制作它们。另外,
gcc
-o
选项可以显著地获取子目录<代码>bin/%:%.c;gcc$<-o$@
foo bar baz:
    gcc $@.c -o $@
    mv $@ ~/bin
foo: foo.c
bar: bar.c
baz: baz.c

foo bar baz:
    gcc $< -o $@
    mv $@ ~/bin