【问题标题】:How can I automatically create (and remove) a temp directory in a Makefile?如何在 Makefile 中自动创建(和删除)临时目录?
【发布时间】:2010-10-10 00:13:13
【问题描述】:

是否可以让make 在执行第一个目标之前创建一个临时目录?也许使用一些技巧,一些额外的目标等?

Makefile 中的所有命令都可以将自动创建的目录引用为$TMPDIR,并且当make 命令结束时,该目录将被自动删除。

【问题讨论】:

    标签: makefile temporary-files


    【解决方案1】:

    至少使用 GNU make,

    TMPDIR := $(shell mktemp -d)
    

    将为您提供临时目录。除了作为all 目标的一部分的明显的rmdir "$(TMPDIR)" 之外,我想不出最后清理它的好方法。

    【讨论】:

    • 如果所有目标都是最新的,那么评估TMPDIR 将创建目录,并且永远不会执行all 的规则来删除它。
    • @Josh Kelley:.PHONY 会解决这个问题。
    • 这将在您每次执行 any 配方时创建一个临时文件,对吗? .PHONY 目标将如何处理删除 TMPDIR
    • @AriSweedler 假设all 是唯一的目标,我想。或者只有几个目标,因此您可以从每个目标中删除。
    • 提供mktemp -p myprefix -drm -rf myprefix*
    【解决方案2】:

    这些先前的答案要么不起作用,要么看起来过于复杂。这是我能够弄清楚的一个更直接的例子:

    PACKAGE := "audit"
    all:
        $(eval TMP := $(shell mktemp -d))
        @mkdir $(TMP)/$(PACKAGE)
        rm -rf $(TMP)
    

    【讨论】:

    • 像 GNU make 中的魅力一样工作。但不在 BSD 中。
    • 如果有任何错误就不会清理,这很重要:)
    【解决方案3】:

    请参阅 Getting the name of the makefile from the makefile 了解 $(self) 技巧

    ifeq ($(tmpdir),)
    
    location = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
    self := $(location)
    
    %:
        @tmpdir=`mktemp --tmpdir -d`; \
        trap 'rm -rf "$$tmpdir"' EXIT; \
        $(MAKE) -f $(self) --no-print-directory tmpdir=$$tmpdir $@
    
    else
    # [your real Makefile]
    %:
        @echo Running target $@ with $(tmpdir)
    endif
    

    【讨论】:

      【解决方案4】:

      我似乎记得能够递归调用 make,类似于:

      all:
          -mkdir $(TEMPDIR)
          $(MAKE) $(MLAGS) old_all
          -rm -rf $(TEMPDIR)
      
      old_all: ... rest of stuff.
      

      我在子目录中做了类似的技巧:

      all:
          @for i in $(SUBDIRS); do \
              echo "make all in $$i..."; \
              (cd $$i; $(MAKE) $(MLAGS) all); \
          done
      

      刚刚检查过,效果很好:

      $ cat Makefile
      all:
          -mkdir tempdir
          -echo hello >tempdir/hello
          -echo goodbye >tempdir/goodbye
          $(MAKE) $(MFLAGS) old_all
          -rm -rf tempdir
      
      old_all:
          ls -al tempdir
      
      $ make all
      mkdir tempdir
      echo hello >tempdir/hello
      echo goodbye >tempdir/goodbye
      make  old_all
      make[1]: Entering directory '/home/pax'
      ls -al tempdir
      total 2
      drwxr-xr-x+ 2 allachan None 0 Feb 26 15:00 .
      drwxrwxrwx+ 4 allachan None 0 Feb 26 15:00 ..
      -rw-r--r--  1 allachan None 8 Feb 26 15:00 goodbye
      -rw-r--r--  1 allachan None 6 Feb 26 15:00 hello
      make[1]: Leaving directory '/home/pax'
      rm -rf tempdir
      
      $ ls -al tempdir
      ls: cannot access tempdir: No such file or directory
      

      【讨论】:

      • 这行得通,但当然前提是用户说“make”而不指定目标。所以“make all”是行不通的等等。
      • 我希望用户知道他们在做什么 :-) 所以他们会使用“make”或“make toplevel”。在任何情况下,如果您想要这种行为,您可以将“all”更改为“old_all”,将“toplevel”更改为“all”。
      • 已更新,您可以“全部制作”,这也是默认规则。
      • mkdir 等之前的破折号是什么?
      • @nnnmmm,他们告诉make 忽略命令的返回码。否则,失败会导致make 停止。
      猜你喜欢
      • 2013-02-08
      • 2019-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-22
      相关资源
      最近更新 更多