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]

ping^5: plugin directory


Hello All,

As Laurynas kindly hinted me in http://gcc.gnu.org/ml/gcc/2010-03/msg00154.html I am pinging for the fifth time the attached patch to trunk rev 157458 for inclusion in GCC 4.5 (which did bootstrap on x86_64-linux). I already proposed that patch several times. http://gcc.gnu.org/ml/gcc-patches/2010-02/msg00353.html http://gcc.gnu.org/ml/gcc-patches/2010-01/msg00476.html etc.

This patch add the following ability to GCC: Users can invoke -fplugin=treehydra instead of -fplugin=/some/distribution/specific/path/to/treehydra.so and -fplugin=melt instead of -fplugin=/some/distribution/specific/path/to/melt.so
provided the plugin/libexec directory contains such commonly used plugins.


For users (and probably also distribution makers), this gives a very significant advantage: the same GCC invocation argument can be used on several (e.g. Linux) distributions. Also, the -fplugin= argument is shorter.

Without this patch, and assuming some set of commonly used plugins will exist, users will have to invoke these plugins with a different & longer (& system specific) program argument to GCC.

If this patch is accepted, the same invocation could work on several systems.

### gcc/ChangeLog entry ###

2010-03-15 Basile Starynkevitch <basile@starynkevitch.net>

	* doc/plugins.texi (Loading Plugins): Document short
	-fplugin=foo option.
	(Plugin API): Added mention of plugin_directory_name function.

	* gcc.c (find_file_spec_function): Added new declaration.
	(static_spec_func): Use it for "find-file".
	(find_file_spec_function): Added new function.

* gcc-plugin.h (plugin_directory_name): Added new declaration.

	* plugin.c (add_new_plugin): Updated comment, and handle short
	plugin name.
	(plugin_directory_name): Added new function.

	* common.opt (iplugindir): New option to set the plugin
	directory.

### gcc/testsuite/ChangeLog entry ####

2010-03-15 Basile Starynkevitch <basile@starynkevitch.net>

	* gcc.dg/plugin/plugdir_plugin.c: Added new file.
	* gcc.dg/plugin/plugdir-test-1.c: Likewise.
	* gcc.dg/plugin/plugin.exp: Use them both.

############################################################

Ok for trunk?

Cheers
--
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mines, sont seulement les miennes} ***
Index: gcc/doc/plugins.texi
===================================================================
--- gcc/doc/plugins.texi	(revision 157458)
+++ gcc/doc/plugins.texi	(working copy)
@@ -22,7 +22,14 @@ The plugin arguments are parsed by GCC and passed
 plugins as key-value pairs. Multiple plugins can be invoked by
 specifying multiple @option{-fplugin} arguments.
 
+A plugin can be simply given by its short name (no dots or
+slashes). When simply passing @option{-fplugin=NAME}, the plugin is
+loaded from @file{libexec/} inside the @file{plugin} directory, so
+@option{-fplugin=NAME} is the same as @option{-fplugin=`gcc
+-print-file-name=plugin`/libexec/NAME.so}, using backquote shell
+syntax to query the @file{plugin} directory.
 
+
 @section Plugin API
 
 Plugins are activated by the compiler at specific events as defined in
@@ -407,6 +414,9 @@ On most systems, you can query this @code{plugin}
 invoking @command{gcc -print-file-name=plugin} (replace if needed
 @command{gcc} with the appropriate program path).
 
+Inside plugins, this @code{plugin} directory name can be queried by
+calling @code{plugin_directory_name ()}.
+
 The following GNU Makefile excerpt shows how to build a simple plugin:
 
 @smallexample
Index: gcc/gcc.c
===================================================================
--- gcc/gcc.c	(revision 157458)
+++ gcc/gcc.c	(working copy)
@@ -403,6 +403,7 @@ static const char *if_exists_else_spec_function (i
 static const char *replace_outfile_spec_function (int, const char **);
 static const char *version_compare_spec_function (int, const char **);
 static const char *include_spec_function (int, const char **);
+static const char *find_file_spec_function (int, const char **);
 static const char *print_asm_header_spec_function (int, const char **);
 static const char *compare_debug_dump_opt_spec_function (int, const char **);
 static const char *compare_debug_self_opt_spec_function (int, const char **);
@@ -905,6 +906,7 @@ static const char *cc1_options =
  %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
  %{fsyntax-only:-o %j} %{-param*}\
  %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}\
+ %{fplugin*:-iplugindir %:find-file(plugin) -fplugin%*}\
  %{coverage:-fprofile-arcs -ftest-coverage}";
 
 static const char *asm_options =
@@ -1726,6 +1728,7 @@ static const struct spec_function static_spec_func
   { "replace-outfile",		replace_outfile_spec_function },
   { "version-compare",		version_compare_spec_function },
   { "include",			include_spec_function },
+  { "find-file",		find_file_spec_function },
   { "print-asm-header",		print_asm_header_spec_function },
   { "compare-debug-dump-opt",	compare_debug_dump_opt_spec_function },
   { "compare-debug-self-opt",	compare_debug_self_opt_spec_function },
@@ -8794,6 +8797,22 @@ include_spec_function (int argc, const char **argv
   return NULL;
 }
 
+/* %:find-file spec function.  This function replace its argument by
+    the file found thru find_file, that is the -print-file-name gcc
+    program option. */
+static const char *
+find_file_spec_function (int argc, const char**argv)
+{
+  const char *file;
+
+  if (argc != 1)
+    abort ();
+
+  file = find_file (argv[0]);
+  return file;
+}
+
+
 /* %:print-asm-header spec function.  Print a banner to say that the
    following output is from the assembler.  */
 
