This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
PR libgcj/38396: [4.4 Regression] libgcj_bc for 4.3 and 4.4 are binary incompatible but have the same SONAME
- From: Andrew Haley <aph at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: Fri, 12 Dec 2008 18:34:22 +0000
- Subject: PR libgcj/38396: [4.4 Regression] libgcj_bc for 4.3 and 4.4 are binary incompatible but have the same SONAME
This happens because ecjx is linked both to libgcj_bc.so.1 and libgcj.so.9.
This is always wrong; a program must be linked to one or the other.
Fixing this turned out to be surprisingly difficult, mostly due to the
difficulty of linking and installing with libtool.
This is for 4.3 branch and trunk.
Andrew.
2008-12-12 Andrew Haley <aph@redhat.com>
* Makefile.am (libgcj_bc_la_LIBADD, libgcj_bc_la_DEPENDENCIES):
Remove.
(libgcj_bc.la): Link with -Wl,-L$(here)/.libs,-lgcj Add comment
explaining this. Add libgcj.la as a make dependency.
(install-exec-hook): Don't relink libgcj_bc.so.1.0.0; instead
simpily copy the correct libgcj_bc.so from the build dir to the
install dir.
(ecjx_DEPENDENCIES): Depend only on libgcj_bc.la.
Index: Makefile.am
===================================================================
--- Makefile.am (revision 142643)
+++ Makefile.am (working copy)
@@ -324,8 +324,6 @@
libgcj_bc_la_SOURCES = libgcj_bc.c
libgcj_bc_la_LDFLAGS = -rpath $(toolexeclibdir) -no-static -version-info 1:0:0
\
$(LIBGCJ_LD_SYMBOLIC_FUNCTIONS)
-libgcj_bc_la_LIBADD = libgcj.la
-libgcj_bc_la_DEPENDENCIES = libgcj.la
libgcj_bc_la_LINK = $(LIBLINK)
## This is specific to Linux/{Free,Net,Open}BSD/Hurd and perhaps few others.
## USE_LIBGCJ_BC shouldn't be set on other targets.
@@ -334,9 +332,18 @@
## This rule creates the libgcj_bc dummy library in the .libs directory, for us
e
## when testing.
-libgcj_bc.la: $(libgcj_bc_la_OBJECTS) $(libgcj_bc_la_DEPENDENCIES)
+##
+## The mysterious -Wl,...-lgcj causes libgcj_bc.so to be linked
+## against libgcj.so without libtool knowing. If we don't hide this,
+## libtool will use libgcj.la as a dependency of libgcj_bc.la and
+## BC-compiled executables in libgcj will have a DT_NEEDED against
+## e.g. libgcj.so.9. We must link against libgcj.so because common
+## symbols such as _Jv_charClass which are defined in both libgcj_bc
+## and libgcj must be merged.
+libgcj_bc.la: libgcj.la $(libgcj_bc_la_OBJECTS) $(libgcj_bc_la_DEPENDENCIES)
$(libgcj_bc_la_LINK) $(am_libgcj_bc_la_rpath) $(libgcj_bc_la_LDFLAGS) \
- $(libgcj_bc_la_OBJECTS) $(libgcj_bc_la_LIBADD) $(LIBS) || exit; \
+ $(libgcj_bc_la_OBJECTS) $(libgcj_bc_la_LIBADD) $(LIBS) \
+ -Wl,-L$(here)/.libs,-lgcj || exit; \
rm .libs/libgcj_bc.so; \
mv .libs/libgcj_bc.so.1.0.0 .libs/libgcj_bc.so; \
$(libgcj_bc_dummy_LINK) -xc /dev/null -Wl,-soname,libgcj_bc.so.1 \
@@ -461,13 +468,9 @@
## Install libgcj_bc dummy lib in the target directory. We also need to delete
## libtool's .la file, this prevents libtool resetting the lib again
## later.
- @echo Installing dummy lib libgcj_bc.so.1.0.0; \
+ echo Installing dummy lib libgcj_bc.so; \
rm $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so; \
- mv $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so.1.0.0 $(DESTDIR)$(toolexecli
bdir)/libgcj_bc.so; \
- $(libgcj_bc_dummy_LINK) -xc /dev/null -Wl,-soname,libgcj_bc.so.1 \
- -o $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so.1.0.0 -lgcj || exit; \
- rm $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so.1; \
- $(LN_S) libgcj_bc.so.1.0.0 $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so.1; \
+ cp $(here)/.libs/libgcj_bc.so $(DESTDIR)$(toolexeclibdir)/libgcj_bc.so;
\
rm $(DESTDIR)$(toolexeclibdir)/libgcj_bc.la;
endif
if BUILD_ECJ1
@@ -713,11 +716,14 @@
ecjx_LDFLAGS = $(ECJX_BASE_FLAGS) $(ECJ_BUILD_JAR) -fbootclasspath=$(BOOTCLASSP
ATH)
endif !ENABLE_SHARED
-ecjx_LDADD = -L$(here)/.libs libgcj.la
-ecjx_DEPENDENCIES = libgcj.la libgcj.spec
+ecjx_LDADD = -L$(here)/.libs
if USE_LIBGCJ_BC
-ecjx_DEPENDENCIES += libgcj_bc.la
-endif
+ecjx_LDADD += libgcj_bc.la
+ecjx_DEPENDENCIES = libgcj_bc.la
+else !USE_LIBGCJ_BC
+ecjx_LDADD += libgcj.la
+ecjx_DEPENDENCIES = libgcj.la libgcj.spec
+endif !USE_LIBGCJ_BC
else !NATIVE