Linux-Makefile shared [Tcl7.4/Tk4.0]b4 libs, used by tclsh+wish

Linux-Makefile shared [Tcl7.4/Tk4.0]b4 libs, used by tclsh+wish

Post by Yotam Medi » Fri, 30 Jun 1995 04:00:00



Here's the Makefile I came up after endless trials and errors.
Hope you'll find it useful. - yotam  (yotam_med...@tmai.com)

-------------------------------- Makefile --------------------------------
# $Id: Makefile,v 1.1 1995/06/29 06:46:35 yotam Exp yotam $
################################################################
# By Yotam Medini / yo...@netcom.com, yotam_med...@tmai.com    #
# May 95                                                       #
################################################################
#
#  I try to do the following:
#    * Install Tcl/Tk with shared library. Also install tclsh/wish
#      using these libtcl/libtk  libraries.
#    * Make all installation, without editing any file.
#    * Put all the installation setting in this single Makefile
#    * Try to use common rule-tricks for both tcl-tk.
#    * Avoid being root as possible.
#
#  Because I don't know how to install shared libraries in arbitrray
#  directory that can used by any tool, the step for installing
#  the shared libraries must be done by root.
#  Thus the installation consist of the following:
#
#    * Arrange the following three files:
#         This Makefile
#         tcl$(VERSION).tar.gz
#         tk$(VERSION).tar.gz
#    * Edit this Makefile, or append make call consistently.
#      Specific make-variables that one may likely want to change are:
#      prefix, SLDIR.
#    * Issue the following 6 make-calls. All from this Makefile's directory.
#      In parenthesis (user)/(root) refering who should issue the call.
#        (user)% make tcl-pre-root
#        (root)# make Tcl-install-shared-lib
#        (user)% make tcl-post-root
#        (user)% make tk-pre-root
#        (root)# make tk-install-shared-lib
#        (user)% make tk-post-root
#
#
#  I did not make any effort to ensure smart dependencies. This may be
#  non-trivial task, since the objects need to be compiled more than once
#  to produce the static library, the jump table and the shared library.
#  Also, this Makefile is supposed to serve installation rather than
#  development.
#  
################################################################

# Here is a quote from the tsx-11.mit.edu distribution.
# (InfoMagic - Disc 3 of the March 95).
#  darkstar:70>cd /cdrom/tsx-11/packages/GCC/src
#  darkstar:71>ls -ldg tools-2.17.tar.gz
#  -r--r--r--   1 root     bin        161297 Feb 25 23:34 tools-2.17.tar.gz
#  darkstar:72>gzip -cd tools-2.17.tar.gz | tar tvf - | grep table_description
#  -rw-r--r-- eric/other    10465 Feb  4 12:49 1995
#                                            tools-2.17/doc/table_description
#
# # This is the database of all registered Linux(TM) libraries. The format of
# # this file is as follows. - Mitch Sep `93
# #
# ...
# Library: libtcl.so
# Description: Tool control library
# Maintainer: Jay Carlson
# Email: n...@theory.cs.mankato.msus.edu
# Start: 0x60c00000
# End: 0x60cfffff
#
# Library: libtk.so
# Maintainer: Jay Carlson
# Email: n...@theory.cs.mankato.msus.edu
# Description: Tool control library
# Start: 0x60d00000
# End: 0x60dfffff
#

prefix = /home/local
# unfortunately, ld.so wants it in pre-configured places
SLDIR           = /usr/local/lib
INSTALL         = /usr/bin/install -c
INSTALL_PROGRAM = $(INSTALL) -s
INSTALL_DATA    = $(INSTALL) -m 644

########################################################################
########################################################################
########################          TCL           ########################

TCLVER = 7.4b4

TCLDIR = tcl$(TCLVER)
TCLTGZ = $(TCLDIR).tar.gz

tcl-extract:
        gzip -cd $(TCLTGZ) | tar xvf -

tcl-config:
        (cd $(TCLDIR); ./configure --prefix=$(prefix))

