This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java 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]

[ecj] Patch: FYI: simplify building with ecj.jar


I'll check this in on the gcj-eclipse branch shortly.  You've got a
little time to let me know what you think :)

This patch makes it somewhat simpler to set up the generics branch for
real use.

I've checked in my additions to ecj in the sources.redhat.com 'rhug'
repository, module 'eclipse-gcj'.  There is a Makefile there that
maintainers can use to check out ecj, build it, make an ecj.jar, and
upload this jar to sources.redhat.com.

I think we ought to do periodic releases of our own ecj.jar for GCC
developers to use.  (I expect distros will use this code in some form
or another; e.g. in Fedora I hope we will just apply GCCMain.java as a
patch to the ecj RPM.)

I've added a contrib script to download ecj-latest.jar from sources.
The '-latest' tag is what we'll use for the development ecj.

I've set up libjava's configure script so that you can specify the
location of an external ecj.jar.  If you do not specify one, and you
have one in the top source directory, libjava will use and install
that jar for you.

There are two modes to support two typical use cases.  First, a distro
will presumably supply ecj.jar as part of the ecj package; the
configure argument supports this.  Second, ordinary GCC developers may
need a more cutting edge jar file; we will provide that (via rhug) and
furthermore we set up the build for maximal convenience.

Finally I've updated jvgenmain so that 'gcj -findirect-dispatch --main=...'
will not try to link against the specified main class.  This lets us
make a wrapper program for a jar file without compiling the jar.  We
then use this to create 'ecj1', which is used by the gcj driver.
(Compiling the ecj.jar and putting it in the global class database
will still work; I leave this up to the end user.  I expect distros
will do this...)

I haven't updated the build/install documentation yet, but I will do
that.

Tom

Index: libjava/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* configure, Makefile.in: Rebuilt.
	* Makefile.am (install-exec-hook): Now unconditional.  Rename ecjx
	if needed.
	(jar_DATA): Add ecj jar when needed.
	(toolexec_PROGRAMS): New variable.
	(ecjx_SOURCES, ecjx_LDFLAGS, ecjx_LDADD, ecjx_DEPENDENCIES):
	Likewise.
	* prims.cc (JvRunMainName): New function.
	* include/jvm.h (JvRunMainName): Declare.
	* configure.ac: Added --with-ecj-jar.
	(ECJ_JAR): New subst.
	(ECJ_BUILD_JAR): Likewise.
	(INSTALL_ECJ_JAR): New conditional.
	(BUILD_ECJ1): Likewise.

Index: gcc/java/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* jvgenmain.c (main): Handle -findirect-dispatch.
	* jvspec.c (jvgenmain_spec): Pass -findirect-dispatch to
	jvgenmain.

Index: contrib/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* download_ecj: New file.

Index: contrib/download_ecj
===================================================================
--- contrib/download_ecj	(revision 0)
+++ contrib/download_ecj	(revision 0)
@@ -0,0 +1,15 @@
+#! /bin/sh
+
+#
+# Download the ecj jar file needed by gcj.
+# Run this from the top level of the gcc source tree and the libjava
+# build will do the right thing.
+#
+# (C) 2006 Free Software Foundation
+#
+# This script is Free Software, and it can be copied, distributed and
+# modified as defined in the GNU General Public License.  A copy of
+# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html
+#
+
+wget -O ecj.jar ftp://sources.redhat.com/pub/java/ecj-latest.jar

Property changes on: contrib/download_ecj
___________________________________________________________________
Name: svn:executable
   + *

Index: gcc/java/jvspec.c
===================================================================
--- gcc/java/jvspec.c	(revision 117511)
+++ gcc/java/jvspec.c	(working copy)
@@ -59,7 +59,7 @@
 int shared_libgcc = 1;
 
 static const char jvgenmain_spec[] =
-  "jvgenmain %{D*} %b %m.i |\n\
+  "jvgenmain %{findirect-dispatch} %{D*} %b %m.i |\n\
    cc1 %m.i %1 \
 		   %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a*}\
 		   %{g*} %{O*} \
