我知道makefile不允许使用目标变量作为目标的先决条件。
我的问题略有不同:是否有办法根据目标变量的不同而生成不同的文件?
比如说,我希望能够生成这样的文件 file_to_generate
使用两种不同的方法,我称之为使用 make example_target_1
或 make example_target_2
作为一个例子,下面的代码为同一个文件给出了2个不同的配方。
example_target_1 : file_to_generate-receipe1
example_target_2 : file_to_generate-receipe2
file_to_generate-receipe1:
/* some shell code here that end up generating file_to_generate */
file_to_generate-receipe2:
/* some different shell code here that also generates file_to_generate*/
发出 make example_target_1
将使用一个配方生成文件,同时发出 make example_target_2
将做同样的使用其他配方。
使用这个问题是两个 example_target_1
和 example_target_2
不检查是否 file_to_generate
是最新的,因为目标的名字并不是一个真正的文件。
有什么方法可以让我们在得到同样的行为的同时,还能检查文件是否是最新的?
有一种方法可以实现,那就是使用特定目标的变量,就像这样。
$ cat Makefile
target1 target2: file_to_generate
cat $<
target1: RECIPE=recipe1
target2: RECIPE=recipe2
file_to_generate:
$(if $(filter recipe1,$(RECIPE)),$(recipe1))
$(if $(filter recipe2,$(RECIPE)),$(recipe2))
define recipe1
echo recipe1
echo foo > $@
endef
define recipe2
echo recipe2
echo bar > $@
endef
尽管它是可行的,但我强烈建议不要这样设计。以非确定的方式生成文件可能很容易导致非平凡的错误。例如,使用这种方法你会生成一个文件,并且会检查它是否是最新的,但是make没有办法猜测它是用recipe1还是recipe2生成的。因此下次调用不同的目标时,即使配方发生了变化,文件也不会被重新生成(因为它已经存在)。
$ make target1
echo recipe1
recipe1
echo foo > file_to_generate
cat file_to_generate
foo
$ make target2
cat file_to_generate
foo
当你用 target2
首先,该文件将有不同的内容,这些内容将被重用在 target1
以及。
$ rm file_to_generate
$ make target2
echo recipe2
recipe2
echo bar > file_to_generate
cat file_to_generate
bar
$ make target1
cat file_to_generate
bar
这可能是,也可能是不可取的, 你需要注意这种行为。