26 Mar 2024 10:36:45 pm Peter Damianov <peter0...@disroot.org>:

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 <peter0...@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
I made this patch against gcc 13.2, because I couldn't get gcc 14 to build.
I got the following errors:

In file included from ../../../../gcc/libgcc/config/i386/cpuinfo.c:30:
../../../../gcc/libgcc/../gcc/common/config/i386/cpuinfo.h: In function 'get_available_features': ../../../../gcc/libgcc/../gcc/common/config/i386/cpuinfo.h:938:21: error: 'bit_USER_MSR' undeclared (first use in this function)
  938 | if (edx & bit_USER_MSR)
      | ^~~~~~~~~~~~
../../../../gcc/libgcc/../gcc/common/config/i386/cpuinfo.h:938:21: note: each undeclared identifier is reported only once for each function it appears in ../../../../gcc/libgcc/../gcc/common/config/i386/cpuinfo.h:950:25: error: 'bit_AVXVNNIINT16' undeclared (first use in this function); did you mean 'bit_AVXVNNIINT8'?
  950 | if (edx & bit_AVXVNNIINT16)
      | ^~~~~~~~~~~~~~~~
      | bit_AVXVNNIINT8

Hopefully it's still okay.

Reply via email to