source: inundation/pmesh/compile.py @ 3494

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

cleaning up

File size: 6.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  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
232
233if __name__ == '__main__':
234
235
236  import sys, os
237  from os.path import splitext
238 
239  if len(sys.argv) > 1:
240      files = sys.argv[1:]
241      for filename in files:
242          root, ext = splitext(filename)
243
244          if ext <> '.c':
245              print 'WARNING (compile.py): Skipping %s. I only compile C-files.' %filename
246     
247  else: 
248      #path = os.path.split(sys.argv[0])[0] or os.getcwd()
249      path = '.'
250      files = os.listdir(path)
251       
252  for filename in files:
253      root, ext = splitext(filename)
254
255      if ext == '.c':
256          for x in ['.dll', '.so']:
257              try:
258                  os.remove(root + x)
259              except:
260                  pass
261
262          print '--------------- Trying to compile c-extension %s' %filename
263          try:
264            if filename == 'triang.c':
265              print "********** Manually doing dependancies **************"
266              compile(['triang.c','triangle.c'])
267            else:
268              compile(filename)
269          except:
270              print 'Could not compile C extension %s' %filename           
271          else:
272              print 'C extension %s OK' %filename
273          print   
274       
275
Note: See TracBrowser for help on using the repository browser.