Makefile 只执行第一个目标
Makefile executes only the first target
我有这样的文件
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
为什么不构建其余目标?
当命令行上没有指定目标时,make 构建 default goal。
默认目标是
the first target (not targets whose names start with ‘.’)
在您的 makefile 中,第一个目标是由 buildVCF
定义创建的第一个目标。
正如 Wintermute 指出的那样,您不能简单地将 all: $(targs)
行移动到循环上方,因为 targs
还没有正确的值。
话虽这么说,您可以将 all:
放在循环上方 "reserve" 默认目标(在这种情况下 all: $(targs)
将先决条件附加到保留目标),或者您可以 manually set the default goal 与 .DEFAULT_GOAL := all
在 makefile 中的任意位置。
另一方面,我还没有完全理解您的设置,但我想您可以使用一组更简单的通用模式(或静态模式)规则来做到这一点。
因为 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_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
为什么不构建其余目标?
当命令行上没有指定目标时,make 构建 default goal。
默认目标是
the first target (not targets whose names start with ‘.’)
在您的 makefile 中,第一个目标是由 buildVCF
定义创建的第一个目标。
正如 Wintermute 指出的那样,您不能简单地将 all: $(targs)
行移动到循环上方,因为 targs
还没有正确的值。
话虽这么说,您可以将 all:
放在循环上方 "reserve" 默认目标(在这种情况下 all: $(targs)
将先决条件附加到保留目标),或者您可以 manually set the default goal 与 .DEFAULT_GOAL := all
在 makefile 中的任意位置。
另一方面,我还没有完全理解您的设置,但我想您可以使用一组更简单的通用模式(或静态模式)规则来做到这一点。
因为 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 $^ > $@