>>> tcl/beta:2 (Message tcl/beta:2) Subject: tcl7.5b1 shared libs patch, message #1 From: John Robert LoVerso Date: Wed, 07 Feb 96 10:14:54 -0500 To: John Ousterhout From loverso@osf.org Wed Feb 7 10: 14:56 1996 X-Face: "UZ!}1W2N?eJdN(`1%|/OOPqJ).Idk?UyvWw'W-%`Gto8^IkEm>.g1O$[.;~}8E=Ire0|lO .o>:NlJS1@vO9bVmswRoq3j DdX9YGSeJ5a(mfX[1u>Z63G5_^+'8LVqjqvn X-Url: http://www.osf.org/~loverso/ You unconditionally add $(MATH_LIBS) to the link line for building the shared version of libtcl. I have not found this necessary on any platform I build on: HP-UX 9 Solaris 2.4 / SunOS 5.4 FreeBSD 2.1 (and, occasionally still, OSF/1) In particular, this caused me problems on my old desktop machine, where there was only a static version of -lm around. This caused the inclusion of absolute code into the shared lib. Anyway, my first suggestion is to remove $(MATH_LIBS) from use in the general case for building the shared libtcl. 295c297 < $(SH_LIBS) $(MATH_LIBS) --- > $(SH_LIBS) Then, for architectues that actually need this, add it to the definition of SH_LIBS. Note that none of those architectures above (sans OSF/1, which is the subject of a different message) require anything for SH_LIBS. That is, under SunOS5.4 the default configure had the shlib being built with: -lsocket -lnsl -lm none of which is necessary. Hence, I propose you also make this change: 73c73 < SH_LIBS = $(LIBS) --- > SH_LIBS = Or, perhaps, replace it with @SH_LIBS@ and give configure the ability to change it for those platforms that need it. John Received: from coltsfoot.osf.org (coltsfoot.osf.org [130.105.3.72]) by postman.osf.org (8.6.9/8.6.x) with SMTP id KAA22538; Wed, 7 Feb 1996 10:14:55 -0500 (Message tcl/beta:2) >>> tcl/beta:3 (Message tcl/beta:3) Subject: tcl7.5b1 shared libs patch, message #2 From: John Robert LoVerso Date: Wed, 07 Feb 96 11:01:19 -0500 To: John Ousterhout From loverso@osf.org Wed Feb 7 11: 01:21 1996 X-Face: "UZ!}1W2N?eJdN(`1%|/OOPqJ).Idk?UyvWw'W-%`Gto8^IkEm>.g1O$[.;~}8E=Ire0|lO .o>:NlJS1@vO9bVmswRoq3j DdX9YGSeJ5a(mfX[1u>Z63G5_^+'8LVqjqvn X-Url: http://www.osf.org/~loverso/ I once swore an oath not to do more work for/with OSF/1, but none-the-less, here are some fixes for 7.5b1 to enable shared libs on OSF/1. These minor patch fixes configure to correctly recognize OSF's OSF/1 releases, in addition to Digital's Alpha OSF/1. There are three components. 1. There are now three cases in the os-version switch for shared libs: OSF/1 1.0 (old loader) OSF/1 1.3 (ELF loader) Digital OSF/1 This change is in the simple patch configure.diffs. 2. The Makefile change I sent in the message prior to this one. This change is part of the patch Makefile.in.diffs. 3. The addition of a new file, "unix/tclLoadOSF.c". This is to support the old OSF loader, which is still used on systems derived from OSF/1 1.0, such as Paragon OSF/1 and others. This change is part of the patch Makefile.in.diffs. John #!/bin/sh # # existing files will NOT be overwritten unless -c is specified # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 1600 -rw-r--r-- Makefile.in.diffs # 1043 -rw-r--r-- configure.diffs # 3968 -rw-r--r-- tclLoadOSF.c # # ============= Makefile.in.diffs ============== if test -f 'Makefile.in.diffs' -a X"$1" != X"-c"; then echo 'x - skipping Makefile.in.diffs (File already exists)' else echo 'x - extracting Makefile.in.diffs (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile.in.diffs' && *** 1.1 1996/02/07 13:55:33 X--- Makefile.in 1996/02/07 15:13:50 *************** *** 70,76 **** X # determined by the configure script. X LIBS = @LIBS@ X ! SH_LIBS = $(LIBS) X X # To change the compiler switches, for example to change from -O X # to -g, change the following line: X--- 70,77 ---- X # determined by the configure script. X LIBS = @LIBS@ X ! # may need $(MATH_LIBS) $(LIBS) ! SH_LIBS = X X # To change the compiler switches, for example to change from -O X # to -g, change the following line: *************** *** 278,283 **** X--- 279,285 ---- X $(UNIX_DIR)/tclLoadDl.c \ X $(UNIX_DIR)/tclLoadDl2.c \ X $(UNIX_DIR)/tclLoadDld.c \ + $(UNIX_DIR)/tclLoadOSF.c \ X $(GENERIC_DIR)/tclLoadNone.c \ X $(UNIX_DIR)/tclLoadShl.c X *************** *** 292,298 **** X libtcl$(VERSION)$(SHLIB_SUFFIX): ${OBJS} X rm -f libtcl$(VERSION)$(SHLIB_SUFFIX) X $(SHLIB_LD) -o libtcl$(VERSION)$(SHLIB_SUFFIX) ${OBJS} \ ! $(SH_LIBS) $(MATH_LIBS) X X libtcl$(VERSION).a: ${OBJS} X rm -f libtcl$(VERSION).a X--- 294,300 ---- X libtcl$(VERSION)$(SHLIB_SUFFIX): ${OBJS} X rm -f libtcl$(VERSION)$(SHLIB_SUFFIX) X $(SHLIB_LD) -o libtcl$(VERSION)$(SHLIB_SUFFIX) ${OBJS} \ ! $(SH_LIBS) X X libtcl$(VERSION).a: ${OBJS} X rm -f libtcl$(VERSION).a *************** *** 536,541 **** X--- 538,546 ---- X X tclLoadDld.o: $(UNIX_DIR)/tclLoadDld.c X $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDld.c + + tclLoadOSF.o: $(UNIX_DIR)/tclLoadOSF.c + $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadOSF.c X X tclLoadNone.o: $(GENERIC_DIR)/tclLoadNone.c X $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLoadNone.c SHAR_EOF chmod 0644 Makefile.in.diffs || echo 'restore of Makefile.in.diffs failed' Wc_c="`wc -c < 'Makefile.in.diffs'`" test 1600 -eq "$Wc_c" || echo 'Makefile.in.diffs: original size 1600, current size' "$Wc_c" fi # ============= configure.diffs ============== if test -f 'configure.diffs' -a X"$1" != X"-c"; then echo 'x - skipping configure.diffs (File already exists)' else echo 'x - extracting configure.diffs (Text)' sed 's/^X//' << 'SHAR_EOF' > 'configure.diffs' && *** 1.1 1996/02/07 13:55:33 X--- configure 1996/02/07 15:55:32 *************** *** 3109,3117 **** X LD_FLAGS="" X LD_SEARCH_FLAGS="" X ;; ! OSF-1.*) X SHLIB_CFLAGS="-fpic" ! SHLIB_LD='ld -shared -expect_unresolved "*"' X SHLIB_SUFFIX=".so" X DL_OBJS="tclLoadDl.o" X DL_LIBS="" X--- 3109,3129 ---- X LD_FLAGS="" X LD_SEARCH_FLAGS="" X ;; ! OSF1-1.[012]) ! # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 ! SHLIB_CFLAGS="" ! # Hack: make package name same as library name ! SHLIB_LD='ld -R -export $@:' ! SHLIB_SUFFIX=".so" ! DL_OBJS="tclLoadOSF.o" ! DL_LIBS="" ! LD_FLAGS="" ! LD_SEARCH_FLAGS="" ! ;; ! OSF1-1.*) ! # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 X SHLIB_CFLAGS="-fpic" ! SHLIB_LD="ld -shared" X SHLIB_SUFFIX=".so" X DL_OBJS="tclLoadDl.o" X DL_LIBS="" *************** *** 3119,3124 **** X--- 3131,3137 ---- X LD_SEARCH_FLAGS="" X ;; X OSF1-V*) + # Digital OSF/1 X SHLIB_CFLAGS="" X SHLIB_LD='ld -shared -expect_unresolved "*"' X SHLIB_SUFFIX=".so" SHAR_EOF chmod 0644 configure.diffs || echo 'restore of configure.diffs failed' Wc_c="`wc -c < 'configure.diffs'`" test 1043 -eq "$Wc_c" || echo 'configure.diffs: original size 1043, current size' "$Wc_c" fi # ============= tclLoadOSF.c ============== if test -f 'tclLoadOSF.c' -a X"$1" != X"-c"; then echo 'x - skipping tclLoadOSF.c (File already exists)' else echo 'x - extracting tclLoadOSF.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'tclLoadOSF.c' && /* X * tclLoadOSF.c -- X * X * This procedure provides a version of the TclLoadFile that works X * under OSF/1 1.0/1.1/1.2 and related systems, utilizing the old OSF/1 X * /sbin/loader and /usr/include/loader.h. OSF/1 versions from 1.3 and X * on use ELF, rtld, and dlopen()[/usr/include/ldfcn.h]. X * X * This is useful for: X * OSF/1 1.0, 1.1, 1.2 (from OSF) X * includes: MK4 and AD1 (from OSF RI) X * OSF/1 1.3 (from OSF) using ROSE X * HP OSF/1 1.0 ("Acorn") using COFF X * X * This is likely to be useful for: X * Paragon OSF/1 (from Intel) X * HI-OSF/1 (from Hitachi) X * X * This is NOT to be used on: X * Digitial Alpha OSF/1 systems X * OSF/1 1.3 or later (from OSF) using ELF X * includes: MK6, MK7, AD2, AD3 (from OSF RI) X * X * This approach to things was utter @&^#; thankfully, X * OSF/1 eventually supported dlopen(). X * X * John Robert LoVerso X * X * Copyright (c) 1995 Sun Microsystems, Inc. X * X * See the file "license.terms" for information on usage and redistribution X * of this file, and for a DISCLAIMER OF ALL WARRANTIES. X */ X static char sccsid[] = "@(#) tclLoadAix.c 1.3 95/12/21 11:54:26"; X #include "tclInt.h" #include #include X /* X *---------------------------------------------------------------------- X * X * TclLoadFile -- X * X * Dynamically loads a binary code file into memory and returns X * the addresses of two procedures within that file, if they X * are defined. X * X * Results: X * A standard Tcl completion code. If an error occurs, an error X * message is left in interp->result. *proc1Ptr and *proc2Ptr X * are filled in with the addresses of the symbols given by X * *sym1 and *sym2, or NULL if those symbols can't be found. X * X * Side effects: X * New code suddenly appears in memory. X * X *---------------------------------------------------------------------- X */ X int TclLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr) X Tcl_Interp *interp; /* Used for error reporting. */ X char *fileName; /* Name of the file containing the desired X * code. */ X char *sym1, *sym2; /* Names of two procedures to look up in X * the file's symbol table. */ X Tcl_PackageInitProc **proc1Ptr, **proc2Ptr; X /* Where to return the addresses corresponding X * to sym1 and sym2. */ { X ldr_module_t lm; X char *pkg; X X lm = (Tcl_PackageInitProc *) load(fileName, LDR_NOFLAGS); X if (lm == LDR_NULL_MODULE) { X Tcl_AppendResult(interp, "couldn't load file \"", fileName, X "\": ", Tcl_PosixError (interp), (char *) NULL); X return TCL_ERROR; X } X X /* X * My convention is to use a [OSF loader] package name the same as shlib, X * since the idiots never implemented ldr_lookup() and it is otherwise X * impossible to get a package name given a module. X * X * I build loadable modules with a makefile rule like X * ld ... -export $@: -o $@ $(OBJS) X */ X if ((pkg = strrchr(fileName, '/')) == NULL) X pkg = fileName; X else X pkg++; X *proc1Ptr = ldr_lookup_package(pkg, sym1); X *proc2Ptr = ldr_lookup_package(pkg, sym2); X return TCL_OK; } X /* X *---------------------------------------------------------------------- X * X * TclGuessPackageName -- X * X * If the "load" command is invoked without providing a package X * name, this procedure is invoked to try to figure it out. X * X * Results: X * Always returns 0 to indicate that we couldn't figure out a X * package name; generic code will then try to guess the package X * from the file name. A return value of 1 would have meant that X * we figured out the package name and put it in bufPtr. X * X * Side effects: X * None. X * X *---------------------------------------------------------------------- X */ X int TclGuessPackageName(fileName, bufPtr) X char *fileName; /* Name of file containing package (already X * translated to local form if needed). */ X Tcl_DString *bufPtr; /* Initialized empty dstring. Append X * package name to this if possible. */ { X return 0; } SHAR_EOF chmod 0644 tclLoadOSF.c || echo 'restore of tclLoadOSF.c failed' Wc_c="`wc -c < 'tclLoadOSF.c'`" test 3968 -eq "$Wc_c" || echo 'tclLoadOSF.c: original size 3968, current size' "$Wc_c" fi exit 0 Received: from coltsfoot.osf.org (coltsfoot.osf.org [130.105.3.72]) by postman.osf.org (8.6.9/8.6.x) with SMTP id LAA25585; Wed, 7 Feb 1996 11:01:20 -0500 (Message tcl/beta:3) >>> tcl/beta:10 (Message tcl/beta:10) Subject: tcl7.5b1 shared libs patch, message #3 From: John Robert LoVerso Date: Wed, 07 Feb 96 16:46:57 -0500 To: John Ousterhout Cc: jkh@freefall.freebsd.org From loverso@osf.org Wed Feb 7 16: 46:58 1996 X-Face: "UZ!}1W2N?eJdN(`1%|/OOPqJ).Idk?UyvWw'W-%`Gto8^IkEm>.g1O$[.;~}8E=Ire0|lO .o>:NlJS1@vO9bVmswRoq3j DdX9YGSeJ5a(mfX[1u>Z63G5_^+'8LVqjqvn X-Url: http://www.osf.org/~loverso/ This is the third set of fixes for shared libraries with 7.5b1/4.1b1. This affects SunOS 5.4, HP-UX 9, FreeBSD 2.1, and probably others. Basically, you are using explicitly named library files when linking tclsh and wish. I.e., this: gcc tclAppInit.o libtcl7.5.so -lm -o tclsh Many shared lib implementations record the name of the library, and remember if it was specified from the library search path via "-l" or given directly. When given directly, as above, the run time loader attempts to find the *file*, but it doesn't look in the library path! Hence, these loads need to be turned into gcc tclAppInit.o -L. -ltcl7.5 -lm -o tclsh Ditto for wish, gcc tkAppInit.o libtk4.1.so ../../tcl7.5b1/unix/libtcl7.5.so \ -L/usr/X11R6/lib -lX11 -lm -o wish should become gcc tkAppInit.o -L. -ltk4.1 -L../../tcl7.5b1/unix -ltcl7.5 \ -L/usr/X11R6/lib -lX11 -lm -o wish Ditto for the build of the libtk4.1.so itself. I ended up doing something like this: TCL_LIB = libtcl${_VERSION}${SHLIB_SUFFIX}.1.0 TCL_LIB_LD = -L. -ltcl${_VERSION} ... ${TCL_LIB}: ${OBJS} rm -f ${TCL_LIB} $(SHLIB_LD) -o ${TCL_LIB} ${OBJS} $(SH_LIBS) and for Tk: TK_LIB = libtk${_VERSION}${SHLIB_SUFFIX}.1.0 TK_LIB_LD = -L. -ltk${_VERSION} ... LIBS = -L$(TCL_BIN_DIR) -ltcl75 $(X11_LIB_SWITCHES) $(DL_LIBS) -lm ... ${TK_LIB}: $(OBJS) rm -f ${TK_LIB} $(SHLIB_LD) -o ${TK_LIB} $(OBJS) $(LIBS) This brings up the last of the sets of shared library build problems: SunOS 5.4: Tcl's Makefile included this, but Tk's did not: LD_FLAGS = -R ${LIB_INSTALL_DIR} FreeBSD (and maybe NetBSD, Linux): Shared libraries are named as: lib.so.. given that m,n are the major/minor revsion of the library. Naming the library (as it does by default) libtcl7.5.so causes the loader to not be able to find the installed lib, since it (mistakenly) believes it has major revision of 5! The solution is to build it as: libtcl75.so.1.0 This is what I did (above) as it is how the Tcl7.4 "package" installs, and it makes the most sense. Other/Older ways of doing this were: libtcl.so.7.5 which is how the Tcl7.3 "package" installs libtcl.so.75.0 which is how the TclX7.4 "package" installs Hence, ${_VERSION} was 75, verses ${VERSION} of 7.5. Without this fix, the compile succeeds on FreeBSD, but the resulting binary won't run. John Received: from coltsfoot.osf.org (coltsfoot.osf.org [130.105.3.72]) by postman.osf.org (8.6.9/8.6.x) with SMTP id QAA19943; Wed, 7 Feb 1996 16:46:57 -0500 (Message tcl/beta:10)