特定于目标的变量作为Makefile中的先决条件

时间:2009-08-27 10:01:46

标签: build-process build dependencies makefile

我正在尝试编写一个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)

3 个答案:

答案 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)

两个要点:

  1. export目标变量,以便在我们重新运行Makefile时可以访问它们。
  2. 创建一个具有target_1 target_2所有原始先决条件的代理目标,并在target_1 target_2中使用此代理目标再次调用Makefile。由于那时目标特定变量将具有值(当时我们 在配方中)它们被export编辑,它们将在target-proxy - 瞧::)
  3. 这种方法的缺点是我们正在创建另一个make进程 - 如果它只是另一个进程那么它可能没问题,但是YMMV因此要格外小心。