source: inundation/pmesh/compile.py @ 2898

Last change on this file since 2898 was 2331, checked in by duncan, 19 years ago

bug fix

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