From: cek@sdc.boeing.com (Conrad Kimball)
Newsgroups: comp.windows.x
Subject: Shared lib patch for X11R4p18 on SunOS 4.1.2
Date: 6 Apr 92 17:53:40 GMT
Organization: Boeing Computer Services (DSTS), Seattle, WA

Over the past several months I've seen several pleas for help in this
newsgroup concerning troubles using X11R4p18 shared libraries on
SunOS 4.1.2 (I was one of them, too).

The problem revolves around an incorrectly built Xmu library, which
leads to ld complaining about undefined symbols at link time, vis:

    ld: Undefined symbol
    _get_wmShellWidgetClass
    _get_applicationShellWidgetClass

We also filed a bug report with Sun, whose reply was 1) not very helpful,
and 2) what was suggested was wrong.  (Which is interesting, since Sun's
OpenWindows 3.0 exhibits the same problems on SunOS 4.1.2 - you'd think
that Sun would at least get it right for their own product!)

As a result I have developed the following patch, which is working at
our site.  If anyone has any corrections or further suggestions, I'd
very much appreciate the feedback.

------------------------------------------------------------------------

This patch fixes the way that X11R4p18 shared libraries (.sa and .so)
are generated on SunOS.  The problem:

1.  The original build procedures for the Xmu and Xt libraries compile
    the sharedlib.c file with different #defines.  The version put into
    the "shared" subdirectory is a dummy version, while the version left
    in the library source directory is a functional version.  The .so
    library is built from the objects in the "shared" subdirectory, except
    that the shared/sharedlib.o objects is omitted.  The .sa library is
    built from the sharedlib.o version in the library source directory.

