2009-08-27 85 views
13

我正在尝试编写一个GNU Make Makefile,它具有类似目标的加载,其中构建命令在它们之间略有不同。 我试图用target-specific variables来表示这些变化。其中一些变量值指的是我想用作先决条件的文件。例如:特定于目标的变量作为Makefile中的先决条件

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) 

当我喊“让target_1”,我想它做target1_prereq如果它不存在。目前,即使使用正确的参数调用build命令(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

目标专用变量仅在目标的命令(或其他特定于目标的赋值)中定义;它不能用作目标的先决条件之一。我不认为有一个干净的方式做你的制作想要的东西,但有几个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,$^) 
+4

为了其他任何人的利益而复活此主题。 [更优雅的解决方案](http://stackoverflow.com/questions/9311743/make-using-target-specific-variables-in-prerequisites)使用二次扩展。 – Seth 2012-10-30 00:30:56

+0

@Seth,我同意:'target_1 target_2:common_filename $$(special_filename_base).exta $$(special_filename_base).extb ...' – Beta 2012-10-30 05:02:20

2

举一个简单的解决方法:

 
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) 

有一定的冗余度,但它是局部的,所以它不是太糟糕了。

+0

我想这解决了我发布的具体情况,但我希望得到更通用的解决方案。 我会用更复杂的例子编辑。 – 2009-08-27 10:29:26

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可 - 瞧:)

的缺点这种方法是我们正在创建另一个make进程 - 如果它只是另一个,那么它可能是好的,但YMMV所以要格外小心。