* [patch] Create sdk style directory on install @ 2008-06-12 20:56 Joshua Sumali 2008-06-13 10:42 ` Andrew Haley 2008-06-13 12:42 ` Matthias Klose 0 siblings, 2 replies; 18+ messages in thread From: Joshua Sumali @ 2008-06-12 20:56 UTC (permalink / raw) To: java-patches; +Cc: Thomas Fitzsimmons [-- Attachment #1: Type: text/plain, Size: 699 bytes --] Hi, Attached is a patch to create a sdk style directory when --enable-java-home is passed to configure. The patch is basically a merge of java-gcj-compat into libgcj. To have this work, at the minimum, pass the following to ./configure: --enable-java-home --with-arch-directory=(your arch). --with-arch-directory specifies what to use for the java-1.5.0-gcj-1.5.0.0/jre/lib/<arch> directory (e.g. I use i386). I've only included the diff to configure.ac and Makefile.am since including the configure and Makefile.in makes the patch quite big, so be sure to autoconf && automake before trying this patch. I can upload the renerated files somewhere if it's absolutely needed, though. Josh [-- Attachment #2: gcc-libjava-sdk-home-symlink.patch --] [-- Type: text/x-patch, Size: 13708 bytes --] Index: ChangeLog =================================================================== --- ChangeLog (revision 136724) +++ ChangeLog (working copy) @@ -1,3 +1,19 @@ +2008-06-12 Joshua Sumali <jsumali@redhat.com> + + * configure.ac (java-home): new AC_ARG_ENABLE. + (CREATE_JAVA_HOME): new AM_CONDITIONAL. + (gcc-suffix): new AC_ARG_WITH. + (arch-directory): Likewise. + (os-directory): Likewise. + (origin-name): Likewise. + (arch-suffix): Likewise. + (jvm-root-dir): Likewise. + (jvm-jar-dir): Likewise. + * Makefile.am (install-data-local): Install an sdk style directory if + --enable-java-home is passed to configure. + * configure: Regenerate. + * Makefile.in: Regenerate. + 2008-06-07 Joseph Myers <joseph@codesourcery.com> * configure.host (strongarm*-elf, xscale*-elf): Remove. Index: Makefile.am =================================================================== --- Makefile.am (revision 136724) +++ Makefile.am (working copy) @@ -85,7 +85,7 @@ ## It is convenient to actually build and install the default database ## when gcj-dbtool is available. dbexec_DATA = $(db_name) -endif +endif bin_SCRIPTS = addr2name.awk @@ -528,8 +528,134 @@ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SinkChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SourceChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ ## Don't install java/nio/DirectByteBufferImpl$$ReadWrite.h here. It's for internal use only. +if CREATE_JAVA_HOME +## Create sdk style directories + $(mkinstalldirs) $(DESTDIR)$(JRE_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/$(OS) + relative() { \ + $(PERL) -e 'use File::Spec; \ + print File::Spec->abs2rel($$ARGV[0], $$ARGV[1])' $$1 $$2; \ + }; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(SDK_BIN_DIR)); \ + ln -sf $$RELATIVE/gij$(gcc_suffix) $(DESTDIR)$(SDK_BIN_DIR)/java; \ + ln -sf $$RELATIVE/gjar$(gcc_suffix) $(DESTDIR)$(SDK_BIN_DIR)/jar; \ + ln -sf $$RELATIVE/gjdoc$(gcc_suffix) $(DESTDIR)$(SDK_BIN_DIR)/javadoc; \ + ln -sf $$RELATIVE/grmic$(gcc_suffix) $(DESTDIR)$(SDK_BIN_DIR)/rmic; \ + ln -sf $$RELATIVE/gjavah$(gcc_suffix) $(DESTDIR)$(SDK_BIN_DIR)/javah; \ + ln -sf $$RELATIVE/ecj $(DESTDIR)$(SDK_BIN_DIR)/javac; \ + ln -sf $$RELATIVE/gappletviewer$(gcc_suffix) \ + $(DESTDIR)$(SDK_BIN_DIR)/appletviewer; \ + ln -sf $$RELATIVE/gjarsigner$(gcc_suffix) $(DESTDIR)$(SDK_BIN_DIR)/jarsigner; \ + ln -sf $$RELATIVE/grmiregistry$(gcc_suffix) \ + $(DESTDIR)$(SDK_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/gkeytool$(gcc_suffix) \ + $(DESTDIR)$(SDK_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/gorbd$(gcc_suffix) $(DESTDIR)$(SDK_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/gnative2ascii$(gcc_suffix) \ + $(DESTDIR)$(SDK_BIN_DIR)/native2ascii; \ + ln -sf $$RELATIVE/grmid$(gcc_suffix) $(DESTDIR)$(SDK_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/gtnameserv$(gcc_suffix) \ + $(DESTDIR)$(SDK_BIN_DIR)/tnameserv; \ + ln -sf $$RELATIVE/gserialver$(gcc_suffix) \ + $(DESTDIR)$(SDK_BIN_DIR)/serialver; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(JRE_BIN_DIR)); \ + ln -sf $$RELATIVE/grmiregistry$(gcc_suffix) \ + $(DESTDIR)$(JRE_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/gkeytool$(gcc_suffix) $(DESTDIR)$(JRE_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/gij$(gcc_suffix) $(DESTDIR)$(JRE_BIN_DIR)/java; \ + ln -sf $$RELATIVE/gorbd$(gcc_suffix) $(DESTDIR)$(JRE_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/grmid$(gcc_suffix) $(DESTDIR)$(JRE_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/gtnameserv$(gcc_suffix) $(DESTDIR)$(JRE_BIN_DIR)/tnameserv; \ + $(mkinstalldirs) $(DESTDIR)$(JVM_JAR_DIR); \ + version=$(JAVA_VERSION).$(BUILD_VERSION); \ + working_dir=`pwd`; \ + cd $(DESTDIR)$(JVM_JAR_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s $$RELATIVE/$$jarname.jar $$jarname-$$version.jar; \ + done; \ + for jar in *-$$version.jar; \ + do \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|-$(JAVA_VERSION).jar|g"); \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|.jar|g"); \ + done; \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/security; \ + RELATIVE=$$(relative $(DESTDIR)$(libdir)/security \ + $(DESTDIR)$(JRE_LIB_DIR)/security); \ + cd $(DESTDIR)$(JRE_LIB_DIR)/security; \ + ln -sf $$RELATIVE/classpath.security java.security; \ + cd $(DESTDIR)$(JVM_ROOT_DIR); \ + ln -s $(JRE_DIR) $(JRE_LNK); \ + ln -s $(SDK_DIR) $(SDK_LNK); \ + cd $(DESTDIR)$(JVM_JAR_ROOT_DIR); \ + ln -s $(SDK_DIR) $(JRE_LNK); \ + ln -s $(SDK_DIR) $(SDK_LNK); \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/linux; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_LIB_DIR); \ + cd $(DESTDIR)$(JRE_LIB_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s rt.jar $$jarname.jar; \ + done; \ + cd $$working_dir; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JRE_LIB_DIR)); \ + GIJ_VERSION=$$($(DESTDIR)$(bindir)/gij --version | head -n2 | tail -n1 \ + | awk '{print $$5}'); \ + ln -sf $$RELATIVE/libgcj-$$GIJ_VERSION.jar \ + $(DESTDIR)$(JRE_LIB_DIR)/rt.jar; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)); \ + if [ -f $$RELATIVE/libjawt.so ]; then \ + ln -sf $$RELATIVE/libjawt.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/libjawt.so; \ + fi; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(SDK_LIB_DIR)); \ + ln -sf $$RELATIVE/libgcj-tools-$$GIJ_VERSION.jar \ + $(DESTDIR)$(SDK_LIB_DIR)/tools.jar; \ + for headername in jawt jni; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/$$headername.h; \ + done; \ + for headername in jawt_md jni_md; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux/$$headername.h; \ + done; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)); \ + if [ -f $$RELATIVE/src-$$GIJ_VERSION.zip ]; then \ + ln -sf $$RELATIVE/src-$$GIJ_VERSION.zip \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)/src.zip; \ + fi; +endif - ## ################################################################ ## Index: configure.ac =================================================================== --- configure.ac (revision 136724) +++ configure.ac (working copy) @@ -117,6 +117,7 @@ AC_CHECK_PROGS([JAR], [jar fastjar gjar], no) AC_PATH_PROG([ZIP], [zip], no) AC_PATH_PROG([UNZIP], [unzip], unzip) +AC_PATH_PROG([PERL], [perl], perl) # We need a jar that supports -@. This is a GNU extension. if test "$JAR" != no; then @@ -1625,6 +1626,183 @@ # We get this from the environment. AC_SUBST(GCJFLAGS) +AC_ARG_ENABLE([java-home], + [AS_HELP_STRING([--enable-java-home], + [create a standard JDK-style directory layout in the install tree [default=no]])], + [case "${enableval}" in + yes) JAVA_HOME_ENABLED=yes ;; + no) JAVA_HOME_ENABLED=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable java-home]) ;; + esac], + [JAVA_HOME_ENABLED=no] +) +AM_CONDITIONAL(CREATE_JAVA_HOME, test "x${JAVA_HOME_ENABLED}" == xyes) + +# Only do these checks if java-home above is enabled. +if test "x${JAVA_HOME_ENABLED}" == xyes +then + + if test "x${prefix}" = "xNONE" + then + sdk_prefix=/usr + else + sdk_prefix=$prefix + fi + + AC_ARG_WITH([gcc-suffix], + AS_HELP_STRING([--with-gcc-suffix], + [the GCC tool suffix (defaults to empty string)]), + [gcc_suffix=$withval], [gcc_suffix=""]) + AC_MSG_RESULT(GCC suffix: ${gcc_suffix}) + AC_SUBST(gcc_suffix) + + AC_ARG_WITH([arch-directory], + AS_HELP_STRING([--with-arch-directory], + [the arch directory under jre/lib (defaults to auto-detect)]), + [host_cpu=$withval], [host_cpu=""]) + + AC_ARG_WITH([os-directory], + AS_HELP_STRING([--with-os-directory], + [the os directory under include (defaults to auto-detect)]), + [host_os=$withval], [host_os=""]) + + AC_ARG_WITH([origin-name], + AS_HELP_STRING([--with-origin-name], + [the JPackage origin name of this package (default is gcj${gcc_suffix}]), + [origin_name=$withval], [origin_name=gcj${gcc_suffix}]) + AC_MSG_RESULT(JPackage origin name: ${origin_name}) + + AC_ARG_WITH([arch-suffix], + AS_HELP_STRING([--with-arch-suffix], + [the arch directory suffix (default is the empty string]), + [arch_suffix=$withval], [arch_suffix=""]) + AC_MSG_RESULT(arch suffix: ${arch_suffix}) + + AC_ARG_WITH([jvm-root-dir], + AS_HELP_STRING([--with-jvm-root-dir], + [where to install SDK (default is ${sdk_prefix}/lib/jvm)]), + [jvm_root_dir=$withval], [jvm_root_dir=${sdk_prefix}/lib/jvm]) + AC_MSG_RESULT(JVM root installation directory: ${jvm_root_dir}) + + AC_ARG_WITH([jvm-jar-dir], + AS_HELP_STRING([--with-jvm-jar-dir], + [where to install jars (default is ${sdk_prefix}/lib/jvm-exports)]), + [jvm_jar_dir=$withval], [jvm_jar_dir=${sdk_prefix}/lib/jvm-exports]) + AC_MSG_RESULT(JAR root installation directory: ${jvm_jar_dir}) + + JAVA_VERSION=1.5.0 + BUILD_VERSION=0 + AC_SUBST(JAVA_VERSION) + AC_SUBST(BUILD_VERSION) + AC_MSG_RESULT(Java version: ${JAVA_VERSION}) + + jre_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix}/jre + sdk_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix} + jre_lnk=jre-${JAVA_VERSION}-${origin_name} + sdk_lnk=java-${JAVA_VERSION}-${origin_name} + + JVM_ROOT_DIR=${jvm_root_dir} + AC_SUBST(JVM_ROOT_DIR) + AC_MSG_RESULT(JVM ROOT directory: ${JVM_ROOT_DIR}) + + JVM_JAR_ROOT_DIR=${jvm_jar_dir} + AC_SUBST(JVM_JAR_ROOT_DIR) + AC_MSG_RESULT(JVM JAR ROOT directory: ${JVM_JAR_ROOT_DIR}) + + JVM_JAR_DIR=${jvm_jar_dir}/${sdk_dir} + AC_SUBST(JVM_JAR_DIR) + AC_MSG_RESULT(JVM JAR directory: ${JVM_JAR_DIR}) + + JRE_DIR=${jre_dir} + AC_SUBST(JRE_DIR) + + SDK_DIR=${sdk_dir} + AC_SUBST(SDK_DIR) + + JRE_LNK=${jre_lnk} + AC_SUBST(JRE_LNK) + + SDK_LNK=${sdk_lnk} + AC_SUBST(SDK_LNK) + + JAVA_HOME_DIR=${jvm_root_dir}/${jre_dir} + AC_SUBST(JAVA_HOME_DIR) + AC_MSG_RESULT(JAVA_HOME directory: ${JAVA_HOME_DIR}) + + SDK_BIN_DIR=${jvm_root_dir}/${sdk_dir}/bin + AC_SUBST(SDK_BIN_DIR) + AC_MSG_RESULT(SDK tools directory: ${SDK_BIN_DIR}) + + SDK_LIB_DIR=${jvm_root_dir}/${sdk_dir}/lib + AC_SUBST(SDK_LIB_DIR) + AC_MSG_RESULT(SDK jar directory: ${SDK_LIB_DIR}) + + SDK_INCLUDE_DIR=${jvm_root_dir}/${sdk_dir}/include + AC_SUBST(SDK_INCLUDE_DIR) + AC_MSG_RESULT(SDK include directory: ${SDK_INCLUDE_DIR}) + + JRE_BIN_DIR=${jvm_root_dir}/${jre_dir}/bin + AC_SUBST(JRE_BIN_DIR) + AC_MSG_RESULT(JRE tools directory: ${JRE_BIN_DIR}) + + JRE_LIB_DIR=${jvm_root_dir}/${jre_dir}/lib + AC_SUBST(JRE_LIB_DIR) + AC_MSG_RESULT(JRE lib directory: ${JRE_LIB_DIR}) + + # Find gcj prefix using gcj found in PATH. + gcj_prefix=`which gcj${gcc_suffix} | sed "s%/bin/gcj${gcc_suffix}%%"` + + # Where do the gcj binaries live? + # For jhbuild based builds, they all live in a sibling of bin called + # gcj-bin. Check for gcj-bin first, and use bin otherwise. + GCJ_BIN_DIR=`if test -d ${gcj_prefix}/gcj-bin; then echo ${gcj_prefix}/gcj-bin; else echo ${gcj_prefix}/bin; fi` + AC_SUBST(GCJ_BIN_DIR) + AC_MSG_RESULT(GCJ tools directory: ${GCJ_BIN_DIR}) + + echo host is ${host} + if test "x${host_cpu}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_cpu=x86;; + i486-* | i586-* | i686-*) + host_cpu=i386;; + *) + host_cpu=${host_cpu};; + esac + fi + AC_MSG_RESULT(arch directory: ${host_cpu}) + CPU=${host_cpu} + AC_SUBST(CPU) + + if test "x${host_os}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_os=win32;; + *-linux*) + host_os=linux;; + *) + host_os=${host_os};; + esac + fi + echo os directory: ${host_os} + OS=${host_os} + AC_SUBST(OS) + + # make an expanded $libdir, for substituting into + # scripts (and other non-Makefile things). + LIBDIR=$libdir + if test "x${exec_prefix}" = "xNONE" + then + lib_exec_prefix=$sdk_prefix + else + lib_exec_prefix=$exec_prefix + fi + LIBDIR=`echo $libdir | sed "s:\\\${exec_prefix}:$lib_exec_prefix:g"` + AC_SUBST(LIBDIR) +fi + AC_CONFIG_FILES([ Makefile libgcj.pc ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-12 20:56 [patch] Create sdk style directory on install Joshua Sumali @ 2008-06-13 10:42 ` Andrew Haley 2008-06-13 12:42 ` Matthias Klose 1 sibling, 0 replies; 18+ messages in thread From: Andrew Haley @ 2008-06-13 10:42 UTC (permalink / raw) To: Joshua Sumali; +Cc: java-patches, Thomas Fitzsimmons Joshua Sumali wrote: > Attached is a patch to create a sdk style directory when > --enable-java-home is passed to configure. The patch is basically a > merge of java-gcj-compat into libgcj. > > To have this work, at the minimum, pass the following to ./configure: > --enable-java-home --with-arch-directory=(your arch). > --with-arch-directory specifies what to use for the > java-1.5.0-gcj-1.5.0.0/jre/lib/<arch> directory (e.g. I use i386). > > I've only included the diff to configure.ac and Makefile.am since > including the configure and Makefile.in makes the patch quite big, so be > sure to autoconf && automake before trying this patch. I can upload the > renerated files somewhere if it's absolutely needed, though. This is OK, thanks. Please don't post autogenerated files. Andrew. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-12 20:56 [patch] Create sdk style directory on install Joshua Sumali 2008-06-13 10:42 ` Andrew Haley @ 2008-06-13 12:42 ` Matthias Klose 2008-06-16 14:37 ` Joshua Sumali 1 sibling, 1 reply; 18+ messages in thread From: Matthias Klose @ 2008-06-13 12:42 UTC (permalink / raw) To: Joshua Sumali; +Cc: java-patches, Thomas Fitzsimmons Joshua Sumali schrieb: > Hi, > > Attached is a patch to create a sdk style directory when > --enable-java-home is passed to configure. The patch is basically a > merge of java-gcj-compat into libgcj. > > To have this work, at the minimum, pass the following to ./configure: > --enable-java-home --with-arch-directory=(your arch). > --with-arch-directory specifies what to use for the > java-1.5.0-gcj-1.5.0.0/jre/lib/<arch> directory (e.g. I use i386). > > I've only included the diff to configure.ac and Makefile.am since > including the configure and Makefile.in makes the patch quite big, so be > sure to autoconf && automake before trying this patch. I can upload the > renerated files somewhere if it's absolutely needed, though. - please use `transform' to install the binaries; just using gcc_suffix is inconsistant with current installation. Same for using GIJ_VERSION. - symlinks for man pages are not installed. intended? - + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns ... I think this is fedora specific to support jpackage? It doesn't hurt to have these symlinks. Maybe the same should be added for IcedTea? - Is the --with-arch-directory really needed? Shouldn't we just use the default. + jre_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix}/jre + sdk_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix} + jre_lnk=jre-${JAVA_VERSION}-${origin_name} + sdk_lnk=java-${JAVA_VERSION}-${origin_name} why using the long version at all? afaik no packaging allows installation of two such packages at the same time (with same jre_link and different jre_dir's). And it makes it difficult for people writing into the ext subdirectory because this changes across minor version upgrades. - The new configure options should be documented in gcc/doc/install.texi (and maybe something about the jpackage compatible (?) layout). - what is the rationale of --with-jvm-jar-dir ? Matthias ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-13 12:42 ` Matthias Klose @ 2008-06-16 14:37 ` Joshua Sumali 2008-06-18 20:39 ` Joshua Sumali 0 siblings, 1 reply; 18+ messages in thread From: Joshua Sumali @ 2008-06-16 14:37 UTC (permalink / raw) To: java-patches; +Cc: Thomas Fitzsimmons Matthias Klose wrote: > Joshua Sumali schrieb: > >> Hi, >> >> Attached is a patch to create a sdk style directory when >> --enable-java-home is passed to configure. The patch is basically a >> merge of java-gcj-compat into libgcj. >> >> To have this work, at the minimum, pass the following to ./configure: >> --enable-java-home --with-arch-directory=(your arch). >> --with-arch-directory specifies what to use for the >> java-1.5.0-gcj-1.5.0.0/jre/lib/<arch> directory (e.g. I use i386). >> >> I've only included the diff to configure.ac and Makefile.am since >> including the configure and Makefile.in makes the patch quite big, so be >> sure to autoconf && automake before trying this patch. I can upload the >> renerated files somewhere if it's absolutely needed, though. >> > > - please use `transform' to install the binaries; just using gcc_suffix is > inconsistant with current installation. Same for using GIJ_VERSION. > I will look into this. > - symlinks for man pages are not installed. intended? > I don't think this was part of java-gcj-compat, so it is not included in my patch. > - + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns ... > I think this is fedora specific to support jpackage? It doesn't hurt > to have these symlinks. Maybe the same should be added for IcedTea? > > - Is the --with-arch-directory really needed? Shouldn't we just use the > default. > Yes, I believe this is necessary for different archs when building an rpm. I can't remember off the top of my head, but for x86 the directory is jre/lib/i386 and x86_64 is perhaps x86_64 or amd64. Anyways, the java-1.5.0-gcj spec file shows configure with "--with-arch-directory=%{_arch}". > + > jre_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix}/jre > + > sdk_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix} > + jre_lnk=jre-${JAVA_VERSION}-${origin_name} > + sdk_lnk=java-${JAVA_VERSION}-${origin_name} > > why using the long version at all? I can't provide an exact answer, as I have just merged what was in java-gcj-compat into this patch. Perhaps fitzsim could provide insight, but I think for Fedora at least, we use the long version (sdk_dir) for jvm installs. > afaik no packaging allows installation of two > such packages at the same time (with same jre_link and different jre_dir's). What do you mean by "same jre_link and different jre_dir" exactly? > And > it makes it difficult for people writing into the ext subdirectory because this > changes across minor version upgrades > - The new configure options should be documented in gcc/doc/install.texi > (and maybe something about the jpackage compatible (?) layout). > Sure, I can do this. > - what is the rationale of --with-jvm-jar-dir ? > It's to provide some control as to where we're installing the jar symlinks. Default is /usr/lib/jvm-exports, but I'm not sure if this is consistent across all distros, so I think it's nice to have an option to change this location. > Matthias > ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-16 14:37 ` Joshua Sumali @ 2008-06-18 20:39 ` Joshua Sumali 2008-06-19 9:54 ` Andrew Haley 0 siblings, 1 reply; 18+ messages in thread From: Joshua Sumali @ 2008-06-18 20:39 UTC (permalink / raw) To: java-patches; +Cc: Thomas Fitzsimmons [-- Attachment #1: Type: text/plain, Size: 3972 bytes --] Joshua Sumali wrote: > Matthias Klose wrote: >> >> - please use `transform' to install the binaries; just using >> gcc_suffix is >> inconsistant with current installation. Same for using GIJ_VERSION. >> > I will look into this. >> - symlinks for man pages are not installed. intended? >> > I don't think this was part of java-gcj-compat, so it is not included > in my patch. >> - + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns ... >> I think this is fedora specific to support jpackage? It doesn't hurt >> to have these symlinks. Maybe the same should be added for IcedTea? >> >> - Is the --with-arch-directory really needed? Shouldn't we just use the >> default. >> > Yes, I believe this is necessary for different archs when building an > rpm. I can't remember off the top of my head, but for x86 the > directory is jre/lib/i386 and x86_64 is perhaps x86_64 or amd64. > Anyways, the java-1.5.0-gcj spec file shows configure with > "--with-arch-directory=%{_arch}". >> + >> jre_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix}/jre >> >> + >> sdk_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix} >> >> + jre_lnk=jre-${JAVA_VERSION}-${origin_name} >> + sdk_lnk=java-${JAVA_VERSION}-${origin_name} >> >> why using the long version at all? > I can't provide an exact answer, as I have just merged what was in > java-gcj-compat into this patch. Perhaps fitzsim could provide > insight, but I think for Fedora at least, we use the long version > (sdk_dir) for jvm installs. >> afaik no packaging allows installation of two >> such packages at the same time (with same jre_link and different >> jre_dir's). > What do you mean by "same jre_link and different jre_dir" exactly? >> And >> it makes it difficult for people writing into the ext subdirectory >> because this >> changes across minor version upgrades >> - The new configure options should be documented in gcc/doc/install.texi >> (and maybe something about the jpackage compatible (?) layout). >> > Sure, I can do this. >> - what is the rationale of --with-jvm-jar-dir ? >> > It's to provide some control as to where we're installing the jar > symlinks. Default is /usr/lib/jvm-exports, but I'm not sure if this is > consistent across all distros, so I think it's nice to have an option > to change this location. >> Matthias >> > Hi, Please see the two (updated) patches. The updated patch for the "Packager files" thread is now part of the sdk-home patch attached here, since I had to modify configure.ac to generate those packager files this time around. gcc-install-and-docs.patch creates man and info pages for aot-compile and rebuild-gcj-db, and also documents the new install options (--enable-java-home, --with-arch-directory, --with-python-dir) as requested by Matthias. gcc-libjava-sdk-home-update.patch is mostly the same as the first patch I posted here, except with these main changes: - aot-compile and rebuild-gcj-db are now installed in $bindir - if --with-python-dir is not specified (say, in a regular upstream build) , classfile.py and aotcompile.py are installed in $(prefix)/share/python. Otherwise, those Python modules will be installed in the path specified with --with-python-dir. I modified aot-compile -> aot-compile.in to append whichever path classfile.py and aotcompile.py was installed in, so that it can actually find these modules (it wouldn't look in $(prefix)/share/python by default). - the SDK symlinked binaries, as well as aot-compile and rebuild-gcj-db are now `transformed' as requested by Matthias. Outstanding issues: 1. @Matthias, I'm still not sure what you mean by "Same for using GIJ_VERSION". Also, the issue about "why using the long version at all?" 2. rebuild-gcj-db doesn't have a licence header on the top of the file... is this required? And if so, what's the right thing to do about it? Josh [-- Attachment #2: gcc-install-and-docs.patch --] [-- Type: text/x-patch, Size: 8419 bytes --] Index: gcc/ChangeLog =================================================================== --- gcc/ChangeLog (revision 136891) +++ gcc/ChangeLog (working copy) @@ -1,3 +1,9 @@ +2008-06-18 Joshua Sumali <jsumali@redhat.com> + + * doc/install.texi (--enable-java-home): Document. + (--with-arch-directory): Likewise. + (--with-python-dir): Likewise. + 2008-06-16 Jan Hubicka <jh@suse.cz> * tree-outof-ssa.c (pass_out_of_ssa): Do not depend on PROP_alias. Index: gcc/doc/install.texi =================================================================== --- gcc/doc/install.texi (revision 136892) +++ gcc/doc/install.texi (working copy) @@ -1602,6 +1602,20 @@ @item --with-win32-nlsapi=ansi, unicows or unicode Indicates how MinGW @samp{libgcj} translates between UNICODE characters and the Win32 API@. + +@item --enable-java-home +If enabled, this creates a JPackage compatible SDK environment during install. +Note that if --enable-java-home is used, --with-arch-directory=ARCH must also +be specified. + +@item --with-arch-directory=ARCH +Specifies the name to use for the @file{jre/lib/ARCH} directory in the SDK +environment created when --enable-java-home is passed. Typical names for this +directory include i386, amd64, ia64, etc. + +@item --with-python-dir=DIR +Specifies where to install the Python modules used for aot-compile. + @table @code @item ansi Use the single-byte @code{char} and the Win32 A functions natively, Index: gcc/java/ChangeLog =================================================================== --- gcc/java/ChangeLog (revision 136890) +++ gcc/java/ChangeLog (working copy) @@ -1,3 +1,14 @@ +2008-06-18 Joshua Sumali <jsumali@redhat.com> + + * Make-lang.in (JAVA_MANFILES): Add doc/aot-compile.1 and + doc/rebuild-gcj-db.1 + (java.uninstall): Likewise. + (java.maintainer-clean): Likewise. + (aot-compile.pod): New rule. + (rebuild-gcj-db.pod): New rule. + (java.install-man): Install doc/aot-compile.1 and doc/rebuild-gcj-db.1 + * gcj.texi: Add new sections for aot-compile and rebuild-gcj-db. + 2008-06-15 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> * gcj.texi: Expand TABs, remove whitespace from blank lines. Index: gcc/java/gcj.texi =================================================================== --- gcc/java/gcj.texi (revision 136890) +++ gcc/java/gcj.texi (working copy) @@ -72,6 +72,11 @@ Generate stubs for Remote Method Invocation. * gc-analyze: (gcj)Invoking gc-analyze. Analyze Garbage Collector (GC) memory dumps. +* aot-compile: (gcj)Invoking aot-compile. + Compile bytecode to native and generate databases. +* rebuild-gcj-db: (gcj)Invoking rebuild-gcj-db. + Merge the per-solib databases made by aot-compile + into one system-wide database. @end direntry @end format @@ -115,6 +120,9 @@ * Invoking jv-convert:: Converting from one encoding to another * Invoking grmic:: Generate stubs for Remote Method Invocation. * Invoking gc-analyze:: Analyze Garbage Collector (GC) memory dumps. +* Invoking aot-compile:: Compile bytecode to native and generate databases. +* Invoking rebuild-gcj-db:: Merge the per-solib databases made by aot-compile + into one system-wide database. * About CNI:: Description of the Compiled Native Interface * System properties:: Modifying runtime behavior of the libgcj library * Resources:: Where to look for more information @@ -921,7 +929,7 @@ [@option{-v}] [@option{-m}] [@option{--version}] [@option{--help}] @c man end -@c man begin SEEALSO gij +@c man begin SEEALSO gcj-dbtool gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), and the Info entries for @file{gcj} and @file{gcc}. @c man end @@ -1219,6 +1227,87 @@ @c man end +@node Invoking aot-compile +@chapter Invoking aot-compile + +@c man title aot-compile Compile bytecode to native and generate databases + +@ignore + +@c man begin SYNOPSIS aot-compile +aot-compile [@option{OPTION}] @dots{} @var{SRCDIR} @var{DSTDIR} + +aot-compile [@option{-M, --make}=@var{PATH}] [@option{-C, --gcj}=@var{PATH}] + [@option{-D, --dbtool}=@var{PATH}] [@option{-m, --makeflags}=@var{FLAGS}] + [@option{-c, --gcjflags}=@var{FLAGS}] [@option{-l, --ldflags}=@var{FLAGS}] + [@option{-e, --exclude}=@var{PATH}] +@c man end + +@c man begin SEEALSO aot-compile +gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), +and the Info entries for @file{gcj} and @file{gcc}. +@c man end + +@end ignore + +@c man begin DESCRIPTION aot-compile +@code{aot-compile} is a script that searches a directory for Java bytecode +(as class files, or in jars) and uses @code{gcj} to compile it to native +code and generate the databases from it. +@c man end + +@c man begin OPTIONS aot-compile +@table @gcctabopt +@item -M, --make=@var{PATH} +Specify the path to the @code{make} executable to use. + +@item -C, --gcj=@var{PATH} +Specify the path to the @code{gcj} executable to use. + +@item -D, --dbtool=@var{PATH} +Specify the path to the @code{gcj-dbtool} executable to use. + +@item -m, --makeflags=@var{FLAGS} +Specify flags to pass to @code{make} during the build. + +@item -c, --gcjflags=@var{FLAGS} +Specify flags to pass to @code{gcj} during compilation, in addition to +'-fPIC -findirect-dispatch -fjni'. + +@item -l, --ldflags=@var{FLAGS} +Specify flags to pass to @code{gcj} during linking, in addition to +'-Wl,-Bsymbolic'. + +@item -e, --exclude=@var{PATH} +Do not compile @var{PATH}. + +@end table + +@c man end + +@node Invoking rebuild-gcj-db +@chapter Invoking rebuild-gcj-db + +@c man title rebuild-gcj-db Merge the per-solib databases made by aot-compile into one system-wide database. +@ignore + +@c man begin SYNOPSIS rebuild-gcj-db +rebuild-gcj-db +@c man end + +@c man begin SEEALSO rebuild-gcj-db +gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), +and the Info entries for @file{gcj} and @file{gcc}. +@c man end + +@end ignore + +@c man begin DESCRIPTION rebuild-gcj-db +@code{rebuild-gcj-db} is a script that merges the per-solib databases made by +@code{aot-compile} into one system-wide database so @code{gij} can find the +solibs. +@c man end + @node About CNI @chapter About CNI Index: gcc/java/Make-lang.in =================================================================== --- gcc/java/Make-lang.in (revision 136890) +++ gcc/java/Make-lang.in (working copy) @@ -143,8 +143,9 @@ java.html: $(build_htmldir)/java/index.html JAVA_MANFILES = doc/gcj.1 doc/jcf-dump.1 doc/gij.1 \ - doc/jv-convert.1 doc/grmic.1\ - doc/gcj-dbtool.1 doc/gc-analyze.1 + doc/jv-convert.1 doc/grmic.1 \ + doc/gcj-dbtool.1 doc/gc-analyze.1 doc/aot-compile.1 \ + doc/rebuild-gcj-db.1 java.man: $(JAVA_MANFILES) @@ -189,6 +190,8 @@ -rm -rf $(DESTDIR)$(man1dir)/gij$(man1ext) -rm -rf $(DESTDIR)$(man1dir)/jv-convert$(man1ext) -rm -rf $(DESTDIR)$(man1dir)/gcj-dbtool$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/aot-compile$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/rebuild-gcj-db$(man1ext) java.install-info: $(DESTDIR)$(infodir)/gcj.info @@ -223,6 +226,8 @@ -rm -f $(docobjdir)/grmic.1 -rm -f $(docobjdir)/gcj-dbtool.1 -rm -f $(docobjdir)/gc-analyze.1 + -rm -f $(docobjdir)/aot-compile.1 + -rm -f $(docobjdir)/rebuild-gcj-db.1 #\f # Stage hooks: # The main makefile has already created stage?/java. @@ -353,15 +358,21 @@ -$(TEXI2POD) -D gcj-dbtool < $< > $@ gc-analyze.pod: java/gcj.texi -$(TEXI2POD) -D gc-analyze < $< > $@ +aot-compile.pod: java/gcj.texi + -$(TEXI2POD) -D aot-compile < $< > $@ +rebuild-gcj-db.pod: java/gcj.texi + -$(TEXI2POD) -D rebuild-gcj-db < $< > $@ # Install the man pages. java.install-man: installdirs \ $(DESTDIR)$(man1dir)/$(JAVA_INSTALL_NAME)$(man1ext) \ $(JAVA_TARGET_INDEPENDENT_BIN_TOOLS:%=doc/%.1) \ doc/gij.1 doc/jv-convert.1 doc/grmic.1 \ - doc/gcj-dbtool.1 doc/gc-analyze.1 + doc/gcj-dbtool.1 doc/gc-analyze.1 \ + doc/aot-compile.1 doc/rebuild-gcj-db.1 for tool in $(JAVA_TARGET_INDEPENDENT_BIN_TOOLS) \ - gij jv-convert grmic gcj-dbtool gc-analyze ; do \ + gij jv-convert grmic gcj-dbtool gc-analyze aot-compile \ + rebuild-gcj-db; do \ tool_transformed_name=`echo $$tool|sed '$(program_transform_name)'`; \ man_name=$(DESTDIR)$(man1dir)/$${tool_transformed_name}$(man1ext); \ rm -f $$man_name ; \ [-- Attachment #3: gcc-libjava-sdk-home-update.patch --] [-- Type: text/x-patch, Size: 46921 bytes --] Index: libjava/contrib/rebuild-gcj-db.in =================================================================== --- libjava/contrib/rebuild-gcj-db.in (revision 0) +++ libjava/contrib/rebuild-gcj-db.in (revision 0) @@ -0,0 +1,16 @@ +#!/bin/bash +# rebuild-gcj-db + +# Rebuild all the standard databases. +for base in /usr/lib*; do + dbLocation=`@prefix@/bin/gcj-dbtool@gcc_suffix@ -p $base` + libdir=$base/gcj + if ! test -d $libdir; then + # No shared libraries here. + continue + fi + dirname $dbLocation | xargs mkdir -p + @prefix@/bin/gcj-dbtool@gcc_suffix@ -n $dbLocation 64 + find $libdir -follow -name '*.db' -print0 | \ + xargs -0 @prefix@/bin/gcj-dbtool@gcc_suffix@ -m $dbLocation $dbLocation +done Index: libjava/contrib/aotcompile.py.in =================================================================== --- libjava/contrib/aotcompile.py.in (revision 0) +++ libjava/contrib/aotcompile.py.in (revision 0) @@ -0,0 +1,412 @@ +# -*- python -*- + +## Copyright (C) 2005, 2006, 2008 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import classfile +import copy +import md5 +import operator +import os +import sys +import cStringIO as StringIO +import zipfile + +PATHS = {"make": "@MAKE@", + "gcj": "@prefix@/bin/gcj@gcc_suffix@", + "dbtool": "@prefix@/bin/gcj-dbtool@gcc_suffix@"} + +MAKEFLAGS = [] +GCJFLAGS = ["-fPIC", "-findirect-dispatch", "-fjni"] +LDFLAGS = ["-Wl,-Bsymbolic"] + +MAX_CLASSES_PER_JAR = 1024 +MAX_BYTES_PER_JAR = 1048576 + +MAKEFILE = "Makefile" + +MAKEFILE_HEADER = '''\ +GCJ = %(gcj)s +DBTOOL = %(dbtool)s +GCJFLAGS = %(gcjflags)s +LDFLAGS = %(ldflags)s + +%%.o: %%.jar + $(GCJ) -c $(GCJFLAGS) $< -o $@ + +TARGETS = \\ +%(targets)s + +all: $(TARGETS)''' + +MAKEFILE_JOB = ''' +%(base)s_SOURCES = \\ +%(jars)s + +%(base)s_OBJECTS = \\ +$(%(base)s_SOURCES:.jar=.o) + +%(dso)s: $(%(base)s_OBJECTS) + $(GCJ) -shared $(GCJFLAGS) $(LDFLAGS) $^ -o $@ + +%(db)s: $(%(base)s_SOURCES) + $(DBTOOL) -n $@ 64 + for jar in $^; do \\ + $(DBTOOL) -f $@ $$jar \\ + %(libdir)s/%(dso)s; \\ + done''' + +ZIPMAGIC, CLASSMAGIC = "PK\x03\x04", "\xca\xfe\xba\xbe" + +class Error(Exception): + pass + +class Compiler: + def __init__(self, srcdir, libdir, prefix = None): + self.srcdir = os.path.abspath(srcdir) + self.libdir = os.path.abspath(libdir) + if prefix is None: + self.dstdir = self.libdir + else: + self.dstdir = os.path.join(prefix, self.libdir.lstrip(os.sep)) + + # Calling code may modify these parameters + self.gcjflags = copy.copy(GCJFLAGS) + self.ldflags = copy.copy(LDFLAGS) + self.makeflags = copy.copy(MAKEFLAGS) + self.exclusions = [] + + def compile(self): + """Search srcdir for classes and jarfiles, then generate + solibs and mappings databases for them all in libdir.""" + if not os.path.isdir(self.dstdir): + os.makedirs(self.dstdir) + oldcwd = os.getcwd() + os.chdir(self.dstdir) + try: + jobs = self.getJobList() + if not jobs: + raise Error, "nothing to do" + self.writeMakefile(MAKEFILE, jobs) + for job in jobs: + job.writeJars() + system([PATHS["make"]] + self.makeflags) + for job in jobs: + job.clean() + os.unlink(MAKEFILE) + finally: + os.chdir(oldcwd) + + def getJobList(self): + """Return all jarfiles and class collections in srcdir.""" + jobs = weed_jobs(find_jobs(self.srcdir, self.exclusions)) + set_basenames(jobs) + return jobs + + def writeMakefile(self, path, jobs): + """Generate a makefile to build the solibs and mappings + databases for the specified list of jobs.""" + fp = open(path, "w") + print >>fp, MAKEFILE_HEADER % { + "gcj": PATHS["gcj"], + "dbtool": PATHS["dbtool"], + "gcjflags": " ".join(self.gcjflags), + "ldflags": " ".join(self.ldflags), + "targets": " \\\n".join(reduce(operator.add, [ + (job.dsoName(), job.dbName()) for job in jobs]))} + for job in jobs: + values = job.ruleArguments() + values["libdir"] = self.libdir + print >>fp, MAKEFILE_JOB % values + fp.close() + +def find_jobs(dir, exclusions = ()): + """Scan a directory and find things to compile: jarfiles (zips, + wars, ears, rars, etc: we go by magic rather than file extension) + and directories of classes.""" + def visit((classes, zips), dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + magic = open(path, "r").read(4) + if magic == ZIPMAGIC: + zips.append(path) + elif magic == CLASSMAGIC: + classes.append(path) + classes, paths = [], [] + os.path.walk(dir, visit, (classes, paths)) + # Convert the list of classes into a list of directories + while classes: + # XXX this requires the class to be correctly located in its heirachy. + path = classes[0][:-len(os.sep + classname(classes[0]) + ".class")] + paths.append(path) + classes = [cls for cls in classes if not cls.startswith(path)] + # Handle exclusions. We're really strict about them because the + # option is temporary in aot-compile-rpm and dead options left in + # specfiles will hinder its removal. + for path in exclusions: + if path in paths: + paths.remove(path) + else: + raise Error, "%s: path does not exist or is not a job" % path + # Build the list of jobs + jobs = [] + paths.sort() + for path in paths: + if os.path.isfile(path): + job = JarJob(path) + else: + job = DirJob(path) + if len(job.classes): + jobs.append(job) + return jobs + +class Job: + """A collection of classes that will be compiled as a unit.""" + + def __init__(self, path): + self.path, self.classes, self.blocks = path, {}, None + + def addClass(self, bytes): + """Subclasses call this from their __init__ method for + every class they find.""" + self.classes[md5.new(bytes).digest()] = bytes + + def __makeBlocks(self): + """Split self.classes into chunks that can be compiled to + native code by gcj. In the majority of cases this is not + necessary -- the job will have come from a jarfile which will + be equivalent to the one we generate -- but this only happens + _if_ the job was a jarfile and _if_ the jarfile isn't too big + and _if_ the jarfile has the correct extension and _if_ all + classes are correctly named and _if_ the jarfile has no + embedded jarfiles. Fitting a special case around all these + conditions is tricky to say the least. + + Note that this could be called at the end of each subclass's + __init__ method. The reason this is not done is because we + need to parse every class file. This is slow, and unnecessary + if the job is subsetted.""" + names = {} + for hash, bytes in self.classes.items(): + name = classname(bytes) + if not names.has_key(name): + names[name] = [] + names[name].append(hash) + names = names.items() + # We have to sort somehow, or the jars we generate + # We sort by name in a simplistic attempt to keep related + # classes together so inter-class optimisation can happen. + names.sort() + self.blocks, bytes = [[]], 0 + for name, hashes in names: + for hash in hashes: + if len(self.blocks[-1]) >= MAX_CLASSES_PER_JAR \ + or bytes >= MAX_BYTES_PER_JAR: + self.blocks.append([]) + bytes = 0 + self.blocks[-1].append((name, hash)) + bytes += len(self.classes[hash]) + + # From Archit Shah: + # The implementation and the documentation don't seem to match. + # + # [a, b].isSubsetOf([a]) => True + # + # Identical copies of all classes this collection do not exist + # in the other. I think the method should be named isSupersetOf + # and the documentation should swap uses of "this" and "other" + # + # XXX think about this when I've had more sleep... + def isSubsetOf(self, other): + """Returns True if identical copies of all classes in this + collection exist in the other.""" + for item in other.classes.keys(): + if not self.classes.has_key(item): + return False + return True + + def __targetName(self, ext): + return self.basename + ext + + def tempJarName(self, num): + return self.__targetName(".%d.jar" % (num + 1)) + + def tempObjName(self, num): + return self.__targetName(".%d.o" % (num + 1)) + + def dsoName(self): + """Return the filename of the shared library that will be + built from this job.""" + return self.__targetName(".so") + + def dbName(self): + """Return the filename of the mapping database that will be + built from this job.""" + return self.__targetName(".db") + + def ruleArguments(self): + """Return a dictionary of values that when substituted + into MAKEFILE_JOB will create the rules required to build + the shared library and mapping database for this job.""" + if self.blocks is None: + self.__makeBlocks() + return { + "base": "".join( + [c.isalnum() and c or "_" for c in self.dsoName()]), + "jars": " \\\n".join( + [self.tempJarName(i) for i in xrange(len(self.blocks))]), + "dso": self.dsoName(), + "db": self.dbName()} + + def writeJars(self): + """Generate jarfiles that can be native compiled by gcj.""" + if self.blocks is None: + self.__makeBlocks() + for block, i in zip(self.blocks, xrange(len(self.blocks))): + jar = zipfile.ZipFile(self.tempJarName(i), "w", zipfile.ZIP_STORED) + for name, hash in block: + jar.writestr( + zipfile.ZipInfo("%s.class" % name), self.classes[hash]) + jar.close() + + def clean(self): + """Delete all temporary files created during this job's build.""" + if self.blocks is None: + self.__makeBlocks() + for i in xrange(len(self.blocks)): + os.unlink(self.tempJarName(i)) + os.unlink(self.tempObjName(i)) + +class JarJob(Job): + """A Job whose origin was a jarfile.""" + + def __init__(self, path): + Job.__init__(self, path) + self._walk(zipfile.ZipFile(path, "r")) + + def _walk(self, zf): + for name in zf.namelist(): + bytes = zf.read(name) + if bytes.startswith(ZIPMAGIC): + self._walk(zipfile.ZipFile(StringIO.StringIO(bytes))) + elif bytes.startswith(CLASSMAGIC): + self.addClass(bytes) + +class DirJob(Job): + """A Job whose origin was a directory of classfiles.""" + + def __init__(self, path): + Job.__init__(self, path) + os.path.walk(path, DirJob._visit, self) + + def _visit(self, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + fp = open(path, "r") + magic = fp.read(4) + if magic == CLASSMAGIC: + self.addClass(magic + fp.read()) + +def weed_jobs(jobs): + """Remove any jarfiles that are completely contained within + another. This is more common than you'd think, and we only + need one nativified copy of each class after all.""" + jobs = copy.copy(jobs) + while True: + for job1 in jobs: + for job2 in jobs: + if job1 is job2: + continue + if job1.isSubsetOf(job2): + msg = "subsetted %s" % job2.path + if job2.isSubsetOf(job1): + if (isinstance(job1, DirJob) and + isinstance(job2, JarJob)): + # In the braindead case where a package + # contains an expanded copy of a jarfile + # the jarfile takes precedence. + continue + msg += " (identical)" + warn(msg) + jobs.remove(job2) + break + else: + continue + break + else: + break + continue + return jobs + +def set_basenames(jobs): + """Ensure that each jarfile has a different basename.""" + names = {} + for job in jobs: + name = os.path.basename(job.path) + if not names.has_key(name): + names[name] = [] + names[name].append(job) + for name, set in names.items(): + if len(set) == 1: + set[0].basename = name + continue + # prefix the jar filenames to make them unique + # XXX will not work in most cases -- needs generalising + set = [(job.path.split(os.sep), job) for job in set] + minlen = min([len(bits) for bits, job in set]) + set = [(bits[-minlen:], job) for bits, job in set] + bits = apply(zip, [bits for bits, job in set]) + while True: + row = bits[-2] + for bit in row[1:]: + if bit != row[0]: + break + else: + del bits[-2] + continue + break + set = zip( + ["_".join(name) for name in apply(zip, bits[-2:])], + [job for bits, job in set]) + for name, job in set: + warn("building %s as %s" % (job.path, name)) + job.basename = name + # XXX keep this check until we're properly general + names = {} + for job in jobs: + name = job.basename + if names.has_key(name): + raise Error, "%s: duplicate jobname" % name + names[name] = 1 + +def system(command): + """Execute a command.""" + status = os.spawnv(os.P_WAIT, command[0], command) + if status > 0: + raise Error, "%s exited with code %d" % (command[0], status) + elif status < 0: + raise Error, "%s killed by signal %d" % (command[0], -status) + +def warn(msg): + """Print a warning message.""" + print >>sys.stderr, "%s: warning: %s" % ( + os.path.basename(sys.argv[0]), msg) + +def classname(bytes): + """Extract the class name from the bytes of a class file.""" + klass = classfile.Class(bytes) + return klass.constants[klass.constants[klass.name][1]][1] Index: libjava/contrib/aot-compile-rpm.in =================================================================== --- libjava/contrib/aot-compile-rpm.in (revision 0) +++ libjava/contrib/aot-compile-rpm.in (revision 0) @@ -0,0 +1,97 @@ +#!/usr/bin/env python + +## Copyright (C) 2005, 2006, 2007 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir@") +import aotcompile +import os + +def libdir(): + cmd = "%s -p" % aotcompile.PATHS["dbtool"] + dir = os.path.abspath(os.popen(cmd, "r").readline().rstrip()) + dir, base = os.path.split(dir) + if base != "classmap.db": + raise aotcompile.Error, "%s: unexpected output" % cmd + dir, base = os.path.split(dir) + if not base.startswith("gcj-"): + raise aotcompile.Error, "%s: unexpected output" % cmd + return dir + +def writeSourceList(srcdir, dstpath): + def visit(fp, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.isfile(path): + print >>fp, path + dstdir = os.path.dirname(dstpath) + if not os.path.isdir(dstdir): + os.makedirs(dstdir) + os.path.walk(srcdir, visit, open(dstpath, "w")) + +def copy(srcdir, dstdir, suffix): + srcdir = os.path.join(srcdir, suffix.lstrip(os.sep)) + dstdir = os.path.join(dstdir, suffix.lstrip(os.sep)) + os.makedirs(os.path.dirname(dstdir)) + aotcompile.system(("/bin/cp", "-a", srcdir, dstdir)) + +try: + name = os.environ.get("RPM_PACKAGE_NAME") + if name is None: + raise aotcompile.Error, "not for use outside rpm specfiles" + arch = os.environ.get("RPM_ARCH") + if arch == "noarch": + raise aotcompile.Error, "cannot be used on noarch packages" + srcdir = os.environ.get("RPM_BUILD_ROOT") + if srcdir in (None, "/"): + raise aotcompile.Error, "bad $RPM_BUILD_ROOT" + tmpdir = os.path.join(os.getcwd(), "aot-compile-rpm") + if os.path.exists(tmpdir): + raise aotcompile.Error, "%s exists" % tmpdir + dstdir = os.path.join(libdir(), "gcj", name) + + compiler = aotcompile.Compiler(srcdir, dstdir, tmpdir) + compiler.gcjflags[0:0] = os.environ.get("RPM_OPT_FLAGS", "").split() + + # XXX: This script should not accept options, because having + # them it cannot be integrated into rpm. But, gcj cannot + # build each and every jarfile yet, so we must be able to + # exclude until it can. + # XXX --exclude is also used in the jonas rpm to stop + # everything being made a subset of the mammoth client + # jarfile. Should adjust the subset checker's bias to + # favour many small jarfiles over one big one. + try: + options, exclusions = sys.argv[1:], [] + while options: + if options.pop(0) != "--exclude": + raise ValueError + compiler.exclusions.append( + os.path.join(srcdir, options.pop(0).lstrip(os.sep))) + except: + print >>sys.stderr, "usage: %s [--exclude PATH]..." % ( + os.path.basename(sys.argv[0])) + sys.exit(1) + + sourcelist = os.path.join(tmpdir, "sources.list") + writeSourceList(os.getcwd(), sourcelist) + compiler.gcjflags.append("-fsource-filename=" + sourcelist) + + compiler.compile() + copy(tmpdir, srcdir, dstdir) + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/contrib/classfile.py =================================================================== --- libjava/contrib/classfile.py (revision 0) +++ libjava/contrib/classfile.py (revision 0) @@ -0,0 +1,221 @@ +## Copyright (C) 2004, 2005 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +"""Read Java(TM) class files.""" + +import cStringIO as StringIO +import struct + +class Class: + def __init__(self, arg): + if hasattr(arg, "read"): + self.fp = arg + elif type(arg) == type(""): + if arg.startswith("\xca\xfe\xba\xbe"): + self.fp = StringIO.StringIO(arg) + else: + self.fp = open(arg, "r") + else: + raise TypeError, type(arg) + + magic = self._read_int() + assert magic == 0xcafebabeL + minor, major = self._read(">HH") + self.version = (major, minor) + + self.pool_integrity_checks = None + try: + assert False + except AssertionError: + self.pool_integrity_checks = [] + + self._read_constants_pool() + + self.access_flags = self._read_short() + self.name = self._read_reference_Class() + self.super = self._read_reference_Class() + + self.interfaces = self._read_interfaces() + self.fields = self._read_fieldsormethods() + self.methods = self._read_fieldsormethods() + self.attributes = self._read_attributes() + + if self.pool_integrity_checks is not None: + for index, tag in self.pool_integrity_checks: + assert self.constants[index][0] == tag + + del self.fp, self.pool_integrity_checks + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) + if not attr.startswith("_") and attr != "Member"] + attrs.sort() + for attr in attrs: + result.append("%-13s %s" % ( + attr + ":", attr == "constants" and + "<ELIDED>" or repr(getattr(self, attr)))) + return "\n".join(result) + + def _read_constants_pool(self): + self.constants = {} + skip = False + for i in xrange(1, self._read_short()): + if skip: + skip = False + continue + tag = { + 1: "Utf8", 3: "Integer", 4: "Float", 5: "Long", + 6: "Double", 7: "Class", 8: "String", 9: "Fieldref", + 10: "Methodref", 11: "InterfaceMethodref", + 12: "NameAndType"}[self._read_byte()] + skip = tag in ("Long", "Double") # crack crack crack! + self.constants[i] = (tag, getattr(self, "_read_constant_" + tag)()) + + def _read_interfaces(self): + result = [] + for i in xrange(self._read_short()): + result.append(self._read_reference_Class()) + return result + + def _read_fieldsormethods(self): + result = [] + for i in xrange(self._read_short()): + result.append(self.Member(self)) + return result + + class Member: + def __init__(self, source): + self.access_flags = source._read_short() + self.name = source._read_reference_Utf8() + self.descriptor = source._read_reference_Utf8() + self.attributes = source._read_attributes() + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) if not attr.startswith("_")] + attrs.sort() + for attr in attrs: + value = getattr(self, attr) + if attr == "attributes" and value.has_key("Code"): + value = value.copy() + value.update({"Code": "<ELIDED>"}) + result.append("%-13s %s" % ( + attr + ":", repr(value).replace( + "'Code': '<ELIDED>'", "'Code': <ELIDED>"))) + return ("\n%s" % (15 * " ")).join(result) + + def _read_attributes(self): + result = {} + for i in xrange(self._read_short()): + name = self._read_reference_Utf8() + data = self.fp.read(self._read_int()) + assert not result.has_key(name) + result[name] = data + return result + + # Constants pool reference reader convenience functions + + def _read_reference_Utf8(self): + return self._read_references("Utf8")[0] + + def _read_reference_Class(self): + return self._read_references("Class")[0] + + def _read_reference_Class_NameAndType(self): + return self._read_references("Class", "NameAndType") + + def _read_references(self, *args): + result = [] + for arg in args: + index = self._read_short() + if self.pool_integrity_checks is not None: + self.pool_integrity_checks.append((index, arg)) + result.append(index) + return result + + # Constants pool constant reader functions + + def _read_constant_Utf8(self): + constant = self.fp.read(self._read_short()) + try: + constant = constant.decode("utf-8") + except UnicodeError: + constant = _bork_utf8_decode(constant) + try: + constant = constant.encode("us-ascii") + except UnicodeError: + pass + return constant + + def _read_constant_Integer(self): + return self._read_int() + + def _read_constant_Float(self): + return self._read(">f")[0] + + def _read_constant_Long(self): + return self._read(">q")[0] + + def _read_constant_Double(self): + return self._read(">d")[0] + + _read_constant_Class = _read_reference_Utf8 + _read_constant_String = _read_reference_Utf8 + _read_constant_Fieldref = _read_reference_Class_NameAndType + _read_constant_Methodref = _read_reference_Class_NameAndType + _read_constant_InterfaceMethodref = _read_reference_Class_NameAndType + + def _read_constant_NameAndType(self): + return self._read_reference_Utf8(), self._read_reference_Utf8() + + # Generic reader functions + + def _read_int(self): + # XXX how else to read 32 bits on a 64-bit box? + h, l = map(long, self._read(">HH")) + return (h << 16) + l + + def _read_short(self): + return self._read(">H")[0] + + def _read_byte(self): + return self._read("B")[0] + + def _read(self, fmt): + return struct.unpack(fmt, self.fp.read(struct.calcsize(fmt))) + +def _bork_utf8_decode(data): + # more crack! + bytes, unicode = map(ord, data), "" + while bytes: + b1 = bytes.pop(0) + if b1 & 0x80: + assert b1 & 0x40 + b2 = bytes.pop(0) + assert b2 & 0xC0 == 0x80 + if b1 & 0x20: + assert not b1 & 0x10 + b3 = bytes.pop(0) + assert b3 & 0xC0 == 0x80 + unicode += unichr( + ((b1 & 0x0f) << 12) + ((b2 & 0x3f) << 6) + (b3 & 0x3f)) + else: + unicode += unichr(((b1 & 0x1f) << 6) + (b2 & 0x3f)) + else: + unicode += unichr(b1) + return unicode + +if __name__ == "__main__": + print Class("/usr/share/katana/build/ListDependentClasses.class") + Index: libjava/contrib/aot-compile.in =================================================================== --- libjava/contrib/aot-compile.in (revision 0) +++ libjava/contrib/aot-compile.in (revision 0) @@ -0,0 +1,88 @@ +#!/usr/bin/env python + +## Copyright (C) 2006 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir@") +import aotcompile +import getopt +import os + +usage = """\ +Usage: %s [OPTION...] SRCDIR DSTDIR +AOT-compile all Java bytecode in SRCDIR into DSTDIR. + +Options: + -M, --make=PATH make executable to use (%s) + -C, --gcj=PATH gcj executable to use (%s) + -D, --dbtool=PATH gcj-dbtool executable to use (%s) + -m, --makeflags=FLAGS flags to pass to make during build + -c, --gcjflags=FLAGS flags to pass to gcj during compilation + in addition to %s + -l, --ldflags=FLAGS flags to pass to gcj during linking + in addition to %s + -e, --exclude=PATH do not compile PATH + +Extra flags may also be passed using the AOT_MAKEFLAGS, AOT_GCJFLAGS +and AOT_LDFLAGS environment variables.""" % ( + os.path.basename(sys.argv[0]), + aotcompile.PATHS["make"], + aotcompile.PATHS["gcj"], + aotcompile.PATHS["dbtool"], + repr(" ".join(aotcompile.GCJFLAGS)), + repr(" ".join(aotcompile.LDFLAGS))) + +try: + if os.environ.has_key("RPM_PACKAGE_NAME"): + raise aotcompile.Error, "not for use within rpm specfiles" + + try: + opts, args = getopt.getopt( + sys.argv[1:], + "M:C:D:m:c:l:e:", + ["make=", "gcj=", "dbtool=", + "makeflags=" "gcjflags=", "ldflags=", + "exclude="]) + srcdir, dstdir = args + except: + print >>sys.stderr, usage + sys.exit(1) + + compiler = aotcompile.Compiler(srcdir, dstdir) + for o, a in opts: + if o in ("-M", "--make"): + aotcompile.PATHS["make"] = a + if o in ("-C", "--gcj"): + aotcompile.PATHS["gcj"] = a + if o in ("-D", "--dbtool"): + aotcompile.PATHS["dbtool"] = a + if o in ("-m", "--makeflags"): + compiler.makeflags[0:0] = a.split() + if o in ("-c", "--gcjflags"): + compiler.gcjflags[0:0] = a.split() + if o in ("-l", "--ldflags"): + compiler.ldflags[0:0] = a.split() + if o in ("-e", "--exclude"): + compiler.exclusions.append(a) + + compiler.makeflags[0:0] = os.environ.get("AOT_MAKEFLAGS", "").split() + compiler.gcjflags[0:0] = os.environ.get("AOT_GCJFLAGS", "").split() + compiler.ldflags[0:0] = os.environ.get("AOT_LDFLAGS", "").split() + + compiler.compile() + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/ChangeLog =================================================================== --- libjava/ChangeLog (revision 136894) +++ libjava/ChangeLog (working copy) @@ -1,3 +1,29 @@ +2008-06-18 Joshua Sumali <jsumali@redhat.com> + + * configure.ac (java-home): new AC_ARG_ENABLE. + (CREATE_JAVA_HOME): new AM_CONDITIONAL. + (gcc-suffix): new AC_ARG_WITH. + (arch-directory): Likewise. + (os-directory): Likewise. + (origin-name): Likewise. + (arch-suffix): Likewise. + (jvm-root-dir): Likewise. + (jvm-jar-dir): Likewise. + (python-dir): Likewise. + (AC_CONFIG_FILES): Add contrib/aotcompile.py, contrib/aot-compile, + contrib/aot-compile-rpm, contrib/rebuild-gcj-db. + * Makefile.am (install-data-local): Install Python modules for + aot-compile. Also install an sdk style directory if --enable-java-home + is passed to configure. + (bin_SCRIPTS): add contrib/rebuild-gcj-db and contrib/aot-compile. + * contrib/aot-compile.in: New file. + * contrib/aotcompile.py.in: Likewise. + * contrib/aot-compile-rpm.in: Likewise. + * contrib/classfile.py: Likewise. + * contrib/rebuild-gcj-db.in: Likewise. + * configure: Regenerate. + * Makefile.in: Regenerate. + 2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> * configure: Regenerate. Index: libjava/Makefile.am =================================================================== --- libjava/Makefile.am (revision 136724) +++ libjava/Makefile.am (working copy) @@ -85,9 +85,9 @@ ## It is convenient to actually build and install the default database ## when gcj-dbtool is available. dbexec_DATA = $(db_name) -endif +endif -bin_SCRIPTS = addr2name.awk +bin_SCRIPTS = addr2name.awk contrib/rebuild-gcj-db contrib/aot-compile if BUILD_ECJ1 ## We build ecjx and not ecj1 because in one mode, ecjx will not work @@ -528,8 +528,153 @@ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SinkChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SourceChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ ## Don't install java/nio/DirectByteBufferImpl$$ReadWrite.h here. It's for internal use only. +## Install Python modules for aot-compile. + $(mkinstalldirs) $(DESTDIR)$(python_mod_dir); \ + $(INSTALL_DATA) $(srcdir)/contrib/classfile.py \ + $(DESTDIR)$(python_mod_dir)/classfile.py; \ + $(INSTALL_DATA) contrib/aotcompile.py \ + $(DESTDIR)$(python_mod_dir)/aotcompile.py; +if CREATE_JAVA_HOME +## Create sdk style directories + $(mkinstalldirs) $(DESTDIR)$(JRE_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/$(OS) + relative() { \ + $(PERL) -e 'use File::Spec; \ + print File::Spec->abs2rel($$ARGV[0], $$ARGV[1])' $$1 $$2; \ + }; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(SDK_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gjar | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jar; \ + ln -sf $$RELATIVE/`echo gjdoc | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javadoc; \ + ln -sf $$RELATIVE/`echo grmic | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmic; \ + ln -sf $$RELATIVE/`echo gjavah | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javah; \ + ln -sf $$RELATIVE/ecj $(DESTDIR)$(SDK_BIN_DIR)/javac; \ + ln -sf $$RELATIVE/`echo gappletviewer | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/appletviewer; \ + ln -sf $$RELATIVE/`echo gjarsigner | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jarsigner; \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo gnative2ascii | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/native2ascii; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/tnameserv; \ + ln -sf $$RELATIVE/`echo gserialver | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/serialver; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(JRE_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/tnameserv; \ + $(mkinstalldirs) $(DESTDIR)$(JVM_JAR_DIR); \ + version=$(JAVA_VERSION).$(BUILD_VERSION); \ + working_dir=`pwd`; \ + cd $(DESTDIR)$(JVM_JAR_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s $$RELATIVE/$$jarname.jar $$jarname-$$version.jar; \ + done; \ + for jar in *-$$version.jar; \ + do \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|-$(JAVA_VERSION).jar|g"); \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|.jar|g"); \ + done; \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/security; \ + RELATIVE=$$(relative $(DESTDIR)$(libdir)/security \ + $(DESTDIR)$(JRE_LIB_DIR)/security); \ + cd $(DESTDIR)$(JRE_LIB_DIR)/security; \ + ln -sf $$RELATIVE/classpath.security java.security; \ + cd $(DESTDIR)$(JVM_ROOT_DIR); \ + ln -s $(JRE_DIR) $(JRE_LNK); \ + ln -s $(SDK_DIR) $(SDK_LNK); \ + cd $(DESTDIR)$(JVM_JAR_ROOT_DIR); \ + ln -s $(SDK_DIR) $(JRE_LNK); \ + ln -s $(SDK_DIR) $(SDK_LNK); \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/linux; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_LIB_DIR); \ + cd $(DESTDIR)$(JRE_LIB_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s rt.jar $$jarname.jar; \ + done; \ + cd $$working_dir; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JRE_LIB_DIR)); \ + GIJ_VERSION=$$($(DESTDIR)$(bindir)/gij --version | head -n2 | tail -n1 \ + | awk '{print $$5}'); \ + ln -sf $$RELATIVE/libgcj-$$GIJ_VERSION.jar \ + $(DESTDIR)$(JRE_LIB_DIR)/rt.jar; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)); \ + if [ -f $$RELATIVE/libjawt.so ]; then \ + ln -sf $$RELATIVE/libjawt.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/libjawt.so; \ + fi; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(SDK_LIB_DIR)); \ + ln -sf $$RELATIVE/libgcj-tools-$$GIJ_VERSION.jar \ + $(DESTDIR)$(SDK_LIB_DIR)/tools.jar; \ + for headername in jawt jni; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/$$headername.h; \ + done; \ + for headername in jawt_md jni_md; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux/$$headername.h; \ + done; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)); \ + if [ -f $$RELATIVE/src-$$GIJ_VERSION.zip ]; then \ + ln -sf $$RELATIVE/src-$$GIJ_VERSION.zip \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)/src.zip; \ + fi; +endif - ## ################################################################ ## Index: libjava/configure.ac =================================================================== --- libjava/configure.ac (revision 136724) +++ libjava/configure.ac (working copy) @@ -1625,6 +1625,206 @@ # We get this from the environment. AC_SUBST(GCJFLAGS) +AC_ARG_WITH([python-dir], + AS_HELP_STRING([--with-python-dir], + [the location to install Python modules]), + [with_python_dir=$withval], [with_python_dir=""]) + +if test "x${with_python_dir}" = "x" +then + if test "x${prefix}" = "xNONE" + then + python_mod_dir=/usr/share/python + else + python_mod_dir=${prefix}/share/python + fi +else + python_mod_dir=$with_python_dir +fi +AC_MSG_RESULT(Python modules dir: ${python_mod_dir}); +AC_SUBST(python_mod_dir) + +# needed for aot-compile-rpm +MAKE=`which make` +AC_SUBST(MAKE) + +AC_ARG_ENABLE([java-home], + [AS_HELP_STRING([--enable-java-home], + [create a standard JDK-style directory layout in the install tree [default=no]])], + [case "${enableval}" in + yes) JAVA_HOME_ENABLED=yes ;; + no) JAVA_HOME_ENABLED=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable java-home]) ;; + esac], + [JAVA_HOME_ENABLED=no] +) +AM_CONDITIONAL(CREATE_JAVA_HOME, test "x${JAVA_HOME_ENABLED}" == xyes) + +# Only do these checks if java-home above is enabled. +if test "x${JAVA_HOME_ENABLED}" == xyes +then + + if test "x${prefix}" = "xNONE" + then + sdk_prefix=/usr + else + sdk_prefix=$prefix + fi + + AC_ARG_WITH([gcc-suffix], + AS_HELP_STRING([--with-gcc-suffix], + [the GCC tool suffix (defaults to empty string)]), + [gcc_suffix=$withval], [gcc_suffix=""]) + AC_MSG_RESULT(GCC suffix: ${gcc_suffix}) + AC_SUBST(gcc_suffix) + + AC_ARG_WITH([arch-directory], + AS_HELP_STRING([--with-arch-directory], + [the arch directory under jre/lib (defaults to auto-detect)]), + [host_cpu=$withval], [host_cpu=""]) + + AC_ARG_WITH([os-directory], + AS_HELP_STRING([--with-os-directory], + [the os directory under include (defaults to auto-detect)]), + [host_os=$withval], [host_os=""]) + + AC_ARG_WITH([origin-name], + AS_HELP_STRING([--with-origin-name], + [the JPackage origin name of this package (default is gcj${gcc_suffix}]), + [origin_name=$withval], [origin_name=gcj${gcc_suffix}]) + AC_MSG_RESULT(JPackage origin name: ${origin_name}) + + AC_ARG_WITH([arch-suffix], + AS_HELP_STRING([--with-arch-suffix], + [the arch directory suffix (default is the empty string]), + [arch_suffix=$withval], [arch_suffix=""]) + AC_MSG_RESULT(arch suffix: ${arch_suffix}) + + AC_ARG_WITH([jvm-root-dir], + AS_HELP_STRING([--with-jvm-root-dir], + [where to install SDK (default is ${sdk_prefix}/lib/jvm)]), + [jvm_root_dir=$withval], [jvm_root_dir=${sdk_prefix}/lib/jvm]) + AC_MSG_RESULT(JVM root installation directory: ${jvm_root_dir}) + + AC_ARG_WITH([jvm-jar-dir], + AS_HELP_STRING([--with-jvm-jar-dir], + [where to install jars (default is ${sdk_prefix}/lib/jvm-exports)]), + [jvm_jar_dir=$withval], [jvm_jar_dir=${sdk_prefix}/lib/jvm-exports]) + AC_MSG_RESULT(JAR root installation directory: ${jvm_jar_dir}) + + JAVA_VERSION=1.5.0 + BUILD_VERSION=0 + AC_SUBST(JAVA_VERSION) + AC_SUBST(BUILD_VERSION) + AC_MSG_RESULT(Java version: ${JAVA_VERSION}) + + jre_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix}/jre + sdk_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix} + jre_lnk=jre-${JAVA_VERSION}-${origin_name} + sdk_lnk=java-${JAVA_VERSION}-${origin_name} + + JVM_ROOT_DIR=${jvm_root_dir} + AC_SUBST(JVM_ROOT_DIR) + AC_MSG_RESULT(JVM ROOT directory: ${JVM_ROOT_DIR}) + + JVM_JAR_ROOT_DIR=${jvm_jar_dir} + AC_SUBST(JVM_JAR_ROOT_DIR) + AC_MSG_RESULT(JVM JAR ROOT directory: ${JVM_JAR_ROOT_DIR}) + + JVM_JAR_DIR=${jvm_jar_dir}/${sdk_dir} + AC_SUBST(JVM_JAR_DIR) + AC_MSG_RESULT(JVM JAR directory: ${JVM_JAR_DIR}) + + JRE_DIR=${jre_dir} + AC_SUBST(JRE_DIR) + + SDK_DIR=${sdk_dir} + AC_SUBST(SDK_DIR) + + JRE_LNK=${jre_lnk} + AC_SUBST(JRE_LNK) + + SDK_LNK=${sdk_lnk} + AC_SUBST(SDK_LNK) + + JAVA_HOME_DIR=${jvm_root_dir}/${jre_dir} + AC_SUBST(JAVA_HOME_DIR) + AC_MSG_RESULT(JAVA_HOME directory: ${JAVA_HOME_DIR}) + + SDK_BIN_DIR=${jvm_root_dir}/${sdk_dir}/bin + AC_SUBST(SDK_BIN_DIR) + AC_MSG_RESULT(SDK tools directory: ${SDK_BIN_DIR}) + + SDK_LIB_DIR=${jvm_root_dir}/${sdk_dir}/lib + AC_SUBST(SDK_LIB_DIR) + AC_MSG_RESULT(SDK jar directory: ${SDK_LIB_DIR}) + + SDK_INCLUDE_DIR=${jvm_root_dir}/${sdk_dir}/include + AC_SUBST(SDK_INCLUDE_DIR) + AC_MSG_RESULT(SDK include directory: ${SDK_INCLUDE_DIR}) + + JRE_BIN_DIR=${jvm_root_dir}/${jre_dir}/bin + AC_SUBST(JRE_BIN_DIR) + AC_MSG_RESULT(JRE tools directory: ${JRE_BIN_DIR}) + + JRE_LIB_DIR=${jvm_root_dir}/${jre_dir}/lib + AC_SUBST(JRE_LIB_DIR) + AC_MSG_RESULT(JRE lib directory: ${JRE_LIB_DIR}) + + # Find gcj prefix using gcj found in PATH. + gcj_prefix=`which gcj${gcc_suffix} | sed "s%/bin/gcj${gcc_suffix}%%"` + + # Where do the gcj binaries live? + # For jhbuild based builds, they all live in a sibling of bin called + # gcj-bin. Check for gcj-bin first, and use bin otherwise. + GCJ_BIN_DIR=`if test -d ${gcj_prefix}/gcj-bin; then echo ${gcj_prefix}/gcj-bin; else echo ${gcj_prefix}/bin; fi` + AC_SUBST(GCJ_BIN_DIR) + AC_MSG_RESULT(GCJ tools directory: ${GCJ_BIN_DIR}) + + echo host is ${host} + if test "x${host_cpu}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_cpu=x86;; + i486-* | i586-* | i686-*) + host_cpu=i386;; + *) + host_cpu=${host_cpu};; + esac + fi + AC_MSG_RESULT(arch directory: ${host_cpu}) + CPU=${host_cpu} + AC_SUBST(CPU) + + if test "x${host_os}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_os=win32;; + *-linux*) + host_os=linux;; + *) + host_os=${host_os};; + esac + fi + echo os directory: ${host_os} + OS=${host_os} + AC_SUBST(OS) + + # make an expanded $libdir, for substituting into + # scripts (and other non-Makefile things). + LIBDIR=$libdir + if test "x${exec_prefix}" = "xNONE" + then + lib_exec_prefix=$sdk_prefix + else + lib_exec_prefix=$exec_prefix + fi + LIBDIR=`echo $libdir | sed "s:\\\${exec_prefix}:$lib_exec_prefix:g"` + AC_SUBST(LIBDIR) +fi + AC_CONFIG_FILES([ Makefile libgcj.pc @@ -1633,6 +1833,10 @@ gcj/Makefile include/Makefile testsuite/Makefile +contrib/aotcompile.py +contrib/aot-compile +contrib/aot-compile-rpm +contrib/rebuild-gcj-db ]) if test ${multilib} = yes; then ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-18 20:39 ` Joshua Sumali @ 2008-06-19 9:54 ` Andrew Haley 2008-06-19 14:24 ` Joshua Sumali 0 siblings, 1 reply; 18+ messages in thread From: Andrew Haley @ 2008-06-19 9:54 UTC (permalink / raw) To: Joshua Sumali; +Cc: java-patches, Thomas Fitzsimmons Joshua Sumali wrote: > > Please see the two (updated) patches. The updated patch for the > "Packager files" thread is now part of the sdk-home patch attached here, > since I had to modify configure.ac to generate those packager files this > time around. > > gcc-install-and-docs.patch creates man and info pages for aot-compile > and rebuild-gcj-db, and also documents the new install options > (--enable-java-home, --with-arch-directory, --with-python-dir) as > requested by Matthias. > gcc-libjava-sdk-home-update.patch is mostly the same as the first patch > I posted here, except with these main changes: > > - aot-compile and rebuild-gcj-db are now installed in $bindir > - if --with-python-dir is not specified (say, in a regular upstream > build) , classfile.py and aotcompile.py are installed in > $(prefix)/share/python. Otherwise, those Python modules will be > installed in the path specified with --with-python-dir. I modified > aot-compile -> aot-compile.in to append whichever path classfile.py and > aotcompile.py was installed in, so that it can actually find these > modules (it wouldn't look in $(prefix)/share/python by default). > - the SDK symlinked binaries, as well as aot-compile and > rebuild-gcj-db are now `transformed' as requested by Matthias. OK, thanks. > Outstanding issues: > 1. @Matthias, I'm still not sure what you mean by "Same for using > GIJ_VERSION". Also, the issue about "why using the long version at all?" > 2. rebuild-gcj-db doesn't have a licence header on the top of the > file... is this required? And if so, what's the right thing to do about it? Make it GPL. Andrew. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-19 9:54 ` Andrew Haley @ 2008-06-19 14:24 ` Joshua Sumali 2008-06-20 4:13 ` Joshua Sumali 2008-06-26 18:18 ` Joshua Sumali 0 siblings, 2 replies; 18+ messages in thread From: Joshua Sumali @ 2008-06-19 14:24 UTC (permalink / raw) To: java-patches; +Cc: Thomas Fitzsimmons [-- Attachment #1: Type: text/plain, Size: 1770 bytes --] Andrew Haley wrote: > Joshua Sumali wrote: > > >> Please see the two (updated) patches. The updated patch for the >> "Packager files" thread is now part of the sdk-home patch attached here, >> since I had to modify configure.ac to generate those packager files this >> time around. >> >> gcc-install-and-docs.patch creates man and info pages for aot-compile >> and rebuild-gcj-db, and also documents the new install options >> (--enable-java-home, --with-arch-directory, --with-python-dir) as >> requested by Matthias. >> gcc-libjava-sdk-home-update.patch is mostly the same as the first patch >> I posted here, except with these main changes: >> >> - aot-compile and rebuild-gcj-db are now installed in $bindir >> - if --with-python-dir is not specified (say, in a regular upstream >> build) , classfile.py and aotcompile.py are installed in >> $(prefix)/share/python. Otherwise, those Python modules will be >> installed in the path specified with --with-python-dir. I modified >> aot-compile -> aot-compile.in to append whichever path classfile.py and >> aotcompile.py was installed in, so that it can actually find these >> modules (it wouldn't look in $(prefix)/share/python by default). >> - the SDK symlinked binaries, as well as aot-compile and >> rebuild-gcj-db are now `transformed' as requested by Matthias. >> > > OK, thanks. > > >> Outstanding issues: >> 1. @Matthias, I'm still not sure what you mean by "Same for using >> GIJ_VERSION". Also, the issue about "why using the long version at all?" >> 2. rebuild-gcj-db doesn't have a licence header on the top of the >> file... is this required? And if so, what's the right thing to do about it? >> > > Make it GPL. > > Andrew. > Updated rebuild-gcj-db with license header. Josh [-- Attachment #2: gcc-libjava-sdk-home-update2.patch --] [-- Type: text/x-patch, Size: 47181 bytes --] Index: libjava/contrib/rebuild-gcj-db.in =================================================================== --- libjava/contrib/rebuild-gcj-db.in (revision 0) +++ libjava/contrib/rebuild-gcj-db.in (revision 0) @@ -0,0 +1,24 @@ +#!/bin/bash +# rebuild-gcj-db + +## Copyright (C) 2000, 2002, 2003, 2008 Free Software Foundation +## +## This file is part of libgcj. +## +## This software is copyrighted work licensed under the terms of the +## Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +## details. + +# Rebuild all the standard databases. +for base in /usr/lib*; do + dbLocation=`@prefix@/bin/gcj-dbtool@gcc_suffix@ -p $base` + libdir=$base/gcj + if ! test -d $libdir; then + # No shared libraries here. + continue + fi + dirname $dbLocation | xargs mkdir -p + @prefix@/bin/gcj-dbtool@gcc_suffix@ -n $dbLocation 64 + find $libdir -follow -name '*.db' -print0 | \ + xargs -0 @prefix@/bin/gcj-dbtool@gcc_suffix@ -m $dbLocation $dbLocation +done Index: libjava/contrib/aotcompile.py.in =================================================================== --- libjava/contrib/aotcompile.py.in (revision 0) +++ libjava/contrib/aotcompile.py.in (revision 0) @@ -0,0 +1,412 @@ +# -*- python -*- + +## Copyright (C) 2005, 2006, 2008 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import classfile +import copy +import md5 +import operator +import os +import sys +import cStringIO as StringIO +import zipfile + +PATHS = {"make": "@MAKE@", + "gcj": "@prefix@/bin/gcj@gcc_suffix@", + "dbtool": "@prefix@/bin/gcj-dbtool@gcc_suffix@"} + +MAKEFLAGS = [] +GCJFLAGS = ["-fPIC", "-findirect-dispatch", "-fjni"] +LDFLAGS = ["-Wl,-Bsymbolic"] + +MAX_CLASSES_PER_JAR = 1024 +MAX_BYTES_PER_JAR = 1048576 + +MAKEFILE = "Makefile" + +MAKEFILE_HEADER = '''\ +GCJ = %(gcj)s +DBTOOL = %(dbtool)s +GCJFLAGS = %(gcjflags)s +LDFLAGS = %(ldflags)s + +%%.o: %%.jar + $(GCJ) -c $(GCJFLAGS) $< -o $@ + +TARGETS = \\ +%(targets)s + +all: $(TARGETS)''' + +MAKEFILE_JOB = ''' +%(base)s_SOURCES = \\ +%(jars)s + +%(base)s_OBJECTS = \\ +$(%(base)s_SOURCES:.jar=.o) + +%(dso)s: $(%(base)s_OBJECTS) + $(GCJ) -shared $(GCJFLAGS) $(LDFLAGS) $^ -o $@ + +%(db)s: $(%(base)s_SOURCES) + $(DBTOOL) -n $@ 64 + for jar in $^; do \\ + $(DBTOOL) -f $@ $$jar \\ + %(libdir)s/%(dso)s; \\ + done''' + +ZIPMAGIC, CLASSMAGIC = "PK\x03\x04", "\xca\xfe\xba\xbe" + +class Error(Exception): + pass + +class Compiler: + def __init__(self, srcdir, libdir, prefix = None): + self.srcdir = os.path.abspath(srcdir) + self.libdir = os.path.abspath(libdir) + if prefix is None: + self.dstdir = self.libdir + else: + self.dstdir = os.path.join(prefix, self.libdir.lstrip(os.sep)) + + # Calling code may modify these parameters + self.gcjflags = copy.copy(GCJFLAGS) + self.ldflags = copy.copy(LDFLAGS) + self.makeflags = copy.copy(MAKEFLAGS) + self.exclusions = [] + + def compile(self): + """Search srcdir for classes and jarfiles, then generate + solibs and mappings databases for them all in libdir.""" + if not os.path.isdir(self.dstdir): + os.makedirs(self.dstdir) + oldcwd = os.getcwd() + os.chdir(self.dstdir) + try: + jobs = self.getJobList() + if not jobs: + raise Error, "nothing to do" + self.writeMakefile(MAKEFILE, jobs) + for job in jobs: + job.writeJars() + system([PATHS["make"]] + self.makeflags) + for job in jobs: + job.clean() + os.unlink(MAKEFILE) + finally: + os.chdir(oldcwd) + + def getJobList(self): + """Return all jarfiles and class collections in srcdir.""" + jobs = weed_jobs(find_jobs(self.srcdir, self.exclusions)) + set_basenames(jobs) + return jobs + + def writeMakefile(self, path, jobs): + """Generate a makefile to build the solibs and mappings + databases for the specified list of jobs.""" + fp = open(path, "w") + print >>fp, MAKEFILE_HEADER % { + "gcj": PATHS["gcj"], + "dbtool": PATHS["dbtool"], + "gcjflags": " ".join(self.gcjflags), + "ldflags": " ".join(self.ldflags), + "targets": " \\\n".join(reduce(operator.add, [ + (job.dsoName(), job.dbName()) for job in jobs]))} + for job in jobs: + values = job.ruleArguments() + values["libdir"] = self.libdir + print >>fp, MAKEFILE_JOB % values + fp.close() + +def find_jobs(dir, exclusions = ()): + """Scan a directory and find things to compile: jarfiles (zips, + wars, ears, rars, etc: we go by magic rather than file extension) + and directories of classes.""" + def visit((classes, zips), dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + magic = open(path, "r").read(4) + if magic == ZIPMAGIC: + zips.append(path) + elif magic == CLASSMAGIC: + classes.append(path) + classes, paths = [], [] + os.path.walk(dir, visit, (classes, paths)) + # Convert the list of classes into a list of directories + while classes: + # XXX this requires the class to be correctly located in its heirachy. + path = classes[0][:-len(os.sep + classname(classes[0]) + ".class")] + paths.append(path) + classes = [cls for cls in classes if not cls.startswith(path)] + # Handle exclusions. We're really strict about them because the + # option is temporary in aot-compile-rpm and dead options left in + # specfiles will hinder its removal. + for path in exclusions: + if path in paths: + paths.remove(path) + else: + raise Error, "%s: path does not exist or is not a job" % path + # Build the list of jobs + jobs = [] + paths.sort() + for path in paths: + if os.path.isfile(path): + job = JarJob(path) + else: + job = DirJob(path) + if len(job.classes): + jobs.append(job) + return jobs + +class Job: + """A collection of classes that will be compiled as a unit.""" + + def __init__(self, path): + self.path, self.classes, self.blocks = path, {}, None + + def addClass(self, bytes): + """Subclasses call this from their __init__ method for + every class they find.""" + self.classes[md5.new(bytes).digest()] = bytes + + def __makeBlocks(self): + """Split self.classes into chunks that can be compiled to + native code by gcj. In the majority of cases this is not + necessary -- the job will have come from a jarfile which will + be equivalent to the one we generate -- but this only happens + _if_ the job was a jarfile and _if_ the jarfile isn't too big + and _if_ the jarfile has the correct extension and _if_ all + classes are correctly named and _if_ the jarfile has no + embedded jarfiles. Fitting a special case around all these + conditions is tricky to say the least. + + Note that this could be called at the end of each subclass's + __init__ method. The reason this is not done is because we + need to parse every class file. This is slow, and unnecessary + if the job is subsetted.""" + names = {} + for hash, bytes in self.classes.items(): + name = classname(bytes) + if not names.has_key(name): + names[name] = [] + names[name].append(hash) + names = names.items() + # We have to sort somehow, or the jars we generate + # We sort by name in a simplistic attempt to keep related + # classes together so inter-class optimisation can happen. + names.sort() + self.blocks, bytes = [[]], 0 + for name, hashes in names: + for hash in hashes: + if len(self.blocks[-1]) >= MAX_CLASSES_PER_JAR \ + or bytes >= MAX_BYTES_PER_JAR: + self.blocks.append([]) + bytes = 0 + self.blocks[-1].append((name, hash)) + bytes += len(self.classes[hash]) + + # From Archit Shah: + # The implementation and the documentation don't seem to match. + # + # [a, b].isSubsetOf([a]) => True + # + # Identical copies of all classes this collection do not exist + # in the other. I think the method should be named isSupersetOf + # and the documentation should swap uses of "this" and "other" + # + # XXX think about this when I've had more sleep... + def isSubsetOf(self, other): + """Returns True if identical copies of all classes in this + collection exist in the other.""" + for item in other.classes.keys(): + if not self.classes.has_key(item): + return False + return True + + def __targetName(self, ext): + return self.basename + ext + + def tempJarName(self, num): + return self.__targetName(".%d.jar" % (num + 1)) + + def tempObjName(self, num): + return self.__targetName(".%d.o" % (num + 1)) + + def dsoName(self): + """Return the filename of the shared library that will be + built from this job.""" + return self.__targetName(".so") + + def dbName(self): + """Return the filename of the mapping database that will be + built from this job.""" + return self.__targetName(".db") + + def ruleArguments(self): + """Return a dictionary of values that when substituted + into MAKEFILE_JOB will create the rules required to build + the shared library and mapping database for this job.""" + if self.blocks is None: + self.__makeBlocks() + return { + "base": "".join( + [c.isalnum() and c or "_" for c in self.dsoName()]), + "jars": " \\\n".join( + [self.tempJarName(i) for i in xrange(len(self.blocks))]), + "dso": self.dsoName(), + "db": self.dbName()} + + def writeJars(self): + """Generate jarfiles that can be native compiled by gcj.""" + if self.blocks is None: + self.__makeBlocks() + for block, i in zip(self.blocks, xrange(len(self.blocks))): + jar = zipfile.ZipFile(self.tempJarName(i), "w", zipfile.ZIP_STORED) + for name, hash in block: + jar.writestr( + zipfile.ZipInfo("%s.class" % name), self.classes[hash]) + jar.close() + + def clean(self): + """Delete all temporary files created during this job's build.""" + if self.blocks is None: + self.__makeBlocks() + for i in xrange(len(self.blocks)): + os.unlink(self.tempJarName(i)) + os.unlink(self.tempObjName(i)) + +class JarJob(Job): + """A Job whose origin was a jarfile.""" + + def __init__(self, path): + Job.__init__(self, path) + self._walk(zipfile.ZipFile(path, "r")) + + def _walk(self, zf): + for name in zf.namelist(): + bytes = zf.read(name) + if bytes.startswith(ZIPMAGIC): + self._walk(zipfile.ZipFile(StringIO.StringIO(bytes))) + elif bytes.startswith(CLASSMAGIC): + self.addClass(bytes) + +class DirJob(Job): + """A Job whose origin was a directory of classfiles.""" + + def __init__(self, path): + Job.__init__(self, path) + os.path.walk(path, DirJob._visit, self) + + def _visit(self, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + fp = open(path, "r") + magic = fp.read(4) + if magic == CLASSMAGIC: + self.addClass(magic + fp.read()) + +def weed_jobs(jobs): + """Remove any jarfiles that are completely contained within + another. This is more common than you'd think, and we only + need one nativified copy of each class after all.""" + jobs = copy.copy(jobs) + while True: + for job1 in jobs: + for job2 in jobs: + if job1 is job2: + continue + if job1.isSubsetOf(job2): + msg = "subsetted %s" % job2.path + if job2.isSubsetOf(job1): + if (isinstance(job1, DirJob) and + isinstance(job2, JarJob)): + # In the braindead case where a package + # contains an expanded copy of a jarfile + # the jarfile takes precedence. + continue + msg += " (identical)" + warn(msg) + jobs.remove(job2) + break + else: + continue + break + else: + break + continue + return jobs + +def set_basenames(jobs): + """Ensure that each jarfile has a different basename.""" + names = {} + for job in jobs: + name = os.path.basename(job.path) + if not names.has_key(name): + names[name] = [] + names[name].append(job) + for name, set in names.items(): + if len(set) == 1: + set[0].basename = name + continue + # prefix the jar filenames to make them unique + # XXX will not work in most cases -- needs generalising + set = [(job.path.split(os.sep), job) for job in set] + minlen = min([len(bits) for bits, job in set]) + set = [(bits[-minlen:], job) for bits, job in set] + bits = apply(zip, [bits for bits, job in set]) + while True: + row = bits[-2] + for bit in row[1:]: + if bit != row[0]: + break + else: + del bits[-2] + continue + break + set = zip( + ["_".join(name) for name in apply(zip, bits[-2:])], + [job for bits, job in set]) + for name, job in set: + warn("building %s as %s" % (job.path, name)) + job.basename = name + # XXX keep this check until we're properly general + names = {} + for job in jobs: + name = job.basename + if names.has_key(name): + raise Error, "%s: duplicate jobname" % name + names[name] = 1 + +def system(command): + """Execute a command.""" + status = os.spawnv(os.P_WAIT, command[0], command) + if status > 0: + raise Error, "%s exited with code %d" % (command[0], status) + elif status < 0: + raise Error, "%s killed by signal %d" % (command[0], -status) + +def warn(msg): + """Print a warning message.""" + print >>sys.stderr, "%s: warning: %s" % ( + os.path.basename(sys.argv[0]), msg) + +def classname(bytes): + """Extract the class name from the bytes of a class file.""" + klass = classfile.Class(bytes) + return klass.constants[klass.constants[klass.name][1]][1] Index: libjava/contrib/aot-compile-rpm.in =================================================================== --- libjava/contrib/aot-compile-rpm.in (revision 0) +++ libjava/contrib/aot-compile-rpm.in (revision 0) @@ -0,0 +1,97 @@ +#!/usr/bin/env python + +## Copyright (C) 2005, 2006, 2007 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir@") +import aotcompile +import os + +def libdir(): + cmd = "%s -p" % aotcompile.PATHS["dbtool"] + dir = os.path.abspath(os.popen(cmd, "r").readline().rstrip()) + dir, base = os.path.split(dir) + if base != "classmap.db": + raise aotcompile.Error, "%s: unexpected output" % cmd + dir, base = os.path.split(dir) + if not base.startswith("gcj-"): + raise aotcompile.Error, "%s: unexpected output" % cmd + return dir + +def writeSourceList(srcdir, dstpath): + def visit(fp, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.isfile(path): + print >>fp, path + dstdir = os.path.dirname(dstpath) + if not os.path.isdir(dstdir): + os.makedirs(dstdir) + os.path.walk(srcdir, visit, open(dstpath, "w")) + +def copy(srcdir, dstdir, suffix): + srcdir = os.path.join(srcdir, suffix.lstrip(os.sep)) + dstdir = os.path.join(dstdir, suffix.lstrip(os.sep)) + os.makedirs(os.path.dirname(dstdir)) + aotcompile.system(("/bin/cp", "-a", srcdir, dstdir)) + +try: + name = os.environ.get("RPM_PACKAGE_NAME") + if name is None: + raise aotcompile.Error, "not for use outside rpm specfiles" + arch = os.environ.get("RPM_ARCH") + if arch == "noarch": + raise aotcompile.Error, "cannot be used on noarch packages" + srcdir = os.environ.get("RPM_BUILD_ROOT") + if srcdir in (None, "/"): + raise aotcompile.Error, "bad $RPM_BUILD_ROOT" + tmpdir = os.path.join(os.getcwd(), "aot-compile-rpm") + if os.path.exists(tmpdir): + raise aotcompile.Error, "%s exists" % tmpdir + dstdir = os.path.join(libdir(), "gcj", name) + + compiler = aotcompile.Compiler(srcdir, dstdir, tmpdir) + compiler.gcjflags[0:0] = os.environ.get("RPM_OPT_FLAGS", "").split() + + # XXX: This script should not accept options, because having + # them it cannot be integrated into rpm. But, gcj cannot + # build each and every jarfile yet, so we must be able to + # exclude until it can. + # XXX --exclude is also used in the jonas rpm to stop + # everything being made a subset of the mammoth client + # jarfile. Should adjust the subset checker's bias to + # favour many small jarfiles over one big one. + try: + options, exclusions = sys.argv[1:], [] + while options: + if options.pop(0) != "--exclude": + raise ValueError + compiler.exclusions.append( + os.path.join(srcdir, options.pop(0).lstrip(os.sep))) + except: + print >>sys.stderr, "usage: %s [--exclude PATH]..." % ( + os.path.basename(sys.argv[0])) + sys.exit(1) + + sourcelist = os.path.join(tmpdir, "sources.list") + writeSourceList(os.getcwd(), sourcelist) + compiler.gcjflags.append("-fsource-filename=" + sourcelist) + + compiler.compile() + copy(tmpdir, srcdir, dstdir) + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/contrib/classfile.py =================================================================== --- libjava/contrib/classfile.py (revision 0) +++ libjava/contrib/classfile.py (revision 0) @@ -0,0 +1,221 @@ +## Copyright (C) 2004, 2005 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +"""Read Java(TM) class files.""" + +import cStringIO as StringIO +import struct + +class Class: + def __init__(self, arg): + if hasattr(arg, "read"): + self.fp = arg + elif type(arg) == type(""): + if arg.startswith("\xca\xfe\xba\xbe"): + self.fp = StringIO.StringIO(arg) + else: + self.fp = open(arg, "r") + else: + raise TypeError, type(arg) + + magic = self._read_int() + assert magic == 0xcafebabeL + minor, major = self._read(">HH") + self.version = (major, minor) + + self.pool_integrity_checks = None + try: + assert False + except AssertionError: + self.pool_integrity_checks = [] + + self._read_constants_pool() + + self.access_flags = self._read_short() + self.name = self._read_reference_Class() + self.super = self._read_reference_Class() + + self.interfaces = self._read_interfaces() + self.fields = self._read_fieldsormethods() + self.methods = self._read_fieldsormethods() + self.attributes = self._read_attributes() + + if self.pool_integrity_checks is not None: + for index, tag in self.pool_integrity_checks: + assert self.constants[index][0] == tag + + del self.fp, self.pool_integrity_checks + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) + if not attr.startswith("_") and attr != "Member"] + attrs.sort() + for attr in attrs: + result.append("%-13s %s" % ( + attr + ":", attr == "constants" and + "<ELIDED>" or repr(getattr(self, attr)))) + return "\n".join(result) + + def _read_constants_pool(self): + self.constants = {} + skip = False + for i in xrange(1, self._read_short()): + if skip: + skip = False + continue + tag = { + 1: "Utf8", 3: "Integer", 4: "Float", 5: "Long", + 6: "Double", 7: "Class", 8: "String", 9: "Fieldref", + 10: "Methodref", 11: "InterfaceMethodref", + 12: "NameAndType"}[self._read_byte()] + skip = tag in ("Long", "Double") # crack crack crack! + self.constants[i] = (tag, getattr(self, "_read_constant_" + tag)()) + + def _read_interfaces(self): + result = [] + for i in xrange(self._read_short()): + result.append(self._read_reference_Class()) + return result + + def _read_fieldsormethods(self): + result = [] + for i in xrange(self._read_short()): + result.append(self.Member(self)) + return result + + class Member: + def __init__(self, source): + self.access_flags = source._read_short() + self.name = source._read_reference_Utf8() + self.descriptor = source._read_reference_Utf8() + self.attributes = source._read_attributes() + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) if not attr.startswith("_")] + attrs.sort() + for attr in attrs: + value = getattr(self, attr) + if attr == "attributes" and value.has_key("Code"): + value = value.copy() + value.update({"Code": "<ELIDED>"}) + result.append("%-13s %s" % ( + attr + ":", repr(value).replace( + "'Code': '<ELIDED>'", "'Code': <ELIDED>"))) + return ("\n%s" % (15 * " ")).join(result) + + def _read_attributes(self): + result = {} + for i in xrange(self._read_short()): + name = self._read_reference_Utf8() + data = self.fp.read(self._read_int()) + assert not result.has_key(name) + result[name] = data + return result + + # Constants pool reference reader convenience functions + + def _read_reference_Utf8(self): + return self._read_references("Utf8")[0] + + def _read_reference_Class(self): + return self._read_references("Class")[0] + + def _read_reference_Class_NameAndType(self): + return self._read_references("Class", "NameAndType") + + def _read_references(self, *args): + result = [] + for arg in args: + index = self._read_short() + if self.pool_integrity_checks is not None: + self.pool_integrity_checks.append((index, arg)) + result.append(index) + return result + + # Constants pool constant reader functions + + def _read_constant_Utf8(self): + constant = self.fp.read(self._read_short()) + try: + constant = constant.decode("utf-8") + except UnicodeError: + constant = _bork_utf8_decode(constant) + try: + constant = constant.encode("us-ascii") + except UnicodeError: + pass + return constant + + def _read_constant_Integer(self): + return self._read_int() + + def _read_constant_Float(self): + return self._read(">f")[0] + + def _read_constant_Long(self): + return self._read(">q")[0] + + def _read_constant_Double(self): + return self._read(">d")[0] + + _read_constant_Class = _read_reference_Utf8 + _read_constant_String = _read_reference_Utf8 + _read_constant_Fieldref = _read_reference_Class_NameAndType + _read_constant_Methodref = _read_reference_Class_NameAndType + _read_constant_InterfaceMethodref = _read_reference_Class_NameAndType + + def _read_constant_NameAndType(self): + return self._read_reference_Utf8(), self._read_reference_Utf8() + + # Generic reader functions + + def _read_int(self): + # XXX how else to read 32 bits on a 64-bit box? + h, l = map(long, self._read(">HH")) + return (h << 16) + l + + def _read_short(self): + return self._read(">H")[0] + + def _read_byte(self): + return self._read("B")[0] + + def _read(self, fmt): + return struct.unpack(fmt, self.fp.read(struct.calcsize(fmt))) + +def _bork_utf8_decode(data): + # more crack! + bytes, unicode = map(ord, data), "" + while bytes: + b1 = bytes.pop(0) + if b1 & 0x80: + assert b1 & 0x40 + b2 = bytes.pop(0) + assert b2 & 0xC0 == 0x80 + if b1 & 0x20: + assert not b1 & 0x10 + b3 = bytes.pop(0) + assert b3 & 0xC0 == 0x80 + unicode += unichr( + ((b1 & 0x0f) << 12) + ((b2 & 0x3f) << 6) + (b3 & 0x3f)) + else: + unicode += unichr(((b1 & 0x1f) << 6) + (b2 & 0x3f)) + else: + unicode += unichr(b1) + return unicode + +if __name__ == "__main__": + print Class("/usr/share/katana/build/ListDependentClasses.class") + Index: libjava/contrib/aot-compile.in =================================================================== --- libjava/contrib/aot-compile.in (revision 0) +++ libjava/contrib/aot-compile.in (revision 0) @@ -0,0 +1,88 @@ +#!/usr/bin/env python + +## Copyright (C) 2006 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir@") +import aotcompile +import getopt +import os + +usage = """\ +Usage: %s [OPTION...] SRCDIR DSTDIR +AOT-compile all Java bytecode in SRCDIR into DSTDIR. + +Options: + -M, --make=PATH make executable to use (%s) + -C, --gcj=PATH gcj executable to use (%s) + -D, --dbtool=PATH gcj-dbtool executable to use (%s) + -m, --makeflags=FLAGS flags to pass to make during build + -c, --gcjflags=FLAGS flags to pass to gcj during compilation + in addition to %s + -l, --ldflags=FLAGS flags to pass to gcj during linking + in addition to %s + -e, --exclude=PATH do not compile PATH + +Extra flags may also be passed using the AOT_MAKEFLAGS, AOT_GCJFLAGS +and AOT_LDFLAGS environment variables.""" % ( + os.path.basename(sys.argv[0]), + aotcompile.PATHS["make"], + aotcompile.PATHS["gcj"], + aotcompile.PATHS["dbtool"], + repr(" ".join(aotcompile.GCJFLAGS)), + repr(" ".join(aotcompile.LDFLAGS))) + +try: + if os.environ.has_key("RPM_PACKAGE_NAME"): + raise aotcompile.Error, "not for use within rpm specfiles" + + try: + opts, args = getopt.getopt( + sys.argv[1:], + "M:C:D:m:c:l:e:", + ["make=", "gcj=", "dbtool=", + "makeflags=" "gcjflags=", "ldflags=", + "exclude="]) + srcdir, dstdir = args + except: + print >>sys.stderr, usage + sys.exit(1) + + compiler = aotcompile.Compiler(srcdir, dstdir) + for o, a in opts: + if o in ("-M", "--make"): + aotcompile.PATHS["make"] = a + if o in ("-C", "--gcj"): + aotcompile.PATHS["gcj"] = a + if o in ("-D", "--dbtool"): + aotcompile.PATHS["dbtool"] = a + if o in ("-m", "--makeflags"): + compiler.makeflags[0:0] = a.split() + if o in ("-c", "--gcjflags"): + compiler.gcjflags[0:0] = a.split() + if o in ("-l", "--ldflags"): + compiler.ldflags[0:0] = a.split() + if o in ("-e", "--exclude"): + compiler.exclusions.append(a) + + compiler.makeflags[0:0] = os.environ.get("AOT_MAKEFLAGS", "").split() + compiler.gcjflags[0:0] = os.environ.get("AOT_GCJFLAGS", "").split() + compiler.ldflags[0:0] = os.environ.get("AOT_LDFLAGS", "").split() + + compiler.compile() + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/ChangeLog =================================================================== --- libjava/ChangeLog (revision 136894) +++ libjava/ChangeLog (working copy) @@ -1,3 +1,29 @@ +2008-06-18 Joshua Sumali <jsumali@redhat.com> + + * configure.ac (java-home): new AC_ARG_ENABLE. + (CREATE_JAVA_HOME): new AM_CONDITIONAL. + (gcc-suffix): new AC_ARG_WITH. + (arch-directory): Likewise. + (os-directory): Likewise. + (origin-name): Likewise. + (arch-suffix): Likewise. + (jvm-root-dir): Likewise. + (jvm-jar-dir): Likewise. + (python-dir): Likewise. + (AC_CONFIG_FILES): Add contrib/aotcompile.py, contrib/aot-compile, + contrib/aot-compile-rpm, contrib/rebuild-gcj-db. + * Makefile.am (install-data-local): Install Python modules for + aot-compile. Also install an sdk style directory if --enable-java-home + is passed to configure. + (bin_SCRIPTS): add contrib/rebuild-gcj-db and contrib/aot-compile. + * contrib/aot-compile.in: New file. + * contrib/aotcompile.py.in: Likewise. + * contrib/aot-compile-rpm.in: Likewise. + * contrib/classfile.py: Likewise. + * contrib/rebuild-gcj-db.in: Likewise. + * configure: Regenerate. + * Makefile.in: Regenerate. + 2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> * configure: Regenerate. Index: libjava/Makefile.am =================================================================== --- libjava/Makefile.am (revision 136724) +++ libjava/Makefile.am (working copy) @@ -85,9 +85,9 @@ ## It is convenient to actually build and install the default database ## when gcj-dbtool is available. dbexec_DATA = $(db_name) -endif +endif -bin_SCRIPTS = addr2name.awk +bin_SCRIPTS = addr2name.awk contrib/rebuild-gcj-db contrib/aot-compile if BUILD_ECJ1 ## We build ecjx and not ecj1 because in one mode, ecjx will not work @@ -528,8 +528,153 @@ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SinkChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SourceChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ ## Don't install java/nio/DirectByteBufferImpl$$ReadWrite.h here. It's for internal use only. +## Install Python modules for aot-compile. + $(mkinstalldirs) $(DESTDIR)$(python_mod_dir); \ + $(INSTALL_DATA) $(srcdir)/contrib/classfile.py \ + $(DESTDIR)$(python_mod_dir)/classfile.py; \ + $(INSTALL_DATA) contrib/aotcompile.py \ + $(DESTDIR)$(python_mod_dir)/aotcompile.py; +if CREATE_JAVA_HOME +## Create sdk style directories + $(mkinstalldirs) $(DESTDIR)$(JRE_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/$(OS) + relative() { \ + $(PERL) -e 'use File::Spec; \ + print File::Spec->abs2rel($$ARGV[0], $$ARGV[1])' $$1 $$2; \ + }; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(SDK_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gjar | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jar; \ + ln -sf $$RELATIVE/`echo gjdoc | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javadoc; \ + ln -sf $$RELATIVE/`echo grmic | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmic; \ + ln -sf $$RELATIVE/`echo gjavah | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javah; \ + ln -sf $$RELATIVE/ecj $(DESTDIR)$(SDK_BIN_DIR)/javac; \ + ln -sf $$RELATIVE/`echo gappletviewer | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/appletviewer; \ + ln -sf $$RELATIVE/`echo gjarsigner | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jarsigner; \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo gnative2ascii | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/native2ascii; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/tnameserv; \ + ln -sf $$RELATIVE/`echo gserialver | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/serialver; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(JRE_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/tnameserv; \ + $(mkinstalldirs) $(DESTDIR)$(JVM_JAR_DIR); \ + version=$(JAVA_VERSION).$(BUILD_VERSION); \ + working_dir=`pwd`; \ + cd $(DESTDIR)$(JVM_JAR_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s $$RELATIVE/$$jarname.jar $$jarname-$$version.jar; \ + done; \ + for jar in *-$$version.jar; \ + do \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|-$(JAVA_VERSION).jar|g"); \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|.jar|g"); \ + done; \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/security; \ + RELATIVE=$$(relative $(DESTDIR)$(libdir)/security \ + $(DESTDIR)$(JRE_LIB_DIR)/security); \ + cd $(DESTDIR)$(JRE_LIB_DIR)/security; \ + ln -sf $$RELATIVE/classpath.security java.security; \ + cd $(DESTDIR)$(JVM_ROOT_DIR); \ + ln -s $(JRE_DIR) $(JRE_LNK); \ + ln -s $(SDK_DIR) $(SDK_LNK); \ + cd $(DESTDIR)$(JVM_JAR_ROOT_DIR); \ + ln -s $(SDK_DIR) $(JRE_LNK); \ + ln -s $(SDK_DIR) $(SDK_LNK); \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/linux; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_LIB_DIR); \ + cd $(DESTDIR)$(JRE_LIB_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s rt.jar $$jarname.jar; \ + done; \ + cd $$working_dir; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JRE_LIB_DIR)); \ + GIJ_VERSION=$$($(DESTDIR)$(bindir)/gij --version | head -n2 | tail -n1 \ + | awk '{print $$5}'); \ + ln -sf $$RELATIVE/libgcj-$$GIJ_VERSION.jar \ + $(DESTDIR)$(JRE_LIB_DIR)/rt.jar; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)); \ + if [ -f $$RELATIVE/libjawt.so ]; then \ + ln -sf $$RELATIVE/libjawt.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/libjawt.so; \ + fi; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(SDK_LIB_DIR)); \ + ln -sf $$RELATIVE/libgcj-tools-$$GIJ_VERSION.jar \ + $(DESTDIR)$(SDK_LIB_DIR)/tools.jar; \ + for headername in jawt jni; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/$$headername.h; \ + done; \ + for headername in jawt_md jni_md; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux/$$headername.h; \ + done; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)); \ + if [ -f $$RELATIVE/src-$$GIJ_VERSION.zip ]; then \ + ln -sf $$RELATIVE/src-$$GIJ_VERSION.zip \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)/src.zip; \ + fi; +endif - ## ################################################################ ## Index: libjava/configure.ac =================================================================== --- libjava/configure.ac (revision 136724) +++ libjava/configure.ac (working copy) @@ -1625,6 +1625,206 @@ # We get this from the environment. AC_SUBST(GCJFLAGS) +AC_ARG_WITH([python-dir], + AS_HELP_STRING([--with-python-dir], + [the location to install Python modules]), + [with_python_dir=$withval], [with_python_dir=""]) + +if test "x${with_python_dir}" = "x" +then + if test "x${prefix}" = "xNONE" + then + python_mod_dir=/usr/share/python + else + python_mod_dir=${prefix}/share/python + fi +else + python_mod_dir=$with_python_dir +fi +AC_MSG_RESULT(Python modules dir: ${python_mod_dir}); +AC_SUBST(python_mod_dir) + +# needed for aot-compile-rpm +MAKE=`which make` +AC_SUBST(MAKE) + +AC_ARG_ENABLE([java-home], + [AS_HELP_STRING([--enable-java-home], + [create a standard JDK-style directory layout in the install tree [default=no]])], + [case "${enableval}" in + yes) JAVA_HOME_ENABLED=yes ;; + no) JAVA_HOME_ENABLED=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable java-home]) ;; + esac], + [JAVA_HOME_ENABLED=no] +) +AM_CONDITIONAL(CREATE_JAVA_HOME, test "x${JAVA_HOME_ENABLED}" == xyes) + +# Only do these checks if java-home above is enabled. +if test "x${JAVA_HOME_ENABLED}" == xyes +then + + if test "x${prefix}" = "xNONE" + then + sdk_prefix=/usr + else + sdk_prefix=$prefix + fi + + AC_ARG_WITH([gcc-suffix], + AS_HELP_STRING([--with-gcc-suffix], + [the GCC tool suffix (defaults to empty string)]), + [gcc_suffix=$withval], [gcc_suffix=""]) + AC_MSG_RESULT(GCC suffix: ${gcc_suffix}) + AC_SUBST(gcc_suffix) + + AC_ARG_WITH([arch-directory], + AS_HELP_STRING([--with-arch-directory], + [the arch directory under jre/lib (defaults to auto-detect)]), + [host_cpu=$withval], [host_cpu=""]) + + AC_ARG_WITH([os-directory], + AS_HELP_STRING([--with-os-directory], + [the os directory under include (defaults to auto-detect)]), + [host_os=$withval], [host_os=""]) + + AC_ARG_WITH([origin-name], + AS_HELP_STRING([--with-origin-name], + [the JPackage origin name of this package (default is gcj${gcc_suffix}]), + [origin_name=$withval], [origin_name=gcj${gcc_suffix}]) + AC_MSG_RESULT(JPackage origin name: ${origin_name}) + + AC_ARG_WITH([arch-suffix], + AS_HELP_STRING([--with-arch-suffix], + [the arch directory suffix (default is the empty string]), + [arch_suffix=$withval], [arch_suffix=""]) + AC_MSG_RESULT(arch suffix: ${arch_suffix}) + + AC_ARG_WITH([jvm-root-dir], + AS_HELP_STRING([--with-jvm-root-dir], + [where to install SDK (default is ${sdk_prefix}/lib/jvm)]), + [jvm_root_dir=$withval], [jvm_root_dir=${sdk_prefix}/lib/jvm]) + AC_MSG_RESULT(JVM root installation directory: ${jvm_root_dir}) + + AC_ARG_WITH([jvm-jar-dir], + AS_HELP_STRING([--with-jvm-jar-dir], + [where to install jars (default is ${sdk_prefix}/lib/jvm-exports)]), + [jvm_jar_dir=$withval], [jvm_jar_dir=${sdk_prefix}/lib/jvm-exports]) + AC_MSG_RESULT(JAR root installation directory: ${jvm_jar_dir}) + + JAVA_VERSION=1.5.0 + BUILD_VERSION=0 + AC_SUBST(JAVA_VERSION) + AC_SUBST(BUILD_VERSION) + AC_MSG_RESULT(Java version: ${JAVA_VERSION}) + + jre_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix}/jre + sdk_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix} + jre_lnk=jre-${JAVA_VERSION}-${origin_name} + sdk_lnk=java-${JAVA_VERSION}-${origin_name} + + JVM_ROOT_DIR=${jvm_root_dir} + AC_SUBST(JVM_ROOT_DIR) + AC_MSG_RESULT(JVM ROOT directory: ${JVM_ROOT_DIR}) + + JVM_JAR_ROOT_DIR=${jvm_jar_dir} + AC_SUBST(JVM_JAR_ROOT_DIR) + AC_MSG_RESULT(JVM JAR ROOT directory: ${JVM_JAR_ROOT_DIR}) + + JVM_JAR_DIR=${jvm_jar_dir}/${sdk_dir} + AC_SUBST(JVM_JAR_DIR) + AC_MSG_RESULT(JVM JAR directory: ${JVM_JAR_DIR}) + + JRE_DIR=${jre_dir} + AC_SUBST(JRE_DIR) + + SDK_DIR=${sdk_dir} + AC_SUBST(SDK_DIR) + + JRE_LNK=${jre_lnk} + AC_SUBST(JRE_LNK) + + SDK_LNK=${sdk_lnk} + AC_SUBST(SDK_LNK) + + JAVA_HOME_DIR=${jvm_root_dir}/${jre_dir} + AC_SUBST(JAVA_HOME_DIR) + AC_MSG_RESULT(JAVA_HOME directory: ${JAVA_HOME_DIR}) + + SDK_BIN_DIR=${jvm_root_dir}/${sdk_dir}/bin + AC_SUBST(SDK_BIN_DIR) + AC_MSG_RESULT(SDK tools directory: ${SDK_BIN_DIR}) + + SDK_LIB_DIR=${jvm_root_dir}/${sdk_dir}/lib + AC_SUBST(SDK_LIB_DIR) + AC_MSG_RESULT(SDK jar directory: ${SDK_LIB_DIR}) + + SDK_INCLUDE_DIR=${jvm_root_dir}/${sdk_dir}/include + AC_SUBST(SDK_INCLUDE_DIR) + AC_MSG_RESULT(SDK include directory: ${SDK_INCLUDE_DIR}) + + JRE_BIN_DIR=${jvm_root_dir}/${jre_dir}/bin + AC_SUBST(JRE_BIN_DIR) + AC_MSG_RESULT(JRE tools directory: ${JRE_BIN_DIR}) + + JRE_LIB_DIR=${jvm_root_dir}/${jre_dir}/lib + AC_SUBST(JRE_LIB_DIR) + AC_MSG_RESULT(JRE lib directory: ${JRE_LIB_DIR}) + + # Find gcj prefix using gcj found in PATH. + gcj_prefix=`which gcj${gcc_suffix} | sed "s%/bin/gcj${gcc_suffix}%%"` + + # Where do the gcj binaries live? + # For jhbuild based builds, they all live in a sibling of bin called + # gcj-bin. Check for gcj-bin first, and use bin otherwise. + GCJ_BIN_DIR=`if test -d ${gcj_prefix}/gcj-bin; then echo ${gcj_prefix}/gcj-bin; else echo ${gcj_prefix}/bin; fi` + AC_SUBST(GCJ_BIN_DIR) + AC_MSG_RESULT(GCJ tools directory: ${GCJ_BIN_DIR}) + + echo host is ${host} + if test "x${host_cpu}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_cpu=x86;; + i486-* | i586-* | i686-*) + host_cpu=i386;; + *) + host_cpu=${host_cpu};; + esac + fi + AC_MSG_RESULT(arch directory: ${host_cpu}) + CPU=${host_cpu} + AC_SUBST(CPU) + + if test "x${host_os}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_os=win32;; + *-linux*) + host_os=linux;; + *) + host_os=${host_os};; + esac + fi + echo os directory: ${host_os} + OS=${host_os} + AC_SUBST(OS) + + # make an expanded $libdir, for substituting into + # scripts (and other non-Makefile things). + LIBDIR=$libdir + if test "x${exec_prefix}" = "xNONE" + then + lib_exec_prefix=$sdk_prefix + else + lib_exec_prefix=$exec_prefix + fi + LIBDIR=`echo $libdir | sed "s:\\\${exec_prefix}:$lib_exec_prefix:g"` + AC_SUBST(LIBDIR) +fi + AC_CONFIG_FILES([ Makefile libgcj.pc @@ -1633,6 +1833,10 @@ gcj/Makefile include/Makefile testsuite/Makefile +contrib/aotcompile.py +contrib/aot-compile +contrib/aot-compile-rpm +contrib/rebuild-gcj-db ]) if test ${multilib} = yes; then ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-19 14:24 ` Joshua Sumali @ 2008-06-20 4:13 ` Joshua Sumali 2008-06-26 18:18 ` Joshua Sumali 1 sibling, 0 replies; 18+ messages in thread From: Joshua Sumali @ 2008-06-20 4:13 UTC (permalink / raw) To: java-patches Joshua Sumali wrote: > Andrew Haley wrote: >> Joshua Sumali wrote: >> >> >>> Please see the two (updated) patches. The updated patch for the >>> "Packager files" thread is now part of the sdk-home patch attached >>> here, >>> since I had to modify configure.ac to generate those packager files >>> this >>> time around. >>> >>> gcc-install-and-docs.patch creates man and info pages for aot-compile >>> and rebuild-gcj-db, and also documents the new install options >>> (--enable-java-home, --with-arch-directory, --with-python-dir) as >>> requested by Matthias. >>> gcc-libjava-sdk-home-update.patch is mostly the same as the first patch >>> I posted here, except with these main changes: >>> >>> - aot-compile and rebuild-gcj-db are now installed in $bindir >>> - if --with-python-dir is not specified (say, in a regular upstream >>> build) , classfile.py and aotcompile.py are installed in >>> $(prefix)/share/python. Otherwise, those Python modules will be >>> installed in the path specified with --with-python-dir. I modified >>> aot-compile -> aot-compile.in to append whichever path classfile.py and >>> aotcompile.py was installed in, so that it can actually find these >>> modules (it wouldn't look in $(prefix)/share/python by default). >>> - the SDK symlinked binaries, as well as aot-compile and >>> rebuild-gcj-db are now `transformed' as requested by Matthias. >>> >> >> OK, thanks. >> >> >>> Outstanding issues: >>> 1. @Matthias, I'm still not sure what you mean by "Same for using >>> GIJ_VERSION". Also, the issue about "why using the long version at >>> all?" >>> 2. rebuild-gcj-db doesn't have a licence header on the top of the >>> file... is this required? And if so, what's the right thing to do >>> about it? >>> >> >> Make it GPL. >> >> Andrew. >> > Updated rebuild-gcj-db with license header. > > Josh Actually, please don't do anything with this patch yet. I've noticed a problem with rpm packaging as the sdk-home and python stuff gets installed into its hardcoded paths instead of using $(prefix). This makes the rpm build fail in the %install section since the files are still installed into the --prefix specified in `./configure --prefix=<...>` instead of the prefix specified by `make prefix=<...> install`. Fixing this problem ... Josh ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-19 14:24 ` Joshua Sumali 2008-06-20 4:13 ` Joshua Sumali @ 2008-06-26 18:18 ` Joshua Sumali 2008-06-30 10:20 ` Andrew Haley 1 sibling, 1 reply; 18+ messages in thread From: Joshua Sumali @ 2008-06-26 18:18 UTC (permalink / raw) To: java-patches [-- Attachment #1: Type: text/plain, Size: 2251 bytes --] Joshua Sumali wrote: > Andrew Haley wrote: >> Joshua Sumali wrote: >> >> >>> Please see the two (updated) patches. The updated patch for the >>> "Packager files" thread is now part of the sdk-home patch attached >>> here, >>> since I had to modify configure.ac to generate those packager files >>> this >>> time around. >>> >>> gcc-install-and-docs.patch creates man and info pages for aot-compile >>> and rebuild-gcj-db, and also documents the new install options >>> (--enable-java-home, --with-arch-directory, --with-python-dir) as >>> requested by Matthias. >>> gcc-libjava-sdk-home-update.patch is mostly the same as the first patch >>> I posted here, except with these main changes: >>> >>> - aot-compile and rebuild-gcj-db are now installed in $bindir >>> - if --with-python-dir is not specified (say, in a regular upstream >>> build) , classfile.py and aotcompile.py are installed in >>> $(prefix)/share/python. Otherwise, those Python modules will be >>> installed in the path specified with --with-python-dir. I modified >>> aot-compile -> aot-compile.in to append whichever path classfile.py and >>> aotcompile.py was installed in, so that it can actually find these >>> modules (it wouldn't look in $(prefix)/share/python by default). >>> - the SDK symlinked binaries, as well as aot-compile and >>> rebuild-gcj-db are now `transformed' as requested by Matthias. >>> >> >> OK, thanks. >> >> >>> Outstanding issues: >>> 1. @Matthias, I'm still not sure what you mean by "Same for using >>> GIJ_VERSION". Also, the issue about "why using the long version at >>> all?" >>> 2. rebuild-gcj-db doesn't have a licence header on the top of the >>> file... is this required? And if so, what's the right thing to do >>> about it? >>> >> >> Make it GPL. >> >> Andrew. >> > Updated rebuild-gcj-db with license header. > > Josh Hi, Updated documentation, and sdk patch attached. I think this one is ready to go in. -cleaned up the sdk patch -- no more $$GIJ_VERSION, and only 'java-1.5.0-gcj-1.5.0.0' is installed in /usr/lib/jvm is installed (as requested by Matthias). /usr/lib/jvm/{java-1.5.0-gcj, jre-1.5.0-gcj} symlinks are instead to be installed by the packages (I believe this is the right approach). Josh [-- Attachment #2: gcc-libjava-sdk-home-update3.patch --] [-- Type: text/x-patch, Size: 47511 bytes --] Index: libjava/contrib/rebuild-gcj-db.in =================================================================== --- libjava/contrib/rebuild-gcj-db.in (revision 0) +++ libjava/contrib/rebuild-gcj-db.in (revision 0) @@ -0,0 +1,24 @@ +#!/bin/bash +# rebuild-gcj-db + +## Copyright (C) 2000, 2002, 2003, 2008 Free Software Foundation +## +## This file is part of libgcj. +## +## This software is copyrighted work licensed under the terms of the +## Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +## details. + +# Rebuild all the standard databases. +for base in /usr/lib*; do + dbLocation=`@prefix@/bin/gcj-dbtool@gcc_suffix@ -p $base` + libdir=$base/gcj + if ! test -d $libdir; then + # No shared libraries here. + continue + fi + dirname $dbLocation | xargs mkdir -p + @prefix@/bin/gcj-dbtool@gcc_suffix@ -n $dbLocation 64 + find $libdir -follow -name '*.db' -print0 | \ + xargs -0 @prefix@/bin/gcj-dbtool@gcc_suffix@ -m $dbLocation $dbLocation +done Index: libjava/contrib/aotcompile.py.in =================================================================== --- libjava/contrib/aotcompile.py.in (revision 0) +++ libjava/contrib/aotcompile.py.in (revision 0) @@ -0,0 +1,412 @@ +# -*- python -*- + +## Copyright (C) 2005, 2006, 2008 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import classfile +import copy +import md5 +import operator +import os +import sys +import cStringIO as StringIO +import zipfile + +PATHS = {"make": "@MAKE@", + "gcj": "@prefix@/bin/gcj@gcc_suffix@", + "dbtool": "@prefix@/bin/gcj-dbtool@gcc_suffix@"} + +MAKEFLAGS = [] +GCJFLAGS = ["-fPIC", "-findirect-dispatch", "-fjni"] +LDFLAGS = ["-Wl,-Bsymbolic"] + +MAX_CLASSES_PER_JAR = 1024 +MAX_BYTES_PER_JAR = 1048576 + +MAKEFILE = "Makefile" + +MAKEFILE_HEADER = '''\ +GCJ = %(gcj)s +DBTOOL = %(dbtool)s +GCJFLAGS = %(gcjflags)s +LDFLAGS = %(ldflags)s + +%%.o: %%.jar + $(GCJ) -c $(GCJFLAGS) $< -o $@ + +TARGETS = \\ +%(targets)s + +all: $(TARGETS)''' + +MAKEFILE_JOB = ''' +%(base)s_SOURCES = \\ +%(jars)s + +%(base)s_OBJECTS = \\ +$(%(base)s_SOURCES:.jar=.o) + +%(dso)s: $(%(base)s_OBJECTS) + $(GCJ) -shared $(GCJFLAGS) $(LDFLAGS) $^ -o $@ + +%(db)s: $(%(base)s_SOURCES) + $(DBTOOL) -n $@ 64 + for jar in $^; do \\ + $(DBTOOL) -f $@ $$jar \\ + %(libdir)s/%(dso)s; \\ + done''' + +ZIPMAGIC, CLASSMAGIC = "PK\x03\x04", "\xca\xfe\xba\xbe" + +class Error(Exception): + pass + +class Compiler: + def __init__(self, srcdir, libdir, prefix = None): + self.srcdir = os.path.abspath(srcdir) + self.libdir = os.path.abspath(libdir) + if prefix is None: + self.dstdir = self.libdir + else: + self.dstdir = os.path.join(prefix, self.libdir.lstrip(os.sep)) + + # Calling code may modify these parameters + self.gcjflags = copy.copy(GCJFLAGS) + self.ldflags = copy.copy(LDFLAGS) + self.makeflags = copy.copy(MAKEFLAGS) + self.exclusions = [] + + def compile(self): + """Search srcdir for classes and jarfiles, then generate + solibs and mappings databases for them all in libdir.""" + if not os.path.isdir(self.dstdir): + os.makedirs(self.dstdir) + oldcwd = os.getcwd() + os.chdir(self.dstdir) + try: + jobs = self.getJobList() + if not jobs: + raise Error, "nothing to do" + self.writeMakefile(MAKEFILE, jobs) + for job in jobs: + job.writeJars() + system([PATHS["make"]] + self.makeflags) + for job in jobs: + job.clean() + os.unlink(MAKEFILE) + finally: + os.chdir(oldcwd) + + def getJobList(self): + """Return all jarfiles and class collections in srcdir.""" + jobs = weed_jobs(find_jobs(self.srcdir, self.exclusions)) + set_basenames(jobs) + return jobs + + def writeMakefile(self, path, jobs): + """Generate a makefile to build the solibs and mappings + databases for the specified list of jobs.""" + fp = open(path, "w") + print >>fp, MAKEFILE_HEADER % { + "gcj": PATHS["gcj"], + "dbtool": PATHS["dbtool"], + "gcjflags": " ".join(self.gcjflags), + "ldflags": " ".join(self.ldflags), + "targets": " \\\n".join(reduce(operator.add, [ + (job.dsoName(), job.dbName()) for job in jobs]))} + for job in jobs: + values = job.ruleArguments() + values["libdir"] = self.libdir + print >>fp, MAKEFILE_JOB % values + fp.close() + +def find_jobs(dir, exclusions = ()): + """Scan a directory and find things to compile: jarfiles (zips, + wars, ears, rars, etc: we go by magic rather than file extension) + and directories of classes.""" + def visit((classes, zips), dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + magic = open(path, "r").read(4) + if magic == ZIPMAGIC: + zips.append(path) + elif magic == CLASSMAGIC: + classes.append(path) + classes, paths = [], [] + os.path.walk(dir, visit, (classes, paths)) + # Convert the list of classes into a list of directories + while classes: + # XXX this requires the class to be correctly located in its heirachy. + path = classes[0][:-len(os.sep + classname(classes[0]) + ".class")] + paths.append(path) + classes = [cls for cls in classes if not cls.startswith(path)] + # Handle exclusions. We're really strict about them because the + # option is temporary in aot-compile-rpm and dead options left in + # specfiles will hinder its removal. + for path in exclusions: + if path in paths: + paths.remove(path) + else: + raise Error, "%s: path does not exist or is not a job" % path + # Build the list of jobs + jobs = [] + paths.sort() + for path in paths: + if os.path.isfile(path): + job = JarJob(path) + else: + job = DirJob(path) + if len(job.classes): + jobs.append(job) + return jobs + +class Job: + """A collection of classes that will be compiled as a unit.""" + + def __init__(self, path): + self.path, self.classes, self.blocks = path, {}, None + + def addClass(self, bytes): + """Subclasses call this from their __init__ method for + every class they find.""" + self.classes[md5.new(bytes).digest()] = bytes + + def __makeBlocks(self): + """Split self.classes into chunks that can be compiled to + native code by gcj. In the majority of cases this is not + necessary -- the job will have come from a jarfile which will + be equivalent to the one we generate -- but this only happens + _if_ the job was a jarfile and _if_ the jarfile isn't too big + and _if_ the jarfile has the correct extension and _if_ all + classes are correctly named and _if_ the jarfile has no + embedded jarfiles. Fitting a special case around all these + conditions is tricky to say the least. + + Note that this could be called at the end of each subclass's + __init__ method. The reason this is not done is because we + need to parse every class file. This is slow, and unnecessary + if the job is subsetted.""" + names = {} + for hash, bytes in self.classes.items(): + name = classname(bytes) + if not names.has_key(name): + names[name] = [] + names[name].append(hash) + names = names.items() + # We have to sort somehow, or the jars we generate + # We sort by name in a simplistic attempt to keep related + # classes together so inter-class optimisation can happen. + names.sort() + self.blocks, bytes = [[]], 0 + for name, hashes in names: + for hash in hashes: + if len(self.blocks[-1]) >= MAX_CLASSES_PER_JAR \ + or bytes >= MAX_BYTES_PER_JAR: + self.blocks.append([]) + bytes = 0 + self.blocks[-1].append((name, hash)) + bytes += len(self.classes[hash]) + + # From Archit Shah: + # The implementation and the documentation don't seem to match. + # + # [a, b].isSubsetOf([a]) => True + # + # Identical copies of all classes this collection do not exist + # in the other. I think the method should be named isSupersetOf + # and the documentation should swap uses of "this" and "other" + # + # XXX think about this when I've had more sleep... + def isSubsetOf(self, other): + """Returns True if identical copies of all classes in this + collection exist in the other.""" + for item in other.classes.keys(): + if not self.classes.has_key(item): + return False + return True + + def __targetName(self, ext): + return self.basename + ext + + def tempJarName(self, num): + return self.__targetName(".%d.jar" % (num + 1)) + + def tempObjName(self, num): + return self.__targetName(".%d.o" % (num + 1)) + + def dsoName(self): + """Return the filename of the shared library that will be + built from this job.""" + return self.__targetName(".so") + + def dbName(self): + """Return the filename of the mapping database that will be + built from this job.""" + return self.__targetName(".db") + + def ruleArguments(self): + """Return a dictionary of values that when substituted + into MAKEFILE_JOB will create the rules required to build + the shared library and mapping database for this job.""" + if self.blocks is None: + self.__makeBlocks() + return { + "base": "".join( + [c.isalnum() and c or "_" for c in self.dsoName()]), + "jars": " \\\n".join( + [self.tempJarName(i) for i in xrange(len(self.blocks))]), + "dso": self.dsoName(), + "db": self.dbName()} + + def writeJars(self): + """Generate jarfiles that can be native compiled by gcj.""" + if self.blocks is None: + self.__makeBlocks() + for block, i in zip(self.blocks, xrange(len(self.blocks))): + jar = zipfile.ZipFile(self.tempJarName(i), "w", zipfile.ZIP_STORED) + for name, hash in block: + jar.writestr( + zipfile.ZipInfo("%s.class" % name), self.classes[hash]) + jar.close() + + def clean(self): + """Delete all temporary files created during this job's build.""" + if self.blocks is None: + self.__makeBlocks() + for i in xrange(len(self.blocks)): + os.unlink(self.tempJarName(i)) + os.unlink(self.tempObjName(i)) + +class JarJob(Job): + """A Job whose origin was a jarfile.""" + + def __init__(self, path): + Job.__init__(self, path) + self._walk(zipfile.ZipFile(path, "r")) + + def _walk(self, zf): + for name in zf.namelist(): + bytes = zf.read(name) + if bytes.startswith(ZIPMAGIC): + self._walk(zipfile.ZipFile(StringIO.StringIO(bytes))) + elif bytes.startswith(CLASSMAGIC): + self.addClass(bytes) + +class DirJob(Job): + """A Job whose origin was a directory of classfiles.""" + + def __init__(self, path): + Job.__init__(self, path) + os.path.walk(path, DirJob._visit, self) + + def _visit(self, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + fp = open(path, "r") + magic = fp.read(4) + if magic == CLASSMAGIC: + self.addClass(magic + fp.read()) + +def weed_jobs(jobs): + """Remove any jarfiles that are completely contained within + another. This is more common than you'd think, and we only + need one nativified copy of each class after all.""" + jobs = copy.copy(jobs) + while True: + for job1 in jobs: + for job2 in jobs: + if job1 is job2: + continue + if job1.isSubsetOf(job2): + msg = "subsetted %s" % job2.path + if job2.isSubsetOf(job1): + if (isinstance(job1, DirJob) and + isinstance(job2, JarJob)): + # In the braindead case where a package + # contains an expanded copy of a jarfile + # the jarfile takes precedence. + continue + msg += " (identical)" + warn(msg) + jobs.remove(job2) + break + else: + continue + break + else: + break + continue + return jobs + +def set_basenames(jobs): + """Ensure that each jarfile has a different basename.""" + names = {} + for job in jobs: + name = os.path.basename(job.path) + if not names.has_key(name): + names[name] = [] + names[name].append(job) + for name, set in names.items(): + if len(set) == 1: + set[0].basename = name + continue + # prefix the jar filenames to make them unique + # XXX will not work in most cases -- needs generalising + set = [(job.path.split(os.sep), job) for job in set] + minlen = min([len(bits) for bits, job in set]) + set = [(bits[-minlen:], job) for bits, job in set] + bits = apply(zip, [bits for bits, job in set]) + while True: + row = bits[-2] + for bit in row[1:]: + if bit != row[0]: + break + else: + del bits[-2] + continue + break + set = zip( + ["_".join(name) for name in apply(zip, bits[-2:])], + [job for bits, job in set]) + for name, job in set: + warn("building %s as %s" % (job.path, name)) + job.basename = name + # XXX keep this check until we're properly general + names = {} + for job in jobs: + name = job.basename + if names.has_key(name): + raise Error, "%s: duplicate jobname" % name + names[name] = 1 + +def system(command): + """Execute a command.""" + status = os.spawnv(os.P_WAIT, command[0], command) + if status > 0: + raise Error, "%s exited with code %d" % (command[0], status) + elif status < 0: + raise Error, "%s killed by signal %d" % (command[0], -status) + +def warn(msg): + """Print a warning message.""" + print >>sys.stderr, "%s: warning: %s" % ( + os.path.basename(sys.argv[0]), msg) + +def classname(bytes): + """Extract the class name from the bytes of a class file.""" + klass = classfile.Class(bytes) + return klass.constants[klass.constants[klass.name][1]][1] Index: libjava/contrib/aot-compile-rpm.in =================================================================== --- libjava/contrib/aot-compile-rpm.in (revision 0) +++ libjava/contrib/aot-compile-rpm.in (revision 0) @@ -0,0 +1,97 @@ +#!/usr/bin/env python + +## Copyright (C) 2005, 2006, 2007 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir_expanded@") +import aotcompile +import os + +def libdir(): + cmd = "%s -p" % aotcompile.PATHS["dbtool"] + dir = os.path.abspath(os.popen(cmd, "r").readline().rstrip()) + dir, base = os.path.split(dir) + if base != "classmap.db": + raise aotcompile.Error, "%s: unexpected output" % cmd + dir, base = os.path.split(dir) + if not base.startswith("gcj-"): + raise aotcompile.Error, "%s: unexpected output" % cmd + return dir + +def writeSourceList(srcdir, dstpath): + def visit(fp, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.isfile(path): + print >>fp, path + dstdir = os.path.dirname(dstpath) + if not os.path.isdir(dstdir): + os.makedirs(dstdir) + os.path.walk(srcdir, visit, open(dstpath, "w")) + +def copy(srcdir, dstdir, suffix): + srcdir = os.path.join(srcdir, suffix.lstrip(os.sep)) + dstdir = os.path.join(dstdir, suffix.lstrip(os.sep)) + os.makedirs(os.path.dirname(dstdir)) + aotcompile.system(("/bin/cp", "-a", srcdir, dstdir)) + +try: + name = os.environ.get("RPM_PACKAGE_NAME") + if name is None: + raise aotcompile.Error, "not for use outside rpm specfiles" + arch = os.environ.get("RPM_ARCH") + if arch == "noarch": + raise aotcompile.Error, "cannot be used on noarch packages" + srcdir = os.environ.get("RPM_BUILD_ROOT") + if srcdir in (None, "/"): + raise aotcompile.Error, "bad $RPM_BUILD_ROOT" + tmpdir = os.path.join(os.getcwd(), "aot-compile-rpm") + if os.path.exists(tmpdir): + raise aotcompile.Error, "%s exists" % tmpdir + dstdir = os.path.join(libdir(), "gcj", name) + + compiler = aotcompile.Compiler(srcdir, dstdir, tmpdir) + compiler.gcjflags[0:0] = os.environ.get("RPM_OPT_FLAGS", "").split() + + # XXX: This script should not accept options, because having + # them it cannot be integrated into rpm. But, gcj cannot + # build each and every jarfile yet, so we must be able to + # exclude until it can. + # XXX --exclude is also used in the jonas rpm to stop + # everything being made a subset of the mammoth client + # jarfile. Should adjust the subset checker's bias to + # favour many small jarfiles over one big one. + try: + options, exclusions = sys.argv[1:], [] + while options: + if options.pop(0) != "--exclude": + raise ValueError + compiler.exclusions.append( + os.path.join(srcdir, options.pop(0).lstrip(os.sep))) + except: + print >>sys.stderr, "usage: %s [--exclude PATH]..." % ( + os.path.basename(sys.argv[0])) + sys.exit(1) + + sourcelist = os.path.join(tmpdir, "sources.list") + writeSourceList(os.getcwd(), sourcelist) + compiler.gcjflags.append("-fsource-filename=" + sourcelist) + + compiler.compile() + copy(tmpdir, srcdir, dstdir) + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/contrib/classfile.py =================================================================== --- libjava/contrib/classfile.py (revision 0) +++ libjava/contrib/classfile.py (revision 0) @@ -0,0 +1,221 @@ +## Copyright (C) 2004, 2005 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +"""Read Java(TM) class files.""" + +import cStringIO as StringIO +import struct + +class Class: + def __init__(self, arg): + if hasattr(arg, "read"): + self.fp = arg + elif type(arg) == type(""): + if arg.startswith("\xca\xfe\xba\xbe"): + self.fp = StringIO.StringIO(arg) + else: + self.fp = open(arg, "r") + else: + raise TypeError, type(arg) + + magic = self._read_int() + assert magic == 0xcafebabeL + minor, major = self._read(">HH") + self.version = (major, minor) + + self.pool_integrity_checks = None + try: + assert False + except AssertionError: + self.pool_integrity_checks = [] + + self._read_constants_pool() + + self.access_flags = self._read_short() + self.name = self._read_reference_Class() + self.super = self._read_reference_Class() + + self.interfaces = self._read_interfaces() + self.fields = self._read_fieldsormethods() + self.methods = self._read_fieldsormethods() + self.attributes = self._read_attributes() + + if self.pool_integrity_checks is not None: + for index, tag in self.pool_integrity_checks: + assert self.constants[index][0] == tag + + del self.fp, self.pool_integrity_checks + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) + if not attr.startswith("_") and attr != "Member"] + attrs.sort() + for attr in attrs: + result.append("%-13s %s" % ( + attr + ":", attr == "constants" and + "<ELIDED>" or repr(getattr(self, attr)))) + return "\n".join(result) + + def _read_constants_pool(self): + self.constants = {} + skip = False + for i in xrange(1, self._read_short()): + if skip: + skip = False + continue + tag = { + 1: "Utf8", 3: "Integer", 4: "Float", 5: "Long", + 6: "Double", 7: "Class", 8: "String", 9: "Fieldref", + 10: "Methodref", 11: "InterfaceMethodref", + 12: "NameAndType"}[self._read_byte()] + skip = tag in ("Long", "Double") # crack crack crack! + self.constants[i] = (tag, getattr(self, "_read_constant_" + tag)()) + + def _read_interfaces(self): + result = [] + for i in xrange(self._read_short()): + result.append(self._read_reference_Class()) + return result + + def _read_fieldsormethods(self): + result = [] + for i in xrange(self._read_short()): + result.append(self.Member(self)) + return result + + class Member: + def __init__(self, source): + self.access_flags = source._read_short() + self.name = source._read_reference_Utf8() + self.descriptor = source._read_reference_Utf8() + self.attributes = source._read_attributes() + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) if not attr.startswith("_")] + attrs.sort() + for attr in attrs: + value = getattr(self, attr) + if attr == "attributes" and value.has_key("Code"): + value = value.copy() + value.update({"Code": "<ELIDED>"}) + result.append("%-13s %s" % ( + attr + ":", repr(value).replace( + "'Code': '<ELIDED>'", "'Code': <ELIDED>"))) + return ("\n%s" % (15 * " ")).join(result) + + def _read_attributes(self): + result = {} + for i in xrange(self._read_short()): + name = self._read_reference_Utf8() + data = self.fp.read(self._read_int()) + assert not result.has_key(name) + result[name] = data + return result + + # Constants pool reference reader convenience functions + + def _read_reference_Utf8(self): + return self._read_references("Utf8")[0] + + def _read_reference_Class(self): + return self._read_references("Class")[0] + + def _read_reference_Class_NameAndType(self): + return self._read_references("Class", "NameAndType") + + def _read_references(self, *args): + result = [] + for arg in args: + index = self._read_short() + if self.pool_integrity_checks is not None: + self.pool_integrity_checks.append((index, arg)) + result.append(index) + return result + + # Constants pool constant reader functions + + def _read_constant_Utf8(self): + constant = self.fp.read(self._read_short()) + try: + constant = constant.decode("utf-8") + except UnicodeError: + constant = _bork_utf8_decode(constant) + try: + constant = constant.encode("us-ascii") + except UnicodeError: + pass + return constant + + def _read_constant_Integer(self): + return self._read_int() + + def _read_constant_Float(self): + return self._read(">f")[0] + + def _read_constant_Long(self): + return self._read(">q")[0] + + def _read_constant_Double(self): + return self._read(">d")[0] + + _read_constant_Class = _read_reference_Utf8 + _read_constant_String = _read_reference_Utf8 + _read_constant_Fieldref = _read_reference_Class_NameAndType + _read_constant_Methodref = _read_reference_Class_NameAndType + _read_constant_InterfaceMethodref = _read_reference_Class_NameAndType + + def _read_constant_NameAndType(self): + return self._read_reference_Utf8(), self._read_reference_Utf8() + + # Generic reader functions + + def _read_int(self): + # XXX how else to read 32 bits on a 64-bit box? + h, l = map(long, self._read(">HH")) + return (h << 16) + l + + def _read_short(self): + return self._read(">H")[0] + + def _read_byte(self): + return self._read("B")[0] + + def _read(self, fmt): + return struct.unpack(fmt, self.fp.read(struct.calcsize(fmt))) + +def _bork_utf8_decode(data): + # more crack! + bytes, unicode = map(ord, data), "" + while bytes: + b1 = bytes.pop(0) + if b1 & 0x80: + assert b1 & 0x40 + b2 = bytes.pop(0) + assert b2 & 0xC0 == 0x80 + if b1 & 0x20: + assert not b1 & 0x10 + b3 = bytes.pop(0) + assert b3 & 0xC0 == 0x80 + unicode += unichr( + ((b1 & 0x0f) << 12) + ((b2 & 0x3f) << 6) + (b3 & 0x3f)) + else: + unicode += unichr(((b1 & 0x1f) << 6) + (b2 & 0x3f)) + else: + unicode += unichr(b1) + return unicode + +if __name__ == "__main__": + print Class("/usr/share/katana/build/ListDependentClasses.class") + Index: libjava/contrib/aot-compile.in =================================================================== --- libjava/contrib/aot-compile.in (revision 0) +++ libjava/contrib/aot-compile.in (revision 0) @@ -0,0 +1,88 @@ +#!/usr/bin/env python + +## Copyright (C) 2006 Red Hat, Inc. +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir_expanded@") +import aotcompile +import getopt +import os + +usage = """\ +Usage: %s [OPTION...] SRCDIR DSTDIR +AOT-compile all Java bytecode in SRCDIR into DSTDIR. + +Options: + -M, --make=PATH make executable to use (%s) + -C, --gcj=PATH gcj executable to use (%s) + -D, --dbtool=PATH gcj-dbtool executable to use (%s) + -m, --makeflags=FLAGS flags to pass to make during build + -c, --gcjflags=FLAGS flags to pass to gcj during compilation + in addition to %s + -l, --ldflags=FLAGS flags to pass to gcj during linking + in addition to %s + -e, --exclude=PATH do not compile PATH + +Extra flags may also be passed using the AOT_MAKEFLAGS, AOT_GCJFLAGS +and AOT_LDFLAGS environment variables.""" % ( + os.path.basename(sys.argv[0]), + aotcompile.PATHS["make"], + aotcompile.PATHS["gcj"], + aotcompile.PATHS["dbtool"], + repr(" ".join(aotcompile.GCJFLAGS)), + repr(" ".join(aotcompile.LDFLAGS))) + +try: + if os.environ.has_key("RPM_PACKAGE_NAME"): + raise aotcompile.Error, "not for use within rpm specfiles" + + try: + opts, args = getopt.getopt( + sys.argv[1:], + "M:C:D:m:c:l:e:", + ["make=", "gcj=", "dbtool=", + "makeflags=" "gcjflags=", "ldflags=", + "exclude="]) + srcdir, dstdir = args + except: + print >>sys.stderr, usage + sys.exit(1) + + compiler = aotcompile.Compiler(srcdir, dstdir) + for o, a in opts: + if o in ("-M", "--make"): + aotcompile.PATHS["make"] = a + if o in ("-C", "--gcj"): + aotcompile.PATHS["gcj"] = a + if o in ("-D", "--dbtool"): + aotcompile.PATHS["dbtool"] = a + if o in ("-m", "--makeflags"): + compiler.makeflags[0:0] = a.split() + if o in ("-c", "--gcjflags"): + compiler.gcjflags[0:0] = a.split() + if o in ("-l", "--ldflags"): + compiler.ldflags[0:0] = a.split() + if o in ("-e", "--exclude"): + compiler.exclusions.append(a) + + compiler.makeflags[0:0] = os.environ.get("AOT_MAKEFLAGS", "").split() + compiler.gcjflags[0:0] = os.environ.get("AOT_GCJFLAGS", "").split() + compiler.ldflags[0:0] = os.environ.get("AOT_LDFLAGS", "").split() + + compiler.compile() + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/ChangeLog =================================================================== --- libjava/ChangeLog (revision 136895) +++ libjava/ChangeLog (working copy) @@ -1,3 +1,31 @@ +2008-06-26 Joshua Sumali <jsumali@redhat.com> + + * configure.ac (java-home): new AC_ARG_ENABLE. + (aot-compile-rpm): Likewise. + (CREATE_JAVA_HOME): new AM_CONDITIONAL. + (INSTALL_AOT_RPM): Likewise. + (gcc-suffix): new AC_ARG_WITH. + (arch-directory): Likewise. + (os-directory): Likewise. + (origin-name): Likewise. + (arch-suffix): Likewise. + (jvm-root-dir): Likewise. + (jvm-jar-dir): Likewise. + (python-dir): Likewise. + (AC_CONFIG_FILES): Add contrib/aotcompile.py, contrib/aot-compile, + contrib/aot-compile-rpm, contrib/rebuild-gcj-db. + * Makefile.am (install-data-local): Install Python modules for + aot-compile. Also install an sdk style directory if --enable-java-home + is passed to configure. + (bin_SCRIPTS): add contrib/rebuild-gcj-db and contrib/aot-compile. + * contrib/aot-compile.in: New file. + * contrib/aotcompile.py.in: Likewise. + * contrib/aot-compile-rpm.in: Likewise. + * contrib/classfile.py: Likewise. + * contrib/rebuild-gcj-db.in: Likewise. + * configure: Regenerate. + * Makefile.in: Regenerate. + 2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> * configure: Regenerate. Index: libjava/Makefile.am =================================================================== --- libjava/Makefile.am (revision 136895) +++ libjava/Makefile.am (working copy) @@ -85,10 +85,14 @@ ## It is convenient to actually build and install the default database ## when gcj-dbtool is available. dbexec_DATA = $(db_name) +endif + +bin_SCRIPTS = addr2name.awk contrib/rebuild-gcj-db contrib/aot-compile + +if INSTALL_AOT_RPM +bin_SCRIPTS += contrib/aot-compile-rpm endif -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 @@ -528,8 +532,141 @@ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SinkChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SourceChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ ## Don't install java/nio/DirectByteBufferImpl$$ReadWrite.h here. It's for internal use only. +## Install Python modules for aot-compile. + $(mkinstalldirs) $(DESTDIR)$(python_mod_dir); \ + $(INSTALL_DATA) $(srcdir)/contrib/classfile.py \ + $(DESTDIR)$(python_mod_dir)/classfile.py; \ + $(INSTALL_DATA) contrib/aotcompile.py \ + $(DESTDIR)$(python_mod_dir)/aotcompile.py; +if CREATE_JAVA_HOME +## Create sdk style directories + $(mkinstalldirs) $(DESTDIR)$(JRE_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/$(OS) + relative() { \ + $(PERL) -e 'use File::Spec; \ + print File::Spec->abs2rel($$ARGV[0], $$ARGV[1])' $$1 $$2; \ + }; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(SDK_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gjar | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jar; \ + ln -sf $$RELATIVE/`echo gjdoc | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javadoc; \ + ln -sf $$RELATIVE/`echo grmic | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmic; \ + ln -sf $$RELATIVE/`echo gjavah | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javah; \ + ln -sf $$RELATIVE/ecj $(DESTDIR)$(SDK_BIN_DIR)/javac; \ + ln -sf $$RELATIVE/`echo gappletviewer | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/appletviewer; \ + ln -sf $$RELATIVE/`echo gjarsigner | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jarsigner; \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo gnative2ascii | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/native2ascii; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/tnameserv; \ + ln -sf $$RELATIVE/`echo gserialver | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/serialver; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(JRE_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/tnameserv; \ + $(mkinstalldirs) $(DESTDIR)$(JVM_JAR_DIR); \ + version=$(JAVA_VERSION).$(BUILD_VERSION); \ + working_dir=`pwd`; \ + cd $(DESTDIR)$(JVM_JAR_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s $$RELATIVE/$$jarname.jar $$jarname-$$version.jar; \ + done; \ + for jar in *-$$version.jar; \ + do \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|-$(JAVA_VERSION).jar|g"); \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|.jar|g"); \ + done; \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/security; \ + RELATIVE=$$(relative $(DESTDIR)$(libdir)/security \ + $(DESTDIR)$(JRE_LIB_DIR)/security); \ + cd $(DESTDIR)$(JRE_LIB_DIR)/security; \ + ln -sf $$RELATIVE/classpath.security java.security; \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/linux; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_LIB_DIR); \ + cd $(DESTDIR)$(JRE_LIB_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s rt.jar $$jarname.jar; \ + done; \ + cd $$working_dir; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JRE_LIB_DIR)); \ + ln -sf $$RELATIVE/libgcj-$(gcc_version).jar \ + $(DESTDIR)$(JRE_LIB_DIR)/rt.jar; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)); \ + ln -sf $$RELATIVE/libjawt.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/libjawt.so; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(SDK_LIB_DIR)); \ + ln -sf $$RELATIVE/libgcj-tools-$(gcc_version).jar \ + $(DESTDIR)$(SDK_LIB_DIR)/tools.jar; \ + for headername in jawt jni; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/$$headername.h; \ + done; \ + for headername in jawt_md jni_md; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux/$$headername.h; \ + done; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)); \ + ln -sf $$RELATIVE/src-$(gcc_version).zip \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)/src.zip; +endif - ## ################################################################ ## Index: libjava/configure.ac =================================================================== --- libjava/configure.ac (revision 136895) +++ libjava/configure.ac (working copy) @@ -1625,6 +1625,211 @@ # We get this from the environment. AC_SUBST(GCJFLAGS) +AC_ARG_WITH([python-dir], + AS_HELP_STRING([--with-python-dir], + [the location to install Python modules. This path should NOT include the prefix.]), + [with_python_dir=$withval], [with_python_dir=""]) + +if test "x${with_python_dir}" = "x" +then + # Needed for installing Python modules during make install. + python_mod_dir="\${prefix}/share/python" + # Needed for substituting into aot-compile* + python_mod_dir_expanded="${prefix}/share/python" +else + python_mod_dir="\${prefix}${with_python_dir}" + python_mod_dir_expanded="${prefix}${with_python_dir}" +fi +AC_MSG_RESULT(Python modules dir: ${python_mod_dir_expanded}); +AC_SUBST(python_mod_dir) +AC_SUBST(python_mod_dir_expanded) + +# needed for aot-compile-rpm +MAKE=`which make` +AC_SUBST(MAKE) + +AC_ARG_ENABLE([aot-compile-rpm], + [AS_HELP_STRING([--enable-aot-compile-rpm], + [enable installation of aot-compile-rpm [default=no]])], + [case "${enableval}" in + yes) AOT_RPM_ENABLED=yes ;; + no) AOT_RPM_ENABLED=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable aot-compile-rpm]) ;; + esac], + [AOT_RPM_ENABLED=no] +) +AM_CONDITIONAL(INSTALL_AOT_RPM, test "x${AOT_RPM_ENABLED}" == xyes) + +AC_ARG_ENABLE([java-home], + [AS_HELP_STRING([--enable-java-home], + [create a standard JDK-style directory layout in the install tree [default=no]])], + [case "${enableval}" in + yes) JAVA_HOME_ENABLED=yes ;; + no) JAVA_HOME_ENABLED=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable java-home]) ;; + esac], + [JAVA_HOME_ENABLED=no] +) +AM_CONDITIONAL(CREATE_JAVA_HOME, test "x${JAVA_HOME_ENABLED}" == xyes) + +# Only do these checks if java-home above is enabled. +if test "x${JAVA_HOME_ENABLED}" == xyes +then + + AC_ARG_WITH([gcc-suffix], + AS_HELP_STRING([--with-gcc-suffix], + [the GCC tool suffix (defaults to empty string)]), + [gcc_suffix=$withval], [gcc_suffix=""]) + AC_MSG_RESULT(GCC suffix: ${gcc_suffix}) + AC_SUBST(gcc_suffix) + + AC_ARG_WITH([arch-directory], + AS_HELP_STRING([--with-arch-directory], + [the arch directory under jre/lib (defaults to auto-detect)]), + [host_cpu=$withval], [host_cpu=""]) + + AC_ARG_WITH([os-directory], + AS_HELP_STRING([--with-os-directory], + [the os directory under include (defaults to auto-detect)]), + [host_os=$withval], [host_os=""]) + + AC_ARG_WITH([origin-name], + AS_HELP_STRING([--with-origin-name], + [the JPackage origin name of this package (default is gcj${gcc_suffix}]), + [origin_name=$withval], [origin_name=gcj${gcc_suffix}]) + AC_MSG_RESULT(JPackage origin name: ${origin_name}) + + AC_ARG_WITH([arch-suffix], + AS_HELP_STRING([--with-arch-suffix], + [the arch directory suffix (default is the empty string]), + [arch_suffix=$withval], [arch_suffix=""]) + AC_MSG_RESULT(arch suffix: ${arch_suffix}) + + AC_ARG_WITH([jvm-root-dir], + AS_HELP_STRING([--with-jvm-root-dir], + [where to install SDK (default is ${prefix}/lib/jvm)]), + [jvm_root_dir=$withval], [jvm_root_dir="\${prefix}/lib/jvm"]) + AC_MSG_RESULT(JVM root installation directory: ${jvm_root_dir}) + + AC_ARG_WITH([jvm-jar-dir], + AS_HELP_STRING([--with-jvm-jar-dir], + [where to install jars (default is ${prefix}/lib/jvm-exports)]), + [jvm_jar_dir=$withval], [jvm_jar_dir=\${prefix}/lib/jvm-exports]) + AC_MSG_RESULT(JAR root installation directory: ${jvm_jar_dir}) + + JAVA_VERSION=1.5.0 + BUILD_VERSION=0 + AC_SUBST(JAVA_VERSION) + AC_SUBST(BUILD_VERSION) + AC_MSG_RESULT(Java version: ${JAVA_VERSION}) + + jre_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix}/jre + sdk_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix} + jre_lnk=jre-${JAVA_VERSION}-${origin_name} + sdk_lnk=java-${JAVA_VERSION}-${origin_name} + + JVM_ROOT_DIR=${jvm_root_dir} + AC_SUBST(JVM_ROOT_DIR) + AC_MSG_RESULT(JVM ROOT directory: ${JVM_ROOT_DIR}) + + JVM_JAR_ROOT_DIR=${jvm_jar_dir} + AC_SUBST(JVM_JAR_ROOT_DIR) + AC_MSG_RESULT(JVM JAR ROOT directory: ${JVM_JAR_ROOT_DIR}) + + JVM_JAR_DIR=${jvm_jar_dir}/${sdk_dir} + AC_SUBST(JVM_JAR_DIR) + AC_MSG_RESULT(JVM JAR directory: ${JVM_JAR_DIR}) + + JRE_DIR=${jre_dir} + AC_SUBST(JRE_DIR) + + SDK_DIR=${sdk_dir} + AC_SUBST(SDK_DIR) + + JRE_LNK=${jre_lnk} + AC_SUBST(JRE_LNK) + + SDK_LNK=${sdk_lnk} + AC_SUBST(SDK_LNK) + + JAVA_HOME_DIR=${jvm_root_dir}/${jre_dir} + AC_SUBST(JAVA_HOME_DIR) + AC_MSG_RESULT(JAVA_HOME directory: ${JAVA_HOME_DIR}) + + SDK_BIN_DIR=${jvm_root_dir}/${sdk_dir}/bin + AC_SUBST(SDK_BIN_DIR) + AC_MSG_RESULT(SDK tools directory: ${SDK_BIN_DIR}) + + SDK_LIB_DIR=${jvm_root_dir}/${sdk_dir}/lib + AC_SUBST(SDK_LIB_DIR) + AC_MSG_RESULT(SDK jar directory: ${SDK_LIB_DIR}) + + SDK_INCLUDE_DIR=${jvm_root_dir}/${sdk_dir}/include + AC_SUBST(SDK_INCLUDE_DIR) + AC_MSG_RESULT(SDK include directory: ${SDK_INCLUDE_DIR}) + + JRE_BIN_DIR=${jvm_root_dir}/${jre_dir}/bin + AC_SUBST(JRE_BIN_DIR) + AC_MSG_RESULT(JRE tools directory: ${JRE_BIN_DIR}) + + JRE_LIB_DIR=${jvm_root_dir}/${jre_dir}/lib + AC_SUBST(JRE_LIB_DIR) + AC_MSG_RESULT(JRE lib directory: ${JRE_LIB_DIR}) + + # Find gcj prefix using gcj found in PATH. + gcj_prefix=`which gcj${gcc_suffix} | sed "s%/bin/gcj${gcc_suffix}%%"` + + # Where do the gcj binaries live? + # For jhbuild based builds, they all live in a sibling of bin called + # gcj-bin. Check for gcj-bin first, and use bin otherwise. + GCJ_BIN_DIR=`if test -d ${gcj_prefix}/gcj-bin; then echo ${gcj_prefix}/gcj-bin; else echo ${gcj_prefix}/bin; fi` + AC_SUBST(GCJ_BIN_DIR) + AC_MSG_RESULT(GCJ tools directory: ${GCJ_BIN_DIR}) + + echo host is ${host} + if test "x${host_cpu}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_cpu=x86;; + i486-* | i586-* | i686-*) + host_cpu=i386;; + *) + host_cpu=${host_cpu};; + esac + fi + AC_MSG_RESULT(arch directory: ${host_cpu}) + CPU=${host_cpu} + AC_SUBST(CPU) + + if test "x${host_os}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_os=win32;; + *-linux*) + host_os=linux;; + *) + host_os=${host_os};; + esac + fi + echo os directory: ${host_os} + OS=${host_os} + AC_SUBST(OS) + + # make an expanded $libdir, for substituting into + # scripts (and other non-Makefile things). + LIBDIR=$libdir + if test "x${exec_prefix}" = "xNONE" + then + lib_exec_prefix=$prefix + else + lib_exec_prefix=$exec_prefix + fi + LIBDIR=`echo $libdir | sed "s:\\\${exec_prefix}:$lib_exec_prefix:g"` + AC_SUBST(LIBDIR) +fi + AC_CONFIG_FILES([ Makefile libgcj.pc @@ -1633,6 +1838,10 @@ gcj/Makefile include/Makefile testsuite/Makefile +contrib/aotcompile.py +contrib/aot-compile +contrib/aot-compile-rpm +contrib/rebuild-gcj-db ]) if test ${multilib} = yes; then [-- Attachment #3: gcc-install-and-docs-update1.patch --] [-- Type: text/x-patch, Size: 9678 bytes --] Index: gcc/ChangeLog =================================================================== --- gcc/ChangeLog (revision 137153) +++ gcc/ChangeLog (working copy) @@ -1,3 +1,15 @@ +2008-06-26 Joshua Sumali <jsumali@redhat.com> + + * doc/install.texi (--enable-java-home): Document. + (--enable-aot-compile-rpm): Likewise. + (--with-arch-directory): Likewise. + (--with-os-directory): Likewise. + (--with-origin-name): Likewise. + (--with-arch-suffix): Likewise. + (--with-jvm-root-dir): Likewise. + (--with-jvm-jar-dir): Likewise. + (--with-python-dir): Likewise. + 2008-06-26 Joseph Myers <joseph@codesourcery.com> * c-decl.c (merge_decls): Use !current_function_decl to check for Index: gcc/doc/install.texi =================================================================== --- gcc/doc/install.texi (revision 137153) +++ gcc/doc/install.texi (working copy) @@ -1607,6 +1607,45 @@ @item --with-win32-nlsapi=ansi, unicows or unicode Indicates how MinGW @samp{libgcj} translates between UNICODE characters and the Win32 API@. + +@item --enable-java-home +If enabled, this creates a JPackage compatible SDK environment during install. +Note that if --enable-java-home is used, --with-arch-directory=ARCH must also +be specified. + +@item --with-arch-directory=ARCH +Specifies the name to use for the @file{jre/lib/ARCH} directory in the SDK +environment created when --enable-java-home is passed. Typical names for this +directory include i386, amd64, ia64, etc. + +@item --with-os-directory=DIR +Specifies the OS directory for the SDK include directory. This is set to auto +detect, and is typically 'linux'. + +@item --with-origin-name=NAME +Specifies the JPackage origin name. This defaults to the 'gcj' in +java-1.5.0-gcj. + +@item --with-arch-suffix=SUFFIX +Specifies the suffix for the sdk directory. Defaults to the empty string. +Examples include '.x86_64' in 'java-1.5.0-gcj-1.5.0.0.x86_64'. + +@item --with-jvm-root-dir=DIR +Specifies where to install the SDK. Default is $(prefix)/lib/jvm. + +@item --with-jvm-jar-dir=DIR +Specifies where to install jars. Default is $(prefix)/lib/jvm-exports. + +@item --with-python-dir=DIR +Specifies where to install the Python modules used for aot-compile. DIR should +not include the prefix used in installation. For example, if the Python modules +are to be installed in /usr/lib/python2.5/site-packages, then +--with-python-dir=/lib/python2.5/site-packages should be passed. If this is +not specified, then the Python modules are installed in $(prefix)/share/python. + +@item --enable-aot-compile-rpm +Adds aot-compile-rpm to the list of installed scripts. + @table @code @item ansi Use the single-byte @code{char} and the Win32 A functions natively, Index: gcc/java/ChangeLog =================================================================== --- gcc/java/ChangeLog (revision 137153) +++ gcc/java/ChangeLog (working copy) @@ -1,3 +1,14 @@ +2008-06-26 Joshua Sumali <jsumali@redhat.com> + + * Make-lang.in (JAVA_MANFILES): Add doc/aot-compile.1 and + doc/rebuild-gcj-db.1 + (java.uninstall): Likewise. + (java.maintainer-clean): Likewise. + (aot-compile.pod): New rule. + (rebuild-gcj-db.pod): New rule. + (java.install-man): Install doc/aot-compile.1 and doc/rebuild-gcj-db.1 + * gcj.texi: Add new sections for aot-compile and rebuild-gcj-db. + 2008-06-24 Tom Tromey <tromey@redhat.com> * jcf-path.c (jcf_path_init): Don't name variable 'try'. Index: gcc/java/gcj.texi =================================================================== --- gcc/java/gcj.texi (revision 137153) +++ gcc/java/gcj.texi (working copy) @@ -72,6 +72,11 @@ Generate stubs for Remote Method Invocation. * gc-analyze: (gcj)Invoking gc-analyze. Analyze Garbage Collector (GC) memory dumps. +* aot-compile: (gcj)Invoking aot-compile. + Compile bytecode to native and generate databases. +* rebuild-gcj-db: (gcj)Invoking rebuild-gcj-db. + Merge the per-solib databases made by aot-compile + into one system-wide database. @end direntry @end format @@ -115,6 +120,9 @@ * Invoking jv-convert:: Converting from one encoding to another * Invoking grmic:: Generate stubs for Remote Method Invocation. * Invoking gc-analyze:: Analyze Garbage Collector (GC) memory dumps. +* Invoking aot-compile:: Compile bytecode to native and generate databases. +* Invoking rebuild-gcj-db:: Merge the per-solib databases made by aot-compile + into one system-wide database. * About CNI:: Description of the Compiled Native Interface * System properties:: Modifying runtime behavior of the libgcj library * Resources:: Where to look for more information @@ -921,7 +929,7 @@ [@option{-v}] [@option{-m}] [@option{--version}] [@option{--help}] @c man end -@c man begin SEEALSO gij +@c man begin SEEALSO gcj-dbtool gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), and the Info entries for @file{gcj} and @file{gcc}. @c man end @@ -1219,6 +1227,87 @@ @c man end +@node Invoking aot-compile +@chapter Invoking aot-compile + +@c man title aot-compile Compile bytecode to native and generate databases + +@ignore + +@c man begin SYNOPSIS aot-compile +aot-compile [@option{OPTION}] @dots{} @var{SRCDIR} @var{DSTDIR} + +aot-compile [@option{-M, --make}=@var{PATH}] [@option{-C, --gcj}=@var{PATH}] + [@option{-D, --dbtool}=@var{PATH}] [@option{-m, --makeflags}=@var{FLAGS}] + [@option{-c, --gcjflags}=@var{FLAGS}] [@option{-l, --ldflags}=@var{FLAGS}] + [@option{-e, --exclude}=@var{PATH}] +@c man end + +@c man begin SEEALSO aot-compile +gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), +and the Info entries for @file{gcj} and @file{gcc}. +@c man end + +@end ignore + +@c man begin DESCRIPTION aot-compile +@code{aot-compile} is a script that searches a directory for Java bytecode +(as class files, or in jars) and uses @code{gcj} to compile it to native +code and generate the databases from it. +@c man end + +@c man begin OPTIONS aot-compile +@table @gcctabopt +@item -M, --make=@var{PATH} +Specify the path to the @code{make} executable to use. + +@item -C, --gcj=@var{PATH} +Specify the path to the @code{gcj} executable to use. + +@item -D, --dbtool=@var{PATH} +Specify the path to the @code{gcj-dbtool} executable to use. + +@item -m, --makeflags=@var{FLAGS} +Specify flags to pass to @code{make} during the build. + +@item -c, --gcjflags=@var{FLAGS} +Specify flags to pass to @code{gcj} during compilation, in addition to +'-fPIC -findirect-dispatch -fjni'. + +@item -l, --ldflags=@var{FLAGS} +Specify flags to pass to @code{gcj} during linking, in addition to +'-Wl,-Bsymbolic'. + +@item -e, --exclude=@var{PATH} +Do not compile @var{PATH}. + +@end table + +@c man end + +@node Invoking rebuild-gcj-db +@chapter Invoking rebuild-gcj-db + +@c man title rebuild-gcj-db Merge the per-solib databases made by aot-compile into one system-wide database. +@ignore + +@c man begin SYNOPSIS rebuild-gcj-db +rebuild-gcj-db +@c man end + +@c man begin SEEALSO rebuild-gcj-db +gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), +and the Info entries for @file{gcj} and @file{gcc}. +@c man end + +@end ignore + +@c man begin DESCRIPTION rebuild-gcj-db +@code{rebuild-gcj-db} is a script that merges the per-solib databases made by +@code{aot-compile} into one system-wide database so @code{gij} can find the +solibs. +@c man end + @node About CNI @chapter About CNI Index: gcc/java/Make-lang.in =================================================================== --- gcc/java/Make-lang.in (revision 137153) +++ gcc/java/Make-lang.in (working copy) @@ -143,8 +143,9 @@ java.html: $(build_htmldir)/java/index.html JAVA_MANFILES = doc/gcj.1 doc/jcf-dump.1 doc/gij.1 \ - doc/jv-convert.1 doc/grmic.1\ - doc/gcj-dbtool.1 doc/gc-analyze.1 + doc/jv-convert.1 doc/grmic.1 \ + doc/gcj-dbtool.1 doc/gc-analyze.1 doc/aot-compile.1 \ + doc/rebuild-gcj-db.1 java.man: $(JAVA_MANFILES) @@ -189,6 +190,8 @@ -rm -rf $(DESTDIR)$(man1dir)/gij$(man1ext) -rm -rf $(DESTDIR)$(man1dir)/jv-convert$(man1ext) -rm -rf $(DESTDIR)$(man1dir)/gcj-dbtool$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/aot-compile$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/rebuild-gcj-db$(man1ext) java.install-info: $(DESTDIR)$(infodir)/gcj.info @@ -223,6 +226,8 @@ -rm -f $(docobjdir)/grmic.1 -rm -f $(docobjdir)/gcj-dbtool.1 -rm -f $(docobjdir)/gc-analyze.1 + -rm -f $(docobjdir)/aot-compile.1 + -rm -f $(docobjdir)/rebuild-gcj-db.1 #\f # Stage hooks: # The main makefile has already created stage?/java. @@ -353,15 +358,21 @@ -$(TEXI2POD) -D gcj-dbtool < $< > $@ gc-analyze.pod: java/gcj.texi -$(TEXI2POD) -D gc-analyze < $< > $@ +aot-compile.pod: java/gcj.texi + -$(TEXI2POD) -D aot-compile < $< > $@ +rebuild-gcj-db.pod: java/gcj.texi + -$(TEXI2POD) -D rebuild-gcj-db < $< > $@ # Install the man pages. java.install-man: installdirs \ $(DESTDIR)$(man1dir)/$(JAVA_INSTALL_NAME)$(man1ext) \ $(JAVA_TARGET_INDEPENDENT_BIN_TOOLS:%=doc/%.1) \ doc/gij.1 doc/jv-convert.1 doc/grmic.1 \ - doc/gcj-dbtool.1 doc/gc-analyze.1 + doc/gcj-dbtool.1 doc/gc-analyze.1 \ + doc/aot-compile.1 doc/rebuild-gcj-db.1 for tool in $(JAVA_TARGET_INDEPENDENT_BIN_TOOLS) \ - gij jv-convert grmic gcj-dbtool gc-analyze ; do \ + gij jv-convert grmic gcj-dbtool gc-analyze aot-compile \ + rebuild-gcj-db; do \ tool_transformed_name=`echo $$tool|sed '$(program_transform_name)'`; \ man_name=$(DESTDIR)$(man1dir)/$${tool_transformed_name}$(man1ext); \ rm -f $$man_name ; \ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-26 18:18 ` Joshua Sumali @ 2008-06-30 10:20 ` Andrew Haley 2008-06-30 13:54 ` Joshua Sumali 0 siblings, 1 reply; 18+ messages in thread From: Andrew Haley @ 2008-06-30 10:20 UTC (permalink / raw) To: Joshua Sumali; +Cc: java-patches Joshua Sumali wrote: > Joshua Sumali wrote: >> Andrew Haley wrote: >>> Joshua Sumali wrote: >>> >>> >>>> Please see the two (updated) patches. The updated patch for the >>>> "Packager files" thread is now part of the sdk-home patch attached >>>> here, >>>> since I had to modify configure.ac to generate those packager files >>>> this >>>> time around. >>>> >>>> gcc-install-and-docs.patch creates man and info pages for aot-compile >>>> and rebuild-gcj-db, and also documents the new install options >>>> (--enable-java-home, --with-arch-directory, --with-python-dir) as >>>> requested by Matthias. >>>> gcc-libjava-sdk-home-update.patch is mostly the same as the first patch >>>> I posted here, except with these main changes: >>>> >>>> - aot-compile and rebuild-gcj-db are now installed in $bindir >>>> - if --with-python-dir is not specified (say, in a regular upstream >>>> build) , classfile.py and aotcompile.py are installed in >>>> $(prefix)/share/python. Otherwise, those Python modules will be >>>> installed in the path specified with --with-python-dir. I modified >>>> aot-compile -> aot-compile.in to append whichever path classfile.py and >>>> aotcompile.py was installed in, so that it can actually find these >>>> modules (it wouldn't look in $(prefix)/share/python by default). >>>> - the SDK symlinked binaries, as well as aot-compile and >>>> rebuild-gcj-db are now `transformed' as requested by Matthias. >>>> >>> >>> OK, thanks. >>> >>> >>>> Outstanding issues: >>>> 1. @Matthias, I'm still not sure what you mean by "Same for using >>>> GIJ_VERSION". Also, the issue about "why using the long version at >>>> all?" >>>> 2. rebuild-gcj-db doesn't have a licence header on the top of the >>>> file... is this required? And if so, what's the right thing to do >>>> about it? >>>> >>> >>> Make it GPL. >>> >>> Andrew. >>> >> Updated rebuild-gcj-db with license header. >> >> Josh > Hi, > > Updated documentation, and sdk patch attached. I think this one is ready > to go in. Nearly there. Please don't put the ChangeLog files into the diffs. Post them as plain text. Please assign all Red Hat copyrights to the FSF. Do I take it that you don't have commit access to the gcc tree? Andrew. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-30 10:20 ` Andrew Haley @ 2008-06-30 13:54 ` Joshua Sumali 2008-06-30 13:57 ` Andrew Haley 0 siblings, 1 reply; 18+ messages in thread From: Joshua Sumali @ 2008-06-30 13:54 UTC (permalink / raw) To: Andrew Haley, java-patches Andrew Haley wrote: > > Nearly there. > > Please don't put the ChangeLog files into the diffs. Post them as plain text. > Will do. > Please assign all Red Hat copyrights to the FSF. > Is there a special way to do this, or do I simply change "Copyright (C) 2005, 2006, 2008 Red Hat, Inc." to "Copyright (C) 2005, 2006, 2008 Free Software Foundation" on the appropriate files? > Do I take it that you don't have commit access to the gcc tree? > I do not. I was hoping someone would be able to commit the patches for me. > Andrew. > Josh ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-30 13:54 ` Joshua Sumali @ 2008-06-30 13:57 ` Andrew Haley 2008-06-30 14:39 ` Joshua Sumali 0 siblings, 1 reply; 18+ messages in thread From: Andrew Haley @ 2008-06-30 13:57 UTC (permalink / raw) To: Joshua Sumali; +Cc: java-patches Joshua Sumali wrote: > Andrew Haley wrote: >> Please assign all Red Hat copyrights to the FSF. >> > Is there a special way to do this, or do I simply change "Copyright (C) > 2005, 2006, 2008 Red Hat, Inc." to "Copyright (C) 2005, 2006, 2008 Free > Software Foundation" on the appropriate files? That's all you have to do. >> Do I take it that you don't have commit access to the gcc tree? >> > I do not. I was hoping someone would be able to commit the patches for me. I'll do it. Andrew. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-30 13:57 ` Andrew Haley @ 2008-06-30 14:39 ` Joshua Sumali 2008-07-01 13:59 ` Andrew Haley 2008-07-02 13:07 ` Andrew Haley 0 siblings, 2 replies; 18+ messages in thread From: Joshua Sumali @ 2008-06-30 14:39 UTC (permalink / raw) To: Andrew Haley; +Cc: java-patches [-- Attachment #1: Type: text/plain, Size: 2630 bytes --] Andrew Haley wrote: > Joshua Sumali wrote: > >> Andrew Haley wrote: >> > > >>> Please assign all Red Hat copyrights to the FSF. >>> >>> >> Is there a special way to do this, or do I simply change "Copyright (C) >> 2005, 2006, 2008 Red Hat, Inc." to "Copyright (C) 2005, 2006, 2008 Free >> Software Foundation" on the appropriate files? >> > > That's all you have to do. > > >>> Do I take it that you don't have commit access to the gcc tree? >>> >>> >> I do not. I was hoping someone would be able to commit the patches for me. >> > > I'll do it. > > Andrew. > > Copyrights assigned to FSF. ChangeLogs removed from patches and are found below. libjava/ 2008-06-30 Joshua Sumali <jsumali@redhat.com> * configure.ac (java-home): new AC_ARG_ENABLE. (aot-compile-rpm): Likewise. (CREATE_JAVA_HOME): new AM_CONDITIONAL. (INSTALL_AOT_RPM): Likewise. (gcc-suffix): new AC_ARG_WITH. (arch-directory): Likewise. (os-directory): Likewise. (origin-name): Likewise. (arch-suffix): Likewise. (jvm-root-dir): Likewise. (jvm-jar-dir): Likewise. (python-dir): Likewise. (AC_CONFIG_FILES): Add contrib/aotcompile.py, contrib/aot-compile, contrib/aot-compile-rpm, contrib/rebuild-gcj-db. * Makefile.am (install-data-local): Install Python modules for aot-compile. Also install an sdk style directory if --enable-java-home is passed to configure. (bin_SCRIPTS): add contrib/rebuild-gcj-db and contrib/aot-compile. * contrib/aot-compile.in: New file. * contrib/aotcompile.py.in: Likewise. * contrib/aot-compile-rpm.in: Likewise. * contrib/classfile.py: Likewise. * contrib/rebuild-gcj-db.in: Likewise. * configure: Regenerate. * Makefile.in: Regenerate. gcc/ 2008-06-30 Joshua Sumali <jsumali@redhat.com> * doc/install.texi (--enable-java-home): Document. (--enable-aot-compile-rpm): Likewise. (--with-arch-directory): Likewise. (--with-os-directory): Likewise. (--with-origin-name): Likewise. (--with-arch-suffix): Likewise. (--with-jvm-root-dir): Likewise. (--with-jvm-jar-dir): Likewise. (--with-python-dir): Likewise. gcc/java/ 2008-06-30 Joshua Sumali <jsumali@redhat.com> * Make-lang.in (JAVA_MANFILES): Add doc/aot-compile.1 and doc/rebuild-gcj-db.1 (java.uninstall): Likewise. (java.maintainer-clean): Likewise. (aot-compile.pod): New rule. (rebuild-gcj-db.pod): New rule. (java.install-man): Install doc/aot-compile.1 and doc/rebuild-gcj-db.1 * gcj.texi: Add new sections for aot-compile and rebuild-gcj-db. [-- Attachment #2: gcc-libjava-sdk-home-update4.patch --] [-- Type: text/x-patch, Size: 46246 bytes --] Index: libjava/contrib/rebuild-gcj-db.in =================================================================== --- libjava/contrib/rebuild-gcj-db.in (revision 0) +++ libjava/contrib/rebuild-gcj-db.in (revision 0) @@ -0,0 +1,24 @@ +#!/bin/bash +# rebuild-gcj-db + +## Copyright (C) 2000, 2002, 2003, 2008 Free Software Foundation +## +## This file is part of libgcj. +## +## This software is copyrighted work licensed under the terms of the +## Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +## details. + +# Rebuild all the standard databases. +for base in /usr/lib*; do + dbLocation=`@prefix@/bin/gcj-dbtool@gcc_suffix@ -p $base` + libdir=$base/gcj + if ! test -d $libdir; then + # No shared libraries here. + continue + fi + dirname $dbLocation | xargs mkdir -p + @prefix@/bin/gcj-dbtool@gcc_suffix@ -n $dbLocation 64 + find $libdir -follow -name '*.db' -print0 | \ + xargs -0 @prefix@/bin/gcj-dbtool@gcc_suffix@ -m $dbLocation $dbLocation +done Index: libjava/contrib/aotcompile.py.in =================================================================== --- libjava/contrib/aotcompile.py.in (revision 0) +++ libjava/contrib/aotcompile.py.in (revision 0) @@ -0,0 +1,412 @@ +# -*- python -*- + +## Copyright (C) 2005, 2006, 2008 Free Software Foundation +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import classfile +import copy +import md5 +import operator +import os +import sys +import cStringIO as StringIO +import zipfile + +PATHS = {"make": "@MAKE@", + "gcj": "@prefix@/bin/gcj@gcc_suffix@", + "dbtool": "@prefix@/bin/gcj-dbtool@gcc_suffix@"} + +MAKEFLAGS = [] +GCJFLAGS = ["-fPIC", "-findirect-dispatch", "-fjni"] +LDFLAGS = ["-Wl,-Bsymbolic"] + +MAX_CLASSES_PER_JAR = 1024 +MAX_BYTES_PER_JAR = 1048576 + +MAKEFILE = "Makefile" + +MAKEFILE_HEADER = '''\ +GCJ = %(gcj)s +DBTOOL = %(dbtool)s +GCJFLAGS = %(gcjflags)s +LDFLAGS = %(ldflags)s + +%%.o: %%.jar + $(GCJ) -c $(GCJFLAGS) $< -o $@ + +TARGETS = \\ +%(targets)s + +all: $(TARGETS)''' + +MAKEFILE_JOB = ''' +%(base)s_SOURCES = \\ +%(jars)s + +%(base)s_OBJECTS = \\ +$(%(base)s_SOURCES:.jar=.o) + +%(dso)s: $(%(base)s_OBJECTS) + $(GCJ) -shared $(GCJFLAGS) $(LDFLAGS) $^ -o $@ + +%(db)s: $(%(base)s_SOURCES) + $(DBTOOL) -n $@ 64 + for jar in $^; do \\ + $(DBTOOL) -f $@ $$jar \\ + %(libdir)s/%(dso)s; \\ + done''' + +ZIPMAGIC, CLASSMAGIC = "PK\x03\x04", "\xca\xfe\xba\xbe" + +class Error(Exception): + pass + +class Compiler: + def __init__(self, srcdir, libdir, prefix = None): + self.srcdir = os.path.abspath(srcdir) + self.libdir = os.path.abspath(libdir) + if prefix is None: + self.dstdir = self.libdir + else: + self.dstdir = os.path.join(prefix, self.libdir.lstrip(os.sep)) + + # Calling code may modify these parameters + self.gcjflags = copy.copy(GCJFLAGS) + self.ldflags = copy.copy(LDFLAGS) + self.makeflags = copy.copy(MAKEFLAGS) + self.exclusions = [] + + def compile(self): + """Search srcdir for classes and jarfiles, then generate + solibs and mappings databases for them all in libdir.""" + if not os.path.isdir(self.dstdir): + os.makedirs(self.dstdir) + oldcwd = os.getcwd() + os.chdir(self.dstdir) + try: + jobs = self.getJobList() + if not jobs: + raise Error, "nothing to do" + self.writeMakefile(MAKEFILE, jobs) + for job in jobs: + job.writeJars() + system([PATHS["make"]] + self.makeflags) + for job in jobs: + job.clean() + os.unlink(MAKEFILE) + finally: + os.chdir(oldcwd) + + def getJobList(self): + """Return all jarfiles and class collections in srcdir.""" + jobs = weed_jobs(find_jobs(self.srcdir, self.exclusions)) + set_basenames(jobs) + return jobs + + def writeMakefile(self, path, jobs): + """Generate a makefile to build the solibs and mappings + databases for the specified list of jobs.""" + fp = open(path, "w") + print >>fp, MAKEFILE_HEADER % { + "gcj": PATHS["gcj"], + "dbtool": PATHS["dbtool"], + "gcjflags": " ".join(self.gcjflags), + "ldflags": " ".join(self.ldflags), + "targets": " \\\n".join(reduce(operator.add, [ + (job.dsoName(), job.dbName()) for job in jobs]))} + for job in jobs: + values = job.ruleArguments() + values["libdir"] = self.libdir + print >>fp, MAKEFILE_JOB % values + fp.close() + +def find_jobs(dir, exclusions = ()): + """Scan a directory and find things to compile: jarfiles (zips, + wars, ears, rars, etc: we go by magic rather than file extension) + and directories of classes.""" + def visit((classes, zips), dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + magic = open(path, "r").read(4) + if magic == ZIPMAGIC: + zips.append(path) + elif magic == CLASSMAGIC: + classes.append(path) + classes, paths = [], [] + os.path.walk(dir, visit, (classes, paths)) + # Convert the list of classes into a list of directories + while classes: + # XXX this requires the class to be correctly located in its heirachy. + path = classes[0][:-len(os.sep + classname(classes[0]) + ".class")] + paths.append(path) + classes = [cls for cls in classes if not cls.startswith(path)] + # Handle exclusions. We're really strict about them because the + # option is temporary in aot-compile-rpm and dead options left in + # specfiles will hinder its removal. + for path in exclusions: + if path in paths: + paths.remove(path) + else: + raise Error, "%s: path does not exist or is not a job" % path + # Build the list of jobs + jobs = [] + paths.sort() + for path in paths: + if os.path.isfile(path): + job = JarJob(path) + else: + job = DirJob(path) + if len(job.classes): + jobs.append(job) + return jobs + +class Job: + """A collection of classes that will be compiled as a unit.""" + + def __init__(self, path): + self.path, self.classes, self.blocks = path, {}, None + + def addClass(self, bytes): + """Subclasses call this from their __init__ method for + every class they find.""" + self.classes[md5.new(bytes).digest()] = bytes + + def __makeBlocks(self): + """Split self.classes into chunks that can be compiled to + native code by gcj. In the majority of cases this is not + necessary -- the job will have come from a jarfile which will + be equivalent to the one we generate -- but this only happens + _if_ the job was a jarfile and _if_ the jarfile isn't too big + and _if_ the jarfile has the correct extension and _if_ all + classes are correctly named and _if_ the jarfile has no + embedded jarfiles. Fitting a special case around all these + conditions is tricky to say the least. + + Note that this could be called at the end of each subclass's + __init__ method. The reason this is not done is because we + need to parse every class file. This is slow, and unnecessary + if the job is subsetted.""" + names = {} + for hash, bytes in self.classes.items(): + name = classname(bytes) + if not names.has_key(name): + names[name] = [] + names[name].append(hash) + names = names.items() + # We have to sort somehow, or the jars we generate + # We sort by name in a simplistic attempt to keep related + # classes together so inter-class optimisation can happen. + names.sort() + self.blocks, bytes = [[]], 0 + for name, hashes in names: + for hash in hashes: + if len(self.blocks[-1]) >= MAX_CLASSES_PER_JAR \ + or bytes >= MAX_BYTES_PER_JAR: + self.blocks.append([]) + bytes = 0 + self.blocks[-1].append((name, hash)) + bytes += len(self.classes[hash]) + + # From Archit Shah: + # The implementation and the documentation don't seem to match. + # + # [a, b].isSubsetOf([a]) => True + # + # Identical copies of all classes this collection do not exist + # in the other. I think the method should be named isSupersetOf + # and the documentation should swap uses of "this" and "other" + # + # XXX think about this when I've had more sleep... + def isSubsetOf(self, other): + """Returns True if identical copies of all classes in this + collection exist in the other.""" + for item in other.classes.keys(): + if not self.classes.has_key(item): + return False + return True + + def __targetName(self, ext): + return self.basename + ext + + def tempJarName(self, num): + return self.__targetName(".%d.jar" % (num + 1)) + + def tempObjName(self, num): + return self.__targetName(".%d.o" % (num + 1)) + + def dsoName(self): + """Return the filename of the shared library that will be + built from this job.""" + return self.__targetName(".so") + + def dbName(self): + """Return the filename of the mapping database that will be + built from this job.""" + return self.__targetName(".db") + + def ruleArguments(self): + """Return a dictionary of values that when substituted + into MAKEFILE_JOB will create the rules required to build + the shared library and mapping database for this job.""" + if self.blocks is None: + self.__makeBlocks() + return { + "base": "".join( + [c.isalnum() and c or "_" for c in self.dsoName()]), + "jars": " \\\n".join( + [self.tempJarName(i) for i in xrange(len(self.blocks))]), + "dso": self.dsoName(), + "db": self.dbName()} + + def writeJars(self): + """Generate jarfiles that can be native compiled by gcj.""" + if self.blocks is None: + self.__makeBlocks() + for block, i in zip(self.blocks, xrange(len(self.blocks))): + jar = zipfile.ZipFile(self.tempJarName(i), "w", zipfile.ZIP_STORED) + for name, hash in block: + jar.writestr( + zipfile.ZipInfo("%s.class" % name), self.classes[hash]) + jar.close() + + def clean(self): + """Delete all temporary files created during this job's build.""" + if self.blocks is None: + self.__makeBlocks() + for i in xrange(len(self.blocks)): + os.unlink(self.tempJarName(i)) + os.unlink(self.tempObjName(i)) + +class JarJob(Job): + """A Job whose origin was a jarfile.""" + + def __init__(self, path): + Job.__init__(self, path) + self._walk(zipfile.ZipFile(path, "r")) + + def _walk(self, zf): + for name in zf.namelist(): + bytes = zf.read(name) + if bytes.startswith(ZIPMAGIC): + self._walk(zipfile.ZipFile(StringIO.StringIO(bytes))) + elif bytes.startswith(CLASSMAGIC): + self.addClass(bytes) + +class DirJob(Job): + """A Job whose origin was a directory of classfiles.""" + + def __init__(self, path): + Job.__init__(self, path) + os.path.walk(path, DirJob._visit, self) + + def _visit(self, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + fp = open(path, "r") + magic = fp.read(4) + if magic == CLASSMAGIC: + self.addClass(magic + fp.read()) + +def weed_jobs(jobs): + """Remove any jarfiles that are completely contained within + another. This is more common than you'd think, and we only + need one nativified copy of each class after all.""" + jobs = copy.copy(jobs) + while True: + for job1 in jobs: + for job2 in jobs: + if job1 is job2: + continue + if job1.isSubsetOf(job2): + msg = "subsetted %s" % job2.path + if job2.isSubsetOf(job1): + if (isinstance(job1, DirJob) and + isinstance(job2, JarJob)): + # In the braindead case where a package + # contains an expanded copy of a jarfile + # the jarfile takes precedence. + continue + msg += " (identical)" + warn(msg) + jobs.remove(job2) + break + else: + continue + break + else: + break + continue + return jobs + +def set_basenames(jobs): + """Ensure that each jarfile has a different basename.""" + names = {} + for job in jobs: + name = os.path.basename(job.path) + if not names.has_key(name): + names[name] = [] + names[name].append(job) + for name, set in names.items(): + if len(set) == 1: + set[0].basename = name + continue + # prefix the jar filenames to make them unique + # XXX will not work in most cases -- needs generalising + set = [(job.path.split(os.sep), job) for job in set] + minlen = min([len(bits) for bits, job in set]) + set = [(bits[-minlen:], job) for bits, job in set] + bits = apply(zip, [bits for bits, job in set]) + while True: + row = bits[-2] + for bit in row[1:]: + if bit != row[0]: + break + else: + del bits[-2] + continue + break + set = zip( + ["_".join(name) for name in apply(zip, bits[-2:])], + [job for bits, job in set]) + for name, job in set: + warn("building %s as %s" % (job.path, name)) + job.basename = name + # XXX keep this check until we're properly general + names = {} + for job in jobs: + name = job.basename + if names.has_key(name): + raise Error, "%s: duplicate jobname" % name + names[name] = 1 + +def system(command): + """Execute a command.""" + status = os.spawnv(os.P_WAIT, command[0], command) + if status > 0: + raise Error, "%s exited with code %d" % (command[0], status) + elif status < 0: + raise Error, "%s killed by signal %d" % (command[0], -status) + +def warn(msg): + """Print a warning message.""" + print >>sys.stderr, "%s: warning: %s" % ( + os.path.basename(sys.argv[0]), msg) + +def classname(bytes): + """Extract the class name from the bytes of a class file.""" + klass = classfile.Class(bytes) + return klass.constants[klass.constants[klass.name][1]][1] Index: libjava/contrib/aot-compile-rpm.in =================================================================== --- libjava/contrib/aot-compile-rpm.in (revision 0) +++ libjava/contrib/aot-compile-rpm.in (revision 0) @@ -0,0 +1,97 @@ +#!/usr/bin/env python + +## Copyright (C) 2005, 2006, 2007 Free Software Foundation +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir_expanded@") +import aotcompile +import os + +def libdir(): + cmd = "%s -p" % aotcompile.PATHS["dbtool"] + dir = os.path.abspath(os.popen(cmd, "r").readline().rstrip()) + dir, base = os.path.split(dir) + if base != "classmap.db": + raise aotcompile.Error, "%s: unexpected output" % cmd + dir, base = os.path.split(dir) + if not base.startswith("gcj-"): + raise aotcompile.Error, "%s: unexpected output" % cmd + return dir + +def writeSourceList(srcdir, dstpath): + def visit(fp, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.isfile(path): + print >>fp, path + dstdir = os.path.dirname(dstpath) + if not os.path.isdir(dstdir): + os.makedirs(dstdir) + os.path.walk(srcdir, visit, open(dstpath, "w")) + +def copy(srcdir, dstdir, suffix): + srcdir = os.path.join(srcdir, suffix.lstrip(os.sep)) + dstdir = os.path.join(dstdir, suffix.lstrip(os.sep)) + os.makedirs(os.path.dirname(dstdir)) + aotcompile.system(("/bin/cp", "-a", srcdir, dstdir)) + +try: + name = os.environ.get("RPM_PACKAGE_NAME") + if name is None: + raise aotcompile.Error, "not for use outside rpm specfiles" + arch = os.environ.get("RPM_ARCH") + if arch == "noarch": + raise aotcompile.Error, "cannot be used on noarch packages" + srcdir = os.environ.get("RPM_BUILD_ROOT") + if srcdir in (None, "/"): + raise aotcompile.Error, "bad $RPM_BUILD_ROOT" + tmpdir = os.path.join(os.getcwd(), "aot-compile-rpm") + if os.path.exists(tmpdir): + raise aotcompile.Error, "%s exists" % tmpdir + dstdir = os.path.join(libdir(), "gcj", name) + + compiler = aotcompile.Compiler(srcdir, dstdir, tmpdir) + compiler.gcjflags[0:0] = os.environ.get("RPM_OPT_FLAGS", "").split() + + # XXX: This script should not accept options, because having + # them it cannot be integrated into rpm. But, gcj cannot + # build each and every jarfile yet, so we must be able to + # exclude until it can. + # XXX --exclude is also used in the jonas rpm to stop + # everything being made a subset of the mammoth client + # jarfile. Should adjust the subset checker's bias to + # favour many small jarfiles over one big one. + try: + options, exclusions = sys.argv[1:], [] + while options: + if options.pop(0) != "--exclude": + raise ValueError + compiler.exclusions.append( + os.path.join(srcdir, options.pop(0).lstrip(os.sep))) + except: + print >>sys.stderr, "usage: %s [--exclude PATH]..." % ( + os.path.basename(sys.argv[0])) + sys.exit(1) + + sourcelist = os.path.join(tmpdir, "sources.list") + writeSourceList(os.getcwd(), sourcelist) + compiler.gcjflags.append("-fsource-filename=" + sourcelist) + + compiler.compile() + copy(tmpdir, srcdir, dstdir) + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/contrib/classfile.py =================================================================== --- libjava/contrib/classfile.py (revision 0) +++ libjava/contrib/classfile.py (revision 0) @@ -0,0 +1,221 @@ +## Copyright (C) 2004, 2005 Free Software Foundation +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +"""Read Java(TM) class files.""" + +import cStringIO as StringIO +import struct + +class Class: + def __init__(self, arg): + if hasattr(arg, "read"): + self.fp = arg + elif type(arg) == type(""): + if arg.startswith("\xca\xfe\xba\xbe"): + self.fp = StringIO.StringIO(arg) + else: + self.fp = open(arg, "r") + else: + raise TypeError, type(arg) + + magic = self._read_int() + assert magic == 0xcafebabeL + minor, major = self._read(">HH") + self.version = (major, minor) + + self.pool_integrity_checks = None + try: + assert False + except AssertionError: + self.pool_integrity_checks = [] + + self._read_constants_pool() + + self.access_flags = self._read_short() + self.name = self._read_reference_Class() + self.super = self._read_reference_Class() + + self.interfaces = self._read_interfaces() + self.fields = self._read_fieldsormethods() + self.methods = self._read_fieldsormethods() + self.attributes = self._read_attributes() + + if self.pool_integrity_checks is not None: + for index, tag in self.pool_integrity_checks: + assert self.constants[index][0] == tag + + del self.fp, self.pool_integrity_checks + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) + if not attr.startswith("_") and attr != "Member"] + attrs.sort() + for attr in attrs: + result.append("%-13s %s" % ( + attr + ":", attr == "constants" and + "<ELIDED>" or repr(getattr(self, attr)))) + return "\n".join(result) + + def _read_constants_pool(self): + self.constants = {} + skip = False + for i in xrange(1, self._read_short()): + if skip: + skip = False + continue + tag = { + 1: "Utf8", 3: "Integer", 4: "Float", 5: "Long", + 6: "Double", 7: "Class", 8: "String", 9: "Fieldref", + 10: "Methodref", 11: "InterfaceMethodref", + 12: "NameAndType"}[self._read_byte()] + skip = tag in ("Long", "Double") # crack crack crack! + self.constants[i] = (tag, getattr(self, "_read_constant_" + tag)()) + + def _read_interfaces(self): + result = [] + for i in xrange(self._read_short()): + result.append(self._read_reference_Class()) + return result + + def _read_fieldsormethods(self): + result = [] + for i in xrange(self._read_short()): + result.append(self.Member(self)) + return result + + class Member: + def __init__(self, source): + self.access_flags = source._read_short() + self.name = source._read_reference_Utf8() + self.descriptor = source._read_reference_Utf8() + self.attributes = source._read_attributes() + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) if not attr.startswith("_")] + attrs.sort() + for attr in attrs: + value = getattr(self, attr) + if attr == "attributes" and value.has_key("Code"): + value = value.copy() + value.update({"Code": "<ELIDED>"}) + result.append("%-13s %s" % ( + attr + ":", repr(value).replace( + "'Code': '<ELIDED>'", "'Code': <ELIDED>"))) + return ("\n%s" % (15 * " ")).join(result) + + def _read_attributes(self): + result = {} + for i in xrange(self._read_short()): + name = self._read_reference_Utf8() + data = self.fp.read(self._read_int()) + assert not result.has_key(name) + result[name] = data + return result + + # Constants pool reference reader convenience functions + + def _read_reference_Utf8(self): + return self._read_references("Utf8")[0] + + def _read_reference_Class(self): + return self._read_references("Class")[0] + + def _read_reference_Class_NameAndType(self): + return self._read_references("Class", "NameAndType") + + def _read_references(self, *args): + result = [] + for arg in args: + index = self._read_short() + if self.pool_integrity_checks is not None: + self.pool_integrity_checks.append((index, arg)) + result.append(index) + return result + + # Constants pool constant reader functions + + def _read_constant_Utf8(self): + constant = self.fp.read(self._read_short()) + try: + constant = constant.decode("utf-8") + except UnicodeError: + constant = _bork_utf8_decode(constant) + try: + constant = constant.encode("us-ascii") + except UnicodeError: + pass + return constant + + def _read_constant_Integer(self): + return self._read_int() + + def _read_constant_Float(self): + return self._read(">f")[0] + + def _read_constant_Long(self): + return self._read(">q")[0] + + def _read_constant_Double(self): + return self._read(">d")[0] + + _read_constant_Class = _read_reference_Utf8 + _read_constant_String = _read_reference_Utf8 + _read_constant_Fieldref = _read_reference_Class_NameAndType + _read_constant_Methodref = _read_reference_Class_NameAndType + _read_constant_InterfaceMethodref = _read_reference_Class_NameAndType + + def _read_constant_NameAndType(self): + return self._read_reference_Utf8(), self._read_reference_Utf8() + + # Generic reader functions + + def _read_int(self): + # XXX how else to read 32 bits on a 64-bit box? + h, l = map(long, self._read(">HH")) + return (h << 16) + l + + def _read_short(self): + return self._read(">H")[0] + + def _read_byte(self): + return self._read("B")[0] + + def _read(self, fmt): + return struct.unpack(fmt, self.fp.read(struct.calcsize(fmt))) + +def _bork_utf8_decode(data): + # more crack! + bytes, unicode = map(ord, data), "" + while bytes: + b1 = bytes.pop(0) + if b1 & 0x80: + assert b1 & 0x40 + b2 = bytes.pop(0) + assert b2 & 0xC0 == 0x80 + if b1 & 0x20: + assert not b1 & 0x10 + b3 = bytes.pop(0) + assert b3 & 0xC0 == 0x80 + unicode += unichr( + ((b1 & 0x0f) << 12) + ((b2 & 0x3f) << 6) + (b3 & 0x3f)) + else: + unicode += unichr(((b1 & 0x1f) << 6) + (b2 & 0x3f)) + else: + unicode += unichr(b1) + return unicode + +if __name__ == "__main__": + print Class("/usr/share/katana/build/ListDependentClasses.class") + Index: libjava/contrib/aot-compile.in =================================================================== --- libjava/contrib/aot-compile.in (revision 0) +++ libjava/contrib/aot-compile.in (revision 0) @@ -0,0 +1,88 @@ +#!/usr/bin/env python + +## Copyright (C) 2006 Free Software Foundation +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir_expanded@") +import aotcompile +import getopt +import os + +usage = """\ +Usage: %s [OPTION...] SRCDIR DSTDIR +AOT-compile all Java bytecode in SRCDIR into DSTDIR. + +Options: + -M, --make=PATH make executable to use (%s) + -C, --gcj=PATH gcj executable to use (%s) + -D, --dbtool=PATH gcj-dbtool executable to use (%s) + -m, --makeflags=FLAGS flags to pass to make during build + -c, --gcjflags=FLAGS flags to pass to gcj during compilation + in addition to %s + -l, --ldflags=FLAGS flags to pass to gcj during linking + in addition to %s + -e, --exclude=PATH do not compile PATH + +Extra flags may also be passed using the AOT_MAKEFLAGS, AOT_GCJFLAGS +and AOT_LDFLAGS environment variables.""" % ( + os.path.basename(sys.argv[0]), + aotcompile.PATHS["make"], + aotcompile.PATHS["gcj"], + aotcompile.PATHS["dbtool"], + repr(" ".join(aotcompile.GCJFLAGS)), + repr(" ".join(aotcompile.LDFLAGS))) + +try: + if os.environ.has_key("RPM_PACKAGE_NAME"): + raise aotcompile.Error, "not for use within rpm specfiles" + + try: + opts, args = getopt.getopt( + sys.argv[1:], + "M:C:D:m:c:l:e:", + ["make=", "gcj=", "dbtool=", + "makeflags=" "gcjflags=", "ldflags=", + "exclude="]) + srcdir, dstdir = args + except: + print >>sys.stderr, usage + sys.exit(1) + + compiler = aotcompile.Compiler(srcdir, dstdir) + for o, a in opts: + if o in ("-M", "--make"): + aotcompile.PATHS["make"] = a + if o in ("-C", "--gcj"): + aotcompile.PATHS["gcj"] = a + if o in ("-D", "--dbtool"): + aotcompile.PATHS["dbtool"] = a + if o in ("-m", "--makeflags"): + compiler.makeflags[0:0] = a.split() + if o in ("-c", "--gcjflags"): + compiler.gcjflags[0:0] = a.split() + if o in ("-l", "--ldflags"): + compiler.ldflags[0:0] = a.split() + if o in ("-e", "--exclude"): + compiler.exclusions.append(a) + + compiler.makeflags[0:0] = os.environ.get("AOT_MAKEFLAGS", "").split() + compiler.gcjflags[0:0] = os.environ.get("AOT_GCJFLAGS", "").split() + compiler.ldflags[0:0] = os.environ.get("AOT_LDFLAGS", "").split() + + compiler.compile() + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/Makefile.am =================================================================== --- libjava/Makefile.am (revision 136895) +++ libjava/Makefile.am (working copy) @@ -85,10 +85,14 @@ ## It is convenient to actually build and install the default database ## when gcj-dbtool is available. dbexec_DATA = $(db_name) +endif + +bin_SCRIPTS = addr2name.awk contrib/rebuild-gcj-db contrib/aot-compile + +if INSTALL_AOT_RPM +bin_SCRIPTS += contrib/aot-compile-rpm endif -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 @@ -528,8 +532,141 @@ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SinkChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SourceChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ ## Don't install java/nio/DirectByteBufferImpl$$ReadWrite.h here. It's for internal use only. +## Install Python modules for aot-compile. + $(mkinstalldirs) $(DESTDIR)$(python_mod_dir); \ + $(INSTALL_DATA) $(srcdir)/contrib/classfile.py \ + $(DESTDIR)$(python_mod_dir)/classfile.py; \ + $(INSTALL_DATA) contrib/aotcompile.py \ + $(DESTDIR)$(python_mod_dir)/aotcompile.py; +if CREATE_JAVA_HOME +## Create sdk style directories + $(mkinstalldirs) $(DESTDIR)$(JRE_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/$(OS) + relative() { \ + $(PERL) -e 'use File::Spec; \ + print File::Spec->abs2rel($$ARGV[0], $$ARGV[1])' $$1 $$2; \ + }; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(SDK_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gjar | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jar; \ + ln -sf $$RELATIVE/`echo gjdoc | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javadoc; \ + ln -sf $$RELATIVE/`echo grmic | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmic; \ + ln -sf $$RELATIVE/`echo gjavah | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javah; \ + ln -sf $$RELATIVE/ecj $(DESTDIR)$(SDK_BIN_DIR)/javac; \ + ln -sf $$RELATIVE/`echo gappletviewer | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/appletviewer; \ + ln -sf $$RELATIVE/`echo gjarsigner | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jarsigner; \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo gnative2ascii | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/native2ascii; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/tnameserv; \ + ln -sf $$RELATIVE/`echo gserialver | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/serialver; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(JRE_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/tnameserv; \ + $(mkinstalldirs) $(DESTDIR)$(JVM_JAR_DIR); \ + version=$(JAVA_VERSION).$(BUILD_VERSION); \ + working_dir=`pwd`; \ + cd $(DESTDIR)$(JVM_JAR_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s $$RELATIVE/$$jarname.jar $$jarname-$$version.jar; \ + done; \ + for jar in *-$$version.jar; \ + do \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|-$(JAVA_VERSION).jar|g"); \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|.jar|g"); \ + done; \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/security; \ + RELATIVE=$$(relative $(DESTDIR)$(libdir)/security \ + $(DESTDIR)$(JRE_LIB_DIR)/security); \ + cd $(DESTDIR)$(JRE_LIB_DIR)/security; \ + ln -sf $$RELATIVE/classpath.security java.security; \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/linux; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_LIB_DIR); \ + cd $(DESTDIR)$(JRE_LIB_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s rt.jar $$jarname.jar; \ + done; \ + cd $$working_dir; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JRE_LIB_DIR)); \ + ln -sf $$RELATIVE/libgcj-$(gcc_version).jar \ + $(DESTDIR)$(JRE_LIB_DIR)/rt.jar; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)); \ + ln -sf $$RELATIVE/libjawt.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/libjawt.so; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(SDK_LIB_DIR)); \ + ln -sf $$RELATIVE/libgcj-tools-$(gcc_version).jar \ + $(DESTDIR)$(SDK_LIB_DIR)/tools.jar; \ + for headername in jawt jni; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/$$headername.h; \ + done; \ + for headername in jawt_md jni_md; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux/$$headername.h; \ + done; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)); \ + ln -sf $$RELATIVE/src-$(gcc_version).zip \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)/src.zip; +endif - ## ################################################################ ## Index: libjava/configure.ac =================================================================== --- libjava/configure.ac (revision 136895) +++ libjava/configure.ac (working copy) @@ -1625,6 +1625,211 @@ # We get this from the environment. AC_SUBST(GCJFLAGS) +AC_ARG_WITH([python-dir], + AS_HELP_STRING([--with-python-dir], + [the location to install Python modules. This path should NOT include the prefix.]), + [with_python_dir=$withval], [with_python_dir=""]) + +if test "x${with_python_dir}" = "x" +then + # Needed for installing Python modules during make install. + python_mod_dir="\${prefix}/share/python" + # Needed for substituting into aot-compile* + python_mod_dir_expanded="${prefix}/share/python" +else + python_mod_dir="\${prefix}${with_python_dir}" + python_mod_dir_expanded="${prefix}${with_python_dir}" +fi +AC_MSG_RESULT(Python modules dir: ${python_mod_dir_expanded}); +AC_SUBST(python_mod_dir) +AC_SUBST(python_mod_dir_expanded) + +# needed for aot-compile-rpm +MAKE=`which make` +AC_SUBST(MAKE) + +AC_ARG_ENABLE([aot-compile-rpm], + [AS_HELP_STRING([--enable-aot-compile-rpm], + [enable installation of aot-compile-rpm [default=no]])], + [case "${enableval}" in + yes) AOT_RPM_ENABLED=yes ;; + no) AOT_RPM_ENABLED=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable aot-compile-rpm]) ;; + esac], + [AOT_RPM_ENABLED=no] +) +AM_CONDITIONAL(INSTALL_AOT_RPM, test "x${AOT_RPM_ENABLED}" == xyes) + +AC_ARG_ENABLE([java-home], + [AS_HELP_STRING([--enable-java-home], + [create a standard JDK-style directory layout in the install tree [default=no]])], + [case "${enableval}" in + yes) JAVA_HOME_ENABLED=yes ;; + no) JAVA_HOME_ENABLED=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable java-home]) ;; + esac], + [JAVA_HOME_ENABLED=no] +) +AM_CONDITIONAL(CREATE_JAVA_HOME, test "x${JAVA_HOME_ENABLED}" == xyes) + +# Only do these checks if java-home above is enabled. +if test "x${JAVA_HOME_ENABLED}" == xyes +then + + AC_ARG_WITH([gcc-suffix], + AS_HELP_STRING([--with-gcc-suffix], + [the GCC tool suffix (defaults to empty string)]), + [gcc_suffix=$withval], [gcc_suffix=""]) + AC_MSG_RESULT(GCC suffix: ${gcc_suffix}) + AC_SUBST(gcc_suffix) + + AC_ARG_WITH([arch-directory], + AS_HELP_STRING([--with-arch-directory], + [the arch directory under jre/lib (defaults to auto-detect)]), + [host_cpu=$withval], [host_cpu=""]) + + AC_ARG_WITH([os-directory], + AS_HELP_STRING([--with-os-directory], + [the os directory under include (defaults to auto-detect)]), + [host_os=$withval], [host_os=""]) + + AC_ARG_WITH([origin-name], + AS_HELP_STRING([--with-origin-name], + [the JPackage origin name of this package (default is gcj${gcc_suffix}]), + [origin_name=$withval], [origin_name=gcj${gcc_suffix}]) + AC_MSG_RESULT(JPackage origin name: ${origin_name}) + + AC_ARG_WITH([arch-suffix], + AS_HELP_STRING([--with-arch-suffix], + [the arch directory suffix (default is the empty string]), + [arch_suffix=$withval], [arch_suffix=""]) + AC_MSG_RESULT(arch suffix: ${arch_suffix}) + + AC_ARG_WITH([jvm-root-dir], + AS_HELP_STRING([--with-jvm-root-dir], + [where to install SDK (default is ${prefix}/lib/jvm)]), + [jvm_root_dir=$withval], [jvm_root_dir="\${prefix}/lib/jvm"]) + AC_MSG_RESULT(JVM root installation directory: ${jvm_root_dir}) + + AC_ARG_WITH([jvm-jar-dir], + AS_HELP_STRING([--with-jvm-jar-dir], + [where to install jars (default is ${prefix}/lib/jvm-exports)]), + [jvm_jar_dir=$withval], [jvm_jar_dir=\${prefix}/lib/jvm-exports]) + AC_MSG_RESULT(JAR root installation directory: ${jvm_jar_dir}) + + JAVA_VERSION=1.5.0 + BUILD_VERSION=0 + AC_SUBST(JAVA_VERSION) + AC_SUBST(BUILD_VERSION) + AC_MSG_RESULT(Java version: ${JAVA_VERSION}) + + jre_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix}/jre + sdk_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix} + jre_lnk=jre-${JAVA_VERSION}-${origin_name} + sdk_lnk=java-${JAVA_VERSION}-${origin_name} + + JVM_ROOT_DIR=${jvm_root_dir} + AC_SUBST(JVM_ROOT_DIR) + AC_MSG_RESULT(JVM ROOT directory: ${JVM_ROOT_DIR}) + + JVM_JAR_ROOT_DIR=${jvm_jar_dir} + AC_SUBST(JVM_JAR_ROOT_DIR) + AC_MSG_RESULT(JVM JAR ROOT directory: ${JVM_JAR_ROOT_DIR}) + + JVM_JAR_DIR=${jvm_jar_dir}/${sdk_dir} + AC_SUBST(JVM_JAR_DIR) + AC_MSG_RESULT(JVM JAR directory: ${JVM_JAR_DIR}) + + JRE_DIR=${jre_dir} + AC_SUBST(JRE_DIR) + + SDK_DIR=${sdk_dir} + AC_SUBST(SDK_DIR) + + JRE_LNK=${jre_lnk} + AC_SUBST(JRE_LNK) + + SDK_LNK=${sdk_lnk} + AC_SUBST(SDK_LNK) + + JAVA_HOME_DIR=${jvm_root_dir}/${jre_dir} + AC_SUBST(JAVA_HOME_DIR) + AC_MSG_RESULT(JAVA_HOME directory: ${JAVA_HOME_DIR}) + + SDK_BIN_DIR=${jvm_root_dir}/${sdk_dir}/bin + AC_SUBST(SDK_BIN_DIR) + AC_MSG_RESULT(SDK tools directory: ${SDK_BIN_DIR}) + + SDK_LIB_DIR=${jvm_root_dir}/${sdk_dir}/lib + AC_SUBST(SDK_LIB_DIR) + AC_MSG_RESULT(SDK jar directory: ${SDK_LIB_DIR}) + + SDK_INCLUDE_DIR=${jvm_root_dir}/${sdk_dir}/include + AC_SUBST(SDK_INCLUDE_DIR) + AC_MSG_RESULT(SDK include directory: ${SDK_INCLUDE_DIR}) + + JRE_BIN_DIR=${jvm_root_dir}/${jre_dir}/bin + AC_SUBST(JRE_BIN_DIR) + AC_MSG_RESULT(JRE tools directory: ${JRE_BIN_DIR}) + + JRE_LIB_DIR=${jvm_root_dir}/${jre_dir}/lib + AC_SUBST(JRE_LIB_DIR) + AC_MSG_RESULT(JRE lib directory: ${JRE_LIB_DIR}) + + # Find gcj prefix using gcj found in PATH. + gcj_prefix=`which gcj${gcc_suffix} | sed "s%/bin/gcj${gcc_suffix}%%"` + + # Where do the gcj binaries live? + # For jhbuild based builds, they all live in a sibling of bin called + # gcj-bin. Check for gcj-bin first, and use bin otherwise. + GCJ_BIN_DIR=`if test -d ${gcj_prefix}/gcj-bin; then echo ${gcj_prefix}/gcj-bin; else echo ${gcj_prefix}/bin; fi` + AC_SUBST(GCJ_BIN_DIR) + AC_MSG_RESULT(GCJ tools directory: ${GCJ_BIN_DIR}) + + echo host is ${host} + if test "x${host_cpu}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_cpu=x86;; + i486-* | i586-* | i686-*) + host_cpu=i386;; + *) + host_cpu=${host_cpu};; + esac + fi + AC_MSG_RESULT(arch directory: ${host_cpu}) + CPU=${host_cpu} + AC_SUBST(CPU) + + if test "x${host_os}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_os=win32;; + *-linux*) + host_os=linux;; + *) + host_os=${host_os};; + esac + fi + echo os directory: ${host_os} + OS=${host_os} + AC_SUBST(OS) + + # make an expanded $libdir, for substituting into + # scripts (and other non-Makefile things). + LIBDIR=$libdir + if test "x${exec_prefix}" = "xNONE" + then + lib_exec_prefix=$prefix + else + lib_exec_prefix=$exec_prefix + fi + LIBDIR=`echo $libdir | sed "s:\\\${exec_prefix}:$lib_exec_prefix:g"` + AC_SUBST(LIBDIR) +fi + AC_CONFIG_FILES([ Makefile libgcj.pc @@ -1633,6 +1838,10 @@ gcj/Makefile include/Makefile testsuite/Makefile +contrib/aotcompile.py +contrib/aot-compile +contrib/aot-compile-rpm +contrib/rebuild-gcj-db ]) if test ${multilib} = yes; then [-- Attachment #3: gcc-install-and-docs-update2.patch --] [-- Type: text/x-patch, Size: 8288 bytes --] Index: gcc/doc/install.texi =================================================================== --- gcc/doc/install.texi (revision 137153) +++ gcc/doc/install.texi (working copy) @@ -1607,6 +1607,45 @@ @item --with-win32-nlsapi=ansi, unicows or unicode Indicates how MinGW @samp{libgcj} translates between UNICODE characters and the Win32 API@. + +@item --enable-java-home +If enabled, this creates a JPackage compatible SDK environment during install. +Note that if --enable-java-home is used, --with-arch-directory=ARCH must also +be specified. + +@item --with-arch-directory=ARCH +Specifies the name to use for the @file{jre/lib/ARCH} directory in the SDK +environment created when --enable-java-home is passed. Typical names for this +directory include i386, amd64, ia64, etc. + +@item --with-os-directory=DIR +Specifies the OS directory for the SDK include directory. This is set to auto +detect, and is typically 'linux'. + +@item --with-origin-name=NAME +Specifies the JPackage origin name. This defaults to the 'gcj' in +java-1.5.0-gcj. + +@item --with-arch-suffix=SUFFIX +Specifies the suffix for the sdk directory. Defaults to the empty string. +Examples include '.x86_64' in 'java-1.5.0-gcj-1.5.0.0.x86_64'. + +@item --with-jvm-root-dir=DIR +Specifies where to install the SDK. Default is $(prefix)/lib/jvm. + +@item --with-jvm-jar-dir=DIR +Specifies where to install jars. Default is $(prefix)/lib/jvm-exports. + +@item --with-python-dir=DIR +Specifies where to install the Python modules used for aot-compile. DIR should +not include the prefix used in installation. For example, if the Python modules +are to be installed in /usr/lib/python2.5/site-packages, then +--with-python-dir=/lib/python2.5/site-packages should be passed. If this is +not specified, then the Python modules are installed in $(prefix)/share/python. + +@item --enable-aot-compile-rpm +Adds aot-compile-rpm to the list of installed scripts. + @table @code @item ansi Use the single-byte @code{char} and the Win32 A functions natively, Index: gcc/java/gcj.texi =================================================================== --- gcc/java/gcj.texi (revision 137153) +++ gcc/java/gcj.texi (working copy) @@ -72,6 +72,11 @@ Generate stubs for Remote Method Invocation. * gc-analyze: (gcj)Invoking gc-analyze. Analyze Garbage Collector (GC) memory dumps. +* aot-compile: (gcj)Invoking aot-compile. + Compile bytecode to native and generate databases. +* rebuild-gcj-db: (gcj)Invoking rebuild-gcj-db. + Merge the per-solib databases made by aot-compile + into one system-wide database. @end direntry @end format @@ -115,6 +120,9 @@ * Invoking jv-convert:: Converting from one encoding to another * Invoking grmic:: Generate stubs for Remote Method Invocation. * Invoking gc-analyze:: Analyze Garbage Collector (GC) memory dumps. +* Invoking aot-compile:: Compile bytecode to native and generate databases. +* Invoking rebuild-gcj-db:: Merge the per-solib databases made by aot-compile + into one system-wide database. * About CNI:: Description of the Compiled Native Interface * System properties:: Modifying runtime behavior of the libgcj library * Resources:: Where to look for more information @@ -921,7 +929,7 @@ [@option{-v}] [@option{-m}] [@option{--version}] [@option{--help}] @c man end -@c man begin SEEALSO gij +@c man begin SEEALSO gcj-dbtool gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), and the Info entries for @file{gcj} and @file{gcc}. @c man end @@ -1219,6 +1227,87 @@ @c man end +@node Invoking aot-compile +@chapter Invoking aot-compile + +@c man title aot-compile Compile bytecode to native and generate databases + +@ignore + +@c man begin SYNOPSIS aot-compile +aot-compile [@option{OPTION}] @dots{} @var{SRCDIR} @var{DSTDIR} + +aot-compile [@option{-M, --make}=@var{PATH}] [@option{-C, --gcj}=@var{PATH}] + [@option{-D, --dbtool}=@var{PATH}] [@option{-m, --makeflags}=@var{FLAGS}] + [@option{-c, --gcjflags}=@var{FLAGS}] [@option{-l, --ldflags}=@var{FLAGS}] + [@option{-e, --exclude}=@var{PATH}] +@c man end + +@c man begin SEEALSO aot-compile +gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), +and the Info entries for @file{gcj} and @file{gcc}. +@c man end + +@end ignore + +@c man begin DESCRIPTION aot-compile +@code{aot-compile} is a script that searches a directory for Java bytecode +(as class files, or in jars) and uses @code{gcj} to compile it to native +code and generate the databases from it. +@c man end + +@c man begin OPTIONS aot-compile +@table @gcctabopt +@item -M, --make=@var{PATH} +Specify the path to the @code{make} executable to use. + +@item -C, --gcj=@var{PATH} +Specify the path to the @code{gcj} executable to use. + +@item -D, --dbtool=@var{PATH} +Specify the path to the @code{gcj-dbtool} executable to use. + +@item -m, --makeflags=@var{FLAGS} +Specify flags to pass to @code{make} during the build. + +@item -c, --gcjflags=@var{FLAGS} +Specify flags to pass to @code{gcj} during compilation, in addition to +'-fPIC -findirect-dispatch -fjni'. + +@item -l, --ldflags=@var{FLAGS} +Specify flags to pass to @code{gcj} during linking, in addition to +'-Wl,-Bsymbolic'. + +@item -e, --exclude=@var{PATH} +Do not compile @var{PATH}. + +@end table + +@c man end + +@node Invoking rebuild-gcj-db +@chapter Invoking rebuild-gcj-db + +@c man title rebuild-gcj-db Merge the per-solib databases made by aot-compile into one system-wide database. +@ignore + +@c man begin SYNOPSIS rebuild-gcj-db +rebuild-gcj-db +@c man end + +@c man begin SEEALSO rebuild-gcj-db +gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), +and the Info entries for @file{gcj} and @file{gcc}. +@c man end + +@end ignore + +@c man begin DESCRIPTION rebuild-gcj-db +@code{rebuild-gcj-db} is a script that merges the per-solib databases made by +@code{aot-compile} into one system-wide database so @code{gij} can find the +solibs. +@c man end + @node About CNI @chapter About CNI Index: gcc/java/Make-lang.in =================================================================== --- gcc/java/Make-lang.in (revision 137153) +++ gcc/java/Make-lang.in (working copy) @@ -143,8 +143,9 @@ java.html: $(build_htmldir)/java/index.html JAVA_MANFILES = doc/gcj.1 doc/jcf-dump.1 doc/gij.1 \ - doc/jv-convert.1 doc/grmic.1\ - doc/gcj-dbtool.1 doc/gc-analyze.1 + doc/jv-convert.1 doc/grmic.1 \ + doc/gcj-dbtool.1 doc/gc-analyze.1 doc/aot-compile.1 \ + doc/rebuild-gcj-db.1 java.man: $(JAVA_MANFILES) @@ -189,6 +190,8 @@ -rm -rf $(DESTDIR)$(man1dir)/gij$(man1ext) -rm -rf $(DESTDIR)$(man1dir)/jv-convert$(man1ext) -rm -rf $(DESTDIR)$(man1dir)/gcj-dbtool$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/aot-compile$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/rebuild-gcj-db$(man1ext) java.install-info: $(DESTDIR)$(infodir)/gcj.info @@ -223,6 +226,8 @@ -rm -f $(docobjdir)/grmic.1 -rm -f $(docobjdir)/gcj-dbtool.1 -rm -f $(docobjdir)/gc-analyze.1 + -rm -f $(docobjdir)/aot-compile.1 + -rm -f $(docobjdir)/rebuild-gcj-db.1 #\f # Stage hooks: # The main makefile has already created stage?/java. @@ -353,15 +358,21 @@ -$(TEXI2POD) -D gcj-dbtool < $< > $@ gc-analyze.pod: java/gcj.texi -$(TEXI2POD) -D gc-analyze < $< > $@ +aot-compile.pod: java/gcj.texi + -$(TEXI2POD) -D aot-compile < $< > $@ +rebuild-gcj-db.pod: java/gcj.texi + -$(TEXI2POD) -D rebuild-gcj-db < $< > $@ # Install the man pages. java.install-man: installdirs \ $(DESTDIR)$(man1dir)/$(JAVA_INSTALL_NAME)$(man1ext) \ $(JAVA_TARGET_INDEPENDENT_BIN_TOOLS:%=doc/%.1) \ doc/gij.1 doc/jv-convert.1 doc/grmic.1 \ - doc/gcj-dbtool.1 doc/gc-analyze.1 + doc/gcj-dbtool.1 doc/gc-analyze.1 \ + doc/aot-compile.1 doc/rebuild-gcj-db.1 for tool in $(JAVA_TARGET_INDEPENDENT_BIN_TOOLS) \ - gij jv-convert grmic gcj-dbtool gc-analyze ; do \ + gij jv-convert grmic gcj-dbtool gc-analyze aot-compile \ + rebuild-gcj-db; do \ tool_transformed_name=`echo $$tool|sed '$(program_transform_name)'`; \ man_name=$(DESTDIR)$(man1dir)/$${tool_transformed_name}$(man1ext); \ rm -f $$man_name ; \ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-30 14:39 ` Joshua Sumali @ 2008-07-01 13:59 ` Andrew Haley 2008-07-01 14:53 ` Joshua Sumali 2008-07-02 13:07 ` Andrew Haley 1 sibling, 1 reply; 18+ messages in thread From: Andrew Haley @ 2008-07-01 13:59 UTC (permalink / raw) To: Joshua Sumali; +Cc: java-patches Joshua Sumali wrote: > Andrew Haley wrote: >> Joshua Sumali wrote: >> >>> Andrew Haley wrote: >>> >> >> >>>> Please assign all Red Hat copyrights to the FSF. >>>> >>> Is there a special way to do this, or do I simply change "Copyright (C) >>> 2005, 2006, 2008 Red Hat, Inc." to "Copyright (C) 2005, 2006, 2008 Free >>> Software Foundation" on the appropriate files? >>> >> >> That's all you have to do. >> >> >>>> Do I take it that you don't have commit access to the gcc tree? >>>> >>> I do not. I was hoping someone would be able to commit the patches >>> for me. >>> >> >> I'll do it. >> >> Andrew. >> >> > Copyrights assigned to FSF. ChangeLogs removed from patches and are > found below. I get: $ automake Makefile.am:67: JAVA_HOME_DIR was already defined in condition TRUE, which includes condition JAVA_HOME_SET ... configure.ac:1759: ... `JAVA_HOME_DIR' previously defined here Makefile.am:70: JAVA_HOME_DIR was already defined in condition TRUE, which includes condition !JAVA_HOME_SET ... > > libjava/ > > 2008-06-30 Joshua Sumali <jsumali@redhat.com> > > * configure.ac (java-home): new AC_ARG_ENABLE. > (aot-compile-rpm): Likewise. > (CREATE_JAVA_HOME): new AM_CONDITIONAL. > (INSTALL_AOT_RPM): Likewise. > (gcc-suffix): new AC_ARG_WITH. > (arch-directory): Likewise. > (os-directory): Likewise. > (origin-name): Likewise. > (arch-suffix): Likewise. > (jvm-root-dir): Likewise. > (jvm-jar-dir): Likewise. > (python-dir): Likewise. > (AC_CONFIG_FILES): Add contrib/aotcompile.py, contrib/aot-compile, > contrib/aot-compile-rpm, contrib/rebuild-gcj-db. > * Makefile.am (install-data-local): Install Python modules for > aot-compile. Also install an sdk style directory if --enable-java-home > is passed to configure. > (bin_SCRIPTS): add contrib/rebuild-gcj-db and contrib/aot-compile. > * contrib/aot-compile.in: New file. > * contrib/aotcompile.py.in: Likewise. > * contrib/aot-compile-rpm.in: Likewise. > * contrib/classfile.py: Likewise. > * contrib/rebuild-gcj-db.in: Likewise. > * configure: Regenerate. > * Makefile.in: Regenerate. > > gcc/ > > 2008-06-30 Joshua Sumali <jsumali@redhat.com> > > * doc/install.texi (--enable-java-home): Document. > (--enable-aot-compile-rpm): Likewise. > (--with-arch-directory): Likewise. > (--with-os-directory): Likewise. > (--with-origin-name): Likewise. > (--with-arch-suffix): Likewise. > (--with-jvm-root-dir): Likewise. > (--with-jvm-jar-dir): Likewise. > (--with-python-dir): Likewise. > > gcc/java/ > > 2008-06-30 Joshua Sumali <jsumali@redhat.com> > > * Make-lang.in (JAVA_MANFILES): Add doc/aot-compile.1 and > doc/rebuild-gcj-db.1 > (java.uninstall): Likewise. > (java.maintainer-clean): Likewise. > (aot-compile.pod): New rule. > (rebuild-gcj-db.pod): New rule. > (java.install-man): Install doc/aot-compile.1 and doc/rebuild-gcj-db.1 > * gcj.texi: Add new sections for aot-compile and rebuild-gcj-db. > > ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-07-01 13:59 ` Andrew Haley @ 2008-07-01 14:53 ` Joshua Sumali 2008-07-01 15:01 ` Andrew Haley 0 siblings, 1 reply; 18+ messages in thread From: Joshua Sumali @ 2008-07-01 14:53 UTC (permalink / raw) To: Andrew Haley; +Cc: java-patches Andrew Haley wrote: > Joshua Sumali wrote: > >> Andrew Haley wrote: >> >>> Joshua Sumali wrote: >>> >>> >>>> Andrew Haley wrote: >>>> >>>> >>> >>> >>>>> Please assign all Red Hat copyrights to the FSF. >>>>> >>>>> >>>> Is there a special way to do this, or do I simply change "Copyright (C) >>>> 2005, 2006, 2008 Red Hat, Inc." to "Copyright (C) 2005, 2006, 2008 Free >>>> Software Foundation" on the appropriate files? >>>> >>>> >>> That's all you have to do. >>> >>> >>> >>>>> Do I take it that you don't have commit access to the gcc tree? >>>>> >>>>> >>>> I do not. I was hoping someone would be able to commit the patches >>>> for me. >>>> >>>> >>> I'll do it. >>> >>> Andrew. >>> >>> >>> >> Copyrights assigned to FSF. ChangeLogs removed from patches and are >> found below. >> > > I get: > > > $ automake > Makefile.am:67: JAVA_HOME_DIR was already defined in condition TRUE, which includes condition JAVA_HOME_SET ... > configure.ac:1759: ... `JAVA_HOME_DIR' previously defined here > Makefile.am:70: JAVA_HOME_DIR was already defined in condition TRUE, which includes condition !JAVA_HOME_SET ... > > > Sorry, my mistake for leaving that in. To fix that, remove the following lines from configure.ac: JAVA_HOME_DIR=${jvm_root_dir}/${jre_dir} AC_SUBST(JAVA_HOME_DIR) AC_MSG_RESULT(JAVA_HOME directory: ${JAVA_HOME_DIR}) They should be around line 1759. (I'd post another patch but I figured that it would be easier to just delete those few lines) Josh ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-07-01 14:53 ` Joshua Sumali @ 2008-07-01 15:01 ` Andrew Haley 0 siblings, 0 replies; 18+ messages in thread From: Andrew Haley @ 2008-07-01 15:01 UTC (permalink / raw) To: Joshua Sumali; +Cc: java-patches Joshua Sumali wrote: > Andrew Haley wrote: >> Joshua Sumali wrote: >> >>> Andrew Haley wrote: >>> >>>> Joshua Sumali wrote: >>>> >>>> >>>>> Andrew Haley wrote: >>>>> >>>> >>>> >>>>>> Please assign all Red Hat copyrights to the FSF. >>>>>> >>>>> Is there a special way to do this, or do I simply change "Copyright >>>>> (C) >>>>> 2005, 2006, 2008 Red Hat, Inc." to "Copyright (C) 2005, 2006, 2008 >>>>> Free >>>>> Software Foundation" on the appropriate files? >>>>> >>>> That's all you have to do. >>>> >>>> >>>> >>>>>> Do I take it that you don't have commit access to the gcc tree? >>>>>> >>>>> I do not. I was hoping someone would be able to commit the patches >>>>> for me. >>>>> >>>> I'll do it. >>>> >>>> Andrew. >>>> >>>> >>> Copyrights assigned to FSF. ChangeLogs removed from patches and are >>> found below. >>> >> >> I get: >> >> >> $ automake >> Makefile.am:67: JAVA_HOME_DIR was already defined in condition TRUE, >> which includes condition JAVA_HOME_SET ... >> configure.ac:1759: ... `JAVA_HOME_DIR' previously defined here >> Makefile.am:70: JAVA_HOME_DIR was already defined in condition TRUE, >> which includes condition !JAVA_HOME_SET ... >> >> >> > Sorry, my mistake for leaving that in. To fix that, remove the following > lines from configure.ac: > > JAVA_HOME_DIR=${jvm_root_dir}/${jre_dir} > AC_SUBST(JAVA_HOME_DIR) > AC_MSG_RESULT(JAVA_HOME directory: ${JAVA_HOME_DIR}) > > They should be around line 1759. > > (I'd post another patch but I figured that it would be easier to just > delete those few lines) OK, TVM. Andrew. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-06-30 14:39 ` Joshua Sumali 2008-07-01 13:59 ` Andrew Haley @ 2008-07-02 13:07 ` Andrew Haley 2008-07-02 13:19 ` Joshua Sumali 1 sibling, 1 reply; 18+ messages in thread From: Andrew Haley @ 2008-07-02 13:07 UTC (permalink / raw) To: Joshua Sumali; +Cc: java-patches Joshua Sumali wrote: > Andrew Haley wrote: >> Joshua Sumali wrote: >> >>> Andrew Haley wrote: >>> >> >> >>>> Please assign all Red Hat copyrights to the FSF. >>>> >>> Is there a special way to do this, or do I simply change "Copyright (C) >>> 2005, 2006, 2008 Red Hat, Inc." to "Copyright (C) 2005, 2006, 2008 Free >>> Software Foundation" on the appropriate files? >>> >> >> That's all you have to do. >> >> >>>> Do I take it that you don't have commit access to the gcc tree? >>>> >>> I do not. I was hoping someone would be able to commit the patches >>> for me. >>> >> >> I'll do it. Here's what I committed. I had partly to rewrite rebuild-gcj-db because it handled multilibs incorrectly, and in the process discovered a bug in gcj-dbtool, but otherwise it's the same. Andrew. 2008-06-30 Joshua Sumali <jsumali@redhat.com> Andrew Haley <aph@redhat.com> * configure.ac (java-home): new AC_ARG_ENABLE. (aot-compile-rpm): Likewise. (CREATE_JAVA_HOME): new AM_CONDITIONAL. (INSTALL_AOT_RPM): Likewise. (gcc-suffix): new AC_ARG_WITH. (arch-directory): Likewise. (os-directory): Likewise. (origin-name): Likewise. (arch-suffix): Likewise. (jvm-root-dir): Likewise. (jvm-jar-dir): Likewise. (python-dir): Likewise. (AC_CONFIG_FILES): Add contrib/aotcompile.py, contrib/aot-compile, contrib/aot-compile-rpm, contrib/rebuild-gcj-db. (gcjsubdir): New AC_SUBST. * Makefile.am (install-data-local): Install Python modules for aot-compile. Also install an sdk style directory if --enable-java-home is passed to configure. (bin_SCRIPTS): Add contrib/rebuild-gcj-db and contrib/aot-compile. (gcjsubdir): Add. (db_pathtail): Redefine in terms of gcjsubdir. * contrib/aot-compile.in: New file. * contrib/aotcompile.py.in: Likewise. * contrib/aot-compile-rpm.in: Likewise. * contrib/classfile.py: Likewise. * contrib/rebuild-gcj-db.in: Likewise. * configure: Regenerate. * Makefile.in: Regenerate. 2008-06-30 Joshua Sumali <jsumali@redhat.com> * doc/install.texi (--enable-java-home): Document. (--enable-aot-compile-rpm): Likewise. (--with-arch-directory): Likewise. (--with-os-directory): Likewise. (--with-origin-name): Likewise. (--with-arch-suffix): Likewise. (--with-jvm-root-dir): Likewise. (--with-jvm-jar-dir): Likewise. (--with-python-dir): Likewise. Index: gcc/doc/install.texi =================================================================== --- gcc/doc/install.texi (revision 137317) +++ gcc/doc/install.texi (working copy) @@ -1607,6 +1607,45 @@ @item --with-win32-nlsapi=ansi, unicows or unicode Indicates how MinGW @samp{libgcj} translates between UNICODE characters and the Win32 API@. + +@item --enable-java-home +If enabled, this creates a JPackage compatible SDK environment during install. +Note that if --enable-java-home is used, --with-arch-directory=ARCH must also +be specified. + +@item --with-arch-directory=ARCH +Specifies the name to use for the @file{jre/lib/ARCH} directory in the SDK +environment created when --enable-java-home is passed. Typical names for this +directory include i386, amd64, ia64, etc. + +@item --with-os-directory=DIR +Specifies the OS directory for the SDK include directory. This is set to auto +detect, and is typically 'linux'. + +@item --with-origin-name=NAME +Specifies the JPackage origin name. This defaults to the 'gcj' in +java-1.5.0-gcj. + +@item --with-arch-suffix=SUFFIX +Specifies the suffix for the sdk directory. Defaults to the empty string. +Examples include '.x86_64' in 'java-1.5.0-gcj-1.5.0.0.x86_64'. + +@item --with-jvm-root-dir=DIR +Specifies where to install the SDK. Default is $(prefix)/lib/jvm. + +@item --with-jvm-jar-dir=DIR +Specifies where to install jars. Default is $(prefix)/lib/jvm-exports. + +@item --with-python-dir=DIR +Specifies where to install the Python modules used for aot-compile. DIR should +not include the prefix used in installation. For example, if the Python modules +are to be installed in /usr/lib/python2.5/site-packages, then +--with-python-dir=/lib/python2.5/site-packages should be passed. If this is +not specified, then the Python modules are installed in $(prefix)/share/python. + +@item --enable-aot-compile-rpm +Adds aot-compile-rpm to the list of installed scripts. + @table @code @item ansi Use the single-byte @code{char} and the Win32 A functions natively, Index: gcc/java/Make-lang.in =================================================================== --- gcc/java/Make-lang.in (revision 137317) +++ gcc/java/Make-lang.in (working copy) @@ -146,8 +146,9 @@ java.html: $(build_htmldir)/java/index.html JAVA_MANFILES = doc/gcj.1 doc/jcf-dump.1 doc/gij.1 \ - doc/jv-convert.1 doc/grmic.1\ - doc/gcj-dbtool.1 doc/gc-analyze.1 + doc/jv-convert.1 doc/grmic.1 \ + doc/gcj-dbtool.1 doc/gc-analyze.1 doc/aot-compile.1 \ + doc/rebuild-gcj-db.1 java.man: $(JAVA_MANFILES) @@ -192,6 +193,8 @@ -rm -rf $(DESTDIR)$(man1dir)/gij$(man1ext) -rm -rf $(DESTDIR)$(man1dir)/jv-convert$(man1ext) -rm -rf $(DESTDIR)$(man1dir)/gcj-dbtool$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/aot-compile$(man1ext) + -rm -rf $(DESTDIR)$(man1dir)/rebuild-gcj-db$(man1ext) java.install-info: $(DESTDIR)$(infodir)/gcj.info @@ -226,6 +229,8 @@ -rm -f $(docobjdir)/grmic.1 -rm -f $(docobjdir)/gcj-dbtool.1 -rm -f $(docobjdir)/gc-analyze.1 + -rm -f $(docobjdir)/aot-compile.1 + -rm -f $(docobjdir)/rebuild-gcj-db.1 #\f # Stage hooks: # The main makefile has already created stage?/java. @@ -356,15 +361,21 @@ -$(TEXI2POD) -D gcj-dbtool < $< > $@ gc-analyze.pod: java/gcj.texi -$(TEXI2POD) -D gc-analyze < $< > $@ +aot-compile.pod: java/gcj.texi + -$(TEXI2POD) -D aot-compile < $< > $@ +rebuild-gcj-db.pod: java/gcj.texi + -$(TEXI2POD) -D rebuild-gcj-db < $< > $@ # Install the man pages. java.install-man: installdirs \ $(DESTDIR)$(man1dir)/$(JAVA_INSTALL_NAME)$(man1ext) \ $(JAVA_TARGET_INDEPENDENT_BIN_TOOLS:%=doc/%.1) \ doc/gij.1 doc/jv-convert.1 doc/grmic.1 \ - doc/gcj-dbtool.1 doc/gc-analyze.1 + doc/gcj-dbtool.1 doc/gc-analyze.1 \ + doc/aot-compile.1 doc/rebuild-gcj-db.1 for tool in $(JAVA_TARGET_INDEPENDENT_BIN_TOOLS) \ - gij jv-convert grmic gcj-dbtool gc-analyze ; do \ + gij jv-convert grmic gcj-dbtool gc-analyze aot-compile \ + rebuild-gcj-db; do \ tool_transformed_name=`echo $$tool|sed '$(program_transform_name)'`; \ man_name=$(DESTDIR)$(man1dir)/$${tool_transformed_name}$(man1ext); \ rm -f $$man_name ; \ Index: gcc/java/ChangeLog =================================================================== --- gcc/java/ChangeLog (revision 137317) +++ gcc/java/ChangeLog (working copy) @@ -1,3 +1,14 @@ +2008-06-30 Joshua Sumali <jsumali@redhat.com> + + * Make-lang.in (JAVA_MANFILES): Add doc/aot-compile.1 and + doc/rebuild-gcj-db.1 + (java.uninstall): Likewise. + (java.maintainer-clean): Likewise. + (aot-compile.pod): New rule. + (rebuild-gcj-db.pod): New rule. + (java.install-man): Install doc/aot-compile.1 and doc/rebuild-gcj-db.1 + * gcj.texi: Add new sections for aot-compile and rebuild-gcj-db. + 2008-06-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * Make-lang.in (java/jcf-io.o-warn): New. Index: gcc/java/gcj.texi =================================================================== --- gcc/java/gcj.texi (revision 137317) +++ gcc/java/gcj.texi (working copy) @@ -72,6 +72,11 @@ Generate stubs for Remote Method Invocation. * gc-analyze: (gcj)Invoking gc-analyze. Analyze Garbage Collector (GC) memory dumps. +* aot-compile: (gcj)Invoking aot-compile. + Compile bytecode to native and generate databases. +* rebuild-gcj-db: (gcj)Invoking rebuild-gcj-db. + Merge the per-solib databases made by aot-compile + into one system-wide database. @end direntry @end format @@ -115,6 +120,9 @@ * Invoking jv-convert:: Converting from one encoding to another * Invoking grmic:: Generate stubs for Remote Method Invocation. * Invoking gc-analyze:: Analyze Garbage Collector (GC) memory dumps. +* Invoking aot-compile:: Compile bytecode to native and generate databases. +* Invoking rebuild-gcj-db:: Merge the per-solib databases made by aot-compile + into one system-wide database. * About CNI:: Description of the Compiled Native Interface * System properties:: Modifying runtime behavior of the libgcj library * Resources:: Where to look for more information @@ -921,7 +929,7 @@ [@option{-v}] [@option{-m}] [@option{--version}] [@option{--help}] @c man end -@c man begin SEEALSO gij +@c man begin SEEALSO gcj-dbtool gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), and the Info entries for @file{gcj} and @file{gcc}. @c man end @@ -1219,6 +1227,87 @@ @c man end +@node Invoking aot-compile +@chapter Invoking aot-compile + +@c man title aot-compile Compile bytecode to native and generate databases + +@ignore + +@c man begin SYNOPSIS aot-compile +aot-compile [@option{OPTION}] @dots{} @var{SRCDIR} @var{DSTDIR} + +aot-compile [@option{-M, --make}=@var{PATH}] [@option{-C, --gcj}=@var{PATH}] + [@option{-D, --dbtool}=@var{PATH}] [@option{-m, --makeflags}=@var{FLAGS}] + [@option{-c, --gcjflags}=@var{FLAGS}] [@option{-l, --ldflags}=@var{FLAGS}] + [@option{-e, --exclude}=@var{PATH}] +@c man end + +@c man begin SEEALSO aot-compile +gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), +and the Info entries for @file{gcj} and @file{gcc}. +@c man end + +@end ignore + +@c man begin DESCRIPTION aot-compile +@code{aot-compile} is a script that searches a directory for Java bytecode +(as class files, or in jars) and uses @code{gcj} to compile it to native +code and generate the databases from it. +@c man end + +@c man begin OPTIONS aot-compile +@table @gcctabopt +@item -M, --make=@var{PATH} +Specify the path to the @code{make} executable to use. + +@item -C, --gcj=@var{PATH} +Specify the path to the @code{gcj} executable to use. + +@item -D, --dbtool=@var{PATH} +Specify the path to the @code{gcj-dbtool} executable to use. + +@item -m, --makeflags=@var{FLAGS} +Specify flags to pass to @code{make} during the build. + +@item -c, --gcjflags=@var{FLAGS} +Specify flags to pass to @code{gcj} during compilation, in addition to +'-fPIC -findirect-dispatch -fjni'. + +@item -l, --ldflags=@var{FLAGS} +Specify flags to pass to @code{gcj} during linking, in addition to +'-Wl,-Bsymbolic'. + +@item -e, --exclude=@var{PATH} +Do not compile @var{PATH}. + +@end table + +@c man end + +@node Invoking rebuild-gcj-db +@chapter Invoking rebuild-gcj-db + +@c man title rebuild-gcj-db Merge the per-solib databases made by aot-compile into one system-wide database. +@ignore + +@c man begin SYNOPSIS rebuild-gcj-db +rebuild-gcj-db +@c man end + +@c man begin SEEALSO rebuild-gcj-db +gcc(1), gcj(1), gcjh(1), jcf-dump(1), gfdl(7), +and the Info entries for @file{gcj} and @file{gcc}. +@c man end + +@end ignore + +@c man begin DESCRIPTION rebuild-gcj-db +@code{rebuild-gcj-db} is a script that merges the per-solib databases made by +@code{aot-compile} into one system-wide database so @code{gij} can find the +solibs. +@c man end + @node About CNI @chapter About CNI Index: libjava/configure.ac =================================================================== --- libjava/configure.ac (revision 137317) +++ libjava/configure.ac (working copy) @@ -1416,6 +1416,7 @@ ;; esac AC_SUBST(dbexecdir) +AC_SUBST(gcjsubdir) AC_DEFINE(JV_VERSION, "1.5.0", [Compatibility version string]) AC_DEFINE(JV_API_VERSION, "1.5", [API compatibility version string]) @@ -1628,6 +1629,207 @@ # We get this from the environment. AC_SUBST(GCJFLAGS) +AC_ARG_WITH([python-dir], + AS_HELP_STRING([--with-python-dir], + [the location to install Python modules. This path should NOT include the prefix.]), + [with_python_dir=$withval], [with_python_dir=""]) + +if test "x${with_python_dir}" = "x" +then + # Needed for installing Python modules during make install. + python_mod_dir="\${prefix}/share/python" + # Needed for substituting into aot-compile* + python_mod_dir_expanded="${prefix}/share/python" +else + python_mod_dir="\${prefix}${with_python_dir}" + python_mod_dir_expanded="${prefix}${with_python_dir}" +fi +AC_MSG_RESULT(Python modules dir: ${python_mod_dir_expanded}); +AC_SUBST(python_mod_dir) +AC_SUBST(python_mod_dir_expanded) + +# needed for aot-compile-rpm +MAKE=`which make` +AC_SUBST(MAKE) + +AC_ARG_ENABLE([aot-compile-rpm], + [AS_HELP_STRING([--enable-aot-compile-rpm], + [enable installation of aot-compile-rpm [default=no]])], + [case "${enableval}" in + yes) AOT_RPM_ENABLED=yes ;; + no) AOT_RPM_ENABLED=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable aot-compile-rpm]) ;; + esac], + [AOT_RPM_ENABLED=no] +) +AM_CONDITIONAL(INSTALL_AOT_RPM, test "x${AOT_RPM_ENABLED}" == xyes) + +AC_ARG_ENABLE([java-home], + [AS_HELP_STRING([--enable-java-home], + [create a standard JDK-style directory layout in the install tree [default=no]])], + [case "${enableval}" in + yes) JAVA_HOME_ENABLED=yes ;; + no) JAVA_HOME_ENABLED=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable java-home]) ;; + esac], + [JAVA_HOME_ENABLED=no] +) +AM_CONDITIONAL(CREATE_JAVA_HOME, test "x${JAVA_HOME_ENABLED}" == xyes) + +# Only do these checks if java-home above is enabled. +if test "x${JAVA_HOME_ENABLED}" == xyes +then + + AC_ARG_WITH([gcc-suffix], + AS_HELP_STRING([--with-gcc-suffix], + [the GCC tool suffix (defaults to empty string)]), + [gcc_suffix=$withval], [gcc_suffix=""]) + AC_MSG_RESULT(GCC suffix: ${gcc_suffix}) + AC_SUBST(gcc_suffix) + + AC_ARG_WITH([arch-directory], + AS_HELP_STRING([--with-arch-directory], + [the arch directory under jre/lib (defaults to auto-detect)]), + [host_cpu=$withval], [host_cpu=""]) + + AC_ARG_WITH([os-directory], + AS_HELP_STRING([--with-os-directory], + [the os directory under include (defaults to auto-detect)]), + [host_os=$withval], [host_os=""]) + + AC_ARG_WITH([origin-name], + AS_HELP_STRING([--with-origin-name], + [the JPackage origin name of this package (default is gcj${gcc_suffix}]), + [origin_name=$withval], [origin_name=gcj${gcc_suffix}]) + AC_MSG_RESULT(JPackage origin name: ${origin_name}) + + AC_ARG_WITH([arch-suffix], + AS_HELP_STRING([--with-arch-suffix], + [the arch directory suffix (default is the empty string]), + [arch_suffix=$withval], [arch_suffix=""]) + AC_MSG_RESULT(arch suffix: ${arch_suffix}) + + AC_ARG_WITH([jvm-root-dir], + AS_HELP_STRING([--with-jvm-root-dir], + [where to install SDK (default is ${prefix}/lib/jvm)]), + [jvm_root_dir=$withval], [jvm_root_dir="\${prefix}/lib/jvm"]) + AC_MSG_RESULT(JVM root installation directory: ${jvm_root_dir}) + + AC_ARG_WITH([jvm-jar-dir], + AS_HELP_STRING([--with-jvm-jar-dir], + [where to install jars (default is ${prefix}/lib/jvm-exports)]), + [jvm_jar_dir=$withval], [jvm_jar_dir=\${prefix}/lib/jvm-exports]) + AC_MSG_RESULT(JAR root installation directory: ${jvm_jar_dir}) + + JAVA_VERSION=1.5.0 + BUILD_VERSION=0 + AC_SUBST(JAVA_VERSION) + AC_SUBST(BUILD_VERSION) + AC_MSG_RESULT(Java version: ${JAVA_VERSION}) + + jre_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix}/jre + sdk_dir=java-${JAVA_VERSION}-${origin_name}-${JAVA_VERSION}.${BUILD_VERSION}${arch_suffix} + jre_lnk=jre-${JAVA_VERSION}-${origin_name} + sdk_lnk=java-${JAVA_VERSION}-${origin_name} + + JVM_ROOT_DIR=${jvm_root_dir} + AC_SUBST(JVM_ROOT_DIR) + AC_MSG_RESULT(JVM ROOT directory: ${JVM_ROOT_DIR}) + + JVM_JAR_ROOT_DIR=${jvm_jar_dir} + AC_SUBST(JVM_JAR_ROOT_DIR) + AC_MSG_RESULT(JVM JAR ROOT directory: ${JVM_JAR_ROOT_DIR}) + + JVM_JAR_DIR=${jvm_jar_dir}/${sdk_dir} + AC_SUBST(JVM_JAR_DIR) + AC_MSG_RESULT(JVM JAR directory: ${JVM_JAR_DIR}) + + JRE_DIR=${jre_dir} + AC_SUBST(JRE_DIR) + + SDK_DIR=${sdk_dir} + AC_SUBST(SDK_DIR) + + JRE_LNK=${jre_lnk} + AC_SUBST(JRE_LNK) + + SDK_LNK=${sdk_lnk} + AC_SUBST(SDK_LNK) + + SDK_BIN_DIR=${jvm_root_dir}/${sdk_dir}/bin + AC_SUBST(SDK_BIN_DIR) + AC_MSG_RESULT(SDK tools directory: ${SDK_BIN_DIR}) + + SDK_LIB_DIR=${jvm_root_dir}/${sdk_dir}/lib + AC_SUBST(SDK_LIB_DIR) + AC_MSG_RESULT(SDK jar directory: ${SDK_LIB_DIR}) + + SDK_INCLUDE_DIR=${jvm_root_dir}/${sdk_dir}/include + AC_SUBST(SDK_INCLUDE_DIR) + AC_MSG_RESULT(SDK include directory: ${SDK_INCLUDE_DIR}) + + JRE_BIN_DIR=${jvm_root_dir}/${jre_dir}/bin + AC_SUBST(JRE_BIN_DIR) + AC_MSG_RESULT(JRE tools directory: ${JRE_BIN_DIR}) + + JRE_LIB_DIR=${jvm_root_dir}/${jre_dir}/lib + AC_SUBST(JRE_LIB_DIR) + AC_MSG_RESULT(JRE lib directory: ${JRE_LIB_DIR}) + + # Find gcj prefix using gcj found in PATH. + gcj_prefix=`which gcj${gcc_suffix} | sed "s%/bin/gcj${gcc_suffix}%%"` + + # Where do the gcj binaries live? + # For jhbuild based builds, they all live in a sibling of bin called + # gcj-bin. Check for gcj-bin first, and use bin otherwise. + GCJ_BIN_DIR=`if test -d ${gcj_prefix}/gcj-bin; then echo ${gcj_prefix}/gcj-bin; else echo ${gcj_prefix}/bin; fi` + AC_SUBST(GCJ_BIN_DIR) + AC_MSG_RESULT(GCJ tools directory: ${GCJ_BIN_DIR}) + + echo host is ${host} + if test "x${host_cpu}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_cpu=x86;; + i486-* | i586-* | i686-*) + host_cpu=i386;; + *) + host_cpu=${host_cpu};; + esac + fi + AC_MSG_RESULT(arch directory: ${host_cpu}) + CPU=${host_cpu} + AC_SUBST(CPU) + + if test "x${host_os}" = "x" + then + case ${host} in + *-mingw* | *-cygwin*) + host_os=win32;; + *-linux*) + host_os=linux;; + *) + host_os=${host_os};; + esac + fi + echo os directory: ${host_os} + OS=${host_os} + AC_SUBST(OS) + + # make an expanded $libdir, for substituting into + # scripts (and other non-Makefile things). + LIBDIR=$libdir + if test "x${exec_prefix}" = "xNONE" + then + lib_exec_prefix=$prefix + else + lib_exec_prefix=$exec_prefix + fi + LIBDIR=`echo $libdir | sed "s:\\\${exec_prefix}:$lib_exec_prefix:g"` + AC_SUBST(LIBDIR) +fi + AC_CONFIG_FILES([ Makefile libgcj.pc @@ -1636,6 +1838,10 @@ gcj/Makefile include/Makefile testsuite/Makefile +contrib/aotcompile.py +contrib/aot-compile +contrib/aot-compile-rpm +contrib/rebuild-gcj-db ]) if test ${multilib} = yes; then Index: libjava/contrib/rebuild-gcj-db.in =================================================================== --- libjava/contrib/rebuild-gcj-db.in (revision 0) +++ libjava/contrib/rebuild-gcj-db.in (revision 0) @@ -0,0 +1,27 @@ +#!/bin/bash +# rebuild-gcj-db + +## Copyright (C) 2000, 2002, 2003, 2008 Free Software Foundation +## +## This file is part of libgcj. +## +## This software is copyrighted work licensed under the terms of the +## Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +## details. + +# Rebuild all the standard databases. +for i in `@prefix@/bin/gcc --print-multi-lib 2>/dev/null`; do + multilib=`echo $i | sed -e 's/^.*;//' | sed -e 's/\@/ -/g'` + dirname=`@prefix@/bin/gcc -print-multi-os-directory $multilib 2>/dev/null` + base=@prefix@/lib/$dirname + dbLocation=`@prefix@/bin/gcj-dbtool -p $base` + libdir=$base/gcj + if ! test -d $libdir; then + # No shared libraries here. + continue + fi + dirname $dbLocation | xargs mkdir -p + @prefix@/bin/gcj-dbtool -n $dbLocation 64 + find $libdir -follow -name '*.db' -print0 | \ + @prefix@/bin/gcj-dbtool -0 -m $dbLocation $dbLocation +done Index: libjava/contrib/aotcompile.py.in =================================================================== --- libjava/contrib/aotcompile.py.in (revision 0) +++ libjava/contrib/aotcompile.py.in (revision 0) @@ -0,0 +1,412 @@ +# -*- python -*- + +## Copyright (C) 2005, 2006, 2008 Free Software Foundation +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import classfile +import copy +import md5 +import operator +import os +import sys +import cStringIO as StringIO +import zipfile + +PATHS = {"make": "@MAKE@", + "gcj": "@prefix@/bin/gcj@gcc_suffix@", + "dbtool": "@prefix@/bin/gcj-dbtool@gcc_suffix@"} + +MAKEFLAGS = [] +GCJFLAGS = ["-fPIC", "-findirect-dispatch", "-fjni"] +LDFLAGS = ["-Wl,-Bsymbolic"] + +MAX_CLASSES_PER_JAR = 1024 +MAX_BYTES_PER_JAR = 1048576 + +MAKEFILE = "Makefile" + +MAKEFILE_HEADER = '''\ +GCJ = %(gcj)s +DBTOOL = %(dbtool)s +GCJFLAGS = %(gcjflags)s +LDFLAGS = %(ldflags)s + +%%.o: %%.jar + $(GCJ) -c $(GCJFLAGS) $< -o $@ + +TARGETS = \\ +%(targets)s + +all: $(TARGETS)''' + +MAKEFILE_JOB = ''' +%(base)s_SOURCES = \\ +%(jars)s + +%(base)s_OBJECTS = \\ +$(%(base)s_SOURCES:.jar=.o) + +%(dso)s: $(%(base)s_OBJECTS) + $(GCJ) -shared $(GCJFLAGS) $(LDFLAGS) $^ -o $@ + +%(db)s: $(%(base)s_SOURCES) + $(DBTOOL) -n $@ 64 + for jar in $^; do \\ + $(DBTOOL) -f $@ $$jar \\ + %(libdir)s/%(dso)s; \\ + done''' + +ZIPMAGIC, CLASSMAGIC = "PK\x03\x04", "\xca\xfe\xba\xbe" + +class Error(Exception): + pass + +class Compiler: + def __init__(self, srcdir, libdir, prefix = None): + self.srcdir = os.path.abspath(srcdir) + self.libdir = os.path.abspath(libdir) + if prefix is None: + self.dstdir = self.libdir + else: + self.dstdir = os.path.join(prefix, self.libdir.lstrip(os.sep)) + + # Calling code may modify these parameters + self.gcjflags = copy.copy(GCJFLAGS) + self.ldflags = copy.copy(LDFLAGS) + self.makeflags = copy.copy(MAKEFLAGS) + self.exclusions = [] + + def compile(self): + """Search srcdir for classes and jarfiles, then generate + solibs and mappings databases for them all in libdir.""" + if not os.path.isdir(self.dstdir): + os.makedirs(self.dstdir) + oldcwd = os.getcwd() + os.chdir(self.dstdir) + try: + jobs = self.getJobList() + if not jobs: + raise Error, "nothing to do" + self.writeMakefile(MAKEFILE, jobs) + for job in jobs: + job.writeJars() + system([PATHS["make"]] + self.makeflags) + for job in jobs: + job.clean() + os.unlink(MAKEFILE) + finally: + os.chdir(oldcwd) + + def getJobList(self): + """Return all jarfiles and class collections in srcdir.""" + jobs = weed_jobs(find_jobs(self.srcdir, self.exclusions)) + set_basenames(jobs) + return jobs + + def writeMakefile(self, path, jobs): + """Generate a makefile to build the solibs and mappings + databases for the specified list of jobs.""" + fp = open(path, "w") + print >>fp, MAKEFILE_HEADER % { + "gcj": PATHS["gcj"], + "dbtool": PATHS["dbtool"], + "gcjflags": " ".join(self.gcjflags), + "ldflags": " ".join(self.ldflags), + "targets": " \\\n".join(reduce(operator.add, [ + (job.dsoName(), job.dbName()) for job in jobs]))} + for job in jobs: + values = job.ruleArguments() + values["libdir"] = self.libdir + print >>fp, MAKEFILE_JOB % values + fp.close() + +def find_jobs(dir, exclusions = ()): + """Scan a directory and find things to compile: jarfiles (zips, + wars, ears, rars, etc: we go by magic rather than file extension) + and directories of classes.""" + def visit((classes, zips), dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + magic = open(path, "r").read(4) + if magic == ZIPMAGIC: + zips.append(path) + elif magic == CLASSMAGIC: + classes.append(path) + classes, paths = [], [] + os.path.walk(dir, visit, (classes, paths)) + # Convert the list of classes into a list of directories + while classes: + # XXX this requires the class to be correctly located in its heirachy. + path = classes[0][:-len(os.sep + classname(classes[0]) + ".class")] + paths.append(path) + classes = [cls for cls in classes if not cls.startswith(path)] + # Handle exclusions. We're really strict about them because the + # option is temporary in aot-compile-rpm and dead options left in + # specfiles will hinder its removal. + for path in exclusions: + if path in paths: + paths.remove(path) + else: + raise Error, "%s: path does not exist or is not a job" % path + # Build the list of jobs + jobs = [] + paths.sort() + for path in paths: + if os.path.isfile(path): + job = JarJob(path) + else: + job = DirJob(path) + if len(job.classes): + jobs.append(job) + return jobs + +class Job: + """A collection of classes that will be compiled as a unit.""" + + def __init__(self, path): + self.path, self.classes, self.blocks = path, {}, None + + def addClass(self, bytes): + """Subclasses call this from their __init__ method for + every class they find.""" + self.classes[md5.new(bytes).digest()] = bytes + + def __makeBlocks(self): + """Split self.classes into chunks that can be compiled to + native code by gcj. In the majority of cases this is not + necessary -- the job will have come from a jarfile which will + be equivalent to the one we generate -- but this only happens + _if_ the job was a jarfile and _if_ the jarfile isn't too big + and _if_ the jarfile has the correct extension and _if_ all + classes are correctly named and _if_ the jarfile has no + embedded jarfiles. Fitting a special case around all these + conditions is tricky to say the least. + + Note that this could be called at the end of each subclass's + __init__ method. The reason this is not done is because we + need to parse every class file. This is slow, and unnecessary + if the job is subsetted.""" + names = {} + for hash, bytes in self.classes.items(): + name = classname(bytes) + if not names.has_key(name): + names[name] = [] + names[name].append(hash) + names = names.items() + # We have to sort somehow, or the jars we generate + # We sort by name in a simplistic attempt to keep related + # classes together so inter-class optimisation can happen. + names.sort() + self.blocks, bytes = [[]], 0 + for name, hashes in names: + for hash in hashes: + if len(self.blocks[-1]) >= MAX_CLASSES_PER_JAR \ + or bytes >= MAX_BYTES_PER_JAR: + self.blocks.append([]) + bytes = 0 + self.blocks[-1].append((name, hash)) + bytes += len(self.classes[hash]) + + # From Archit Shah: + # The implementation and the documentation don't seem to match. + # + # [a, b].isSubsetOf([a]) => True + # + # Identical copies of all classes this collection do not exist + # in the other. I think the method should be named isSupersetOf + # and the documentation should swap uses of "this" and "other" + # + # XXX think about this when I've had more sleep... + def isSubsetOf(self, other): + """Returns True if identical copies of all classes in this + collection exist in the other.""" + for item in other.classes.keys(): + if not self.classes.has_key(item): + return False + return True + + def __targetName(self, ext): + return self.basename + ext + + def tempJarName(self, num): + return self.__targetName(".%d.jar" % (num + 1)) + + def tempObjName(self, num): + return self.__targetName(".%d.o" % (num + 1)) + + def dsoName(self): + """Return the filename of the shared library that will be + built from this job.""" + return self.__targetName(".so") + + def dbName(self): + """Return the filename of the mapping database that will be + built from this job.""" + return self.__targetName(".db") + + def ruleArguments(self): + """Return a dictionary of values that when substituted + into MAKEFILE_JOB will create the rules required to build + the shared library and mapping database for this job.""" + if self.blocks is None: + self.__makeBlocks() + return { + "base": "".join( + [c.isalnum() and c or "_" for c in self.dsoName()]), + "jars": " \\\n".join( + [self.tempJarName(i) for i in xrange(len(self.blocks))]), + "dso": self.dsoName(), + "db": self.dbName()} + + def writeJars(self): + """Generate jarfiles that can be native compiled by gcj.""" + if self.blocks is None: + self.__makeBlocks() + for block, i in zip(self.blocks, xrange(len(self.blocks))): + jar = zipfile.ZipFile(self.tempJarName(i), "w", zipfile.ZIP_STORED) + for name, hash in block: + jar.writestr( + zipfile.ZipInfo("%s.class" % name), self.classes[hash]) + jar.close() + + def clean(self): + """Delete all temporary files created during this job's build.""" + if self.blocks is None: + self.__makeBlocks() + for i in xrange(len(self.blocks)): + os.unlink(self.tempJarName(i)) + os.unlink(self.tempObjName(i)) + +class JarJob(Job): + """A Job whose origin was a jarfile.""" + + def __init__(self, path): + Job.__init__(self, path) + self._walk(zipfile.ZipFile(path, "r")) + + def _walk(self, zf): + for name in zf.namelist(): + bytes = zf.read(name) + if bytes.startswith(ZIPMAGIC): + self._walk(zipfile.ZipFile(StringIO.StringIO(bytes))) + elif bytes.startswith(CLASSMAGIC): + self.addClass(bytes) + +class DirJob(Job): + """A Job whose origin was a directory of classfiles.""" + + def __init__(self, path): + Job.__init__(self, path) + os.path.walk(path, DirJob._visit, self) + + def _visit(self, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.islink(path) or not os.path.isfile(path): + continue + fp = open(path, "r") + magic = fp.read(4) + if magic == CLASSMAGIC: + self.addClass(magic + fp.read()) + +def weed_jobs(jobs): + """Remove any jarfiles that are completely contained within + another. This is more common than you'd think, and we only + need one nativified copy of each class after all.""" + jobs = copy.copy(jobs) + while True: + for job1 in jobs: + for job2 in jobs: + if job1 is job2: + continue + if job1.isSubsetOf(job2): + msg = "subsetted %s" % job2.path + if job2.isSubsetOf(job1): + if (isinstance(job1, DirJob) and + isinstance(job2, JarJob)): + # In the braindead case where a package + # contains an expanded copy of a jarfile + # the jarfile takes precedence. + continue + msg += " (identical)" + warn(msg) + jobs.remove(job2) + break + else: + continue + break + else: + break + continue + return jobs + +def set_basenames(jobs): + """Ensure that each jarfile has a different basename.""" + names = {} + for job in jobs: + name = os.path.basename(job.path) + if not names.has_key(name): + names[name] = [] + names[name].append(job) + for name, set in names.items(): + if len(set) == 1: + set[0].basename = name + continue + # prefix the jar filenames to make them unique + # XXX will not work in most cases -- needs generalising + set = [(job.path.split(os.sep), job) for job in set] + minlen = min([len(bits) for bits, job in set]) + set = [(bits[-minlen:], job) for bits, job in set] + bits = apply(zip, [bits for bits, job in set]) + while True: + row = bits[-2] + for bit in row[1:]: + if bit != row[0]: + break + else: + del bits[-2] + continue + break + set = zip( + ["_".join(name) for name in apply(zip, bits[-2:])], + [job for bits, job in set]) + for name, job in set: + warn("building %s as %s" % (job.path, name)) + job.basename = name + # XXX keep this check until we're properly general + names = {} + for job in jobs: + name = job.basename + if names.has_key(name): + raise Error, "%s: duplicate jobname" % name + names[name] = 1 + +def system(command): + """Execute a command.""" + status = os.spawnv(os.P_WAIT, command[0], command) + if status > 0: + raise Error, "%s exited with code %d" % (command[0], status) + elif status < 0: + raise Error, "%s killed by signal %d" % (command[0], -status) + +def warn(msg): + """Print a warning message.""" + print >>sys.stderr, "%s: warning: %s" % ( + os.path.basename(sys.argv[0]), msg) + +def classname(bytes): + """Extract the class name from the bytes of a class file.""" + klass = classfile.Class(bytes) + return klass.constants[klass.constants[klass.name][1]][1] Index: libjava/contrib/aot-compile-rpm.in =================================================================== --- libjava/contrib/aot-compile-rpm.in (revision 0) +++ libjava/contrib/aot-compile-rpm.in (revision 0) @@ -0,0 +1,97 @@ +#!/usr/bin/env python + +## Copyright (C) 2005, 2006, 2007 Free Software Foundation +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir_expanded@") +import aotcompile +import os + +def libdir(): + cmd = "%s -p" % aotcompile.PATHS["dbtool"] + dir = os.path.abspath(os.popen(cmd, "r").readline().rstrip()) + dir, base = os.path.split(dir) + if base != "classmap.db": + raise aotcompile.Error, "%s: unexpected output" % cmd + dir, base = os.path.split(dir) + if not base.startswith("gcj-"): + raise aotcompile.Error, "%s: unexpected output" % cmd + return dir + +def writeSourceList(srcdir, dstpath): + def visit(fp, dir, items): + for item in items: + path = os.path.join(dir, item) + if os.path.isfile(path): + print >>fp, path + dstdir = os.path.dirname(dstpath) + if not os.path.isdir(dstdir): + os.makedirs(dstdir) + os.path.walk(srcdir, visit, open(dstpath, "w")) + +def copy(srcdir, dstdir, suffix): + srcdir = os.path.join(srcdir, suffix.lstrip(os.sep)) + dstdir = os.path.join(dstdir, suffix.lstrip(os.sep)) + os.makedirs(os.path.dirname(dstdir)) + aotcompile.system(("/bin/cp", "-a", srcdir, dstdir)) + +try: + name = os.environ.get("RPM_PACKAGE_NAME") + if name is None: + raise aotcompile.Error, "not for use outside rpm specfiles" + arch = os.environ.get("RPM_ARCH") + if arch == "noarch": + raise aotcompile.Error, "cannot be used on noarch packages" + srcdir = os.environ.get("RPM_BUILD_ROOT") + if srcdir in (None, "/"): + raise aotcompile.Error, "bad $RPM_BUILD_ROOT" + tmpdir = os.path.join(os.getcwd(), "aot-compile-rpm") + if os.path.exists(tmpdir): + raise aotcompile.Error, "%s exists" % tmpdir + dstdir = os.path.join(libdir(), "gcj", name) + + compiler = aotcompile.Compiler(srcdir, dstdir, tmpdir) + compiler.gcjflags[0:0] = os.environ.get("RPM_OPT_FLAGS", "").split() + + # XXX: This script should not accept options, because having + # them it cannot be integrated into rpm. But, gcj cannot + # build each and every jarfile yet, so we must be able to + # exclude until it can. + # XXX --exclude is also used in the jonas rpm to stop + # everything being made a subset of the mammoth client + # jarfile. Should adjust the subset checker's bias to + # favour many small jarfiles over one big one. + try: + options, exclusions = sys.argv[1:], [] + while options: + if options.pop(0) != "--exclude": + raise ValueError + compiler.exclusions.append( + os.path.join(srcdir, options.pop(0).lstrip(os.sep))) + except: + print >>sys.stderr, "usage: %s [--exclude PATH]..." % ( + os.path.basename(sys.argv[0])) + sys.exit(1) + + sourcelist = os.path.join(tmpdir, "sources.list") + writeSourceList(os.getcwd(), sourcelist) + compiler.gcjflags.append("-fsource-filename=" + sourcelist) + + compiler.compile() + copy(tmpdir, srcdir, dstdir) + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/contrib/classfile.py =================================================================== --- libjava/contrib/classfile.py (revision 0) +++ libjava/contrib/classfile.py (revision 0) @@ -0,0 +1,221 @@ +## Copyright (C) 2004, 2005 Free Software Foundation +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +"""Read Java(TM) class files.""" + +import cStringIO as StringIO +import struct + +class Class: + def __init__(self, arg): + if hasattr(arg, "read"): + self.fp = arg + elif type(arg) == type(""): + if arg.startswith("\xca\xfe\xba\xbe"): + self.fp = StringIO.StringIO(arg) + else: + self.fp = open(arg, "r") + else: + raise TypeError, type(arg) + + magic = self._read_int() + assert magic == 0xcafebabeL + minor, major = self._read(">HH") + self.version = (major, minor) + + self.pool_integrity_checks = None + try: + assert False + except AssertionError: + self.pool_integrity_checks = [] + + self._read_constants_pool() + + self.access_flags = self._read_short() + self.name = self._read_reference_Class() + self.super = self._read_reference_Class() + + self.interfaces = self._read_interfaces() + self.fields = self._read_fieldsormethods() + self.methods = self._read_fieldsormethods() + self.attributes = self._read_attributes() + + if self.pool_integrity_checks is not None: + for index, tag in self.pool_integrity_checks: + assert self.constants[index][0] == tag + + del self.fp, self.pool_integrity_checks + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) + if not attr.startswith("_") and attr != "Member"] + attrs.sort() + for attr in attrs: + result.append("%-13s %s" % ( + attr + ":", attr == "constants" and + "<ELIDED>" or repr(getattr(self, attr)))) + return "\n".join(result) + + def _read_constants_pool(self): + self.constants = {} + skip = False + for i in xrange(1, self._read_short()): + if skip: + skip = False + continue + tag = { + 1: "Utf8", 3: "Integer", 4: "Float", 5: "Long", + 6: "Double", 7: "Class", 8: "String", 9: "Fieldref", + 10: "Methodref", 11: "InterfaceMethodref", + 12: "NameAndType"}[self._read_byte()] + skip = tag in ("Long", "Double") # crack crack crack! + self.constants[i] = (tag, getattr(self, "_read_constant_" + tag)()) + + def _read_interfaces(self): + result = [] + for i in xrange(self._read_short()): + result.append(self._read_reference_Class()) + return result + + def _read_fieldsormethods(self): + result = [] + for i in xrange(self._read_short()): + result.append(self.Member(self)) + return result + + class Member: + def __init__(self, source): + self.access_flags = source._read_short() + self.name = source._read_reference_Utf8() + self.descriptor = source._read_reference_Utf8() + self.attributes = source._read_attributes() + + def __repr__(self): + result = [] + attrs = [attr for attr in dir(self) if not attr.startswith("_")] + attrs.sort() + for attr in attrs: + value = getattr(self, attr) + if attr == "attributes" and value.has_key("Code"): + value = value.copy() + value.update({"Code": "<ELIDED>"}) + result.append("%-13s %s" % ( + attr + ":", repr(value).replace( + "'Code': '<ELIDED>'", "'Code': <ELIDED>"))) + return ("\n%s" % (15 * " ")).join(result) + + def _read_attributes(self): + result = {} + for i in xrange(self._read_short()): + name = self._read_reference_Utf8() + data = self.fp.read(self._read_int()) + assert not result.has_key(name) + result[name] = data + return result + + # Constants pool reference reader convenience functions + + def _read_reference_Utf8(self): + return self._read_references("Utf8")[0] + + def _read_reference_Class(self): + return self._read_references("Class")[0] + + def _read_reference_Class_NameAndType(self): + return self._read_references("Class", "NameAndType") + + def _read_references(self, *args): + result = [] + for arg in args: + index = self._read_short() + if self.pool_integrity_checks is not None: + self.pool_integrity_checks.append((index, arg)) + result.append(index) + return result + + # Constants pool constant reader functions + + def _read_constant_Utf8(self): + constant = self.fp.read(self._read_short()) + try: + constant = constant.decode("utf-8") + except UnicodeError: + constant = _bork_utf8_decode(constant) + try: + constant = constant.encode("us-ascii") + except UnicodeError: + pass + return constant + + def _read_constant_Integer(self): + return self._read_int() + + def _read_constant_Float(self): + return self._read(">f")[0] + + def _read_constant_Long(self): + return self._read(">q")[0] + + def _read_constant_Double(self): + return self._read(">d")[0] + + _read_constant_Class = _read_reference_Utf8 + _read_constant_String = _read_reference_Utf8 + _read_constant_Fieldref = _read_reference_Class_NameAndType + _read_constant_Methodref = _read_reference_Class_NameAndType + _read_constant_InterfaceMethodref = _read_reference_Class_NameAndType + + def _read_constant_NameAndType(self): + return self._read_reference_Utf8(), self._read_reference_Utf8() + + # Generic reader functions + + def _read_int(self): + # XXX how else to read 32 bits on a 64-bit box? + h, l = map(long, self._read(">HH")) + return (h << 16) + l + + def _read_short(self): + return self._read(">H")[0] + + def _read_byte(self): + return self._read("B")[0] + + def _read(self, fmt): + return struct.unpack(fmt, self.fp.read(struct.calcsize(fmt))) + +def _bork_utf8_decode(data): + # more crack! + bytes, unicode = map(ord, data), "" + while bytes: + b1 = bytes.pop(0) + if b1 & 0x80: + assert b1 & 0x40 + b2 = bytes.pop(0) + assert b2 & 0xC0 == 0x80 + if b1 & 0x20: + assert not b1 & 0x10 + b3 = bytes.pop(0) + assert b3 & 0xC0 == 0x80 + unicode += unichr( + ((b1 & 0x0f) << 12) + ((b2 & 0x3f) << 6) + (b3 & 0x3f)) + else: + unicode += unichr(((b1 & 0x1f) << 6) + (b2 & 0x3f)) + else: + unicode += unichr(b1) + return unicode + +if __name__ == "__main__": + print Class("/usr/share/katana/build/ListDependentClasses.class") + Index: libjava/contrib/aot-compile.in =================================================================== --- libjava/contrib/aot-compile.in (revision 0) +++ libjava/contrib/aot-compile.in (revision 0) @@ -0,0 +1,88 @@ +#!/usr/bin/env python + +## Copyright (C) 2006 Free Software Foundation +## Written by Gary Benson <gbenson@redhat.com> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +import sys +sys.path.append("@python_mod_dir_expanded@") +import aotcompile +import getopt +import os + +usage = """\ +Usage: %s [OPTION...] SRCDIR DSTDIR +AOT-compile all Java bytecode in SRCDIR into DSTDIR. + +Options: + -M, --make=PATH make executable to use (%s) + -C, --gcj=PATH gcj executable to use (%s) + -D, --dbtool=PATH gcj-dbtool executable to use (%s) + -m, --makeflags=FLAGS flags to pass to make during build + -c, --gcjflags=FLAGS flags to pass to gcj during compilation + in addition to %s + -l, --ldflags=FLAGS flags to pass to gcj during linking + in addition to %s + -e, --exclude=PATH do not compile PATH + +Extra flags may also be passed using the AOT_MAKEFLAGS, AOT_GCJFLAGS +and AOT_LDFLAGS environment variables.""" % ( + os.path.basename(sys.argv[0]), + aotcompile.PATHS["make"], + aotcompile.PATHS["gcj"], + aotcompile.PATHS["dbtool"], + repr(" ".join(aotcompile.GCJFLAGS)), + repr(" ".join(aotcompile.LDFLAGS))) + +try: + if os.environ.has_key("RPM_PACKAGE_NAME"): + raise aotcompile.Error, "not for use within rpm specfiles" + + try: + opts, args = getopt.getopt( + sys.argv[1:], + "M:C:D:m:c:l:e:", + ["make=", "gcj=", "dbtool=", + "makeflags=" "gcjflags=", "ldflags=", + "exclude="]) + srcdir, dstdir = args + except: + print >>sys.stderr, usage + sys.exit(1) + + compiler = aotcompile.Compiler(srcdir, dstdir) + for o, a in opts: + if o in ("-M", "--make"): + aotcompile.PATHS["make"] = a + if o in ("-C", "--gcj"): + aotcompile.PATHS["gcj"] = a + if o in ("-D", "--dbtool"): + aotcompile.PATHS["dbtool"] = a + if o in ("-m", "--makeflags"): + compiler.makeflags[0:0] = a.split() + if o in ("-c", "--gcjflags"): + compiler.gcjflags[0:0] = a.split() + if o in ("-l", "--ldflags"): + compiler.ldflags[0:0] = a.split() + if o in ("-e", "--exclude"): + compiler.exclusions.append(a) + + compiler.makeflags[0:0] = os.environ.get("AOT_MAKEFLAGS", "").split() + compiler.gcjflags[0:0] = os.environ.get("AOT_GCJFLAGS", "").split() + compiler.ldflags[0:0] = os.environ.get("AOT_LDFLAGS", "").split() + + compiler.compile() + +except aotcompile.Error, e: + print >>sys.stderr, "%s: error: %s" % ( + os.path.basename(sys.argv[0]), e) + sys.exit(1) Index: libjava/Makefile.am =================================================================== --- libjava/Makefile.am (revision 137317) +++ libjava/Makefile.am (working copy) @@ -74,7 +74,8 @@ ## Name of the default .db. db_name = classmap.db ## Compiler specific component of the .db file -db_pathtail = gcj-$(gcc_version)/$(db_name) +gcjsubdir = @gcjsubdir@ +db_pathtail = $(gcjsubdir)/$(db_name) ## For now, only on native systems. FIXME. if NATIVE @@ -85,9 +86,13 @@ ## It is convenient to actually build and install the default database ## when gcj-dbtool is available. dbexec_DATA = $(db_name) -endif +endif -bin_SCRIPTS = addr2name.awk +bin_SCRIPTS = addr2name.awk contrib/rebuild-gcj-db contrib/aot-compile + +if INSTALL_AOT_RPM +bin_SCRIPTS += contrib/aot-compile-rpm +endif if BUILD_ECJ1 ## We build ecjx and not ecj1 because in one mode, ecjx will not work @@ -528,7 +533,140 @@ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SinkChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ $(INSTALL_DATA) $(srcdir)/'gnu/java/nio/PipeImpl$$SourceChannelImpl.h' $(DESTDIR)$(gxx_include_dir)/gnu/java/nio/ ## Don't install java/nio/DirectByteBufferImpl$$ReadWrite.h here. It's for internal use only. - +## Install Python modules for aot-compile. + $(mkinstalldirs) $(DESTDIR)$(python_mod_dir); \ + $(INSTALL_DATA) $(srcdir)/contrib/classfile.py \ + $(DESTDIR)$(python_mod_dir)/classfile.py; \ + $(INSTALL_DATA) contrib/aotcompile.py \ + $(DESTDIR)$(python_mod_dir)/aotcompile.py; +if CREATE_JAVA_HOME +## Create sdk style directories + $(mkinstalldirs) $(DESTDIR)$(JRE_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_BIN_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR) + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR) + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/$(OS) + relative() { \ + $(PERL) -e 'use File::Spec; \ + print File::Spec->abs2rel($$ARGV[0], $$ARGV[1])' $$1 $$2; \ + }; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(SDK_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gjar | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jar; \ + ln -sf $$RELATIVE/`echo gjdoc | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javadoc; \ + ln -sf $$RELATIVE/`echo grmic | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmic; \ + ln -sf $$RELATIVE/`echo gjavah | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/javah; \ + ln -sf $$RELATIVE/ecj $(DESTDIR)$(SDK_BIN_DIR)/javac; \ + ln -sf $$RELATIVE/`echo gappletviewer | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/appletviewer; \ + ln -sf $$RELATIVE/`echo gjarsigner | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/jarsigner; \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo gnative2ascii | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/native2ascii; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/tnameserv; \ + ln -sf $$RELATIVE/`echo gserialver | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(SDK_BIN_DIR)/serialver; \ + RELATIVE=$$(relative $(DESTDIR)$(bindir) $(DESTDIR)$(JRE_BIN_DIR)); \ + ln -sf $$RELATIVE/`echo grmiregistry | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmiregistry; \ + ln -sf $$RELATIVE/`echo gkeytool | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/keytool; \ + ln -sf $$RELATIVE/`echo gij | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/java; \ + ln -sf $$RELATIVE/`echo gorbd | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/orbd; \ + ln -sf $$RELATIVE/`echo grmid | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/rmid; \ + ln -sf $$RELATIVE/`echo gtnameserv | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'` \ + $(DESTDIR)$(JRE_BIN_DIR)/tnameserv; \ + $(mkinstalldirs) $(DESTDIR)$(JVM_JAR_DIR); \ + version=$(JAVA_VERSION).$(BUILD_VERSION); \ + working_dir=`pwd`; \ + cd $(DESTDIR)$(JVM_JAR_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s $$RELATIVE/$$jarname.jar $$jarname-$$version.jar; \ + done; \ + for jar in *-$$version.jar; \ + do \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|-$(JAVA_VERSION).jar|g"); \ + ln -sf $$jar $$(echo $$jar | sed "s|-$$version.jar|.jar|g"); \ + done; \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/security; \ + RELATIVE=$$(relative $(DESTDIR)$(libdir)/security \ + $(DESTDIR)$(JRE_LIB_DIR)/security); \ + cd $(DESTDIR)$(JRE_LIB_DIR)/security; \ + ln -sf $$RELATIVE/classpath.security java.security; \ + cd $$working_dir; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_INCLUDE_DIR)/linux; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client; \ + $(mkinstalldirs) $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server; \ + $(mkinstalldirs) $(DESTDIR)$(SDK_LIB_DIR); \ + cd $(DESTDIR)$(JRE_LIB_DIR); \ + for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ + jndi-ldap jndi-rmi jsse sasl; \ + do \ + ln -s rt.jar $$jarname.jar; \ + done; \ + cd $$working_dir; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JRE_LIB_DIR)); \ + ln -sf $$RELATIVE/libgcj-$(gcc_version).jar \ + $(DESTDIR)$(JRE_LIB_DIR)/rt.jar; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)); \ + ln -sf $$RELATIVE/libjawt.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/libjawt.so; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/client/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(dbexecdir) \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server); \ + ln -sf $$RELATIVE/libjvm.so \ + $(DESTDIR)$(JRE_LIB_DIR)/$(CPU)/server/libjvm.so; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(SDK_LIB_DIR)); \ + ln -sf $$RELATIVE/libgcj-tools-$(gcc_version).jar \ + $(DESTDIR)$(SDK_LIB_DIR)/tools.jar; \ + for headername in jawt jni; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/$$headername.h; \ + done; \ + for headername in jawt_md jni_md; do \ + DIRECTORY=$$(dirname $$($(DESTDIR)$(bindir)/gcj \ + -print-file-name=include/$$headername.h)); \ + RELATIVE=$$(relative $(DESTDIR)$$DIRECTORY \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux); \ + ln -sf $$RELATIVE/$$headername.h \ + $(DESTDIR)$(SDK_INCLUDE_DIR)/linux/$$headername.h; \ + done; \ + RELATIVE=$$(relative $(DESTDIR)$(datarootdir)/java \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)); \ + ln -sf $$RELATIVE/src-$(gcc_version).zip \ + $(DESTDIR)$(JVM_ROOT_DIR)/$(SDK_DIR)/src.zip; +endif ## ################################################################ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch] Create sdk style directory on install 2008-07-02 13:07 ` Andrew Haley @ 2008-07-02 13:19 ` Joshua Sumali 0 siblings, 0 replies; 18+ messages in thread From: Joshua Sumali @ 2008-07-02 13:19 UTC (permalink / raw) To: Andrew Haley; +Cc: java-patches Andrew Haley wrote: > Joshua Sumali wrote: > >> Andrew Haley wrote: >> >>> Joshua Sumali wrote: >>> >>> >>>> Andrew Haley wrote: >>>> >>>> >>> >>> >>>>> Please assign all Red Hat copyrights to the FSF. >>>>> >>>>> >>>> Is there a special way to do this, or do I simply change "Copyright (C) >>>> 2005, 2006, 2008 Red Hat, Inc." to "Copyright (C) 2005, 2006, 2008 Free >>>> Software Foundation" on the appropriate files? >>>> >>>> >>> That's all you have to do. >>> >>> >>> >>>>> Do I take it that you don't have commit access to the gcc tree? >>>>> >>>>> >>>> I do not. I was hoping someone would be able to commit the patches >>>> for me. >>>> >>>> >>> I'll do it. >>> > > Here's what I committed. I had partly to rewrite rebuild-gcj-db because it > handled multilibs incorrectly, and in the process discovered a bug in > gcj-dbtool, but otherwise it's the same. > > Andrew. > > TVM for the help with this patch :) Josh ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2008-07-02 13:19 UTC | newest] Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-06-12 20:56 [patch] Create sdk style directory on install Joshua Sumali 2008-06-13 10:42 ` Andrew Haley 2008-06-13 12:42 ` Matthias Klose 2008-06-16 14:37 ` Joshua Sumali 2008-06-18 20:39 ` Joshua Sumali 2008-06-19 9:54 ` Andrew Haley 2008-06-19 14:24 ` Joshua Sumali 2008-06-20 4:13 ` Joshua Sumali 2008-06-26 18:18 ` Joshua Sumali 2008-06-30 10:20 ` Andrew Haley 2008-06-30 13:54 ` Joshua Sumali 2008-06-30 13:57 ` Andrew Haley 2008-06-30 14:39 ` Joshua Sumali 2008-07-01 13:59 ` Andrew Haley 2008-07-01 14:53 ` Joshua Sumali 2008-07-01 15:01 ` Andrew Haley 2008-07-02 13:07 ` Andrew Haley 2008-07-02 13:19 ` Joshua Sumali
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).