Unverified Commit 2deaafc4 authored by John Ericson's avatar John Ericson Committed by GitHub
Browse files

gccNGPackages: init (#414299)

parents 8c17f9cd 101bb13d
Loading
Loading
Loading
Loading
+137 −0
Original line number Diff line number Diff line
From 3af17de3a5f6acd5a2f9340d84b8667459f43eea Mon Sep 17 00:00:00 2001
From: John Ericson <git@JohnEricson.me>
Date: Wed, 18 Aug 2021 01:55:31 -0400
Subject: [PATCH 1/3] find_a_program: First search with machine prefix

This matches the behavior of Clang, and makes it easier to work with
cross compilers without heeding to hard-code paths at build time.
---
 gcc/gcc.cc | 78 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 68 insertions(+), 10 deletions(-)

diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 4fd87f2c4a1..55738d258b3 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -1600,6 +1600,11 @@ static const char *machine_suffix = 0;
 
 static const char *just_machine_suffix = 0;
 
+/* Prefix to attach to *basename* of commands being searched.
+   This is just `MACHINE-'.  */
+
+static const char *just_machine_prefix = 0;
+
 /* Adjusted value of GCC_EXEC_PREFIX envvar.  */
 
 static const char *gcc_exec_prefix;
@@ -3043,15 +3048,6 @@ file_at_path (char *path, void *data)
   memcpy (path + len, info->name, info->name_len);
   len += info->name_len;
 
-  /* Some systems have a suffix for executable files.
-     So try appending that first.  */
-  if (info->suffix_len)
-    {
-      memcpy (path + len, info->suffix, info->suffix_len + 1);
-      if (access_check (path, info->mode) == 0)
-	return path;
-    }
-
   path[len] = '\0';
   if (access_check (path, info->mode) == 0)
     return path;
@@ -3091,12 +3087,52 @@ find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
 				file_at_path, &info);
 }
 
+/* Callback for find_a_program.  Appends the file name to the directory
+   path. Like file_at_path but tries machine prefix and exe suffix too. */
+
+static void *
+program_at_path (char *path, void *data)
+{
+  /* try first with machine-prefixed name */
+  struct file_at_path_info *info = (struct file_at_path_info *) data;
+  size_t path_len = strlen (path);
+
+  for (auto prefix : { just_machine_prefix, "" })
+    {
+      auto len = path_len;
+
+      auto prefix_len = strlen(prefix);
+      memcpy (path + len, prefix, prefix_len);
+      len += prefix_len;
+
+      memcpy (path + len, info->name, info->name_len);
+      len += info->name_len;
+
+      /* Some systems have a suffix for executable files.
+	 So try appending that first.  */
+      if (info->suffix_len)
+	{
+	  memcpy (path + len, info->suffix, info->suffix_len + 1);
+	  if (access_check (path, info->mode) == 0)
+	    return path;
+	}
+
+      path[len] = '\0';
+      if (access_check (path, info->mode) == 0)
+	return path;
+    }
+
+  return NULL;
+}
+
 /* Specialization of find_a_file for programs that also takes into account
    configure-specified default programs. */
 
 static char*
 find_a_program (const char *name)
 {
+  const int mode = X_OK;
+
   /* Do not search if default matches query. */
 
 #ifdef DEFAULT_ASSEMBLER
@@ -3114,7 +3150,28 @@ find_a_program (const char *name)
     return xstrdup (DEFAULT_DSYMUTIL);
 #endif
 
-  return find_a_file (&exec_prefixes, name, X_OK, false);
+  /* Find the filename in question (special case for absolute paths).  */
+
+  if (IS_ABSOLUTE_PATH (name))
+    {
+      if (access (name, mode) == 0)
+	return xstrdup (name);
+
+      return NULL;
+    }
+
+  struct file_at_path_info info;
+
+  info.name = name;
+  info.suffix = HOST_EXECUTABLE_SUFFIX;
+  info.name_len = strlen (info.name);
+  info.suffix_len = strlen (info.suffix);
+  info.mode = mode;
+
+  return (char*) for_each_path (
+    &exec_prefixes, false,
+    info.name_len + info.suffix_len + strlen(just_machine_prefix),
+    program_at_path, &info);
 }
 
 /* Ranking of prefixes in the sort list. -B prefixes are put before
@@ -8492,6 +8549,7 @@ driver::set_up_specs () const
   machine_suffix = concat (spec_host_machine, dir_separator_str, spec_version,
 			   accel_dir_suffix, dir_separator_str, NULL);
   just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
+  just_machine_prefix = concat (spec_machine, "-", NULL);
 
   specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, true);
   /* Read the specs file unless it is a default one.  */