Index: gcc/java/jvgenmain.c
===================================================================
--- gcc/java/jvgenmain.c	(revision 117511)
+++ gcc/java/jvgenmain.c	(working copy)
@@ -1,5 +1,5 @@
 /* Program to generate "main" a Java(TM) class containing a main method.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -57,14 +57,23 @@
   FILE *stream;
   const char *mangled_classname;
   int i, last_arg;
+  int indirect = 0;
+  char *prog_name = argv[0];
 
   /* Unlock the stdio streams.  */
   unlock_std_streams ();
 
   gcc_init_libintl ();
 
+  if (argc > 1 && ! strcmp (argv[1], "-findirect-dispatch"))
+    {
+      indirect = 1;
+      ++argv;
+      --argc;
+    }
+
   if (argc < 2)
-    usage (argv[0]);
+    usage (prog_name);
 
   for (i = 1; i < argc; ++i)
     {
@@ -77,7 +86,7 @@
     }
 
   if (i < argc - 2 || i == argc)
-    usage (argv[0]);
+    usage (prog_name);
   last_arg = i;
 
   classname = argv[i];
@@ -85,7 +94,7 @@
   /* gcj always appends `main' to classname.  We need to strip this here.  */
   p = strrchr (classname, 'm');
   if (p == NULL || p == classname || strcmp (p, "main") != 0)
-    usage (argv[0]);
+    usage (prog_name);
   else
     *p = '\0';
 
@@ -99,7 +108,7 @@
       if (stream == NULL)
 	{
 	  fprintf (stderr, _("%s: Cannot open output file: %s\n"),
-		   argv[0], outfile);
+		   prog_name, outfile);
 	  exit (1);
 	}
     }
@@ -130,13 +139,18 @@
   fprintf (stream, "int main (int argc, const char **argv)\n");
   fprintf (stream, "{\n");
   fprintf (stream, "   _Jv_Compiler_Properties = props;\n");
-  fprintf (stream, "   extern void *%s;\n", mangled_classname);
-  fprintf (stream, "   JvRunMain (%s, argc, argv);\n", mangled_classname);
+  if (indirect)
+    fprintf (stream, "   JvRunMainName (\"%s\", argc, argv);\n", classname);
+  else
+    {
+      fprintf (stream, "   extern void *%s;\n", mangled_classname);
+      fprintf (stream, "   JvRunMain (%s, argc, argv);\n", mangled_classname);
+    }
   fprintf (stream, "}\n");
   if (stream != stdout && fclose (stream) != 0)
     {
       fprintf (stderr, _("%s: Failed to close output file %s\n"),
-	       argv[0], argv[2]);
+	       prog_name, argv[2]);
       exit (1);
     }
   return 0;
Index: libjava/configure.ac
===================================================================
--- libjava/configure.ac	(revision 117705)
+++ libjava/configure.ac	(working copy)
@@ -452,6 +452,23 @@
    enable_hash_synchronization=$enable_hash_synchronization_default
 fi
 
+
+install_ecj_jar=no
+ECJ_BUILD_JAR=
+ECJ_JAR=
+AC_ARG_WITH(ecj-jar,
+	AS_HELP_STRING([--with-ecj-jar=FILE], [use preinstalled ecj jar]),
+	[ECJ_JAR=$withval],
+	[if test -f $libgcj_basedir/../ecj.jar; then
+	   ECJ_BUILD_JAR=$libgcj_basedir/../ecj.jar
+	   ECJ_JAR='$(jardir)/ecj.jar'
+	   install_ecj_jar=yes
+	 fi])
+AC_SUBST(ECJ_BUILD_JAR)
+AC_SUBST(ECJ_JAR)
+AM_CONDITIONAL(BUILD_ECJ1, test "$ECJ_JAR" != "")
+AM_CONDITIONAL(INSTALL_ECJ_JAR, test $install_ecj_jar = yes)
+
 AC_ARG_WITH(java-home,
   AS_HELP_STRING([--with-java-home=DIRECTORY],
                  [value of java.home system property]),
Index: libjava/include/jvm.h
===================================================================
--- libjava/include/jvm.h	(revision 117705)
+++ libjava/include/jvm.h	(working copy)
@@ -413,6 +413,8 @@
 void _Jv_SetStackSize (const char *arg);
 
 extern "C" void JvRunMain (jclass klass, int argc, const char **argv);
+extern "C" void JvRunMainName (const char *name, int argc, const char **argv);
+
 void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, 
 		  bool is_jar);
 
