This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[jit] Use the full name of the installed driver binary


On Fri, 2014-09-26 at 21:55 +0000, Joseph S. Myers wrote:
On Thu, 25 Sep 2014, David Malcolm wrote:
> 
> > Should this have the $(exeext) suffix seen in Makefile.in?
> >   $(target_noncanonical)-gcc-$(version)$(exeext)
> 
> Depends on whether that's needed for the pex code to find it.
> > As for (B), would it make sense to "bake in" the path to the binary into
> > the pex invocation, and hence to turn off PEX_SEARCH?  If so, presumably
> > I need to somehow expand the Makefile's value of $(bindir) into
> > internal-api.c, right?  (I tried this in configure.ac, but merely got
> > "$(exec_prefix)/bin" iirc).
> 
> An installation must be relocatable.  Thus, you can't just hardcode 
> looking in the configured prefix; you'd need to locate it relative to 
> libgccjit.so in some way (i.e. using make_relative_prefix, but I don't 
> know offhand how libgccjit.so would locate itself).
> 
> > A better long-term approach to this would be to extract the spec
> > machinery from gcc.c (perhaps into a "libdriver.a"?) and run it directly
> > from the jit library - but that's a rather involved patch, I suspect.
> 
> And you'd still need libgccjit.so to locate itself for proper 
> relocatability in finding other pieces such as assembler and linker.
> 
> > I wonder if the appropriate approach here is to have a single library
> > with multiple plugin backends e.g. one for the CPU, one for each GPU
> > family, with the ability to load multiple "backends" at once.
> 
> If you can get that working, sure.
> 
> > Unfortunately, "backend" is horribly overloaded here - I mean basically
> > all of gcc here, everything other than the libgccjit.h API seen by
> > client code.
> 
> (Though preferably as much as possible could be shared, i.e. properly 
> define the parts of GCC that need building separately for each target and 
> limit them as much as possible.  Joern's multi-target patches from 2010 
> that selectively built parts of GCC using namespaces while sharing others 
> without an obvious clear separation seemed very fragile.  For something 
> robust you either build everything separately for each target, or have a 
> well-defined separation between bits needing building separately and bits 
> that can be built once and ways to avoid non-obvious target dependencies 
> in bits built once.)

I've been experimenting with directly embedding the gcc.c driver code
in-process, but that patch was getting unwieldy, so for now, I'm going
with the simpler approach: just call the driver out-of-process,
specifying the full installed name:
  $(target_noncanonical)-gcc-$(version)$(exeext)
as expanded at configuration time, requiring it to be on the PATH.

Hopefully this addresses the last of the concerns raised in your initial
review; I'll do some more testing and then try to resubmit to the list
(I'm also thinking about breaking up internal-api.c/h, as they've become
rather large, into jit-recording/jit-playback.c/h)

Committed to branch dmalcolm/jit:

gcc/ChangeLog.jit:
	* Makefile.in (site.exp): When constructing site.exp, add a line
	to set "bindir".
	* configure.ac: Generate a gcc-driver-name.h file containing
	GCC_DRIVER_NAME for the benefit of jit/internal-api.c.
	* configure: Regenerate.

gcc/jit/ChangeLog.jit:
	* docs/internals/index.rst
	(Using a working copy without installing): Rename to...
	(Using a working copy without installing every time): ...this, and
	update to reflect the need to have installed the driver binary
	when running directly from a build directory.
	(Running the test suite): Add PATH setting to the example.
	* docs/intro/install.rst ("Hello world"): Likewise.
	* internal-api.c: Include new autogenerated header
	"gcc-driver-name.h".
	(gcc::jit::playback::context::compile): Rather than looking for a
	"gcc" on the path, look for GCC_DRIVER_NAME from gcc-driver-name.h,
	as created by the configure script, so that we are using one for
	the correct target.

gcc/testsuite/ChangeLog.jit:
	* jit.dg/jit.exp (jit-dg-test): Prepend the installed bindir to
	the PATH before invoking built binaries using the library, so that
	the library can find the driver.  Restore the PATH immediately
	afterwards.
---
 gcc/ChangeLog.jit                |  8 +++++
 gcc/Makefile.in                  |  1 +
 gcc/configure                    |  6 ++++
 gcc/configure.ac                 |  6 ++++
 gcc/jit/ChangeLog.jit            | 16 ++++++++++
 gcc/jit/docs/internals/index.rst | 64 ++++++++++++++++++++++++++++++++++++----
 gcc/jit/docs/intro/install.rst   | 36 ++++++++++++++--------
 gcc/jit/internal-api.c           | 10 +++++--
 gcc/testsuite/ChangeLog.jit      |  7 +++++
 gcc/testsuite/jit.dg/jit.exp     | 14 +++++++++
 10 files changed, 147 insertions(+), 21 deletions(-)

