PR jit/87808: Allow libgccjit to work without an external gcc driver

Message ID c35cf6d3-0eab-92fa-458d-2a544b7f9e66@ubuntu.com
State New
Headers show
Series
  • PR jit/87808: Allow libgccjit to work without an external gcc driver
Related show

Commit Message

Matthias Klose March 21, 2019, 11:26 a.m.
Fix PR jit/87808, the embedded driver still needing the external gcc driver to
find the gcc_lib_dir. This can happen in a packaging context when libgccjit
doesn't depend on the gcc package, but just on binutils and libgcc-dev packages.
libgccjit probably could use /proc/self/maps to find the gcc_lib_dir, but that
doesn't seem to be very portable.

Ok for the trunk and the branches?

Matthias

Comments

David Malcolm March 22, 2019, 10 p.m. | #1
On Thu, 2019-03-21 at 12:26 +0100, Matthias Klose wrote:
> Fix PR jit/87808, the embedded driver still needing the external gcc

> driver to

> find the gcc_lib_dir. This can happen in a packaging context when

> libgccjit

> doesn't depend on the gcc package, but just on binutils and libgcc-

> dev packages.

> libgccjit probably could use /proc/self/maps to find the gcc_lib_dir,

> but that

> doesn't seem to be very portable.

> 

> Ok for the trunk and the branches?

> 

> Matthias


[CCing the jit list]

I've been trying to reproduce this bug in a working copy, and failing.

Matthias, do you have a recipe you've been using to reproduce this?

Thanks
Dave
Matthias Klose March 26, 2019, 11:52 a.m. | #2
On 22.03.19 23:00, David Malcolm wrote:
> On Thu, 2019-03-21 at 12:26 +0100, Matthias Klose wrote:

>> Fix PR jit/87808, the embedded driver still needing the external gcc

>> driver to

>> find the gcc_lib_dir. This can happen in a packaging context when

>> libgccjit

>> doesn't depend on the gcc package, but just on binutils and libgcc-

>> dev packages.

>> libgccjit probably could use /proc/self/maps to find the gcc_lib_dir,

>> but that

>> doesn't seem to be very portable.

>>

>> Ok for the trunk and the branches?

>>

>> Matthias

> 

> [CCing the jit list]

> 

> I've been trying to reproduce this bug in a working copy, and failing.

> 

> Matthias, do you have a recipe you've been using to reproduce this?


the JIT debug log shows the driver names that it wants to call.  Are you sure
that this driver isn't available anywhere?  I configure the gcc build with
--program-suffix=-8 --program-prefix=x86_64-linux-gnu-, and that one was only
available in one place, /usr/bin.

Matthias

Patch

# DP: Fix PR jit/87808.

	* Make-lang.in (CFLAGS-jit/jit-playback.o): Pass fallback
	  GCC_EXEC_PREFIX.
	* jit-playback.c (invoke_embedded_driver): Use fallback GCC_EXEC_PREFIX
	  when external driver is not present.

--- a/src/gcc/jit/Make-lang.in
+++ b/src/gcc/jit/Make-lang.in
@@ -84,6 +84,9 @@ 
 	jit/jit-spec.o \
 	gcc.o
 
+CFLAGS-jit/jit-playback.o += \
+	-DFALLBACK_GCC_EXEC_PREFIX=\"$(libdir)/gcc/$(target_subdir)/$(version)\"
+
 # Use strict warnings for this front end.
 jit-warn = $(STRICT_WARN)
 
--- a/src/gcc/jit/jit-playback.c
+++ b/src/gcc/jit/jit-playback.c
@@ -39,6 +39,7 @@ 
 #include "opt-suggestions.h"
 #include "gcc.h"
 #include "diagnostic.h"
+#include "file-find.h"
 
 #include <pthread.h>
 
@@ -2482,7 +2483,31 @@ 
 playback::context::
 invoke_embedded_driver (const vec <char *> *argvec)
 {
+  static char* gcc_driver_file = NULL;
+
   JIT_LOG_SCOPE (get_logger ());
+
+  /* process_command() uses make_relative_prefix(), searches PATH
+     for the external driver, which might not be found.  In this case
+     fall back to the configured default.  */
+#ifdef FALLBACK_GCC_EXEC_PREFIX
+  if (gcc_driver_file == NULL && ::getenv ("GCC_EXEC_PREFIX") == NULL)
+    {
+      struct path_prefix path;
+
+      prefix_from_env ("PATH", &path);
+      gcc_driver_file = find_a_file (&path, gcc_driver_name, X_OK);
+      if (gcc_driver_file == NULL)
+        {
+	  char *str = concat ("GCC_EXEC_PREFIX=",
+			      FALLBACK_GCC_EXEC_PREFIX, NULL);
+	  ::putenv (str);
+	  log ("gcc driver %s not found, using fallback GCC_EXEC_PREFIX=%s",
+	       gcc_driver_name, FALLBACK_GCC_EXEC_PREFIX);
+        }
+    }
+#endif
+
   driver d (true, /* can_finalize */
 	    false); /* debug */
   int result = d.main (argvec->length (),