source: inundation/utilities/compile.py @ 3330

Last change on this file since 3330 was 2778, checked in by steve, 19 years ago

On our 64 bit machine, ran into problem in pmesh/mesh.py where seg[0], seg[1], triangle,
and neighbor where not seen as integers. Had to wrap them in int(..)

File size: 8.3 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    python_include = os.path.join(sys.exec_prefix, 'include')   
159  else: 
160    python_include = os.path.join(os.path.join(sys.exec_prefix, 'include'),
161                                  'python' + version)
162
163  # Check existence of Python.h
164  #
165  headerfile = python_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
176  #Add Python path + utilities to includelist (see ticket:31)
177  #Assume there is only one 'utilities' dir under path dirs
178
179  utilities_include_dir = None
180  for pathdir in sys.path:
181
182    utilities_include_dir = pathdir + os.sep + 'utilities'
183    #print pathdir
184    #print utilities_include_dir
185    try:
186      os.stat(utilities_include_dir)
187    except OSError:
188      pass
189    else:
190      #print 'Found %s to be used as include dir' %utilities_include_dir
191      break
192     
193
194     
195
196 
197 
198  # Check filename(s)
199  #
200  object_files = ''
201  for FN in FNs:       
202    root, ext = os.path.splitext(FN)
203    if ext == '':
204      FN = FN + '.c'
205    elif ext.lower() != '.c':
206      raise Exception, "Unrecognised extension: " + FN
207   
208    try:
209      open(FN, 'r')
210    except:
211      #print 'CWD:', os.getcwd()     
212      raise Exception, "Could not open: " + FN
213
214    if not object_files: root1 = root  #Remember first filename       
215    object_files += root + '.o ' 
216 
217 
218    # Compile
219    #
220    if utilities_include_dir is None:   
221      s = '%s -c %s -I%s -o %s.o -Wall -O3'\
222          %(compiler, FN, python_include, root)
223    else:
224      s = '%s -c %s -I%s -I%s -o %s.o -Wall -O3'\
225          %(compiler, FN, python_include, utilities_include_dir, root)
226
227    if os.name == 'posix' and os.uname()[4] == 'x86_64':
228      #Extra flags for 64 bit architectures
229      #Second clause will always fail on Win32 because uname is UNIX specific
230      #but won't get past first clause
231
232      #FIXME: Which one?
233      #s += ' -fPIC'
234      s += ' -fPIC -m64' 
235     
236     
237    if verbose:
238      print s
239    else:
240      s = s + ' 2> /dev/null' #Suppress errors
241 
242    try:
243      err = os.system(s)
244      if err != 0:
245          raise 'Attempting to compile %s failed - please try manually' %FN
246    except:
247      raise 'Could not compile %s - please try manually' %FN 
248
249 
250  # Make shared library (*.so or *.dll)
251 
252  s = "%s -%s %s -o %s.%s %s -lm" %(loader, sharedflag, object_files, root1, libext, libs)
253  if verbose:
254    print s
255  else:
256    s = s + ' 2> /dev/null' #Suppress warnings
257 
258  try: 
259    err=os.system(s)
260    if err != 0:       
261        raise 'Atempting to link %s failed - please try manually' %root1     
262  except:
263    raise 'Could not link %s - please try manually' %root1
264   
265
266def can_use_C_extension(filename):
267    """Determine whether specified C-extension
268    can and should be used.
269    """
270
271
272    from os.path import splitext
273
274    root, ext = splitext(filename)
275   
276    C=False
277
278    try:
279        s = 'import %s' %root
280        #print s
281        exec(s)
282    except:
283        try:
284            open(filename)
285        except:
286            msg = 'C extension %s cannot be opened' %filename
287            print msg               
288        else:   
289            print '------- Trying to compile c-extension %s' %filename
290
291            #compile(filename)       
292            try:
293                compile(filename)
294            except:
295                print 'WARNING: Could not compile C-extension %s'\
296                      %filename
297            else:
298                try:
299                    exec('import %s' %root)
300                except:
301                    msg = 'C extension %s seems to compile OK, '
302                    msg += 'but it can still not be imported.'
303                    raise msg
304                else:
305                    C=True
306    else:
307        C=True
308           
309    if not C:
310        pass
311        print 'NOTICE: C-extension %s not used' %filename
312
313    return C
314
315
316
317
318if __name__ == '__main__':
319
320
321  import sys, os
322  from os.path import splitext
323 
324  if len(sys.argv) > 1:
325      files = sys.argv[1:]
326      for filename in files:
327          root, ext = splitext(filename)
328
329          if ext <> '.c':
330              print 'WARNING (compile.py): Skipping %s. I only compile C-files.' %filename
331     
332  else: 
333      #path = os.path.split(sys.argv[0])[0] or os.getcwd()
334      path = '.'
335      files = os.listdir(path)
336     
337     
338
339  for filename in files:
340      root, ext = splitext(filename)
341
342      if ext == '.c':
343          for x in ['.dll', '.so']:
344              try:
345                  os.remove(root + x)
346              except:
347                  pass
348
349          print '--------------------------------------'     
350          print 'Trying to compile c-extension %s in %s'\
351                %(filename, os.getcwd())
352
353          try:
354              compile(filename)
355          except Exception, e:
356              print 'Could not compile C extension %s' %filename
357          else:
358              print 'C extension %s OK' %filename
359          print   
360       
361
Note: See TracBrowser for help on using the repository browser.