~sircmpwn/email-test-drive

lto: Don't assume a posix shell is usable on windows [PR110710] v1 PROPOSED

Peter Damianov: 1
 lto: Don't assume a posix shell is usable on windows [PR110710]

 1 files changed, 32 insertions(+), 3 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/email-test-drive/patches/50468/mbox | git am -3
Learn more about email & git

[PATCH] lto: Don't assume a posix shell is usable on windows [PR110710] Export this patch

lto-wrapper generates Makefiles that use the following:
touch -r file file.tmp && mv file.tmp file
to truncate files.
If there is no suitable "touch" or "mv" available, then this errors with
"The system cannot find the file specified".

The solution here is to check if sh -c true works, before trying to use it in
the Makefile. If it doesn't, then fall back to "copy /y nul file" instead.
The fallback doesn't work exactly the same (the modified time of the file gets
updated), but this doesn't seem to matter in practice.

I tested this both in environments both with and without sh present, and
observed no issues.

Signed-off-by: Peter Damianov <peter0x44@disroot.org>
---
 gcc/lto-wrapper.cc | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/gcc/lto-wrapper.cc b/gcc/lto-wrapper.cc
index 5186d040ce0..8dee0aaa2d8 100644
--- a/gcc/lto-wrapper.cc
+++ b/gcc/lto-wrapper.cc
@@ -1389,6 +1389,27 @@ make_exists (void)
  return errmsg == NULL && exit_status == 0 && err == 0;
}

/* Test that an sh command is present and working, return true if so.
   This is only relevant for windows hosts, where a /bin/sh shell cannot
   be assumed to exist. */

static bool
sh_exists (void)
{
  const char *sh = "sh";
  const char *sh_args[] = {sh, "-c", "true", NULL};
#ifdef _WIN32
  int exit_status = 0;
  int err = 0;
  const char *errmsg
    = pex_one (PEX_SEARCH, sh_args[0], CONST_CAST (char **, sh_args),
	       "sh", NULL, NULL, &exit_status, &err);
  return errmsg == NULL && exit_status == 0 && err == 0;
#else
  return true;
#endif
}

/* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */

static void
@@ -1402,6 +1423,7 @@ run_gcc (unsigned argc, char *argv[])
  const char *collect_gcc;
  char *collect_gcc_options;
  int parallel = 0;
  bool have_sh = sh_exists ();
  int jobserver = 0;
  bool jobserver_requested = false;
  int auto_parallel = 0;
@@ -2016,6 +2038,7 @@ cont:
	  argv_ptr[5] = NULL;
	  if (parallel)
	    {
	      fprintf (mstream, "SHELL=%s\n", have_sh ? "sh" : "cmd");
	      fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
	      for (j = 1; new_argv[j] != NULL; ++j)
		fprintf (mstream, " '%s'", new_argv[j]);
@@ -2024,9 +2047,15 @@ cont:
	         truncate them as soon as we have processed it.  This
		 reduces temporary disk-space usage.  */
	      if (! save_temps)
		fprintf (mstream, "\t@-touch -r \"%s\" \"%s.tem\" > /dev/null "
			 "2>&1 && mv \"%s.tem\" \"%s\"\n",
			 input_name, input_name, input_name, input_name); 
		{
		  fprintf (mstream,
			   have_sh
			   ? "\t@-touch -r \"%s\" \"%s.tem\" > /dev/null "
			     "2>&1 && mv \"%s.tem\" \"%s\"\n"
			   : "\t@-copy /y nul \"%s\" > NUL "
			     "2>&1\n",
			   input_name, input_name, input_name, input_name);
		}
	    }
	  else
	    {
-- 
2.39.2