tcl-compile:
        (cd $(TCLDIR); make -w)

########################################################################
# The following inspired from:
# "A Method for Building Shared Libraries" / Eric Kasten
#  Linux Journal April 1995.
#
# Values are taken from Makefile of sunsite.unc.edu Linux archive
# in which README.linux is signed by  David Engel da...@ods.com
#
# LIBGCC                 = /usr/lib/gcc-lib/i486-linux/2.6.3/libgcc.a
LIBGCC                 := $(shell $(CC) -print-libgcc-file-name)
GCCJUMPAS              = gcc -B/usr/bin/jump
SL_PATH                = $(prefix)/lib
TCL_SL_VERSION         = 7.4.0
TCL_SL_LOAD_ADDRESS    = 0x60c00000
TCL_SL_JUMP_TABLE_SIZE = 0x4000
TCL_SL_GOT_SIZE        = 4096
TCL_SL_IMPORT          = /usr/lib/libc.sa
TCL_SL_EXTRA_LIBS      = $(LIBGCC) -lm -lc

TCL_SHPARMS = \
        -l $(SL_PATH)/libtcl \
        -v $(TCL_SL_VERSION) \
        -a $(TCL_SL_LOAD_ADDRESS) \
        -j $(TCL_SL_JUMP_TABLE_SIZE) \
        -g $(TCL_SL_GOT_SIZE)

TCL_VERIFYPARMS = -llibtcl.so.$(TCL_SL_VERSION) -- libtcl.sa

TCL_JUMPDIR = $(TCLDIR)/jump

$(TCL_JUMPDIR):
        mkdir -p $(TCL_JUMPDIR)

$(TCL_JUMPDIR)/jump.import: $(TCL_JUMPDIR)
        make \
                JUMPIMPORT=$(TCL_JUMPDIR)/jump.import \
                SL_IMPORT=$(TCL_SL_IMPORT) \
                shlib-import

tcl-shlib-import: $(TCL_JUMPDIR)/jump.import

# Generate dummy .c files
$(TCLDIR)/dummyMain.c:
         (echo '#include "tcl.h"'; \
          echo 'int main(int ac, char **av)'; \
          echo '{ Tcl_Main(ac, av, (Tcl_AppInitProc*)0); return 0;}') > $@
$(TCLDIR)/dummyInit.c:
         (echo '#include "tcl.h"'; \
          echo 'int Tcl_AppInit(Tcl_Interp *interp)'; \
          echo '{return TCL_ERROR;}') > $@

# tcl - shared object
# Note, the sub-make call use stdin as Makefile, (adding objs target)
# so it will only compile library objects.
TCLDUMSRC = $(TCLDIR)/dummyMain.c $(TCLDIR)/dummyInit.c
tcl-shobjs: $(TCL_JUMPDIR)/jump.import  $(TCLDUMSRC)
        (cd $(TCLDIR); \
         /bin/rm -f jump/jump.log *.o; \
         make dummyMain.o ; \
         JUMP_LIB=libtcl; export JUMP_LIB; \
         JUMP_DIR=`pwd`/jump; export JUMP_DIR; \
         (cat Makefile; echo objs: '$$(OBJS)') | \
          make -f - dummyInit.o objs CC="$(GCCJUMPAS)")

$(TCL_JUMPDIR)/jump.log: tcl-shobjs

tclvarsfuncs: $(TCL_JUMPDIR)/jump.log
        (cd $(TCL_JUMPDIR); \
         JUMP_DIR=`pwd`; export JUMP_DIR; \
        getvars; getfuncs; /bin/rm -f jump.log)