diff --git a/gcc/ChangeLog.jit b/gcc/ChangeLog.jit
index e71f7c4..ca73c04 100644
--- a/gcc/ChangeLog.jit
+++ b/gcc/ChangeLog.jit
@@ -1,3 +1,11 @@
+2014-10-07  David Malcolm  <dmalcolm@redhat.com>
+
+	* Makefile.in (site.exp): When constructing site.exp, add a line
+	to set "bindir".
+	* configure.ac: Generate a gcc-driver-name.h file containing
+	GCC_DRIVER_NAME for the benefit of jit/internal-api.c.
+	* configure: Regenerate.
+
 2014-10-03  David Malcolm  <dmalcolm@redhat.com>
 
 	* diagnostic.c (diagnostic_finish): Free the memory for
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 069a6e8..f5e3d4c 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3504,6 +3504,7 @@ site.exp: ./config.status Makefile
 	@echo "# add them to the last section" >> ./site.tmp
 	@echo "set rootme \"`${PWD_COMMAND}`\"" >> ./site.tmp
 	@echo "set srcdir \"`cd ${srcdir}; ${PWD_COMMAND}`\"" >> ./site.tmp
+	@echo "set bindir \"`cd ${bindir}; ${PWD_COMMAND}`\"" >> ./site.tmp
 	@echo "set host_triplet $(host)" >> ./site.tmp
 	@echo "set build_triplet $(build)" >> ./site.tmp
 	@echo "set target_triplet $(target)" >> ./site.tmp
diff --git a/gcc/configure b/gcc/configure
index b943c20..8ec141f 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -28190,6 +28190,12 @@ _ACEOF
 
 fi
 
+# Generate gcc-driver-name.h containing GCC_DRIVER_NAME for the benefit
+# of jit/internal-api.c.
+cat > gcc-driver-name.h <<EOF
+#define GCC_DRIVER_NAME "${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}"
+EOF
+
 # Configure the subdirectories
 # AC_CONFIG_SUBDIRS($subdirs)
 
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 7319f1c..62e5ad7 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -5679,6 +5679,12 @@ if test x"${LINKER_HASH_STYLE}" != x; then
                                          [The linker hash style])
 fi
 
+# Generate gcc-driver-name.h containing GCC_DRIVER_NAME for the benefit
+# of jit/internal-api.c.
+cat > gcc-driver-name.h <<EOF
+#define GCC_DRIVER_NAME "${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}"
+EOF
+
 # Configure the subdirectories
 # AC_CONFIG_SUBDIRS($subdirs)
 
diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index ac8f28d..07438b9 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,3 +1,19 @@
+2014-10-07  David Malcolm  <dmalcolm@redhat.com>
+
+	* docs/internals/index.rst
+	(Using a working copy without installing): Rename to...
+	(Using a working copy without installing every time): ...this, and
+	update to reflect the need to have installed the driver binary
+	when running directly from a build directory.
+	(Running the test suite): Add PATH setting to the example.
+	* docs/intro/install.rst ("Hello world"): Likewise.
+	* internal-api.c: Include new autogenerated header
+	"gcc-driver-name.h".
+	(gcc::jit::playback::context::compile): Rather than looking for a
+	"gcc" on the path, look for GCC_DRIVER_NAME from gcc-driver-name.h,
+	as created by the configure script, so that we are using one for
+	the correct target.
+
 2014-09-26  David Malcolm  <dmalcolm@redhat.com>
 
 	* internal-api.h (gcc::jit::recording::context): Convert field
diff --git a/gcc/jit/docs/internals/index.rst b/gcc/jit/docs/internals/index.rst
index 9765862..7823b12 100644
--- a/gcc/jit/docs/internals/index.rst
+++ b/gcc/jit/docs/internals/index.rst
@@ -18,17 +18,66 @@
 Internals
 =========
 
-Using a working copy without installing
----------------------------------------
+Using a working copy without installing every time
+--------------------------------------------------
 When directly working on the library you can avoid needing to install to
