]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Support the MAKE_TMPDIR environment variable
authorPaul Smith <psmith@gnu.org>
Sun, 11 Sep 2022 14:56:08 +0000 (10:56 -0400)
committerPaul Smith <psmith@gnu.org>
Sun, 11 Sep 2022 14:56:08 +0000 (10:56 -0400)
Allow build systems to choose an alternative location for make to
store its temporary files.

* NEWS: Announce the new environment variable.
* doc/make.texi (Temporary Files): Provide documentation.
* src/misc.c (get_tmpdir): Split into a new function.  Compute the
temporary directory and store it in a static location.
* tests/scripts/features/jobserver: Add a test of MAKE_TMPDIR.

NEWS
doc/make.texi
src/misc.c
tests/scripts/features/jobserver

diff --git a/NEWS b/NEWS
index 4d6358209e727ab0266739c24058162d309bb3d8..5a8c85ec02a333b9331b401470b140247ae61c2e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -88,6 +88,14 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
   top-level invocation of GNU make, or via MAKEFLAGS or GNUMAKEFLAGS.
   To detect this change search for 'jobserver-fifo' in the .FEATURES variable.
 
+* New feature: The MAKE_TMPDIR environment variable
+  If you prefer that GNU make place temporary files in a different directory
+  than the standard TMPDIR (or TMP or TEMP on Windows), set the MAKE_TMPDIR
+  environment variable before starting make (this value CANNOT be set inside
+  the makefile, since make needs to find its temporary directory before the
+  makefiles are parsed).  This is useful for build systems which reset TMPDIR
+  and clean it out during the build process.
+
 * Some POSIX systems (*BSD) do not allow locks to be taken on pipes, which
   caused the output sync feature to not work properly there.  Also multiple
   invocations of make redirecting to the same output file (e.g., /dev/null)
index 47595bbd20a8b8c542892de530c95f3002503317..920e646095b7d47f36144d534a7202dc2b350b55 100644 (file)
@@ -309,6 +309,7 @@ How to Run @code{make}
                                   an alternate compiler and other things.
 * Testing::                     How to proceed past some errors, to
                                   test compilation.
+* Temporary Files::             Where @code{make} keeps its temporary files.
 * Options Summary::             Summary of Options
 
 Using Implicit Rules
@@ -8773,6 +8774,7 @@ determines that some target is not already up to date.
                                   an alternate compiler and other things.
 * Testing::                     How to proceed past some errors, to
                                   test compilation.
+* Temporary Files::             Where @code{make} keeps its temporary files.
 * Options Summary::             Summary of Options
 @end menu
 
@@ -9164,7 +9166,7 @@ overridden.  This is to use the @code{override} directive, which is a line
 that looks like this: @samp{override @var{variable} = @var{value}}
 (@pxref{Override Directive, ,The @code{override} Directive}).
 
-@node Testing, Options Summary, Overriding, Running
+@node Testing, Temporary Files, Overriding, Running
 @section Testing the Compilation of a Program
 @cindex testing compilation
 @cindex compilation, testing
@@ -9202,7 +9204,35 @@ program, perhaps to find several independent problems so that you can
 correct them all before the next attempt to compile.  This is why Emacs'
 @kbd{M-x compile} command passes the @samp{-k} flag by default.
 
