OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [library/] [ldAout.tcl] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
# ldAout.tcl --
2
#
3
#       This "tclldAout" procedure in this script acts as a replacement
4
#       for the "ld" command when linking an object file that will be
5
#       loaded dynamically into Tcl or Tk using pseudo-static linking.
6
#
7
# Parameters:
8
#       The arguments to the script are the command line options for
9
#       an "ld" command.
10
#
11
# Results:
12
#       The "ld" command is parsed, and the "-o" option determines the
13
#       module name.  ".a" and ".o" options are accumulated.
14
#       The input archives and object files are examined with the "nm"
15
#       command to determine whether the modules initialization
16
#       entry and safe initialization entry are present.  A trivial
17
#       C function that locates the entries is composed, compiled, and
18
#       its .o file placed before all others in the command; then
19
#       "ld" is executed to bind the objects together.
20
#
21
# RCS: @(#) $Id: ldAout.tcl,v 1.1.1.1 2002-01-16 10:25:30 markom Exp $
22
#
23
# Copyright (c) 1995, by General Electric Company. All rights reserved.
24
#
25
# See the file "license.terms" for information on usage and redistribution
26
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
27
#
28
# This work was supported in part by the ARPA Manufacturing Automation
29
# and Design Engineering (MADE) Initiative through ARPA contract
30
# F33615-94-C-4400.
31
 
