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

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

Added detection of 64 architecture

File size: 7.4 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 AMD 64
200      s += ' -fPIC -amd64'
201     
202    if verbose:
203      print s
204    else:
205      s = s + ' 2> /dev/null' #Suppress errors
206 
207    try:
208      err = os.system(s)
209      if err != 0:
210          raise 'Attempting to compile %s failed - please try manually' %FN
211    except:
212      raise 'Could not compile %s - please try manually' %FN 
213
214 
215  # Make shared library (*.so or *.dll)
216 
217  s = "%s -%s %s -o %s.%s %s -lm" %(loader, sharedflag, object_files, root1, libext, libs)
218  if verbose:
219    print s
220  else:
221    s = s + ' 2> /dev/null' #Suppress warnings
222 
223  try: 
224    err=os.system(s)
225    if err != 0:       
226        raise 'Atempting to link %s failed - please try manually' %root1     
227  except:
228    raise 'Could not link %s - please try manually' %root1
229   
230
231def can_use_C_extension(filename):
232    """Determine whether specified C-extension
233    can and should be used.
234    """
235
236    from config import use_extensions
237
238    from os.path import splitext
239
240    root, ext = splitext(filename)
241   
242    C=False
243    if use_extensions:
244        try:
245            s = 'import %s' %root
246            #print s
247            exec(s)
248        except:
249            try:
250                open(filename)
251            except:
252                msg = 'C extension %s cannot be opened' %filename
253                print msg               
254            else:   
255                print '------- Trying to compile c-extension %s' %filename
256           
257                try:
258                    compile(filename)
259                except:
260                    print 'WARNING: Could not compile C-extension %s'\
261                          %filename
262                else:
263                    try:
264                        exec('import %s' %root)
265                    except:
266                        msg = 'C extension %s seems to compile OK, '
267                        msg += 'but it can still not be imported.'
268                        raise msg
269                    else:
270                        C=True
271        else:
272            C=True
273           
274    if not C:
275        pass
276        print 'NOTICE: C-extension %s not used' %filename
277
278    return C
279
280
281
282
283if __name__ == '__main__':
284
285
286  import sys, os
287  from os.path import splitext
288 
289  if len(sys.argv) > 1:
290      files = sys.argv[1:]
291      for filename in files:
292          root, ext = splitext(filename)
293
294          if ext <> '.c':
295              print 'WARNING (compile.py): Skipping %s. I only compile C-files.' %filename
296     
297  else: 
298      #path = os.path.split(sys.argv[0])[0] or os.getcwd()
299      path = '.'
300      files = os.listdir(path)
301     
302     
303
304  for filename in files:
305      root, ext = splitext(filename)
306
307      if ext == '.c':
308          for x in ['.dll', '.so']:
309              try:
310                  os.remove(root + x)
311              except:
312                  pass
313
314          print '--------------- Trying to compile c-extension %s' %filename
315          try:
316              compile(filename)
317          except:
318              print 'Could not compile C extension %s' %filename           
319          else:
320              print 'C extension %s OK' %filename
321          print   
322       
323
Note: See TracBrowser for help on using the repository browser.