diff mbox

nvptx mkoffload: For non-installed testing, look in all COMPILER_PATHs for GCC_INSTALL_NAME (was: nvptx offloading patches [4/n])

Message ID 87fva3fwx6.fsf@kepler.schwinge.homeip.net
State New
Headers show

Commit Message

Thomas Schwinge Feb. 18, 2015, 8:25 a.m. UTC
Hi!

On Sat, 1 Nov 2014 13:11:29 +0100, Bernd Schmidt <bernds@codesourcery.com> wrote:
> [nvptx mkoffload]

To support the --enable-offload-targets=nvptx-none=[install directory]
configuration option, I committed the following to trunk in r220782 (and
filed <https://gcc.gnu.org/PR65097>):

commit a7243b5200794d53b01d59fa69d467a0545db73f
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Feb 18 08:17:32 2015 +0000

    nvptx mkoffload: For non-installed testing, look in all COMPILER_PATHs for GCC_INSTALL_NAME.
    
    	gcc/
    	* config/nvptx/mkoffload.c (parse_env_var, free_array_of_ptrs)
    	(access_check): New functions, copied from
    	config/i386/intelmic-mkoffload.c.
    	(main): For non-installed testing, look in all COMPILER_PATHs for
    	GCC_INSTALL_NAME.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220782 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                |    6 +++
 gcc/config/nvptx/mkoffload.c |  103 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+)



Grüße,
 Thomas
diff mbox

Patch

diff --git gcc/ChangeLog gcc/ChangeLog
index 180a605..0f144f5 100644
--- gcc/ChangeLog
+++ gcc/ChangeLog
@@ -1,5 +1,11 @@ 
 2015-02-18  Thomas Schwinge  <thomas@codesourcery.com>
 
+	* config/nvptx/mkoffload.c (parse_env_var, free_array_of_ptrs)
+	(access_check): New functions, copied from
+	config/i386/intelmic-mkoffload.c.
+	(main): For non-installed testing, look in all COMPILER_PATHs for
+	GCC_INSTALL_NAME.
+
 	* config/nvptx/nvptx.h (GOMP_SELF_SPECS): Define macro.
 
 2015-02-18  Andrew Pinski  <apinski@cavium.com>
diff --git gcc/config/nvptx/mkoffload.c gcc/config/nvptx/mkoffload.c
index 96341b8..02c44b6 100644
--- gcc/config/nvptx/mkoffload.c
+++ gcc/config/nvptx/mkoffload.c
@@ -762,6 +762,78 @@  parse_file (Token *tok)
   return tok;
 }
 
+/* Parse STR, saving found tokens into PVALUES and return their number.
+   Tokens are assumed to be delimited by ':'.  */
+static unsigned
+parse_env_var (const char *str, char ***pvalues)
+{
+  const char *curval, *nextval;
+  char **values;
+  unsigned num = 1, i;
+
+  curval = strchr (str, ':');
+  while (curval)
+    {
+      num++;
+      curval = strchr (curval + 1, ':');
+    }
+
+  values = (char **) xmalloc (num * sizeof (char *));
+  curval = str;
+  nextval = strchr (curval, ':');
+  if (nextval == NULL)
+    nextval = strchr (curval, '\0');
+
+  for (i = 0; i < num; i++)
+    {
+      int l = nextval - curval;
+      values[i] = (char *) xmalloc (l + 1);
+      memcpy (values[i], curval, l);
+      values[i][l] = 0;
+      curval = nextval + 1;
+      nextval = strchr (curval, ':');
+      if (nextval == NULL)
+	nextval = strchr (curval, '\0');
+    }
+  *pvalues = values;
+  return num;
+}
+
+/* Auxiliary function that frees elements of PTR and PTR itself.
+   N is number of elements to be freed.  If PTR is NULL, nothing is freed.
+   If an element is NULL, subsequent elements are not freed.  */
+static void
+free_array_of_ptrs (void **ptr, unsigned n)
+{
+  unsigned i;
+  if (!ptr)
+    return;
+  for (i = 0; i < n; i++)
+    {
+      if (!ptr[i])
+	break;
+      free (ptr[i]);
+    }
+  free (ptr);
+  return;
+}
+
+/* Check whether NAME can be accessed in MODE.  This is like access,
+   except that it never considers directories to be executable.  */
+static int
+access_check (const char *name, int mode)
+{
+  if (mode == X_OK)
+    {
+      struct stat st;
+
+      if (stat (name, &st) < 0 || S_ISDIR (st.st_mode))
+	return -1;
+    }
+
+  return access (name, mode);
+}
+
 static void
 process (FILE *in, FILE *out)
 {
@@ -853,6 +925,37 @@  main (int argc, char **argv)
     driver_used = sprintf (driver, "%s/", gcc_path);
   sprintf (driver + driver_used, "%s", GCC_INSTALL_NAME);
 
+  bool found = false;
+  if (gcc_path == NULL)
+    found = true;
+  else if (access_check (driver, X_OK) == 0)
+    found = true;
+  else
+    {
+      /* Don't use alloca pointer with XRESIZEVEC.  */
+      driver = NULL;
+      /* Look in all COMPILER_PATHs for GCC_INSTALL_NAME.  */
+      char **paths = NULL;
+      unsigned n_paths;
+      n_paths = parse_env_var (getenv ("COMPILER_PATH"), &paths);
+      for (unsigned i = 0; i < n_paths; i++)
+	{
+	  len = strlen (paths[i]) + 1 + strlen (GCC_INSTALL_NAME) + 1;
+	  driver = XRESIZEVEC (char, driver, len);
+	  sprintf (driver, "%s/%s", paths[i], GCC_INSTALL_NAME);
+	  if (access_check (driver, X_OK) == 0)
+	    {
+	      found = true;
+	      break;
+	    }
+	}
+      free_array_of_ptrs ((void **) paths, n_paths);
+    }
+
+  if (!found)
+    fatal_error (input_location,
+		 "offload compiler %s not found", GCC_INSTALL_NAME);
+
   /* We may be called with all the arguments stored in some file and
      passed with @file.  Expand them into argv before processing.  */
   expandargv (&argc, &argv);