home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / devel / tcl / tclx7_31.z / tclx7_31 / tcldev / tclX7.3a-p1 / README.SHLIBS < prev    next >
Encoding:
Text File  |  1994-01-05  |  8.2 KB  |  240 lines

  1.                Building Shared Libraries for Tcl, Tk and TclX.
  2.                              Dr. Joseph E. Sacco
  3.                                 jsacco@ssl.com
  4.  
  5.  
  6. The following is a discussion of the construction and use of shared libraries
  7. for building TCL applications. The principal source of information for this 
  8. discussion is the set of SUN Reference Manuals.
  9.  
  10. Shared Libraries
  11. -----------------
  12.  
  13. Some operating systems allow a single physical copy of a program's text (code) 
  14. to be shared in memory by all the processes executing it. Such sharing results 
  15. in a more efficient use of memory since the code is not duplicated for each 
  16. process executing it. This is particularly true for applications that use
  17. libraries. If the contents of a library can be shared among several processes
  18. the savings can be significant.
  19.  
  20. Libraries of shared objects offer the additional benefit of a space/time trade
  21. off though run-time binding. An executable that uses shared objects does not
  22. have copies of these shared objects bound into it when linked but rather 
  23. maintains references to these objects which are satisfied at run-time. This 
  24. can result in a significant reduction in storage space for an program at a 
  25. cost of a small delay in startup time. For example, on a SPARC10 under OS4.1.3 
  26. using gcc-2.5.3, the storage requirements for "wishx", which uses functions 
  27. from several libraries, ranges from 57.3KB to 991.2KB depending upon the 
  28. degree to which shared libraries are used in its construction. For "wishx"
  29. on a SPARC10 there is no user preceptible difference in the startup time
  30. between any of these versions.
  31.  
  32. The paradigm for constructing libraries of shared objects varies from one
  33. operating system to another. Central to all of these is the notion of 
  34. position independent code [pic] which is code that requires link editing only 
  35. to relocate objects that are external to the given module. [Each reference to
  36. a global datum is generated as a dereference of a pointer in a global offset
  37. table. Each function call is generated in pc-relative addressing mode through
  38. a procedure linkage table.] Such code is readily shared. The basic approach to 
  39. creating a shared library is to use the compiler [and assembler] to generate 
  40. position independent code objects and then use the link editor to "join" these 
  41. objects together. 
  42.  
  43. It must be noted that not all source code can be converted into a position 
  44. independent object. Modules that "export" "initialized" data items cannot be 
  45. expressed as position independent code. A data item is "exported" from a 
  46. module if a program that uses that module refers to that data item by name.
  47. User transparent mechanisms are provided to handle the non-position-independent
  48. code that is used by shared libraries. One such scheme that is used by SUN is 
  49. to [manually] collect the non-position-independent code into an [static] 
  50. archive format library from which objects are extracted and copied into the 
  51. executable by the link editor during the link stage.
  52.  
  53. Building Shared Libraries
  54. -------------------------
  55.  
  56. What follows are instructions for *manually* constructing shared libraries for 
  57. Tcl, Tk and TclX on a SUN system with *minimal* changes to the existing
  58. code. Other systems may follow different procedures so consult your local 
  59. system manuals for specifics.
  60.  
  61. The basic approach that will be used in each case is to set a compiler flag 
  62. to create position independent code and run the makefile. The contents of a 
  63. resulting archive library will then be extracted and relinked into a shared 
  64. library. This approach is not very elegant but it works. It is not difficult
  65. to modify the makefiles to automatically construct shared libraries for a
  66. SUN system. Xiaokun Zhu [xiaokun@stats.gla.ac.uk] has done an excellent job
  67. of this for Tcl and Tk. However, such modifications are SUN-specific and are 
  68. of limited value for non-SUN platforms.
  69.  
  70.  
  71. TCL
  72. ---
  73. Do the following:
  74.  
  75.     (1) run configure
  76.  
  77.     (2) edit the makefile. add the appropriate position-independent-code 
  78.         flag for your compiler to CFLAGS:
  79.  
  80.     CFLAGS = -O -PIC         <--- SUN cc
  81.     CFLAGS = -O -fPIC        <--- GNU gcc
  82.  
  83.         Note that "PIC" rather than "pic" is used. Libtcl does not need
  84.         the larger global offset table created when using PIC but libtk does.
  85.  
  86.     (3) Patch tclAppInit.c [explanation will follow]
  87.  
  88.         Note that this file is used to build tclsh and is not 
  89.         included in the tcl library.
  90.        
  91.  
  92.     *** tclAppInit.c.dist   Mon Nov  8 21:54:21 1993
  93.     --- tclAppInit.c        Mon Nov  8 22:02:09 1993
  94.     ***************
  95.     *** 39,44 ****
  96.     --- 39,53 ----
  97.       
  98.       extern int main();
  99.       int *tclDummyMainPtr = (int *) main;
  100.     + 
  101.     + /*
  102.     +  * The following variable is a special hack that insures the tcl
  103.     +  * version of matherr() is used when linking against shared libraries
  104.     +  */
  105.     + 
  106.     + extern int matherr();
  107.     + int *tclDummyMathPtr = (int *) matherr;
  108.     + 
  109.       
  110.      
  111.       /*
  112.        *----------------------------------------------------------------------
  113.  
  114.     (4) % make
  115.  
  116.     (5) create a directory named ./shared and move to it.
  117.  
  118.         % mkdir ./shared
  119.         % cd ./shared
  120.  
  121.     (6) extract the objects from libtcl.a into ./shared
  122.  
  123.         % ar xv ../libtcl.a
  124.  
  125.     (7) remove tclMtherr.o 
  126.  
  127.     (8) create the .so part of the shared library
  128.  
  129.     % ld -o libtcl.so.7.1 *.o -assert pure-text   <--- there should be
  130.                                no complaints from
  131.                                the assertion
  132.         % cp libtcl.so.7.1 ../
  133.  
  134.     (9) create the .sa part of the shared library
  135.  
  136.     % cd ../
  137.     % ar rcv libtcl.sa.7.1 tclMtherr.o
  138.     % ranlib libtcl.sa.7.1
  139.  
  140.    (10) build a version of tclsh using shared libraries
  141.  
  142.         % gcc -O tclsh.shared tclAppInit.o -L./ -ltcl -lm
  143.  
  144.         check out dynamic dependencies
  145.  
  146.             % ldd tclsh.shared
  147.  
  148.         -ltcl.7 => .//libtcl.so.7.1
  149.         -lc.1 => /usr/lib/libc.so.1.8
  150.         -ldl.1 => /usr/lib/libdl.so.1.0
  151.  
  152.         check out its size
  153.  
  154.             % ls -l tclsh.shared
  155.  
  156.         -rwxr-xr-x   1 root     daemon      57344 Nov 14 10:39 tclsh.shared
  157.  
  158.             [compare to the statically linked version and smile]
  159.  
  160.    (11) Copy the .so and .sa pieces of the library to their destination.
  161.         Run "ranlib -t" on the .sa piece once it has been installed.
  162.  
  163.  
  164. The reason for the patch to tclAppInit.c is to guarantee the tcl-version of
  165. matherr() is used rather than the system version contained in the math library,
  166. libm.a. The dummy reference to matherr() creates a demand that is resolved 
  167. at link time by the tcl-version of matherr() contained in the [static] 
  168. archive libtcl.sa.7.1. Note that this is a hack since tclMtherr.c contains
  169. no exported, initialized data items. To see see the consequences of these
  170. actions try :
  171.  
  172.           % tclsh.shared
  173.           % catch {acos(-2)}
  174.             1
  175.  
  176. Without this hack, the system version of matherr() would be used and catch
  177. would fail to "catch" the acos domain error.
  178.  
  179. TK
  180. ---
  181. Do the following:
  182.  
  183.     (1) run configure
  184.     (2) Edit the makfile: add the PIC flag to CFLAGS
  185.     (3) patch tkAppInit.c
  186.  
  187.     *** tkAppInit.c.dist    Tue Nov  9 00:10:15 1993
  188.     --- tkAppInit.c Tue Nov  9 00:11:04 1993
  189.     ***************
  190.     *** 40,45 ****
  191.     --- 40,53 ----
  192.       
  193.       extern int main();
  194.       int *tclDummyMainPtr = (int *) main;
  195.     + 
  196.     + /*
  197.     +  * The following variable is a special hack to insure that the tcl
  198.     +  * version of matther() is used when linking against shared libraries
  199.     +  */
  200.     + extern int matherr();
  201.     + int *tclDummyMathPtr = (int *) matherr;
  202.     + 
  203.       
  204.      
  205.       /*
  206.        *----------------------------------------------------------------------
  207.  
  208.     (4) run make
  209.     (5) % mkdir ./shared
  210.         % cd ./shared
  211.  
  212.     (6) % ar xv ../libtk.a
  213.         % ld -o libtk.so.3.4 *.o -assert pure-text
  214.         % cp libtk.so.3.4 ../
  215.  
  216.     (7) build a version of wish using shared libaries
  217.  
  218.         % gcc -O -o wish.shared -L./ -ltk -L../tcl7.1 -ltcl -lX11 -lm
  219.  
  220. TCLX
  221. ----
  222.  
  223.     (1) run configure
  224.     (2) edit Config.mk: add PIC flag to CFLAGS
  225.     (3) run make
  226.     (4) % cd tclmaster/lib
  227.         % mkdir shared
  228.         % cd shared
  229.         % ar xv ../libtclx.a
  230.         % ld -o libtclx.so.7.1 *.o -assert pure-text
  231.         % cp libtclx.so.7.1 ../
  232.     (5) % cd ./tkmaster/lib
  233.         % mkdir shared
  234.         % cd shared
  235.         % ar xv ../libtkx.a
  236.         % ld -o libtkx.so.3.4 *.o -assert pure-text
  237.         % cp libtkx.so.3.4 ../
  238.  
  239.     (6) copy the two shared libaries to their final destination
  240.