aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac59
-rw-r--r--m4/gcc-plugin.m4125
-rw-r--r--odb/Makefile.am4
-rw-r--r--odb/odb.cxx131
4 files changed, 245 insertions, 74 deletions
diff --git a/configure.ac b/configure.ac
index 320b060..35a0fa1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,29 +20,37 @@ AC_CANONICAL_HOST
AC_PROG_CXX
AC_LANG(C++)
+# Create the libtool executable so that we can use it in further tests.
+#
+LT_OUTPUT
+
+# Test for plugin support in GCC.
+#
+GCC_PLUGIN
+
# See if we are building static plugin. Static build should only be
# used if you are building a custom version of GCC with the ODB
# plugin linked-in statically. This is primarily useful on Windows
# where GCC plugins are not (yet) supported due to dynamic loading
-# limitations.
+# limitations. In this case the headers normally come from the GCC
+# build directly via CPPFLAGS.
#
-static_plugin="$enable_static"
-
-AS_IF([test x$static_plugin = xyes],
+if test x$static_plugin = xyes; then
AC_WARN([Building static plugin for direct linking into GCC executable!])
- AC_DEFINE([ODB_STATIC_PLUGIN], [1], [Building static plugin.]))
+ AC_DEFINE([ODB_STATIC_PLUGIN], [1], [Building static plugin.])
+ plugindir='$(pkglibexecdir)'
-# Check for plugin support in GCC unless we are building a static plugin.
-# In the latter case the headers normally come from the GCC build directly
-# via CPPFLAGS.
+# Otherwise, see if we should install the plugin into the GCC plugin dir.
#
-AS_IF([test x$static_plugin = xno], GCC_PLUGIN)
+elif test x$gcc_plugin_dir != xno; then
+ AC_DEFINE([ODB_GCC_PLUGIN_DIR], [1], [Plugin is in GCC plugin directory.])
+ plugindir=$gcc_plugin_dir
-# Unless we are building a static plugin, try to figure out a relative
-# path from the driver (bindir) to the plugin (libexecdir).
+# Otherwise, try to figure out a relative path from the driver (bindir) to
+# the plugin (libexecdir).
#
-if test x$static_plugin = xno; then
- # Get the expanded values for bindif and libexecdir.
+elif test x$static_plugin = xno; then
+ # Get the expanded values for bindir and libexecdir.
#
if test x$exec_prefix = xNONE; then
if test x$prefix = xNONE; then
@@ -60,32 +68,35 @@ if test x$static_plugin = xno; then
# Try to find a common prefix.
#
common=$e_bindir
- odb_plugindir=$e_pkglibexecdir
+ rel_plugindir=$e_pkglibexecdir
while test x$common != x/; do
suffix=`echo "$e_pkglibexecdir" | sed "s?^$common/*??"`
if test x$suffix != x$e_pkglibexecdir; then
# Replace all the remaining directories in bindir with ".."
# and append the suffix.
- odb_plugindir=`echo "$e_bindir" | sed "s?^$common/*??"`
- odb_plugindir=`echo "$odb_plugindir" | sed ['s?[^/][^/]*?..?g']`
- if test x$odb_plugindir != x -a x$suffix != x; then
- odb_plugindir="$odb_plugindir/$suffix"
+ rel_plugindir=`echo "$e_bindir" | sed "s?^$common/*??"`
+ rel_plugindir=`echo "$rel_plugindir" | sed ['s?[^/][^/]*?..?g']`
+ if test x$rel_plugindir != x -a x$suffix != x; then
+ rel_plugindir="$rel_plugindir/$suffix"
else
- odb_plugindir="$odb_plugindir$suffix"
+ rel_plugindir="$rel_plugindir$suffix"
fi
break
fi
common=`AS_DIRNAME(["$common"])`
done
- AC_DEFINE_UNQUOTED([ODB_PLUGIN_PATH], ["$odb_plugindir"], [Plugin path.])
+ AC_DEFINE_UNQUOTED([ODB_PLUGIN_PATH], ["$rel_plugindir"], [Plugin path.])
+ plugindir='$(pkglibexecdir)'
fi
+AC_SUBST([plugindir])
+
# G++ name.
#
AC_ARG_WITH(
[gxx-name],
- [AC_HELP_STRING([--with-gxx-name=NAME], [g++ binary to embed in the driver])],
+ [AC_HELP_STRING([--with-gxx-name=NAME], [g++ executable name to embed in the ODB compiler driver])],
[case $withval in
no)
gxx_name=
@@ -125,16 +136,10 @@ AS_IF(
[test "x$options_file" != x],
[AC_DEFINE_UNQUOTED([ODB_DEFAULT_OPTIONS_FILE], ["$options_file"], [default options file path.])])
-# Create the libtool executable so that we can use it in further tests.
-#
-LT_OUTPUT
-
-
# Check for libcutl.
#
LIBCUTL([],[AC_MSG_ERROR([libcutl is not found; consider using --with-libcutl=DIR])])
-
# Check if we should disable rpath.
#
DISABLE_RPATH
diff --git a/m4/gcc-plugin.m4 b/m4/gcc-plugin.m4
index 27453a2..27ce15d 100644
--- a/m4/gcc-plugin.m4
+++ b/m4/gcc-plugin.m4
@@ -5,23 +5,124 @@ dnl
dnl GCC_PLUGIN
dnl
AC_DEFUN([GCC_PLUGIN], [
-gcc_plugin_support=no
+static_plugin=$enable_static
-if test x"$GXX" != xyes; then
- AC_MSG_ERROR([$CXX is not a GNU C++ compiler])
+AC_ARG_WITH(
+ [gcc-plugin-dir],
+ [AC_HELP_STRING([--with-gcc-plugin-dir=DIR], [install ODB plugin into the GCC plugin directory])],
+ [gcc_plugin_dir=$withval],
+ [gcc_plugin_dir=test])
+
+if test x"$static_plugin" = xyes; then
+ gcc_plugin_dir=no
+else
+ if test x"$cross_compiling" = xyes; then
+ AC_MSG_CHECKING([whether to install into default GCC plugin dir])
+ case $gcc_plugin_dir in
+ yes)
+ AC_MSG_ERROR([GCC plugin directory must be specified explicitly when cross-compiling])
+ ;;
+ test)
+ # We cannot detect the plugin directory since there is no way to
+ # run host GCC. So assume no.
+ #
+ gcc_plugin_dir=no
+ ;;
+ no)
+ ;;
+ *)
+ # Add the include/ subdirectory of the plugin dir to CPPFLAGS since
+ # the plugin headers are normally installed there.
+ #
+ CPPFLAGS="$CPPFLAGS -I$gcc_plugin_dir/include"
+ ;;
+ esac
+ else
+ if test x"$GXX" != xyes; then
+ AC_MSG_ERROR([$CXX is not a GNU C++ compiler])
+ fi
+
+ AC_MSG_CHECKING([whether $CXX supports plugins])
+ dir=`$CXX -print-file-name=plugin 2>/dev/null`
+
+ if test x"$dir" = xplugin; then
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([$CXX does not support plugins; reconfigure GCC with --enable-plugin])
+ else
+ AC_MSG_RESULT([yes])
+ fi
+
+ CPPFLAGS="$CPPFLAGS -I$dir/include"
+
+ AC_MSG_CHECKING([whether to install ODB plugin into default GCC plugin directory])
+ case $gcc_plugin_dir in
+ yes)
+ gcc_plugin_dir=$dir
+ ;;
+ test)
+ # Only install into the GCC plugin dir if both GCC and ODB are
+ # installed into the same prefix. Testing whether $libdir or
+ # $libexecdir is a prefix of the GCC plugin dir is a good
+ # approximation.
+ #
+
+ # Get the expanded values for libdir and libexecdir.
+ #
+ if test x$exec_prefix = xNONE; then
+ if test x$prefix = xNONE; then
+ e_exec_prefix=$ac_default_prefix
+ else
+ e_exec_prefix=$prefix
+ fi
+ else
+ e_exec_prefix=$exec_prefix
+ fi
+
+ e_libdir=`echo "$libdir" | sed "s?^\\\${exec_prefix}?$e_exec_prefix?"`
+ e_libexecdir=`echo "$libexecdir" | sed "s?^\\\${exec_prefix}?$e_exec_prefix?"`
+
+ # See if either one of them is a prefix of the plugin dir.
+ #
+ ld_suffix=`echo "$dir" | sed "s?^$e_libdir/*??"`
+ led_suffix=`echo "$dir" | sed "s?^$e_libexecdir/*??"`
+
+ if test x$ld_suffix != x$dir -o x$led_suffix != x$dir; then
+ gcc_plugin_dir=$dir
+ else
+ gcc_plugin_dir=no
+ fi
+ ;;
+ *)
+ ;;
+ esac
+ fi
+
+ if test x"$gcc_plugin_dir" != xno; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
fi
-AC_MSG_CHECKING([whether $CXX supports plugins])
+AC_MSG_CHECKING([for GCC plugin headers])
-gcc_plugin_base=`$CXX -print-file-name=plugin 2>/dev/null`
+CXX_LIBTOOL_LINK_IFELSE([
+AC_LANG_SOURCE([
+#include <bversion.h>
-if test x"$gcc_plugin_base" = xplugin; then
- AC_MSG_RESULT([no])
- AC_MSG_ERROR([$CXX does not support plugins; reconfigure GCC with --enable-plugin or install plugin headers])
-else
+#ifndef BUILDING_GCC_MAJOR
+# error no BUILDING_GCC_MAJOR in bversion.h
+#endif
+
+int main () {}
+])],
+[gcc_plugin_headers=yes],
+[gcc_plugin_headers=no])
+
+if test x"$gcc_plugin_headers" = xyes; then
AC_MSG_RESULT([yes])
- gcc_plugin_support=yes
+else
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([GCC plugin headers not found; consider installing GCC plugin development package])
fi
-
-CPPFLAGS="$CPPFLAGS -I$gcc_plugin_base/include"
])dnl
diff --git a/odb/Makefile.am b/odb/Makefile.am
index bc2fc76..f9d9703 100644
--- a/odb/Makefile.am
+++ b/odb/Makefile.am
@@ -2,7 +2,7 @@
# copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
# license : GNU GPL v3; see accompanying LICENSE file
-plugindir = $(pkglibexecdir)
+plugindir = @plugindir@
bin_PROGRAMS = odb
plugin_LTLIBRARIES = odb.la
@@ -19,7 +19,7 @@ odb_la_LDFLAGS = -module -shrext .so -avoid-version
# Remove the .la file from the final install.
#
install-data-hook:
- rm -f '$(DESTDIR)$(pkglibexecdir)/odb.la'
+ rm -f '$(DESTDIR)$(plugindir)/odb.la'
# Driver.
#
diff --git a/odb/odb.cxx b/odb/odb.cxx
index 9491252..74ef5a4 100644
--- a/odb/odb.cxx
+++ b/odb/odb.cxx
@@ -70,7 +70,7 @@ driver_path (path const& driver);
#ifndef ODB_STATIC_PLUGIN
static path
-plugin_path (path const& driver);
+plugin_path (path const& driver, string const& gxx);
#endif
//
@@ -140,25 +140,6 @@ main (int argc, char* argv[])
try
{
- // Find the plugin. It should be in the same directory as the
- // driver.
- //
-#ifndef ODB_STATIC_PLUGIN
- path plugin (plugin_path (path (argv[0])));
-#else
- // Use a dummy name if the plugin is linked into the compiler.
- //
- path plugin ("odb");
-#endif
-
- if (plugin.empty ())
- {
- e << argv[0] << ": error: unable to locate ODB GCC plugin" << endl;
- e << argv[0] << ": info: make sure '" << argv[0] << ".so' is in "
- << "the same directory as '" << argv[0] << "'" << endl;
- return 1;
- }
-
strings args, plugin_args;
bool v (false);
@@ -236,7 +217,7 @@ main (int argc, char* argv[])
args.push_back ("-S");
args.push_back ("-Wunknown-pragmas");
args.push_back ("-Wno-deprecated");
- args.push_back ("-fplugin=" + plugin.string ());
+ args.push_back (""); // Reserve space for -fplugin=path.
// Parse the default options file if we have one.
//
@@ -522,6 +503,23 @@ main (int argc, char* argv[])
//
args.insert (args.end (), def_inc_dirs.begin (), def_inc_dirs.end ());
+ // Find the plugin.
+ //
+ {
+#ifndef ODB_STATIC_PLUGIN
+ path plugin (plugin_path (path (argv[0]), args[0]));
+#else
+ // Use a dummy name if the plugin is linked into the compiler.
+ //
+ path plugin ("odb");
+#endif
+
+ if (plugin.empty ())
+ return 1; // Diagnostics has already been issued.
+
+ args[7] = "-fplugin=" + plugin.string ();
+ }
+
// Parse plugin options. We have to do it twice to get the target
// database which is needed while loading profiles.
//
@@ -1433,7 +1431,12 @@ driver_path (path const& drv)
#ifndef ODB_STATIC_PLUGIN
static path
-plugin_path (path const& drv)
+plugin_path (path const& drv,
+#ifdef ODB_GCC_PLUGIN_DIR
+ string const& gxx)
+#else
+ string const&)
+#endif
{
// Figure out the plugin base name which is just the driver name.
// If the driver name starts with 'lt-', then we are running through
@@ -1448,7 +1451,10 @@ plugin_path (path const& drv)
path dp (driver_path (drv));
if (dp.empty ())
- return path (); // Fail.
+ {
+ cerr << drv << ": error: unable to resolve ODB driver path" << endl;
+ return path ();
+ }
dp = dp.directory ();
struct stat info;
@@ -1465,32 +1471,91 @@ plugin_path (path const& drv)
return pp;
}
-#ifdef ODB_PLUGIN_PATH
+#ifdef ODB_GCC_PLUGIN_DIR
+ // Plugin should be installed into the GCC default plugin directory.
+ // Ideally, in this situation, we would simply pass the plugin name and
+ // let GCC append the correct directory. Unfortunately, this mechanism
+ // was only added in GCC 4.6 so in order to support 4.5 we will have to
+ // emulate it ourselves.
+ //
+ if (!lt)
+ {
+ // First get the default GCC plugin directory.
+ //
+ path d;
+ vector<char const*> exec_args;
+ exec_args.push_back (gxx.c_str ());
+ exec_args.push_back ("-print-file-name=plugin");
+ exec_args.push_back (0);
+
+ process_info pi (
+ start_process (
+ &exec_args[0], drv.string ().c_str (), false, true));
+ close (pi.out_fd);
+
+ // Read the path from stdout.
+ //
+ {
+ __gnu_cxx::stdio_filebuf<char> fb (pi.in_ofd, ios_base::in);
+ istream is (&fb);
+ string line;
+ getline (is, line);
+ d = path (line);
+ }
+
+ if (!wait_process (pi, drv.string ().c_str ()))
+ return path (); // Assume GCC issued some diagnostics.
+
+ if (d.string () == "plugin")
+ {
+ cerr << drv << ": error: unable to obtain GCC plugin directory" << endl;
+ return path ();
+ }
+
+ // See if the plugin is there.
+ //
+ pp = d / path (b + ".so");
+ if (stat (pp.string ().c_str (), &info) != 0)
+ {
+ cerr << drv << ": error: no ODB plugin in GCC plugin directory '" <<
+ d << "'" << endl;
+ return path ();
+ }
+
+ return pp;
+ }
+#elif defined (ODB_PLUGIN_PATH)
// If we were given a plugin path, use that unless we are running
// via libtool.
//
if (!lt)
{
string rp (ODB_PLUGIN_PATH);
- pp = dp;
if (!rp.empty ())
- pp /= path (rp);
- pp /= path (b + ".so");
+ dp /= path (rp);
- if (stat (pp.string ().c_str (), &info) == 0)
- return pp;
+ pp = dp / path (b + ".so");
+
+ if (stat (pp.string ().c_str (), &info) != 0)
+ {
+ cerr << drv << ": error: no ODB plugin in '" << dp << "'" << endl;
+ return path ();
+ }
- return path (); // Fail.
+ return pp;
}
#endif
// Try .so in the current directory.
//
pp = dp / path (b + ".so");
- if (stat (pp.string ().c_str (), &info) == 0)
- return pp;
+ if (stat (pp.string ().c_str (), &info) != 0)
+ {
+ cerr << drv << ": error: unable to locate ODB plugin" << endl;
+ return path ();
+ }
- return path ();
+ return pp;
}
#endif