-@node Options Summary,  , Testing, Running
+@node Temporary Files, Options Summary, Testing, Running
+@section Temporary Files
+@cindex temporary files
+
+In some situations, @code{make} will need to create its own temporary files.
+These files must not be disturbed while @code{make} is running, including all
+recursively-invoked instances of @code{make}.
+
+@cindex @code{MAKE_TMPDIR}
+If the environment variable @code{MAKE_TMPDIR} is set then all temporary files
+created by @code{make} will be placed there.
+
+@cindex @code{TMPDIR}
+@cindex @code{TMP}
+@cindex @code{TEMP}
+If @code{MAKE_TMPDIR} is not set, then the standard location for temporary
+files for the current operating system will be used.  For POSIX systems this
+will be the location set in the @code{TMPDIR} environment variable, or else
+the system's default location (e.g., @file{/tmp}) is used.  On Windows,
+first @code{TMP} then @code{TEMP} will be checked, then @code{TMPDIR}, and
+finally the system default temporary file location will be used.
+
+Note that this directory must already exist or @code{make} will fail:
+@code{make} will not attempt to create it.
+
+These variables @emph{cannot} be set from within a makefile: GNU @code{make}
+must have access to this location before it begins reading the makefiles.
+
+@node Options Summary,  , Temporary Files, Running
 @section Summary of Options
 @cindex options
 @cindex flags
index aa1fbde0b4ce9e481f8ad7464ac5ed32281d18c4..597e7a336b851a0fd664148063e41b5220d3316f 100644 (file)
@@ -506,15 +506,9 @@ umask (mode_t mask)
 }
 #endif
 
-static char *
-get_tmptemplate ()
-{
-  const char *tmpdir;
-  char *template;
-  size_t len;
-
+#define MAKE_TMPDIR         "MAKE_TMPDIR"
 #ifdef VMS
-# define DEFAULT_TMPFILE     "sys$scratch:gnv$make_cmdXXXXXX.com"
+# define DEFAULT_TMPFILE    "sys$scratch:gnv$make_cmdXXXXXX.com"
 # define DEFAULT_TMPDIR     "/sys$scratch/"
 #else
 # define DEFAULT_TMPFILE     "GmXXXXXX"
@@ -525,13 +519,31 @@ get_tmptemplate ()
 # endif
 #endif
 
-  if (
+static const char *
+get_tmpdir ()
+{
+  static const char *tmpdir = NULL;
+
+  if (!tmpdir)
+    {
+      if (((tmpdir = getenv (MAKE_TMPDIR)) == NULL || *tmpdir == '\0')
 #if defined (__MSDOS__) || defined (WINDOWS32) || defined (__EMX__)
-      ((tmpdir = getenv ("TMP")) == NULL || *tmpdir == '\0') &&
-      ((tmpdir = getenv ("TEMP")) == NULL || *tmpdir == '\0') &&
+          && ((tmpdir = getenv ("TMP")) == NULL || *tmpdir == '\0')
+          && ((tmpdir = getenv ("TEMP")) == NULL || *tmpdir == '\0')
 #endif
-      ((tmpdir = getenv ("TMPDIR")) == NULL || *tmpdir == '\0'))
-    tmpdir = DEFAULT_TMPDIR;
+          && ((tmpdir = getenv ("TMPDIR")) == NULL || *tmpdir == '\0'))
+        tmpdir = DEFAULT_TMPDIR;
+    }
+
+  return tmpdir;
+}
+
+static char *
+get_tmptemplate ()
+{
+  const char *tmpdir = get_tmpdir ();
+  char *template;
+  size_t len;
 
   len = strlen (tmpdir);
   template = xmalloc (len + CSTRLEN (DEFAULT_TMPFILE) + 2);
index d56c6f409e7829db9601febc4399b13104aca23c..8ecbe3458a6b18f625c5d40fb195829d8feab0c5 100644 (file)
@@ -145,6 +145,16 @@ if (exists $FEATURES{'jobserver-fifo'}) {
 
   $ENV{TMPDIR} = "nosuchdir";
   run_make_test(undef, '-j2', "/Nothing to be done/");
+
+  # Verify that MAKE_TMPDIR is preferred if provided
+  $ENV{MAKE_TMPDIR} = '.';
+  $ENV{TMPDIR} = 'nosuchdir';
+
+  run_make_test(q!
+recurse: ; @$(MAKE) -f #MAKEFILE# all
+all:;@echo "$$MAKEFLAGS"
+!,
+              "-j2 --no-print-directory", "/--jobserver-auth=fifo:\\./");
 }
 
 1;