# Generate list of  tcl.h - declared  exported functions
# We add:
#    matherr(), since tclAppInit.c needs it.
#    panic(), TclOpen(), TclRead(), TclWaitpid(), TclWrite() since Tk uses it.
tclexpflist: $(TCLDIR)/tcl.h
        echo matherr > $@
        echo panic >> $@
        echo TclOpen >> $@
        echo TclRead >> $@
        echo TclWaitpid >> $@
        echo TclWrite >> $@
        (cd $(TCLDIR); \
        grep EXTERN tcl.h | grep Tcl_ | grep _ANSI_ARGS_ | \
        sed 's/.*Tcl_\(.*\) _ANSI.*/Tcl_\1/') >> $@

# split $(TCLDIR)/jump/jumps.func  into  jump.func.new + jump.fignore
tclfignore: tclexpflist
        cp $(TCLDIR)/jump/jump.funcs jump.fignore
        /bin/rm -f jump.funcs.new
        for ef in `cat tclexpflist`; \
        do \
           grep "T _$$ef " jump.fignore >> jump.funcs.new; \
           grep -v "T _$$ef " jump.fignore > jump.fignore.new; \
           mv jump.fignore.new jump.fignore; \
        done

# split $(TCLDIR)/jump/jumps.vars  into  jump.vars.new + jump.vignore
# The list is limited, so we hard code it
# rather then making an analog tclexpvlist
tclvignore:
        cp $(TCLDIR)/jump/jump.vars jump.vignore
        /bin/rm -f jump.vars.new
        for ev in tcl_AsyncReady tcl_FileCloseProc tcl_RcFileName; \
        do \
           grep "D _$$ev " jump.vignore >> jump.vars.new; \
           grep -v "D _$$ev " jump.vignore > jump.vignore.new; \
           mv jump.vignore.new jump.vignore; \
        done

tcl-ignore: tclvarsfuncs tclfignore tclvignore
        cat jump.fignore jump.vignore > $(TCLDIR)/jump/jump.ignore
        cp  jump.funcs.new $(TCLDIR)/jump/jump.funcs
        cp  jump.vars.new $(TCLDIR)/jump/jump.vars
        /bin/rm -f jump.fignore jump.vignore jump.funcs.new jump.vars.new

# After the jump.vars, jump.funcs, jump.ignore were made
# getsize requires re-compilation of the shared objects!!
# So call 'make tcl-shobjs' again.
tcl-varsize:
        $(MAKE) TDIR=$(TCLDIR) varsize

tclolist:
        (cd $(TCLDIR); \
         (cat Makefile; echo -ne "echoobjs:\n\t@echo"; echo ' $$(OBJS)') | \
          make -f - --no-print-directory echoobjs) > $@

tcl-shlib: tclolist
        (cd $(TCLDIR); \
         JUMP_LIB=libtcl; export JUMP_LIB; \
         JUMP_DIR=`pwd`/jump; export JUMP_DIR; \
         mkimage $(TCL_SHPARMS) -- \
                dummyInit.o `cat ../tclolist` $(TCL_SL_EXTRA_LIBS); \
         mkstubs $(TCL_SHPARMS) -- libtcl; \
         ar rs libtcl.sa dummyMain.o; \
         verify-shlib $(TCL_VERIFYPARMS))

# instead of a script
tcl-pre-root:
        /bin/rm -rf $(TCLDIR) jump.* tclexpflist tclolist
        $(MAKE) tcl-extract tcl-config tcl-compile
        (cd $(TCLDIR); mv libtcl.a libtcl.a.SAVE)
        $(MAKE) tcl-ignore
        $(MAKE) tcl-shobjs
        $(MAKE) tcl-varsize
        $(MAKE) tcl-shlib

# By root only
tcl-install-shared-lib:
        make -w PKGDIR=$(TCLDIR) LIB=libtcl JUMPVER=$(TCL_SL_VERSION) \
                install-shared-lib

#         echo -ne "\t\$${CC} \$${LDFLAGS_SWITCHES} \$${CC_SWITCHES} ";
tclsh:
        (cd $(TCLDIR); \
         /bin/rm -f tclsh tclAppInit.o; \
         (cat Makefile; echo tclsh.so: tclAppInit.o; \
          echo -ne "\tgcc \$${LDFLAGS_SWITCHES} "; \
          echo "tclAppInit.o -L/usr/local/lib -ltcl \$${MATH_LIBS} -o tclsh") \
         |  make -w -f - tclsh.so)

