Make

makefile 的參數列表太長錯誤

  • November 10, 2018

在makefile中,我有

@echo "$(IGNORE_DIRS) $(CLEAN_FILES) $(CLEAN_DIRS) $(REALCLEAN_FILES)" | tr ' ' '\n' >> $@

問題是它$(CLEAN_FILES)很大,所以當我執行 make 時,我得到

make: execvp: /bin/sh: Argument list too long

我在 Xubuntu 18.10 上。

編輯:我應該提供更多的上下文。我正在研究的是一個生成規則(我正在使用 GNU make)來自動生成.hgignore文件。以下是完整的 make 規則:

.hgignore : .hgignore_extra
   @echo "Making $@"
   @rm -f $@
   @echo "# Automatically generated by Make. Edit .hgignore_extra instead." > $@
   @tail -n +2 $< >> $@
   @echo "" >> $@
   @echo "# The following files come from the Makefile." >> $@
   @echo "syntax: glob" >> $@
   @echo "$(IGNORE_DIRS) $(CLEAN_FILES) $(CLEAN_DIRS) $(REALCLEAN_FILES)" | tr ' ' '\n' >> $@
   @chmod a-w $@
.PHONY : .hgignore

編輯2:在@mosvy 的建議下,我也嘗試過

.hgignore : .hgignore_extra
   @echo "Making $@"
   @rm -f $@
   @echo "# Automatically generated by Make. Edit .hgignore_extra instead." > $@
   @tail -n +2 $< >> $@
   @echo "" >> $@
   @echo "# The following files come from the Makefile." >> $@
   @echo "syntax: glob" >> $@
   $(file >$@) $(foreach V,$(IGNORE_DIRS) $(CLEAN_FILES) $(CLEAN_DIRS) $(REALCLEAN_FILES),$(file >>$@,$V))
   @true
   @chmod a-w $@
.PHONY : .hgignore

執行make .hgignore這個,我不再得到“參數列表太長”錯誤,但生成的 .hgignore 文件只包含輸出到該syntax: glob行,然後什麼都沒有。

正如@schily 已經解釋的那樣,這不是一個shell問題,不能用xargs、引用、拆分為更多的 echo;等來解決。來自 make 操作的所有文本都作為參數傳遞給單個execve(2),它不能超過作業系統允許的最大大小。

如果您使用的是 GNU make(linux 上的預設設置),您可以使用它的fileforeach函式:

TEST = $(shell yes foobar | sed 200000q)

/tmp/junk:
       $(file >$@) $(foreach V,$(TEST),$(file >>$@,$V))
       @true

.PHONY: /tmp/junk

這會將由換行符分隔的所有單詞列印$(TEST)到名為 in 的文件中$@。它基於 make’s manual中的一個類似範例。

您的 Makefile 可能會被重新設計成更易於管理的東西,不需要花哨的 GNU 功能,但很難從您發布的片段中判斷出如何。

更新:

對於問題的確切片段,可以這樣做:

.hgignore : .hgignore_extra
   $(info Making $@)
   $(file >$@.new)
   $(file >>$@.new,# Automatically generated by Make. Edit .hgignore_extra instead.)
   $(shell tail -n 2 $< >>$@.new)
   $(file >>$@.new,)
   $(file >>$@.new,# The following files come from the Makefile.)
   $(file >>$@.new,syntax: glob)
   $(foreach L, $(IGNORE_DIRS) $(CLEAN_FILES) $(CLEAN_DIRS) $(REALCLEAN_FILES), $(file >>$@.new,$L))
   @mv -f $@.new $@
   @chmod a-w $@
.PHONY : .hgignore

我做了一點改動,所以它首先寫入.hgignore.new,如果一切順利,然後才移動.hgignore.new.hgignore. 您必須將縮進空格改回製表符,因為這個愚蠢的界面正在破壞空格。

引用自:https://unix.stackexchange.com/questions/480685