-test changes.
+test every change.
+
+You need to do a ``make install`` of the ``gcc`` subdirectory to install
+the driver binary (the top-level ``gcc`` binary).  This is used internally
+by the library for converting from .s assembler files to .so shared
+libraries.  Specifically, it looks for an executable on the ``$PATH`` with
+a name expanded by the ``configure`` script from
+``${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}``,
+such as ``x86_64-unknown-linux-gnu-gcc-5.0.0``.
+
+For example, if you configured with a prefix of ``$PREFIX`` like this:
+
+.. code-block:: bash
+
+  mkdir build
+  mkdir install
+  PREFIX=$(pwd)/install
+  cd build
+  ../src/configure \
+     --enable-host-shared \
+     --enable-languages=jit \
+     --disable-bootstrap \
+     --enable-checking=release \
+     --prefix=$PREFIX
+
+then you can install (once) to ensure that ``$PREFIX/bin/`` is populated:
+
+.. code-block:: console
+
+  [build]$ ll ../install/bin/*gcc*
+  -rwxr-xr-x. 3 david david 2733458 Oct  6 14:25 ../install/bin/gcc
+  -rwxr-xr-x. 2 david david  136921 Oct  6 14:25 ../install/bin/gcc-ar
+  -rwxr-xr-x. 2 david david  136857 Oct  6 14:25 ../install/bin/gcc-nm
+  -rwxr-xr-x. 2 david david  136869 Oct  6 14:25 ../install/bin/gcc-ranlib
+  -rwxr-xr-x. 3 david david 2733458 Oct  6 14:25 ../install/bin/x86_64-unknown-linux-gnu-gcc
+  -rwxr-xr-x. 3 david david 2733458 Oct  6 14:25 ../install/bin/x86_64-unknown-linux-gnu-gcc-5.0.0
+  -rwxr-xr-x. 2 david david  136921 Oct  6 14:25 ../install/bin/x86_64-unknown-linux-gnu-gcc-ar
+  -rwxr-xr-x. 2 david david  136857 Oct  6 14:25 ../install/bin/x86_64-unknown-linux-gnu-gcc-nm
+  -rwxr-xr-x. 2 david david  136869 Oct  6 14:25 ../install/bin/x86_64-unknown-linux-gnu-gcc-ranlib
+
+Note the presence above of ``../install/bin/x86_64-unknown-linux-gnu-gcc``.
 
 When building code using the API you need to ensure that ``-I`` points to
 the directory containing ``libgccjit.h`` and ``-L`` points to the
 directory containing the built library.
 
-You'll need to manually set ``LD_LIBRARY_PATH`` to the directory containing
-``libgccjit.so`` when running binaries (or debugging them).
+When running binaries (or debugging them), you'll need to manually set
+``LD_LIBRARY_PATH`` to the directory containing ``libgccjit.so``, and
+``PATH`` needs to contain the path to the installed binaries.
+
+and then you can run from a built (but not installed) copy:
+
+.. code-block:: console
+
+  [gcc]$ PATH=../../install/bin:$PATH LD_LIBRARY_PATH=. ./testsuite/jit/test-factorial.exe
+
+without needing to reinstall everything for every tweak to the library.
 
 Running the test suite
 ----------------------
@@ -68,7 +117,10 @@ and once a test has been compiled, you can debug it directly:
 
 .. code-block:: console
 
-   [gcc] $ LD_LIBRARY_PATH=. gdb testsuite/jit/test-factorial.exe
+   [gcc] $ PATH=../../install/bin:$PATH \
+           LD_LIBRARY_PATH=. \
+             gdb --args \
+               testsuite/jit/test-factorial.exe
 
 
 Overview of code structure
diff --git a/gcc/jit/docs/intro/install.rst b/gcc/jit/docs/intro/install.rst
index 0e14db0..a0641b7 100644
--- a/gcc/jit/docs/intro/install.rst
+++ b/gcc/jit/docs/intro/install.rst
@@ -189,17 +189,6 @@ specify the compilation and linkage flags:
       -o jit-hello-world \
       $(pkg-config libgccjit --cflags --libs)
 
-and ensure that `LD_LIBRARY_PATH` is set appropriate when running the
-built program, so that it can locate and dynamically link against
-`libgccjit.so`:
-
-.. code-block:: console
-
-  # Run the built program:
-  $ export LD_LIBRARY_PATH=$PREFIX/lib
-  $ ./jit-hello-world
-  hello world
-
 This is equivalent to handcoding the include and library paths with `-I`
 and `-L` and specifying `-lgccjit` (i.e. linkage against libgccjit):
 
@@ -211,5 +200,28 @@ and `-L` and specifying `-lgccjit` (i.e. linkage against libgccjit):
       -lgccjit \
       -I$PREFIX/include -L$PREFIX/lib
 
-  $ LD_LIBRARY_PATH=$PREFIX/lib ./jit-hello-world
+When running the built test program against a locally-built tree, two
+environment variables need to be set up:
+
+* `LD_LIBRARY_PATH` needs to be set up appropriately so that the dynamic
+  linker can locate the `libgccjit.so`
+
+* `PATH` needs to include the `bin` subdirectory below the installation
+  prefix, so that the library can locate a driver binary.  This is used
+  internally by the library for converting from .s assembler files to
+  .so shared libraries.
+
+  ..
+     Specifically, it looks for a name expanded from
+     ``${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}`` on the
+     ``$PATH``, such as ``x86_64-unknown-linux-gnu-gcc-5.0.0``).
+
+For example, if you configured with a prefix of ``$PREFIX`` like above,
+you need an invocation like this:
+
+.. code-block:: console
+
+  $ LD_LIBRARY_PATH=$PREFIX/lib:$LD_LIBRARY_PATH \
+    PATH=$PREFIX/bin:$PATH \
+    ./jit-hello-world
   hello world
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 8ef9af9..6849403 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stor-layout.h"
 #include "print-tree.h"
 #include "gimplify.h"
+#include "gcc-driver-name.h"
 
 #include <pthread.h>
 
@@ -4998,7 +4999,9 @@ compile ()
   /* Gross hacks follow:
      We have a .s file; we want a .so file.
      We could reuse parts of gcc/gcc.c to do this.
-     For now, just use the /usr/bin/gcc on the system...
+     For now, just use the driver binary from the install, as
+     named in gcc-driver-name.h
+     e.g. "x86_64-unknown-linux-gnu-gcc-5.0.0".
    */
   {
     auto_timevar assemble_timevar (TV_ASSEMBLE);
@@ -5006,8 +5009,9 @@ compile ()
     const char *argv[6];
     int exit_status = 0;
     int err = 0;
+    const char *gcc_driver_name = GCC_DRIVER_NAME;
 
-    argv[0] = "gcc";
+    argv[0] = gcc_driver_name;
     argv[1] = "-shared";
     /* The input: assembler.  */
     argv[2] = m_path_s_file;
@@ -5018,7 +5022,7 @@ compile ()
     argv[5] = NULL;
 
     errmsg = pex_one (PEX_SEARCH, /* int flags, */
-		      "gcc", /* const char *executable */
+		      gcc_driver_name,
 		      const_cast<char * const *> (argv),
 		      ctxt_progname, /* const char *pname */
 		      NULL, /* const char *outname */
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index 4572c3d..798f7c9 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,3 +1,10 @@
+2014-10-07  David Malcolm  <dmalcolm@redhat.com>
+
+	* jit.dg/jit.exp (jit-dg-test): Prepend the installed bindir to
+	the PATH before invoking built binaries using the library, so that
+	the library can find the driver.  Restore the PATH immediately
+	afterwards.
+
 2014-09-24  David Malcolm  <dmalcolm@redhat.com>
 
 	* ChangeLog.jit: Add copyright footer.
diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
index 7986185..4672063 100644
--- a/gcc/testsuite/jit.dg/jit.exp
+++ b/gcc/testsuite/jit.dg/jit.exp
@@ -92,12 +92,26 @@ proc jit-dg-test { prog do_what extra_tool_flags } {
     #
     unsetenv GCC_EXEC_PREFIX
 
+    # libgccjit uses the driver to convert .s files to .so libraries
+    # via its *installed* name, the expansion of:
+    #   ${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}
+    # e.g. "x86_64-unknown-linux-gnu-gcc-5.0.0"
+    # looking for it on PATH.  Hence we need to prepend the installation
+    # bindir to PATH when running the tests
+    global env
+    global bindir
+    set old_path $env(PATH)
+    setenv "PATH" $bindir:$env(PATH)
+
     # dejagnu.exp's host_execute has code to scrape out test results
     # from the DejaGnu C API and bring back into the tcl world, so we
     # use that to invoke the built code:
     set result [host_execute $output_file]
     verbose "result: $result"
 
+    # Restore PATH
+    setenv "PATH" $old_path
+
     restore_ld_library_path_env_vars
 }
 
-- 
1.7.11.7


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]