如何(有效地)将GNU Make 3.81“字典”输出到文件

时间:2016-12-19 16:06:12

标签: makefile gnu-make

我在GNU make中有一个“词典”项目。

MY_KEYS:=foo bar baz
foo_VALUE:=thing1
bar_VALUE:=thing2
baz_VALUE:=thing3

我希望这个项目字典输出到一个文件,所以它看起来像......

foo=thing1
bar=thing2
baz=thing3

难度:“真正的”字典大小为几kb,并耗尽了Windows上的命令行限制。

我当前的低效实现最终会产生太多的sh.exe进程,并最终需要花费大约20秒的时间才能发出几个kb的数据。

#Slow implementation
define NEWLINE


endef

list.txt:
    @printf '' > $@
    @$(foreach key,$(MY_KEYS), \
       printf '$(key)=$($(key)_VALUE)\n' >> $@ $(NEWLINE) )

$(文件)函数在GNU make 3.81中也不可用,因为这将是“明显的”修复。

2 个答案:

答案 0 :(得分:0)

您可以将密钥列表切割为适合命令行的子列表:

var radioButtons = document.querySelectorAll('input[type=radio]');

for (var i = 0; i < radioButtons.length; i++) {
  radioButtons[i].addEventListener('change', function() {
    if (this.checked) {
      document.getElementById("paragraph").innerHTML = this.value;
    }
  });
}

例如,在我的系统上,限制介于10K到100K之间:

slice?=2
count?=3

$(shell echo -n 'MY_KEYS:=' > a.txt)
$(shell for i in `seq $(count)` ; do echo -n foo$$i' ' >> a.txt ; done)
$(shell echo >> a.txt)
$(shell for i in `seq $(count)` ; do echo foo$${i}_VALUE:=thing$$i >> a.txt ; done)

include a.txt

slices:=$(shell seq 1 $(slice) $(words $(MY_KEYS)))

define NEWLINE


endef

list.txt:
        @echo -n > $@
        @$(foreach s, $(slices), $(foreach key, $(wordlist $(s), $(shell echo $$(( $(s)+$(slice)-1 )) ), $(MY_KEYS)), echo $(key)=$($(key)_VALUE) >> $@ ; ) ${NEWLINE})

切入10K子列表工作并且仍然相当快:

x@vb:/tmp$ rm -f list.txt ; time make slice=100000 count=100000 list.txt 
make: execvp: /bin/sh: Argument list too long
Makefile:19: recipe for target 'list.txt' failed
make: *** [list.txt] Error 127

real    0m4.366s
user    0m1.452s
sys 0m2.772s

答案 1 :(得分:0)

Make 通常会直接执行命令而不涉及shell。 然而,您的配方中的>>重定向导致 make 将配方传递给实际的shell。 首先加速就是避免配方中的shell元字符, 把叉子的数量减半。

使用单个重定向的递归make符合此处的法案。 草图:

.PHONY: dump
dump:
    $(foreach _,${MY_KEYS},echo $_=${$__VALUE}${NEWLINE})

list.txt:
    ${MAKE} -s dump >$@

这使叉子的数量减少了一半。天真的版本。

所有dump规则都是为了回应某些内容。 但 make 无论如何都会这样做 (实际上我们添加了-s标志来阻止它。)

我们可以利用这个优势,避免所有分叉。 -n标志将 make 进行回音, 并且不涉及外壳。

.PHONY: dump
dump:
    $(foreach _,${MY_KEYS},$_=${$__VALUE}${NEWLINE})

list.txt:
    ${MAKE} -s -n dump >$@

的Pow!

但是,升级你的 make 。 这是20世纪; - )