Makefile - 根据目标生成不同的相同文件
Makefile - Generate same file differently depending on the target
我知道 makefile 不允许使用目标特定变量作为目标先决条件。
我的问题略有不同:有没有办法根据调用的目标生成不同的相同文件?
例如,假设我希望能够使用我使用 make example_target_1
或 make example_target_2
调用的两种不同方法生成 file_to_generate
例如,以下代码为同一文件提供了 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
这可能是可取的,也可能不是可取的,您需要注意此类行为。
我知道 makefile 不允许使用目标特定变量作为目标先决条件。
我的问题略有不同:有没有办法根据调用的目标生成不同的相同文件?
例如,假设我希望能够使用我使用 make example_target_1
或 make example_target_2
file_to_generate
例如,以下代码为同一文件提供了 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
这可能是可取的,也可能不是可取的,您需要注意此类行为。