Index: gcc/testsuite/gcc.dg/plugin/plugdir-test-1.c
===================================================================
--- gcc/testsuite/gcc.dg/plugin/plugdir-test-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/plugin/plugdir-test-1.c	(revision 0)
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int main (int argc, char **argv) 
+{ 
+  return 0;  
+}
Index: gcc/testsuite/gcc.dg/plugin/plugdir_plugin.c
===================================================================
--- gcc/testsuite/gcc.dg/plugin/plugdir_plugin.c	(revision 0)
+++ gcc/testsuite/gcc.dg/plugin/plugdir_plugin.c	(revision 0)
@@ -0,0 +1,42 @@
+/* This test plugin just displays the plugin directory. */
+#include "gcc-plugin.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "toplev.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+#include "plugin-version.h"
+
+int plugin_is_GPL_compatible;
+
+
+static void 
+start_callback (void *gcc_data, void *user_data)
+{
+  inform (UNKNOWN_LOCATION, "plugin directory is %s", 
+	  plugin_directory_name ());
+}
+
+/* The initialization routine exposed to and called by GCC. The spec of this
+   function is defined in gcc/gcc-plugin.h.
+
+   PLUGIN_NAME - name of the plugin (useful for error reporting)
+   ARGC        - the size of the ARGV array
+   ARGV        - an array of key-value argument pair
+
+   Returns 0 if initialization finishes successfully.
+
+   Note that this function needs to be named exactly "plugin_init".  */
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+             struct plugin_gcc_version *version)
+{
+  register_callback ("plugdir", PLUGIN_START_UNIT, &start_callback, NULL);
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/plugin/plugin.exp
===================================================================
--- gcc/testsuite/gcc.dg/plugin/plugin.exp	(revision 157458)
+++ gcc/testsuite/gcc.dg/plugin/plugin.exp	(working copy)
@@ -51,6 +51,7 @@ set plugin_test_list [list \
     { ggcplug.c ggcplug-test-1.c } \
     { one_time_plugin.c one_time-test-1.c } \
     { start_unit_plugin.c start_unit-test-1.c } \
+    { plugdir_plugin.c plugdir-test-1.c } \
     { finish_unit_plugin.c finish_unit-test-1.c } \
 ]
 
Index: gcc/gcc-plugin.h
===================================================================
--- gcc/gcc-plugin.h	(revision 157458)
+++ gcc/gcc-plugin.h	(working copy)
@@ -141,4 +141,10 @@ extern void register_callback (const char *plugin_
 
 extern int unregister_callback (const char *plugin_name, int event);
 
+
+/* Retrieve the plugin directory name, as returned by the
+   -fprint-file-name=plugin argument to the gcc program, which is the
+   -iplugindir program argument to cc1.  */
+extern const char* plugin_directory_name (void);
+
 #endif /* GCC_PLUGIN_H */
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 157458)
+++ gcc/common.opt	(working copy)
@@ -1535,6 +1535,11 @@ gxcoff+
 Common JoinedOrMissing Negative(gcoff)
 Generate debug information in extended XCOFF format
 
+
+iplugindir
+Common Joined Separate Var(plugindir_string)
+-iplugindir <dir>	Set <dir> to be the plugin directory
+
 o
 Common Joined Separate
 -o <file>	Place output into <file>
Index: gcc/plugin.c
===================================================================
--- gcc/plugin.c	(revision 157458)
+++ gcc/plugin.c	(working copy)
@@ -1,5 +1,5 @@
 /* Support for GCC plugin mechanism.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -124,17 +124,40 @@ get_plugin_base_name (const char *full_name)
 }
 
 
-/* Create a plugin_name_args object for the give plugin and insert it to
-   the hash table. This function is called when -fplugin=/path/to/NAME.so
-   option is processed.  */
+/* Create a plugin_name_args object for the give plugin and insert it
+   to the hash table. This function is called when
+   -fplugin=/path/to/NAME.so or -fplugin=NAME option is processed.  */
 
 void
 add_new_plugin (const char* plugin_name)
 {
   struct plugin_name_args *plugin;
   void **slot;
-  char *base_name = get_plugin_base_name (plugin_name);
+  char *base_name;
+  bool name_is_short = true;
+  const char *pc;
 
+  /* Replace short names by their full path when relevant.  */
+  for (pc = plugin_name; *pc && name_is_short; pc++)
+    if (*pc == '.' || *pc == '/')
+      name_is_short = false;
+
+  if (name_is_short)
+    {
+      base_name = CONST_CAST (char*, plugin_name);
+      /* FIXME: the ".so" suffix is currently builtin.  When plugins
+	 shall be available on non ELF systems, this should be
+	 improved.  */
+      plugin_name = concat (plugin_directory_name (), "/libexec/",
+			    plugin_name, ".so", NULL);
+      if (access (plugin_name, R_OK))
+	fatal_error
+	  ("inacessible file %s expanded from plugin short name %s: %m",
+	   plugin_name, base_name);
+    }
+  else
+    base_name = get_plugin_base_name (plugin_name);
+
   /* If this is the first -fplugin= option we encounter, create
      'plugin_name_args_tab' hash table.  */
   if (!plugin_name_args_tab)
@@ -809,6 +832,7 @@ plugin_default_version_check (struct plugin_gcc_ve
   return true;
 }
 
+
 /* Return the current value of event_last, so that plugins which provide
    additional functionality for events for the benefit of high-level plugins
    know how many valid entries plugin_event_name holds.  */
@@ -818,3 +842,12 @@ get_event_last (void)
 {
   return event_last;
 }
+
+/* Retrieve the plugin directory.  The gcc driver should have passed it
+   as -iplugindir <dir> to the cc1 program, and it is queriable thru the
+   -print-file-name=plugin option to gcc.  */
+const char*
+plugin_directory_name (void)
+{
+  return plugindir_string;
+}

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