32
proc tclLdAout {{cc {}} {shlib_suffix {}} {shlib_cflags none}} {
33
  global env
34
  global argv
35
 
36
  if {$cc==""} {
37
    set cc $env(CC)
38
  }
39
 
40
  # if only two parameters are supplied there is assumed that the
41
  # only shlib_suffix is missing. This parameter is anyway available
42
  # as "info sharedlibextension" too, so there is no need to transfer
43
  # 3 parameters to the function tclLdAout. For compatibility, this
44
  # function now accepts both 2 and 3 parameters.
45
 
46
  if {$shlib_suffix==""} {
47
    set shlib_cflags $env(SHLIB_CFLAGS)
48
  } else {
49
    if {$shlib_cflags=="none"} {
50
      set shlib_cflags $shlib_suffix
51
    }
52
  }
53
 
54
  # seenDotO is nonzero if a .o or .a file has been seen
55
 
56
  set seenDotO 0
57
 
58
  # minusO is nonzero if the last command line argument was "-o".
59
 
60
  set minusO 0
61
 
62
  # head has command line arguments up to but not including the first
63
  # .o or .a file. tail has the rest of the arguments.
64
 
65
  set head {}
66
  set tail {}
67
 
68
  # nmCommand is the "nm" command that lists global symbols from the
69
  # object files.
70
 
71
  set nmCommand {|nm -g}
72
 
73
  # entryProtos is the table of _Init and _SafeInit prototypes found in the
74
  # module.
75
 
76
  set entryProtos {}
77
 
78
  # entryPoints is the table of _Init and _SafeInit entries found in the
79
  # module.
80
 
81
  set entryPoints {}
82
 
83
  # libraries is the list of -L and -l flags to the linker.
84
 
85
  set libraries {}
86
  set libdirs {}
87
 
88
  # Process command line arguments
89
 
90
  foreach a $argv {
91
    if {!$minusO && [regexp {\.[ao]$} $a]} {
92
      set seenDotO 1
93
      lappend nmCommand $a
94
    }
95
    if {$minusO} {
96
      set outputFile $a
97
      set minusO 0
98
    } elseif {![string compare $a -o]} {
99
      set minusO 1
100
    }
101
    if {[regexp {^-[lL]} $a]} {
102
        lappend libraries $a
103
        if {[regexp {^-L} $a]} {
104
            lappend libdirs [string range $a 2 end]
105
        }
106
    } elseif {$seenDotO} {
107
        lappend tail $a
108
    } else {
109
        lappend head $a
110
    }
111
  }
112
  lappend libdirs /lib /usr/lib
113
 
114
  # MIPS -- If there are corresponding G0 libraries, replace the
115
  # ordinary ones with the G0 ones.
116
 
117
  set libs {}
118
  foreach lib $libraries {
119
      if {[regexp {^-l} $lib]} {
120
          set lname [string range $lib 2 end]
121
          foreach dir $libdirs {
122
              if {[file exists [file join $dir lib${lname}_G0.a]]} {
123
                  set lname ${lname}_G0
124
                  break
125
              }
126
          }
127
          lappend libs -l$lname
128
      } else {
129
          lappend libs $lib
130
      }
131
  }
132
  set libraries $libs
133
 
134
  # Extract the module name from the "-o" option
135
 
136
  if {![info exists outputFile]} {
137
    error "-o option must be supplied to link a Tcl load module"
138
  }
139
  set m [file tail $outputFile]
140
  if {[regexp {\.a$} $outputFile]} {
141
    set shlib_suffix .a
142
  } else {
143
    set shlib_suffix ""
144
  }
145
  if {[regexp {\..*$} $outputFile match]} {
146
    set l [expr {[string length $m] - [string length $match]}]
147
  } else {
148
    error "Output file does not appear to have a suffix"
149
  }
150
  set modName [string tolower [string range $m 0 [expr {$l-1}]]]
151
  if {[regexp {^lib} $modName]} {
152
    set modName [string range $modName 3 end]
153
  }
154
  if {[regexp {[0-9\.]*(_g0)?$} $modName match]} {
155
    set modName [string range $modName 0 [expr {[string length $modName]-[string length $match]-1}]]
156
  }
157
  set modName "[string toupper [string index $modName 0]][string range $modName 1 end]"
158
 
159
  # Catalog initialization entry points found in the module
160
 
161
  set f [open $nmCommand r]
162
  while {[gets $f l] >= 0} {
163
    if {[regexp {T[     ]*_?([A-Z][a-z0-9_]*_(Safe)?Init(__FP10Tcl_Interp)?)$} $l trash symbol]} {
164
      if {![regexp {_?([A-Z][a-z0-9_]*_(Safe)?Init)} $symbol trash s]} {
165
        set s $symbol
166
      }
167
      append entryProtos {extern int } $symbol { (); } \n
168
      append entryPoints {  } \{ { "} $s {", } $symbol { } \} , \n
169
    }
170
  }
171
  close $f
172
 
173
  if {$entryPoints==""} {
174
    error "No entry point found in objects"
175
  }
176
 
177
  # Compose a C function that resolves the initialization entry points and
178
  # embeds the required libraries in the object code.
179
 
180
  set C {#include <string.h>}
181
  append C \n
182
  append C {char TclLoadLibraries_} $modName { [] =} \n
183
  append C {  "@LIBS: } $libraries {";} \n
184
  append C $entryProtos
185
  append C {static struct } \{ \n
186
  append C {  char * name;} \n
187
  append C {  int (*value)();} \n
188
  append C \} {dictionary [] = } \{ \n
189
  append C $entryPoints
190
  append C {  0, 0 } \n \} \; \n
191
  append C {typedef struct Tcl_Interp Tcl_Interp;} \n
192
  append C {typedef int Tcl_PackageInitProc (Tcl_Interp *);} \n
193
  append C {Tcl_PackageInitProc *} \n
194
  append C TclLoadDictionary_ $modName { (symbol)} \n
195
  append C {    char * symbol;} \n
196
  append C {{
197
    int i;
198
    for (i = 0; dictionary [i] . name != 0; ++i) {
199
      if (!strcmp (symbol, dictionary [i] . name)) {
200
        return dictionary [i].value;
201
      }
202
    }
203
    return 0;
204
}} \n
205
 
206
  # Write the C module and compile it
207
 
208
  set cFile tcl$modName.c
209
  set f [open $cFile w]
210
  puts -nonewline $f $C
211
  close $f
212
  set ccCommand "$cc -c $shlib_cflags $cFile"
213
  puts stderr $ccCommand
214
  eval exec $ccCommand
215
 
216
  # Now compose and execute the ld command that packages the module
217
 
218
  if {$shlib_suffix == ".a"} {
219
    set ldCommand "ar cr $outputFile"
220
    regsub { -o} $tail {} tail
221
  } else {
222
    set ldCommand ld
223
    foreach item $head {
224
      lappend ldCommand $item
225
    }
226
  }
227
  lappend ldCommand tcl$modName.o
228
  foreach item $tail {
229
    lappend ldCommand $item
230
  }
231
  puts stderr $ldCommand
232
  eval exec $ldCommand
233
  if {$shlib_suffix == ".a"} {
234
    exec ranlib $outputFile
235
  }
236
 
237
  # Clean up working files
238
 
239
  exec /bin/rm $cFile [file rootname $cFile].o
240
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.