This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFC & help: Retrieve programmatically the plugin directory name.
- From: Basile STARYNKEVITCH <basile at starynkevitch dot net>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 25 Nov 2009 14:15:00 +0100
- Subject: RFC & help: Retrieve programmatically the plugin directory name.
Hello All,
The attached patch to trunk 154643 provides a way to retrieve programmatically the plugin directory name.
See http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01545.html & http://gcc.gnu.org/ml/gcc/2009-11/msg00655.html
The intent is that some plugins may find useful to get some of their configuration files within the plugin/ directory as
returned by the command
gcc -print-file-name=plugin
So this patch provides a plugin_directory_name () function to retrieve programmatically that directory.
It works in a similar way to the add_standard_paths function of gcc/incpath.c by calling make_relative_prefix with a
dummy filename.
Unfortunately, it does not seems to work as expected. My intuitive feeling is that gcc should in fact pass some argument
[like -iplugindir] to cc1, computed from the prefix and the spec file. Unfortunately, I don't understand these.
So this patch is *not* OK but I am still asking for help.
#### bad gcc/ChangeLog entry: ####
2009-11-25 Basile Starynkevitch <basile@starynkevitch.net>
* gcc-plugin.h (plugin_directory_name): Added new declaration.
* plugin.c: Includes prefix.h & cppdefault.h.
(plugind_directory_name): Added new function.
* Makefile.in (plugin.o): also depends upon prefix.h & cppdefault.h.
#### bad gcc/testsuite/ChangeLog entry: ####
2009-11-25 Basile Starynkevitch <basile@starynkevitch.net>
* plugdir-test-1.c: Added new test case for plugin_directory_name.
* plugdir_plugin.c: ditto.
* plugin.exp: ditto.
#####################
My general feeling is that GCC passes, in particular plugin provided passes, may legitimately need to access files
within the GCC installation file tree, and I feel that we are lacking some functions (or at least documentations) to
make that easy from within cc1 and plugins.
Once suich a plugin_directory_name function exists and is working, it is quite easy to patch plugin.c so that
-fplugin=foo is a simpler way to pass -fplugin=`gcc -print-file-name=plugin`/libexec/foo.so [notice the backquote for
the shell].
Comments and suggestions are welcome.
Regards.
--
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-trunk-bstarynk/gcc/doc/plugins.texi
===================================================================
--- gcc-trunk-bstarynk/gcc/doc/plugins.texi (revision 154643)
+++ gcc-trunk-bstarynk/gcc/doc/plugins.texi (working copy)
@@ -348,6 +348,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-trunk-bstarynk/gcc/testsuite/gcc.dg/plugin/plugdir-test-1.c
===================================================================
--- gcc-trunk-bstarynk/gcc/testsuite/gcc.dg/plugin/plugdir-test-1.c (revision 0)
+++ gcc-trunk-bstarynk/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-trunk-bstarynk/gcc/testsuite/gcc.dg/plugin/plugdir_plugin.c
===================================================================
--- gcc-trunk-bstarynk/gcc/testsuite/gcc.dg/plugin/plugdir_plugin.c (revision 0)
+++ gcc-trunk-bstarynk/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-trunk-bstarynk/gcc/testsuite/gcc.dg/plugin/plugin.exp
===================================================================
--- gcc-trunk-bstarynk/gcc/testsuite/gcc.dg/plugin/plugin.exp (revision 154643)
+++ gcc-trunk-bstarynk/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-trunk-bstarynk/gcc/gcc-plugin.h
===================================================================
--- gcc-trunk-bstarynk/gcc/gcc-plugin.h (revision 154643)
+++ gcc-trunk-bstarynk/gcc/gcc-plugin.h (working copy)
@@ -137,4 +137,8 @@ extern void register_callback (const char *plugin_
plugin_callback_func callback,
void *user_data);
+/* Retrieve the plugin directory name, as returned by the
+ -fprint-file-name=plugin argument to the gcc program. */
+extern const char* plugin_directory_name (void);
+
#endif /* GCC_PLUGIN_H */
Index: gcc-trunk-bstarynk/gcc/plugin.c
===================================================================
--- gcc-trunk-bstarynk/gcc/plugin.c (revision 154643)
+++ gcc-trunk-bstarynk/gcc/plugin.c (working copy)
@@ -38,6 +38,8 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "plugin.h"
#include "timevar.h"
+#include "prefix.h"
+#include "cppdefault.h"
#include "ggc.h"
#ifdef ENABLE_PLUGIN
@@ -686,3 +688,37 @@ plugin_default_version_check (struct plugin_gcc_ve
return false;
return true;
}
+
+/* Retrieve the plugin directory name, using the make_relative_prefix
+ utility function, which expects a program name, not a directory
+ name. So we use "plugin-dummy" as the ``program'' name. */
+const char*
+plugin_directory_name (void)
+{
+ struct stat dirst;
+ const char* dummyplugin;
+ char* relocprefix;
+ static char* plugdirname;
+ /* When called more than once, return the memoized result. */
+ if (plugdirname)
+ return plugdirname;
+ /* We are doing like add_standard_paths from incpath.c. */
+ dummyplugin =
+ gcc_exec_prefix?
+ concat (gcc_exec_prefix, "plugin-dummy", NULL)
+ : "plugin-dummy"
+ ;
+ relocprefix = make_relative_prefix (dummyplugin,
+ cpp_EXEC_PREFIX,
+ cpp_PREFIX);
+ plugdirname = concat (relocprefix, "plugin", NULL);
+ /* The plugdirname is never freed. */
+ memset (&dirst, 0, sizeof(dirst));
+ /* Sanity checks: the plugin directory should exist and be a directory! */
+ if (stat (plugdirname, &dirst))
+ fatal_error ("cannot stat the plugin directory %s - %m", plugdirname);
+ if (!S_ISDIR (dirst.st_mode))
+ fatal_error ("%s should be the plugin directory, but is not a directory.",
+ plugdirname);
+ return plugdirname;
+}
Index: gcc-trunk-bstarynk/gcc/Makefile.in
===================================================================
--- gcc-trunk-bstarynk/gcc/Makefile.in (revision 154643)
+++ gcc-trunk-bstarynk/gcc/Makefile.in (working copy)
@@ -2728,7 +2728,8 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) corety
gt-passes.h $(DF_H) $(PREDICT_H) $(LTO_HEADER_H) $(LTO_SECTION_OUT_H)
plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H)
+ $(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H) \
+ prefix.h cppdefault.h
main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H)