我正在尝试编写一个GNU make Makefile,它有一些类似的目标,其中构建命令在它们之间略有不同。 我正在尝试使用target-specific variables来表示这些变体。其中一些变量值指的是我想用作先决条件的文件。例如:
target_1:special_filename=target1_prereq
target_2:special_filename=target2_prereq
target_1 target_2: common_filename $(special_filename)
do_something common_filename --a-weird-option=$(special_filename)
当我调用'make target_1'时,我希望它生成target1_prereq(如果它不存在)。目前,即使使用正确的参数调用构建命令(do_something),它似乎也不会使用target1_prereq作为先决条件。
我正在使用GNU Make 3.80。
编辑: 真实系统的一些复杂问题。一些变量本身基于其他变量的值。手动指定先决条件将无法扩展。 一个稍微复杂的例子:
target_1:special_filename_base=target1_prereq
target_2:special_filename_base=target2_prereq
some_filename_a = $(special_filename_base).exta
some_filename_b = $(special_filename_base).extb
target_1 target_2: common_filename $(special_filename_b) $(special_filename_a)
do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b)
答案 0 :(得分:3)
作为一个简单的解决方法:
target_1:special_filename=target1_prereq target_1:target1_prereq target_2:special_filename=target2_prereq target_2:target2_prereq target_1 target_2: common_filename $(special_filename) do_something common_filename --a-weird-option=$(special_filename)
有一些冗余,但它是本地化的,所以它不是太糟糕。
答案 1 :(得分:3)
特定于目标的变量仅在目标命令中定义(或在其他特定于目标的分配中);它不能用作目标的先决条件之一。我不认为在Make中有一个干净的方法可以做你想要的,但有几种kludgey方法,如下所示:
EXTENSIONS = .exta .extb target_1: $(addprefix target1_prereq,$(EXTENSIONS)) target_2: $(addprefix target2_prereq,$(EXTENSIONS)) target_1 target_2: common_filename do_something common_filename --a-weird-option=$(filter %.exta,$^) --second=$(filter %.extb,$^)
答案 2 :(得分:2)
我找到了一种相当干净的方法来踩踏这个限制。它会是这样的:
target_1:export special_filename_base=target1_prereq
target_2:export special_filename_base=target2_prereq
some_filename_a = $(special_filename_base).exta
some_filename_b = $(special_filename_base).extb
target_1 target_2:
$(MAKE) -f $(firstword $(MAKEFILE_LIST)) target-proxy
target-proxy: common_filename $(special_filename_b) $(special_filename_a)
do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b)
两个要点:
export
目标变量,以便在我们重新运行Makefile时可以访问它们。target_1 target_2
所有原始先决条件的代理目标,并在target_1 target_2
中使用此代理目标再次调用Makefile。由于那时目标特定变量将具有值(当时我们 在配方中)和它们被export
编辑,它们将在target-proxy
- 瞧::)这种方法的缺点是我们正在创建另一个make
进程 - 如果它只是另一个进程那么它可能没问题,但是YMMV因此要格外小心。