# Install the static libtcl.a and the dynimically linked tclsh.
# Do touches so nothing will re-compile.
tcl-install: tclsh
        (cd $(TCLDIR); \
        mv libtcl.a.SAVE libtcl.a; \
        touch libtcl.a; touch tclsh; \
        make -w install)

tcl-install-link:
        $(MAKE) TDIR=$(TCLDIR) LIB=libtcl TOOL=tclsh install-link

tcl-post-root: tcl-install tcl-install-link

########################     end of TCL         ########################
########################################################################
########################################################################

########################################################################
########################################################################
########################           TK           ########################

TKVER = 4.0b4

TKDIR = tk$(TKVER)
TKTGZ = $(TKDIR).tar.gz

tk-extract:
        mkdir -p $(TKDIR)
        chmod -R +w $(TKDIR)
        /bin/rm -rf $(TKDIR)
        gzip -cd $(TKTGZ) | tar xvf -

tk-config:
        (cd $(TKDIR); ./configure --prefix=$(prefix))

tk-compile:
        (cd $(TKDIR); make -w)

TK_SL_VERSION         = 4.0.0
TK_SL_LOAD_ADDRESS    = 0x60d00000
TK_SL_JUMP_TABLE_SIZE = 0x4000
TK_SL_GOT_SIZE        = 4096
TK_SL_IMPORT          = /usr/lib/libc.sa
TK_SL_EXTRA_LIBS      = -ltcl -lX11 $(LIBGCC) -lm -lc

TK_SHPARMS = \
        -l $(SL_PATH)/libtk \
        -v $(TK_SL_VERSION) \
        -a $(TK_SL_LOAD_ADDRESS) \
        -j $(TK_SL_JUMP_TABLE_SIZE) \
        -g $(TK_SL_GOT_SIZE)

TK_VERIFYPARMS = -llibtk.so.$(TK_SL_VERSION) -- libtk.sa

TK_JUMPDIR = $(TKDIR)/jump

$(TK_JUMPDIR):
        mkdir -p $(TK_JUMPDIR)

$(TK_JUMPDIR)/jump.import: $(TK_JUMPDIR)
        make \
                JUMPIMPORT=$(TK_JUMPDIR)/jump.import \
                SL_IMPORT=$(TK_SL_IMPORT) \
                shlib-import

tk-shlib-import: $(TK_JUMPDIR)/jump.import

# Generate dummy .c files
$(TKDIR)/dummyMain.c:
         (echo '#include "tk.h"'; \
          echo 'int main(int ac, char **av)'; \
          echo '{ Tk_Main(ac, av, (Tcl_AppInitProc*)0); return 0;}') > $@

# $(TKDIR)/dummyInit.c:
#        (echo '#include "tk.h"'; \
#         echo 'int Tk_Init(Tcl_Interp *interp)'; \
#         echo '{return TCL_ERROR;}') > $@

# tk - shared object
# Note, the sub-make call use stdin as Makefile, (adding objs target)
# so it will only compile library objects.
TKDUMSRC = $(TKDIR)/dummyMain.c
tk-shobjs: $(TK_JUMPDIR)/jump.import  $(TKDUMSRC)
        (cd $(TKDIR); \
         /bin/rm -f jump/jump.log *.o; \
         make dummyMain.o ; \
         JUMP_LIB=libtk; export JUMP_LIB; \
         JUMP_DIR=`pwd`/jump; export JUMP_DIR; \
         (cat Makefile; echo objs: '$$(OBJS)') | \
          make -f - objs CC="$(GCCJUMPAS)")

$(TK_JUMPDIR)/jump.log: tk-shobjs

tkvarsfuncs: $(TK_JUMPDIR)/jump.log
        (cd $(TK_JUMPDIR); \
         JUMP_DIR=`pwd`; export JUMP_DIR; \
        getvars; getfuncs; ls -l jump; /bin/rm -f jump.log)