Index: libjava/Makefile.am
===================================================================
--- libjava/Makefile.am	(revision 117714)
+++ libjava/Makefile.am	(working copy)
@@ -53,6 +53,9 @@
 
 jardir = $(datadir)/java
 jar_DATA = libgcj-$(gcc_version).jar
+if INSTALL_ECJ_JAR
+jar_DATA += $(ECJ_BUILD_JAR)
+endif
 
 if JAVA_HOME_SET
 JAVA_HOME_DIR = $(JAVA_HOME)
@@ -83,6 +86,13 @@
 
 bin_SCRIPTS = addr2name.awk
 
+if BUILD_ECJ1
+## We build ecjx and not ecj1 because in one mode, ecjx will not work
+## until after 'make install', and we don't want it to be picked up in
+## the build tree by gcj via a -B option.
+toolexec_PROGRAMS = ecjx
+endif
+
 ## ################################################################
 
 ##
@@ -420,12 +430,12 @@
 $(extra_headers) $(srcdir)/java/lang/Object.h $(srcdir)/java/lang/Class.h:
 	@:
 
+install-exec-hook: install-toolexeclibLTLIBRARIES install-toolexecPROGRAMS
 ## Support for libgcj_bc: dummy shared library used only at link-time.
 if USE_LIBGCJ_BC
 ## Install libgcj_bc dummy lib in the target directory. We also need to delete
 ## libtool's .la file, this prevents libtool resetting the lib again 
 ## later.
-install-exec-hook: install-toolexeclibLTLIBRARIES
 	@echo Installing dummy lib libgcj_bc.so.1.0.0; \
 	rm $(toolexeclibdir)/libgcj_bc.so; \
 	mv $(toolexeclibdir)/libgcj_bc.so.1.0.0 $(toolexeclibdir)/libgcj_bc.so; \
@@ -435,6 +445,9 @@
 	$(LN_S) libgcj_bc.so.1.0.0 $(toolexeclibdir)/libgcj_bc.so.1; \
 	rm $(toolexeclibdir)/libgcj_bc.la;
 endif
+if BUILD_ECJ1
+	mv $(DESTDIR)$(toolexecdir)/ecjx $(DESTDIR)$(toolexecdir)/ecj1
+endif
 
 ## Install the headers.  It is fairly ugly that we have to do this by
 ## hand.
@@ -660,6 +673,18 @@
 ## linking this program.
 grmiregistry_DEPENDENCIES = libgcj.la libgcj.spec
 
+## Build an ecjx from a .jar.
+ecjx_SOURCES =
+## We use the BC ABI here so that we don't need to compile ecj.jar.
+## Hopefully the user has compiled it into his system .db.
+## However, even if not it will run reasonably quickly.
+ecjx_LDFLAGS = -findirect-dispatch \
+	--main=org.eclipse.jdt.internal.compiler.batch.GCCMain \
+	-Djava.class.path=$(ECJ_JAR)
+ecjx_LINK = $(GCJLINK)
+ecjx_LDADD = -L$(here)/.libs libgcj.la
+ecjx_DEPENDENCIES = libgcj.la libgcj.spec
+
 ## ################################################################
 
 ## This lists all the C++ source files in subdirectories.
Index: libjava/prims.cc
===================================================================
--- libjava/prims.cc	(revision 117705)
+++ libjava/prims.cc	(working copy)
@@ -1584,6 +1584,12 @@
   _Jv_RunMain (klass, NULL, argc, argv, false);
 }
 
+void
+JvRunMainName (const char *name, int argc, const char **argv)
+{
+  _Jv_RunMain (NULL, name, argc, argv, false);
+}
+
 
 
 // Parse a string and return a heap size.


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