Makefile只执行第一个目标

时间:2015-04-15 22:20:31

标签: makefile gnu-make

我的文件看起来像这样

1_0_fa.bam  1_1_fa.bam  1_2_fa.bam  1_3_fa.bam  1_4_fa.bam  1_5_fa.bam
1_6_fa.bam  1_7_fa.bam  1_8_fa.bam  1_9_fa.bam  1_0_mo.bam  1_1_mo.bam
1_2_mo.bam  1_3_mo.bam  1_4_mo.bam  1_5_mo.bam  1_6_mo.bam  1_7_mo.bam
1_8_mo.bam  1_9_mo.bam  1_0_p1.bam  1_1_p1.bam  1_2_p1.bam  1_3_p1.bam
1_4_p1.bam  1_5_p1.bam  1_6_p1.bam  1_7_p1.bam  1_8_p1.bam  1_9_p1.bam

我希望用bin组合它们,这是名字中的第二个数字。这是我的Makefile(GNU make 3.81)

SHELL = /bin/sh
bins = 0 1 2 3 4 5 6 7 8 9
$(info $(bins))
code = 1

define buildVCF

$(info $(1))
$(eval targ = $(code)_$(1)_bin.vcf)
$(info $(targ))
targs += $(targ)
$(eval deps = $(wildcard $(code)_$(1)_*.bam))
$(info $(deps))

$(targ): $(deps)
    cat $$^ > $$@

endef

$(foreach bin,$(bins),$(eval $(call buildVCF,$(bin))))

all: $(targs)

如果我make -n,它会产生

0 1 2 3 4 5 6 7 8 9
0
1_0_bin.vcf
1_0_p1.bam 1_0_mo.bam 1_0_fa.bam
1
1_1_bin.vcf
1_1_fa.bam 1_1_p1.bam 1_1_mo.bam
2
1_2_bin.vcf
1_2_mo.bam 1_2_p1.bam 1_2_fa.bam
3
1_3_bin.vcf
1_3_fa.bam 1_3_mo.bam 1_3_p1.bam
4
1_4_bin.vcf
1_4_mo.bam 1_4_fa.bam 1_4_p1.bam
5
1_5_bin.vcf
1_5_fa.bam 1_5_mo.bam 1_5_p1.bam
6
1_6_bin.vcf
1_6_p1.bam 1_6_fa.bam 1_6_mo.bam
7
1_7_bin.vcf
1_7_fa.bam 1_7_p1.bam 1_7_mo.bam
8
1_8_bin.vcf
1_8_fa.bam 1_8_mo.bam 1_8_p1.bam
9
1_9_bin.vcf
1_9_mo.bam 1_9_p1.bam 1_9_fa.bam
cat 1_0_p1.bam 1_0_mo.bam 1_0_fa.bam > 1_0_bin.vcf

为什么不构建剩余的目标?

2 个答案:

答案 0 :(得分:3)

因为all目标不是Makefile中的第一个。当你在没有目标的情况下调用make时,会构建Makefile中的第一个规则,在这种情况下是1_0_bin.vcf的规则(因为它是先生成的)。如果您致电make -n all,它将按预期运作。

要使其在没有明确规则的情况下正常运行,只需将all目标移至顶部将无效,因为targs此时没有正确的值,但您可以将其设置为使用间接级别工作:

all: dummy

define buildVCF
...
endef

$(foreach bin,$(bins),$(eval $(call buildVCF,$(bin))))

dummy: $(targs)

然而,这似乎是一种相当迂回的做事方式。如果我是你,我会尝试使用静态模式规则解决问题,例如

targs = $(foreach bin,$(bins),$(code)_$(bin)_bin.vcf)

all: $(targs)

$(targs) : $(code)_%_bin.vcf : $(foreach i,fa mo p1,$(code)_%_$(i).bam)
    cat $^ > $@

答案 1 :(得分:1)

如果在命令行中未指定目标,则构建default goal

默认目标是

  

第一个目标(不是名称以'。'开头的目标)

在你的makefile中,第一个目标是buildVCF define创建的第一个目标。

正如Wintermute所指出的那样,你不能简单地将all: $(targs)行移到循环之上,因为targs还没有正确的值。

话虽如此,您可以将all:置于循环之上以“保留”默认目标(在这种情况下all: $(targs)将先决条件附加到保留目标)或者您可manually set the default goal在makefile中的任何地方.DEFAULT_GOAL := all

另一方面,我还没有完全理解你的设置,但我想你可以用更简单的一般模式(或静态模式)规则来做到这一点。