# Generate list of  tk.h - declared  exported functions
tkexpflist: $(TKDIR)/tk.h
        echo matherr > $@
        (cd $(TKDIR); \
        grep EXTERN tk.h | grep Tk_ | grep _ANSI_ARGS_ | \
        sed 's/.*Tk_\(.*\) _ANSI.*/Tk_\1/') >> $@

# split $(TKDIR)/jump/jumps.func  into  jump.func.new + jump.fignore
tkfignore: tkexpflist
        cp $(TKDIR)/jump/jump.funcs jump.fignore
        /bin/rm -f jump.funcs.new
        for ef in `cat tkexpflist`; \
        do \
           grep "T _$$ef " jump.fignore >> jump.funcs.new; \
           grep -v "T _$$ef " jump.fignore > jump.fignore.new; \
           mv jump.fignore.new jump.fignore; \
        done

# split $(TKDIR)/jump/jumps.vars  into  jump.vars.new + jump.vignore
tkvignore:
        $(MAKE) \
                JUMPDIR=$(TKDIR)/jump \
                VLIST='tk_CanvasTagsOption tk_NumMainWindows' \
                vignore

tk-ignore: tkvarsfuncs tkfignore tkvignore
        cat jump.fignore jump.vignore > $(TKDIR)/jump/jump.ignore
        cp  jump.funcs.new $(TKDIR)/jump/jump.funcs
        cp  jump.vars.new $(TKDIR)/jump/jump.vars
        /bin/rm -f jump.fignore jump.vignore jump.funcs.new jump.vars.new

# After the jump.vars, jump.funcs, jump.ignore were made
# getsize requires re-compilation of the shared objects!!
# So call 'make tk-shobjs' again.
tk-varsize:
        $(MAKE) TDIR=$(TKDIR) varsize

tkolist:
        (cd $(TKDIR); \
         (cat Makefile; echo -ne "echoobjs:\n\t@echo"; echo ' $$(OBJS)') | \
          make -f - --no-print-directory echoobjs) > $@

tk-shlib: tkolist
        (cd $(TKDIR); \
         JUMP_LIB=libtk; export JUMP_LIB; \
         JUMP_DIR=`pwd`/jump; export JUMP_DIR; \
         mkimage $(TK_SHPARMS) -- \
                 `cat ../tkolist` $(TK_SL_EXTRA_LIBS); \
         mkstubs $(TK_SHPARMS) -- libtk; \
         ar rs libtk.sa dummyMain.o; \
         verify-shlib $(TK_VERIFYPARMS))

# instead of a script
tk-pre-root:
        /bin/rm -rf $(TKDIR) jump.* tkexpflist tkolist
        $(MAKE) tk-extract tk-config tk-compile
        (cd $(TKDIR); mv libtk.a libtk.a.SAVE)
        $(MAKE) tk-ignore
        $(MAKE) tk-shobjs
        $(MAKE) tk-varsize
        $(MAKE) tk-shlib

# By root only
tk-install-shared-lib:
        make -w PKGDIR=$(TKDIR) LIB=libtk JUMPVER=$(TK_SL_VERSION) \
                install-shared-lib

wish:
        (cd $(TKDIR); \
         /bin/rm -f wish tkAppInit.o; \
         (cat Makefile; echo wish.so: tkAppInit.o; \
          echo -ne "\tgcc \$${LDFLAGS_SWITCHES} tkAppInit.o "; \
          echo -ne "-L/usr/local/lib -ltk -ltcl \$${X11_LIB_SWITCHES} "; \
          echo "-lm -o wish") \
         |  make -w -f - wish.so)

tk-install: wish
        (cd $(TKDIR); \
        mv libtk.a.SAVE libtk.a; \
        make -w libtk.a; \
        mv tkAppInit.o.SAVE tkAppInit.o; \
        touch libtk.a; touch wish; \
        make -w install)