-- 
2.47.2
+103 −0
Original line number Diff line number Diff line
From 8e1b7a128a69393c6d3f53b8f66bd52c6bbce908 Mon Sep 17 00:00:00 2001
From: John Ericson <git@JohnEricson.me>
Date: Wed, 18 Aug 2021 01:55:45 -0400
Subject: [PATCH 2/3] driver: for_each_pass: Pass to callback whether dir is
 machine-disambiguated

We will use this in the subsequent diff to control what basenames we
search for. In machine-specific subdirectories, we should just look for
the original basename, but in machine-agnostic subdirectories, we might
additionally look for prefixed disambiguated names, as an alternate
method of keeping targets apart.
---
 gcc/gcc.cc | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 55738d258b3..f9f83d1a804 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -2783,7 +2783,7 @@ static void *
 for_each_path (const struct path_prefix *paths,
 	       bool do_multi,
 	       size_t extra_space,
-	       void *(*callback) (char *, void *),
+	       void *(*callback) (char *, bool, void *),
 	       void *callback_info)
 {
   struct prefix_list *pl;
@@ -2844,7 +2844,7 @@ for_each_path (const struct path_prefix *paths,
 	  if (!skip_multi_dir)
 	    {
 	      memcpy (path + len, multi_suffix, suffix_len + 1);
-	      ret = callback (path, callback_info);
+	      ret = callback (path, true, callback_info);
 	      if (ret)
 		break;
 	    }
@@ -2855,7 +2855,7 @@ for_each_path (const struct path_prefix *paths,
 	      && pl->require_machine_suffix == 2)
 	    {
 	      memcpy (path + len, just_multi_suffix, just_suffix_len + 1);
-	      ret = callback (path, callback_info);
+	      ret = callback (path, true, callback_info);
 	      if (ret)
 		break;
 	    }
@@ -2865,7 +2865,7 @@ for_each_path (const struct path_prefix *paths,
 	      && !pl->require_machine_suffix && multiarch_dir)
 	    {
 	      memcpy (path + len, multiarch_suffix, multiarch_len + 1);
-	      ret = callback (path, callback_info);
+	      ret = callback (path, true, callback_info);
 	      if (ret)
 		break;
 	    }
@@ -2893,7 +2893,7 @@ for_each_path (const struct path_prefix *paths,
 	      else
 		path[len] = '\0';
 
-	      ret = callback (path, callback_info);
+	      ret = callback (path, false, callback_info);
 	      if (ret)
 		break;
 	    }
@@ -2948,7 +2948,7 @@ struct add_to_obstack_info {
 };
 
 static void *
-add_to_obstack (char *path, void *data)
+add_to_obstack (char *path, bool, void *data)
 {
   struct add_to_obstack_info *info = (struct add_to_obstack_info *) data;
 
@@ -3040,7 +3040,7 @@ struct file_at_path_info {
 };
 
 static void *
-file_at_path (char *path, void *data)
+file_at_path (char *path, bool, void *data)
 {
   struct file_at_path_info *info = (struct file_at_path_info *) data;
   size_t len = strlen (path);
@@ -3091,7 +3091,7 @@ find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
    path. Like file_at_path but tries machine prefix and exe suffix too. */
 
 static void *
-program_at_path (char *path, void *data)
+program_at_path (char *path, bool machine_specific, void *data)
 {
   /* try first with machine-prefixed name */
   struct file_at_path_info *info = (struct file_at_path_info *) data;
@@ -6074,7 +6074,7 @@ struct spec_path_info {
 };
 
 static void *
-spec_path (char *path, void *data)
+spec_path (char *path, bool, void *data)
 {
   struct spec_path_info *info = (struct spec_path_info *) data;
   size_t len = 0;
-- 
2.47.2
+75 −0
Original line number Diff line number Diff line
From e1ee1a2df1ad32de24e8fdaeac0a533681710578 Mon Sep 17 00:00:00 2001
From: John Ericson <git@JohnEricson.me>
Date: Wed, 18 Aug 2021 01:55:52 -0400
Subject: [PATCH 3/3] find_a_program: Only search for prefixed paths in
 undisambiguated dirs

This means, we might search for:

- path/$machine/$version/prog
- path/$machine/prog
- path/$machine-prog

But not

- path/$machine/$version/$machine-prog

because disambiguating $machine twice is unnecessary.

This does mean we less liberal in what we accept than LLVM, but that's
OK. The down side of always Postel's law is everyone converges on
accepting all sorts of garbage, which makes debugging end-to-end hard
when mistakes are not caught early.
---
 gcc/gcc.cc | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index f9f83d1a804..d837b6ea779 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -3097,15 +3097,9 @@ program_at_path (char *path, bool machine_specific, void *data)
   struct file_at_path_info *info = (struct file_at_path_info *) data;
   size_t path_len = strlen (path);
 
-  for (auto prefix : { just_machine_prefix, "" })
+  auto search = [=](size_t len) -> void *
     {
-      auto len = path_len;
-
-      auto prefix_len = strlen(prefix);
-      memcpy (path + len, prefix, prefix_len);
-      len += prefix_len;
-
-      memcpy (path + len, info->name, info->name_len);
+      memcpy (path + len, info->name, info->name_len + 1);
       len += info->name_len;
 
       /* Some systems have a suffix for executable files.
@@ -3120,9 +3114,22 @@ program_at_path (char *path, bool machine_specific, void *data)
       path[len] = '\0';
       if (access_check (path, info->mode) == 0)
 	return path;
+
+      return NULL;
+    };
+
+  /* Additionally search for $target-prog in machine-agnostic dirs, as an
+     additional way to disambiguate targets. Do not do this in machine-specific
+     dirs because so further disambiguation is needed. */
+  if (!machine_specific)
+    {
+      auto prefix_len = strlen(just_machine_prefix);
+      memcpy (path + path_len, just_machine_prefix, prefix_len);
+      auto res = search(path_len + prefix_len);
+      if (res) return res;
     }
 
-  return NULL;
+  return search(path_len);
 }
 
 /* Specialization of find_a_file for programs that also takes into account
-- 
2.47.2
+180 −0
Original line number Diff line number Diff line
From 1eaf7ce77bb4eb73e5565ede220557c2ef0290b0 Mon Sep 17 00:00:00 2001
From: John Ericson <git@JohnEricson.me>
Date: Sun, 22 Aug 2021 01:14:22 -0400
Subject: [PATCH] Allow explicitly specifying the thread model for runtime libs

Previously, they always scraped the thread mode from `$CC -v', now, that
is the default but one may pass `--with-threads=MODEL` to be explicit
instead.

One use-case is bootstraping with a shorter critical path. The
traditionally route was to build an entire "static stage" GCC, build
libc, and then build GCC again supporting dynamic linking,
multithreading, etc. But this is wasteful in that GCC itself is built
twice.

With this change, rather than having to mess with spec files we can just
configure the runtime libraries the way we want directly. In turn, that
opens to just building libgcc twice rather than all of GCC.

Frankly, specs were always a rather indirect approach to coordinate this
during GCC's bootstrap, since GCC itself really doesn't care what the
threading model is, just that the runtime libraries agree among
themselves. Relying on a hard-coded spec for this also keeps us one step
further from the long-term goal of multi-target GCC, for what it's
worth.

For the record, "single stage" builds of GCC have some precedent in
downstream packaging, for example with [1]. That one, as far as I can
tell, builds libgcc once, but with the headers of the libc
implementation provided and then cyclic linking down later. They are
both fine approaches, but I don't think one should have to be forced
into cyclic dependencies if they don't want to. That opens the door to
non-terminating programs due to, e.g., atomics used in a threads
implementation being lowered to threads absent hardware support.

Finally, I understand that such custom bootstrapping is not officially
supported. I don't mean to imply it should be --- a lot more cleanup
work to the build system would be necessary before supporting it
wouldn't be a huge additional maintainer burden --- I just hope to add a
reasonable knob for those comfortable with doing unsupported things
already.

[1]: https://github.com/richfelker/musl-cross-make
---
 config/gthr.m4              | 32 ++++++++++++++++++++++++++++++++
 libatomic/configure.ac      |  4 +---
 libgcc/configure.ac         |  4 +---
 libphobos/m4/druntime/os.m4 |  2 +-
 libstdc++-v3/acinclude.m4   |  8 +++-----
 5 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/config/gthr.m4 b/config/gthr.m4
index 11996247f15..7aed5d3df0d 100644
--- a/config/gthr.m4
+++ b/config/gthr.m4
@@ -5,6 +5,35 @@ dnl Public License, this file may be distributed as part of a program
 dnl that contains a configuration script generated by Autoconf, under
 dnl the same distribution terms as the rest of that program.
 
+dnl Define thread model
+
+dnl usage: GCC_AC_THREAD_MODEL
+AC_DEFUN([GCC_AC_THREAD_MODEL],
+[
+# With threads
+# Pass with no value to take from compiler's metadata
+# Pass with a value to specify a thread package
+# 'single' means single threaded -- without threads.
+AC_ARG_WITH(threads,
+[AS_HELP_STRING([[--with-threads=MODEL]],
+		[specify thread model for this GCC
+		 runtime library])],,
+[with_threads=''])
+
+if test x"$with_threads" = x'yes'; then
+    AC_MSG_ERROR([Cannot pass bare --with-threads, must pass explicit --with-threads=MODEL])
+elif test x"$with_threads" = x'no'; then
+    target_thread_file=single
+elif test x"$with_threads" = x''; then
+    AC_MSG_CHECKING([for thread model used by GCC])
+    target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
+    AC_MSG_RESULT([$target_thread_file])
+else
+    target_thread_file=$with_threads
+fi
+])
+
+
 dnl Define header location by thread model
 
 dnl usage: GCC_AC_THREAD_HEADER([thread_model])
@@ -23,6 +52,9 @@ case $1 in
     vxworks)	thread_header=config/gthr-vxworks.h ;;
     win32)	thread_header=config/i386/gthr-win32.h ;;
     mcf)	thread_header=config/i386/gthr-mcf.h ;;
+    *)
+        AC_MSG_ERROR([No known header for threading model '$1'.])
+        ;;
 esac
 AC_SUBST(thread_header)
 ])
diff --git a/libatomic/configure.ac b/libatomic/configure.ac
index 85824fa7614..691f4948f6c 100644
--- a/libatomic/configure.ac
+++ b/libatomic/configure.ac
@@ -162,9 +162,7 @@ libtool_VERSION=3:0:2
 AC_SUBST(libtool_VERSION)
 
 # Check for used threading-model
-AC_MSG_CHECKING([for thread model used by GCC])
-target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
-AC_MSG_RESULT([$target_thread_file])
+GCC_AC_THREAD_MODEL
 
 case "$target" in
  *aarch64*)
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 4e8c036990f..acf54e24c79 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -305,9 +305,7 @@ AC_SUBST([use_tm_clone_registry])
 
 AC_LIB_PROG_LD_GNU
 
-AC_MSG_CHECKING([for thread model used by GCC])
-target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
-AC_MSG_RESULT([$target_thread_file]) 
+GCC_AC_THREAD_MODEL
 
 # Check for assembler CFI support.
 AC_CACHE_CHECK([whether assembler supports CFI directives], [libgcc_cv_cfi],
diff --git a/libphobos/m4/druntime/os.m4 b/libphobos/m4/druntime/os.m4
index 15cde3b04b8..28bd4d3d2bd 100644
--- a/libphobos/m4/druntime/os.m4
+++ b/libphobos/m4/druntime/os.m4
@@ -32,7 +32,7 @@ case $1 in
     # TODO: These targets need porting.
     dce|mipssde|rtems|tpf|vxworks)
 	    DCFG_THREAD_MODEL="Single" ;;
-    *)	    as_fn_error "Thread implementation '$1' not recognised" "$LINENO" 5 ;;
+    *)	    AC_MSG_ERROR([Thread implementation '$1' not recognised]) ;;
 esac
 AC_SUBST(DCFG_THREAD_MODEL)
 ])
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 51a08bcc8b1..71697f59d6d 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4342,9 +4342,7 @@ dnl Substs:
 dnl  thread_header
 dnl
 AC_DEFUN([GLIBCXX_ENABLE_THREADS], [
-  AC_MSG_CHECKING([for thread model used by GCC])
-  target_thread_file=`$CXX -v 2>&1 | sed -n 's/^Thread model: //p'`
-  AC_MSG_RESULT([$target_thread_file])
+  GCC_AC_THREAD_MODEL
   GCC_AC_THREAD_HEADER([$target_thread_file])
 ])
 
@@ -4354,7 +4352,8 @@ dnl Check if gthread implementation defines the types and functions
 dnl required by the c++0x thread library.  Conforming gthread
 dnl implementations can define __GTHREADS_CXX0X to enable use with c++0x.
 dnl
-dnl GLIBCXX_ENABLE_SYMVERS must be done before this.
+dnl GLIBCXX_ENABLE_SYMVERS and GLIBCXX_ENABLE_THREADS must be done
+dnl before this.
 dnl
 AC_DEFUN([GLIBCXX_CHECK_GTHREADS], [
   GLIBCXX_ENABLE(libstdcxx-threads,auto,,[enable C++11 threads support])
@@ -4369,7 +4368,6 @@ AC_DEFUN([GLIBCXX_CHECK_GTHREADS], [
   CXXFLAGS="$CXXFLAGS -fno-exceptions \
 	-I${toplevel_srcdir}/libgcc -I${toplevel_builddir}/libgcc"
 
-  target_thread_file=`$CXX -v 2>&1 | sed -n 's/^Thread model: //p'`
   case $target_thread_file in
     posix)
       CXXFLAGS="$CXXFLAGS -DSUPPORTS_WEAK -DGTHREAD_USE_WEAK -D_PTHREADS"
-- 
2.44.1
+315 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading