source: inundation/ga/storm_surge/pyvolution/compile.py @ 333

Last change on this file since 333 was 196, checked in by ole, 20 years ago

Added new compile module instead of pytools

File size: 7.2 KB
Line 
1"""compile.py - compile Python C-extension
2
3   Commandline usage:
4     python compile.py <filename>
5
6   Usage from within Python:
7     import compile
8     compile.compile(<filename>,..)
9
10   Ole Nielsen, Oct 2001     
11"""     
12 
13def compile(FNs=None, CC=None, LD = None, SFLAG = None, verbose = 1):
14  """compile(FNs=None, CC=None, LD = None, SFLAG = None):
15 
16     Compile FN(s) using compiler CC (e.g. mpicc),
17     Loader LD and shared flag SFLAG.
18     If CC is absent use default compiler dependent on platform
19     if LD is absent CC is used.
20     if SFLAG is absent platform default is used
21     FNs can be either one filename or a list of filenames
22     In the latter case, the first will be used to name so file.
23  """
24  import os, string, sys, types
25 
26  # Input check
27  #
28  assert not FNs is None, "No filename provided"
29
30  if not type(FNs) == types.ListType:
31    FNs = [FNs]
32
33
34  libext = 'so' #Default extension (Unix)
35  libs = ''
36  version = sys.version[:3]
37 
38  # Determine platform and compiler
39  #
40  if sys.platform == 'sunos5':  #Solaris
41    if CC:
42      compiler = CC
43    else: 
44      compiler = 'gcc'
45    if LD:
46      loader = LD
47    else: 
48      loader = compiler
49    if SFLAG:
50      sharedflag = SFLAG
51    else: 
52      sharedflag = 'G'
53     
54  elif sys.platform == 'osf1V5':  #Compaq AlphaServer
55    if CC:
56      compiler = CC
57    else: 
58      compiler = 'cc'
59    if LD:
60      loader = LD
61    else: 
62      loader = compiler
63    if SFLAG:
64      sharedflag = SFLAG
65    else: 
66      sharedflag = 'shared'   
67     
68  elif sys.platform == 'linux2':  #Linux
69    if CC:
70      compiler = CC
71    else: 
72      compiler = 'gcc'
73    if LD:
74      loader = LD
75    else: 
76      loader = compiler
77    if SFLAG:
78      sharedflag = SFLAG
79    else: 
80      sharedflag = 'shared'   
81     
82  elif sys.platform == 'darwin':  #Mac OS X:
83    if CC:
84      compiler = CC
85    else: 
86      compiler = 'cc'
87    if LD:
88      loader = LD
89    else: 
90      loader = compiler
91    if SFLAG:
92      sharedflag = SFLAG
93    else: 
94      sharedflag = 'bundle -flat_namespace -undefined suppress'
95
96  elif sys.platform == 'cygwin':  #Cygwin (compilation same as linux)
97    if CC:
98      compiler = CC
99    else: 
100      compiler = 'gcc'
101    if LD:
102      loader = LD
103    else: 
104      loader = compiler
105    if SFLAG:
106      sharedflag = SFLAG
107    else: 
108      sharedflag = 'shared'
109    libext = 'dll'
110    libs = '/lib/python%s/config/libpython%s.dll.a' %(version,version)
111     
112  elif sys.platform == 'win32':  #Windows
113    if CC:
114      compiler = CC
115    else: 
116      compiler = 'gcc'
117    if LD:
118      loader = LD
119    else: 
120      loader = compiler
121    if SFLAG:
122      sharedflag = SFLAG
123    else: 
124      sharedflag = 'shared'
125    libext = 'dll'
126
127    v = version.replace('.','')
128    dllfilename = 'python%s.dll' %(v)
129    libs = os.path.join(sys.exec_prefix,dllfilename)
130     
131     
132  else:
133    if verbose: print "Unrecognised platform %s - revert to default"\
134                %sys.platform
135   
136    if CC:
137      compiler = CC
138    else: 
139      compiler = 'cc'
140    if LD:
141      loader = LD
142    else: 
143      loader = 'ld'
144    if SFLAG:
145      sharedflag = SFLAG
146    else: 
147      sharedflag = 'G'
148
149           
150  # Find location of include files
151  #
152  if sys.platform == 'win32':  #Windows
153    include = os.path.join(sys.exec_prefix, 'include')   
154  else: 
155    include = os.path.join(os.path.join(sys.exec_prefix, 'include'),
156                           'python'+version)
157
158  # Check existence of Python.h
159  #
160  headerfile = include + os.sep +'Python.h'
161  try:
162    open(headerfile, 'r')
163  except:
164    raise """Did not find Python header file %s.
165    Make sure files for Python C-extensions are installed.
166    In debian linux, for example, you need to install a
167    package called something like python2.3-dev""" %headerfile
168 
169 
170  # Check filename(s)
171  #
172  object_files = ''
173  for FN in FNs:       
174    root, ext = os.path.splitext(FN)
175    if ext == '':
176      FN = FN + '.c'
177    elif ext.lower() != '.c':
178      raise Exception, "Unrecognised extension: " + FN
179   
180    try:
181      open(FN,'r')
182    except:   
183      raise Exception, "Could not open: " + FN
184
185    if not object_files: root1 = root  #Remember first filename       
186    object_files += root + '.o ' 
187 
188 
189    # Compile
190    #
191   
192    s = "%s -c %s -I%s -o %s.o -Wall -O" %(compiler, FN, include, root)
193    if verbose:
194      print s
195    else:
196      s = s + ' 2> /dev/null' #Suppress errors
197 
198    try:
199      err = os.system(s)
200      if err != 0:
201          raise 'Attempting to compile %s failed - please try manually' %FN
202    except:
203      raise 'Could not compile %s - please try manually' %FN 
204
205 
206  # Make shared library (*.so or *.dll)
207 
208  s = "%s -%s %s -o %s.%s %s -lm" %(loader, sharedflag, object_files, root1, libext, libs)
209  if verbose:
210    print s
211  else:
212    s = s + ' 2> /dev/null' #Suppress warnings
213 
214  try: 
215    err=os.system(s)
216    if err != 0:       
217        raise 'Atempting to link %s failed - please try manually' %root1     
218  except:
219    raise 'Could not link %s - please try manually' %root1
220   
221
222def can_use_C_extension(filename):
223    """Determine whether specified C-extension
224    can and should be used.
225    """
226
227    from config import use_extensions
228
229    from os.path import splitext
230
231    root, ext = splitext(filename)
232   
233    C=False
234    if use_extensions:
235        try:
236            s = 'import %s' %root
237            #print s
238            exec(s)
239        except:
240            try:
241                open(filename)
242            except:
243                msg = 'C extension %s cannot be opened' %filename
244                print msg               
245            else:   
246                print '------- Trying to compile c-extension %s' %filename
247           
248                try:
249                    compile(filename)
250                except:
251                    print 'WARNING: Could not compile C-extension %s'\
252                          %filename
253                else:
254                    try:
255                        exec('import %s' %root)
256                    except:
257                        msg = 'C extension %s seems to compile OK, '
258                        msg += 'but it can still not be imported.'
259                        raise msg
260                    else:
261                        C=True
262        else:
263            C=True
264           
265    if not C:
266        pass
267        print 'NOTICE: C-extension %s not used' %filename
268
269    return C
270
271
272
273
274if __name__ == '__main__':
275
276
277  import sys, os
278  from os.path import splitext
279   
280  path = os.path.split(sys.argv[0])[0] or os.getcwd()
281  files = os.listdir(path)
282
283  for filename in files:
284      root, ext = splitext(filename)
285
286
287      if ext == '.c':
288          for x in ['.dll', '.so']:
289              try:
290                  os.remove(root + x)
291              except:
292                  pass
293
294          print '--------------- Trying to compile c-extension %s' %filename
295          try:
296              compile(filename)
297          except:
298              print 'Could not compile C extension %s' %filename           
299          else:
300              print 'C extension %s OK' %filename
301          print   
302       
303
Note: See TracBrowser for help on using the repository browser.