source: inundation/utilities/compile.py @ 1910

Last change on this file since 1910 was 1910, checked in by ole, 18 years ago

Made utilities a Python package
Added numerical_tools (and test) containing ensure_numeric from the old util module.
Added test_polygon.py

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