How can I automatically create (and delete) a temporary directory in a Makefile?

Is it possible that make creates a temporary directory before it fulfills the first target? Perhaps with the help of some hack, some additional goal, etc.?

All commands in the Makefile will be able to reference the automatically created directory as $TMPDIR , and the directory will be automatically deleted after the make command completes.

+6
makefile temporary-files
source share
4 answers

I seem to remind you that you can call make recursively, something like:

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

I did similar tricks for creating in subdirectories:

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

Just checked and this works fine:

 $ 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 
+5
source share

With GNU make, at least

 TMPDIR := $(shell mktemp -d) 

will provide you with your temporary directory. I can't think of a good way to clear it at the end, except for the obvious rmdir "$(TMPDIR)" as part of the goal of all .

+9
source share

See Getting the makefile name from the makefile for the $(self) trick $(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 
+6
source share

These previous answers either didn't work or seemed overly complex. Here is a much more direct example that I could figure out:

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

All Articles