2.  If you try to link with this Xmu library on SunOS 4.1.2 (or SunOS 4.1.1
    in which you've installed Sun's ld patch 100170-6), you get
    "ld: Undefined symbol" errors for at least:

	_get_wmShellWidgetClass
	_get_applicationShellWidgetClass
	_floor
	_pow

    You may also get undefined symbols from the Xt and X11 libraries, too,
    if you don't explicitly link with those libraries.  However, if you
    do a static link using -Bstatic, the link works OK.

    It almost seems as if the semantics of linking with shared libraries
    has changed.  The old semantics seemed to be roughly the same as for a
    static link: link with the Xmu library, and for just those Xmu objects
    that are used by the program, ensure their external symbols are
    satisfied by some other library.  Now, the semantics seems to be to
    try to satisfy external symbol references from *all* objects in the Xmu
    library at link time, which triggers detecting the undefined symbols
    from the .sa file and the math library (and from the Xt, Xext, and/or
    X11 libraries, if you haven't explicitly linked with them, either).
    This, even though the application never references the objects that in
    turn reference these other libraries.  Perhaps this explains the
    recommendation someone gave me, to build all applications with the
    "-assert definitions" ld option, which tells ld to not complain about
    this situation (at the risk of you not finding out about other, truly
    serious, undefined symbols).

    I fervently hope that someone with a better understanding of Sun shared
    libraries can provide some understanding here.

    Note: the R5 libraries seem to be built the same way, yet they have
    no problems being using with SunOS 4.1.2 (at least with patches 9 and
    10 installed).  Why is this?  Are they really being built incorrectly,
    and just getting away with it, due to some specific characteristics
    of the R5 shared libraries that don't trigger the problem?

3.  The Sun Programming Utilities and Libraries manual, in section 1.5
    (about building .sa files), says that "everything placed in a .sa file
    must also appear in the .so file."  The original build procedures are
    not doing this, so the solution seems to be to see that this happens.

4.  The OpenWindows 3.0 libraries (provided by Sun!) exhibit these
    same Xmu library problems on SunOS 4.1.2.  This is a sad comment on
    Sun's quality control, especially considering that we originally
    filed a bug report with Sun in January, and got this less than helpful
    response:

>	This is not a bug.  The X11R4 shared libraries are incorrectly
>	constructed.  They were always incorrectly constructed, but 
>	previous bugs in the loader masked the error.
>
>	MIT knows about this problem and will be correcting their
>	distribution.
>
>	In the interim, the customer can apply the fixes that MIT
>	would have done, which is to build X11 shared objects to 
>	explicitly depend upon the other shared objects from which
>	they import symbols.

    (Sheesh... Sun thinks the problem can be fixed by simply making
    the Xmu library explicitly depend on the other libraries, when
    the real problem is that the libraries aren't including the
    proper objects.  The explicit dependency is simply a convenience,
    so that users of the Xmu library don't have to put "-lXt -lXext -lX11"
    in their link command.)

The solution I've come up with looks like:

1.  Change the NormalSharedLibraryDataTarget macro in Imake.rules to build
    the .sa file from objects in the "shared" subdirectory, rather than
    from the library source directory.

2.  Change the Xt and Xmu library Imakefile's to incorporate the
    shared/sharedlib.o object in the .so file, and change the #ifdef
    tests in the Xt and Xmu sharedlib.c files so the version that goes
    into the "shared" subdirectory is the functional version, and the
    version in the library source directory is the dummy version.

3.  Change the extensions library Imakefile to build the Xext library in
    shared mode, and change sun.cf to "#define SharedLibExt YES".  (This
    borrowed from R5.)

4.  Change the NormalSharedLibraryTarget macro in Imake.rules to include
    the $(REQUIREDLIBS) make macro in the ld command that builds the
    .so library.  (This borrowed from R5.)

5.  Change the Xmu library Imakefile to be dependent on the extensions
    library, and if necessary, cause that library to be built before
    building the libXmu.so file.  Also, if SunPost411FCSLd is #defined,
    set the $(REQUIREDLIBS) make macro to refer to the Xt, Xext, and X11
    libraries.  This "tells" the shared Xmu library that, when it is
    linked with, to also link with the Xt, Xext, and X11 shared libraries.
    This is done because many application Imakefile's are set up to link
    with the Xmu library but not all of the Xt, Xext, and X11 libraries,
    which won't work anymore.  Rather than adjusting all those Imakefiles,
    it is simpler to incorporate references to these libraries in the
    libXmu.so file.  (This borrowed from R5.)

6.  Change the Project.tmpl file to fix the definition of EXTENSIONLIB
    to be correct when using a shared extension library (simply a bug),
    and if SunPost411FCSLd is #defined, have the XMULIB make macro include
    appropriate "-L" references to the directories in which the Xt, Xext,
    and X11 shared libraries reside.  This lets those clients, whose
    Imakefiles link with the Xmu library but not all of the Xt, Xext, and
    X11 libraries, find the Xt, Xext, and X11 libraries that are now
    referenced by the Xmu shared library.  (This borrowed from R5).

7.  Now, this seems to fix the Xmu library problems, and the problems
    of linking with Xmu but not explicitly with Xt, Xext, and/or X11,
    but it still leaves undefined symbols for some math functions that
    the Xmu library calls.  So, in sun.cf "#define ExtraLoadFlags -lm".
    Too bad the math library doesn't have a shared version, or else
    we could have included it in the $(REQUIREDLIBS) list when building
    the Xmu shared library.

8.  If you are running SunOS 4.1.2, or SunOS 4.1.1 with Sun's ld patch
    100170-6, in sun.cf "#define SunPost411FCSLd YES".  (This borrowed
    from R5.)
    

*** mit/lib/Xt/Imakefile.orig	Sun Oct  6 20:51:26 1991
--- mit/lib/Xt/Imakefile	Wed Apr  1 12:10:58 1992
***************
*** 131,137 ****
  	Varargs.o \
  	Vendor.o
  
! UNSHAREDOBJS = sharedlib.o
  
  all::
  
--- 131,137 ----
  	Varargs.o \
  	Vendor.o
  
! SHAREDDATAOBJS = sharedlib.o
  
  all::
  
***************
*** 179,186 ****
   * always generate unshared library too 
   */
  #if SharedLibXt
! NormalSharedLibraryTarget(Xt,$(SOXTREV),$(OBJS))
! NormalSharedLibraryDataTarget(Xt,$(SOXTREV),$(UNSHAREDOBJS))
  InstallSharedLibrary(Xt,$(SOXTREV),$(USRLIBDIR))
  InstallSharedLibraryData(Xt,$(SOXTREV),$(USRLIBDIR))
  #endif
--- 179,186 ----
   * always generate unshared library too 
   */
  #if SharedLibXt
! NormalSharedLibraryTarget(Xt,$(SOXTREV),$(OBJS) $(SHAREDDATAOBJS))
! NormalSharedLibraryDataTarget(Xt,$(SOXTREV),$(SHAREDDATAOBJS))
  InstallSharedLibrary(Xt,$(SOXTREV),$(USRLIBDIR))
  InstallSharedLibraryData(Xt,$(SOXTREV),$(USRLIBDIR))
  #endif
*** mit/lib/Xt/sharedlib.c.orig	Sun Oct  6 20:50:17 1991
--- mit/lib/Xt/sharedlib.c	Wed Apr  1 12:10:59 1992
***************
*** 8,14 ****
   * generating shared code so that this gets copied into the application binary.
   */
  
! #if defined(SUNSHLIB) && !defined(SHAREDCODE)
  #include "IntrinsicI.h"
  #include "VarargsI.h"
  
--- 8,14 ----
   * generating shared code so that this gets copied into the application binary.
   */
  
! #if defined(SHAREDCODE)
  #include "IntrinsicI.h"
  #include "VarargsI.h"
  
***************
*** 94,97 ****
  
  #else
  static int dummy;			/* avoid warning from ranlib */
! #endif /* SUNSHLIB */
--- 94,97 ----
  
  #else
  static int dummy;			/* avoid warning from ranlib */
! #endif /* SHAREDCODE */
*** mit/lib/Xmu/Imakefile.orig	Tue Mar 31 23:05:52 1992
--- mit/lib/Xmu/Imakefile	Wed Apr  1 14:50:18 1992
***************
*** 5,10 ****
--- 5,14 ----
  /**/# of the Xlib standard.
  /**/#
  
+ #if defined(SunArchitecture) && SunPost411FCSLd
+ REQUIREDLIBS = -L../$(TOOLKITSRC) -lXt -L../$(EXTENSIONSRC)/lib -lXext -L../$(XLIBSRC) -lX11
+ #endif
+ 
     INSTALLFLAGS = $(INSTINCFLAGS)
         LINTLIBS = $(LINTXLIB) 
  
***************
*** 114,120 ****
  	VisCmap.o \
  	Xct.o
  
! UNSHAREDOBJS = sharedlib.o
  
  all::
  
--- 118,124 ----
  	VisCmap.o \
  	Xct.o
  
! SHAREDDATAOBJS = sharedlib.o
  
  all::
  
***************
*** 147,154 ****
  #endif
  
  #if SharedLibXmu
! NormalSharedLibraryTarget(Xmu,$(SOXMUREV),$(OBJS))
! NormalSharedLibraryDataTarget(Xmu,$(SOXMUREV),$(UNSHAREDOBJS))
  InstallSharedLibrary(Xmu,$(SOXMUREV),$(USRLIBDIR))
  InstallSharedLibraryData(Xmu,$(SOXMUREV),$(USRLIBDIR))
  #endif
--- 151,164 ----
  #endif
  
  #if SharedLibXmu
! #if defined(SunArchitecture) && SunPost411FCSLd
! libXmu.so.$(SOXMUREV): $(EXTENSIONSRC)/lib/libXext.so.$(SOXEXTREV)
! 
! $(EXTENSIONSRC)/lib/libXext.so.$(SOXEXTREV):
!         cd $(EXTENSIONSRC)/lib; make all
! #endif
! NormalSharedLibraryTarget(Xmu,$(SOXMUREV),$(OBJS) $(SHAREDDATAOBJS))
! NormalSharedLibraryDataTarget(Xmu,$(SOXMUREV),$(SHAREDDATAOBJS))
  InstallSharedLibrary(Xmu,$(SOXMUREV),$(USRLIBDIR))
  InstallSharedLibraryData(Xmu,$(SOXMUREV),$(USRLIBDIR))
  #endif
*** mit/lib/Xmu/sharedlib.c.orig	Mon Oct  9 11:28:58 1989
--- mit/lib/Xmu/sharedlib.c	Wed Apr  1 12:10:58 1992
***************
*** 6,12 ****
   * This file is used to force shared libraries to get the right routines.
   */
  
! #if defined(SUNSHLIB) && !defined(SHAREDCODE)
  #include <X11/IntrinsicP.h>
  
  /*
--- 6,12 ----
   * This file is used to force shared libraries to get the right routines.
   */
  
! #if defined(SHAREDCODE)
  #include <X11/IntrinsicP.h>
  
  /*
***************
*** 28,32 ****
  
  #else
  static int dummy;                       /* avoid warning from ranlib */
! #endif /* SHAREDCODE && SUNSHLIB */
  
--- 28,32 ----
  
  #else
  static int dummy;                       /* avoid warning from ranlib */
! #endif /* SHAREDCODE */
  
*** mit/extensions/lib/Imakefile.orig	Tue Dec 12 13:45:05 1989
--- mit/extensions/lib/Imakefile	Wed Apr  1 14:59:34 1992
***************
*** 22,39 ****
  		MITMisc.o XTestExt1.o 
       LINTLIBS = $(LINTXLIB)
  
! #if DebugLibXext && ProfileLibXext
! DebuggedAndProfiledLibraryObjectRule()
! #else
  # if DebugLibXext
! DebuggedLibraryObjectRule()
  # else
! #  if ProfileLibXext
! ProfiledLibraryObjectRule()
  #  else
  NormalLibraryObjectRule()
  #  endif
  # endif
  #endif
  
  NormalLibraryTarget(Xext,$(OBJS))
--- 22,52 ----
  		MITMisc.o XTestExt1.o 
       LINTLIBS = $(LINTXLIB)
  
! #if SharedLibXext
  # if DebugLibXext
! SharedAndDebuggedLibraryObjectRule()
  # else
! SharedLibraryObjectRule()
! # endif
! #else
! # if DebugLibXext && ProfileLibXext
! DebuggedAndProfiledLibraryObjectRule()
! # else
! #  if DebugLibXext
! DebuggedLibraryObjectRule()
  #  else
+ #   if ProfileLibXext
+ ProfiledLibraryObjectRule()
+ #   else
  NormalLibraryObjectRule()
+ #   endif
  #  endif
  # endif
+ #endif
+ 
+ #if SharedLibXext
+ NormalSharedLibraryTarget(Xext,$(SOXEXTREV),$(OBJS) $(SHAREDDATAOBJS))
+ InstallSharedLibrary(Xext,$(SOXEXTREV),$(USRLIBDIR))
  #endif
  
  NormalLibraryTarget(Xext,$(OBJS))
*** mit/config/Imake.rules.orig	Tue Mar 31 23:05:55 1992
--- mit/config/Imake.rules	Wed Apr  1 13:37:11 1992
***************
*** 883,889 ****
  									@@\
  lib/**/libname.so.rev:  solist						@@\
  	$(RM) $@~							@@\
! 	(cd shared; $(LD) -o ../$@~ -assert pure-text solist)		@@\
  	$(RM) $@ 							@@\
  	$(MV) $@~ $@							@@\
  									@@\
--- 883,889 ----
  									@@\
  lib/**/libname.so.rev:  solist						@@\
  	$(RM) $@~							@@\
! 	(cd shared; $(LD) -o ../$@~ -assert pure-text solist $(REQUIREDLIBS)) @@\
  	$(RM) $@ 							@@\
  	$(MV) $@~ $@							@@\
  									@@\
***************
*** 902,910 ****
  AllTarget(lib/**/libname.sa.rev)					@@\
  									@@\
  lib/**/libname.sa.rev:  salist						@@\
  	$(RM) $@							@@\
! 	$(AR) $@ salist							@@\
! 	$(RANLIB) $@							@@\
  									@@\
  clean::									@@\
  	$(RM) lib/**/libname.sa.rev
--- 902,912 ----
  AllTarget(lib/**/libname.sa.rev)					@@\
  									@@\
  lib/**/libname.sa.rev:  salist						@@\
+ 	$(RM) $@~							@@\
+ 	(cd shared; $(AR) ../$@~ salist)				@@\
+ 	$(RANLIB) $@~							@@\
  	$(RM) $@							@@\
! 	$(MV) $@~ $@							@@\
  									@@\
  clean::									@@\
  	$(RM) lib/**/libname.sa.rev
*** mit/config/Project.tmpl.orig	Wed Apr  1 21:29:41 1992
--- mit/config/Project.tmpl	Wed Apr  1 22:13:15 1992
***************
*** 431,437 ****
  #endif
  #if SharedLibXext
    DEPEXTENSIONLIB = /* _Use($(USRLIBDIR),$(EXTENSIONSRC)/lib)/libXext.so.$(SOXEXTREV) */
!      EXTENSIONLIB = _Use(-lXext,-L$(EXTENSIONSRC) -lXext)
  #else
    DEPEXTENSIONLIB = _Use($(USRLIBDIR),$(EXTENSIONSRC)/lib)/libXext.a
       EXTENSIONLIB = LoaderLibPrefix _Use(-lXext, $(DEPEXTENSIONLIB))
--- 431,437 ----
  #endif
  #if SharedLibXext
    DEPEXTENSIONLIB = /* _Use($(USRLIBDIR),$(EXTENSIONSRC)/lib)/libXext.so.$(SOXEXTREV) */
!      EXTENSIONLIB = _Use(-lXext,-L$(EXTENSIONSRC)/lib -lXext)
  #else
    DEPEXTENSIONLIB = _Use($(USRLIBDIR),$(EXTENSIONSRC)/lib)/libXext.a
       EXTENSIONLIB = LoaderLibPrefix _Use(-lXext, $(DEPEXTENSIONLIB))
***************
*** 446,453 ****
--- 446,462 ----
        DEPXAUTHLIB = _Use($(USRLIBDIR),$(XAUTHSRC))/libXau.a
           XAUTHLIB = LoaderLibPrefix _Use(-lXau,$(DEPXAUTHLIB))
  #if SharedLibXmu
+ #if defined(SunArchitecture) && SunPost411FCSLd
          DEPXMULIB = /* _Use($(USRLIBDIR),$(XMUSRC))/libXmu.so.$(SOXMUREV) */
+        XMULIBONLY = _Use(-lXmu,-L$(XMUSRC) -lXmu)
+            XMULIB = _Use(-lXmu,-L$(XMUSRC) -lXmu -L$(TOOLKITSRC) -L$(EXTENSIONSRC)/lib -L$(XLIBSRC))
+ #if !defined(UseInstalled) && !defined(XawClientLibs)
+ #define XawClientLibs $(XAWLIB) $(XMULIBONLY) $(XTOOLLIB) $(XLIB)
+ #endif
+ #else	/* !SunPost411FCSLd */
+         DEPXMULIB = /* _Use($(USRLIBDIR),$(XMUSRC))/libXmu.so.$(SOXMUREV) */
             XMULIB = _Use(-lXmu,-L$(XMUSRC) -lXmu)
+ #endif	/* SunPost411FCSLd */
  #else
          DEPXMULIB = _Use($(USRLIBDIR),$(XMUSRC))/libXmu.a
             XMULIB = LoaderLibPrefix _Use(-lXmu,$(DEPXMULIB))
*** mit/config/sun.cf.orig	Tue Mar 31 23:05:56 1992
--- mit/config/sun.cf	Wed Apr  1 15:25:08 1992
***************
*** 77,79 ****
--- 77,82 ----
  #if OSMajorVersion >= 4 && OSMinorVersion >= 0
  #define SetTtyGroup YES
  #endif
+ 
+ #define ExtraLoadFlags -lm
+ #define SharedLibXext YES

--
Conrad Kimball		| Dist. Sys. Tech Support, Boeing Computer Services
cek@sdc.boeing.com	| P.O. Box 24346, MS 7A-35
(206) 865-6410		| Seattle, WA  98124-0346