source: anuga_core/source/anuga/mesh_engine/me_compile.py @ 4155

Last change on this file since 4155 was 4144, checked in by duncan, 18 years ago

Changing the mesh generator and triangle interface to work with Numeric arrys, as input. Fixed to work on Linux

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