tk-install-link:
        $(MAKE) TDIR=$(TKDIR) LIB=libtk TOOL=wish install-link

tk-post-root: tk-install tk-install-link

########################     end of TK          ########################
########################################################################
########################################################################

########################################################################
#  Tcl/Tk - common rules, targets, etc.

# split $(JUMPDIR)/jumps.vars  into  jump.vars.new + jump.vignore
# The list is limited, so we don't use fancy grep as for [foo]expflist
# rather then making an analog tkexpvlist
vignore:
        cp $(JUMPDIR)/jump.vars jump.vignore; \
        /bin/rm -f jump.vars.new; \
        for ev in $(VLIST); \
        do \
           egrep "[CD] _$$ev " jump.vignore >> jump.vars.new; \
           egrep -v "[CD] _$$ev " jump.vignore > jump.vignore.new; \
           mv jump.vignore.new jump.vignore; \
        done

shlib-import:
        echo -n > $(JUMPIMPORT)
        for lib in $(SL_IMPORT); \
          do nm --no-cplus -o $$lib | grep '__GOT__' | sed 's/__GOT__/_/'  \
                >> $(JUMPIMPORT); \
          done

varsize:
        (cd $(TDIR)/jump; \
         JUMP_DIR=`pwd`; export JUMP_DIR; \
        getsize > jump.vars-new; \
        mv jump.vars jump.vars-old; \
        mv jump.vars-new jump.vars)

# By root only!
#        $(INSTALL_PROGRAM) $(LIB).so.$(JUMPVER) $(SLDIR) )
install-shared-lib:
        (cd $(SLDIR); rm -f $(LIB).so.* $(LIB).sa)
        (cd $(PKGDIR); \
         $(INSTALL_DATA) $(LIB).sa $(SLDIR); \
         $(INSTALL) $(LIB).so.$(JUMPVER) $(SLDIR) )
        /sbin/ldconfig -vn $(SLDIR)

install-link:
        (VERSION=`grep VERSION $(TDIR)/Makefile \
                | head -1 | cut -d= -f2 | tr -d " "`;\
                (cd $(prefix)/lib; \
                /bin/rm -f $(LIB).a; \
                ln -s $(LIB)$$VERSION.a $(LIB).a); \
                (cd $(prefix)/bin; \
                /bin/rm -f  $(TOOL); \
                ln -s $(TOOL)$$VERSION $(TOOL)))

# convinient date; target; date
dtd:
        date
        $(MAKE) $(TARGET)
        date

 
 
 

1. Building Tcl7.4/Tk4.0 as shared libraries in Linux?

Can someone tell me how to build Tcl7.4 and Tk4.0 as shared libraries
under Linux (Kernel 1.1.59, Gcc 2.5.8), or where I can get such things
ready made?

Is this sort of thing easier in *BSD?

Thanks,
        Chris Fox

(Email preferred)

--
_________________________________________________________

 Department of Computer Science
 University of Essex            
 Wivenhoe Park
 Colchester CO4 3SQ             Tel:  +44 (0) 1206 872669
 United Kingdom                 Fax:  +44 (0) 1206 872788

2. How about a Linux kernel that uses the BIOS for harddrive I/O

3. Need help with Tcl7.6/Tk4.2, gcc, FORTRAN/C/C++ shared libraries (LONG)

4. RHIDE in X core dumped

5. Tcl7.4/Tk4.0 extension a.out shared libraries

6. ftp connections stuck in CLOSE_WAIT

7. How to: tcl7.5a1 and tk4.1a1 for Linux ELF

8. mod_rewrite and mass vhosts

9. Compiling tcl7.4 and tk4.0 under LInux for ELF

10. tcl7.5, tk4.1, scotty-2.1.5, linux 2.0.22

11. When to get tcl7.6 and tk4.2 ?

12. problems compiling uudeview code with tcl7.5/tk4.1

13. tkgnuplot for tcl7.4/tk4.0/Tix4.0?