source: tools/pytools/compile.py @ 361

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

Added old pytools module from CVS

File size: 5.5 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 
13def compile(FNs=None, CC=None, LD = None, SFLAG = None, verbose = 1):
14  """compile(FNs=None, CC=None, LD = None, SFLAG = None):
15 
16     Compile FN(s) using compiler CC (e.g. mpicc),
17     Loader LD and shared flag SFLAG.
18     If CC is absent use default compiler dependent on platform
19     if LD is absent CC is used.
20     if SFLAG is absent platform default is used
21     FNs can be either one filename or a list of filenames
22     In the latter case, the first will be used to name so file.
23  """
24  import os, string, sys, types
25 
26  # Input check
27  #
28  assert not FNs is None, "No filename provided"
29
30  if not type(FNs) == types.ListType:
31    FNs = [FNs]
32
33
34  libext = 'so' #Default extension (Unix)
35  libs = ''
36  version = sys.version[:3]
37 
38  # Determine platform and compiler
39  #
40  if sys.platform == 'sunos5':  #Solaris
41    if CC:
42      compiler = CC
43    else: 
44      compiler = 'gcc'
45    if LD:
46      loader = LD
47    else: 
48      loader = compiler
49    if SFLAG:
50      sharedflag = SFLAG
51    else: 
52      sharedflag = 'G'
53     
54  elif sys.platform == 'osf1V5':  #Compaq AlphaServer
55    if CC:
56      compiler = CC
57    else: 
58      compiler = 'cc'
59    if LD:
60      loader = LD
61    else: 
62      loader = compiler
63    if SFLAG:
64      sharedflag = SFLAG
65    else: 
66      sharedflag = 'shared'   
67     
68  elif sys.platform == 'linux2':  #Linux
69    if CC:
70      compiler = CC
71    else: 
72      compiler = 'gcc'
73    if LD:
74      loader = LD
75    else: 
76      loader = compiler
77    if SFLAG:
78      sharedflag = SFLAG
79    else: 
80      sharedflag = 'shared'   
81     
82  elif sys.platform == 'darwin':  #Mac OS X:
83    if CC:
84      compiler = CC
85    else: 
86      compiler = 'cc'
87    if LD:
88      loader = LD
89    else: 
90      loader = compiler
91    if SFLAG:
92      sharedflag = SFLAG
93    else: 
94      sharedflag = 'bundle -flat_namespace -undefined suppress'
95
96  elif sys.platform == 'cygwin':  #Cygwin (compilation same as linux)
97    if CC:
98      compiler = CC
99    else: 
100      compiler = 'gcc'
101    if LD:
102      loader = LD
103    else: 
104      loader = compiler
105    if SFLAG:
106      sharedflag = SFLAG
107    else: 
108      sharedflag = 'shared'
109    libext = 'dll'
110    libs = '/lib/python%s/config/libpython%s.dll.a' %(version,version)
111     
112  elif sys.platform == 'win32':  #Windows
113    if CC:
114      compiler = CC
115    else: 
116      compiler = 'gcc'
117    if LD:
118      loader = LD
119    else: 
120      loader = compiler
121    if SFLAG:
122      sharedflag = SFLAG
123    else: 
124      sharedflag = 'shared'
125    libext = 'dll'
126
127    v = version.replace('.','')
128    dllfilename = 'python%s.dll' %(v)
129    libs = os.path.join(sys.exec_prefix,dllfilename)
130     
131     
132  else:
133    if verbose: print "Unrecognised platform %s - revert to default"\
134                %sys.platform
135   
136    if CC:
137      compiler = CC
138    else: 
139      compiler = 'cc'
140    if LD:
141      loader = LD
142    else: 
143      loader = 'ld'
144    if SFLAG:
145      sharedflag = SFLAG
146    else: 
147      sharedflag = 'G'
148
149           
150  # Find location of include files
151  #
152  if sys.platform == 'win32':  #Windows
153    include = os.path.join(sys.exec_prefix, 'include')   
154  else: 
155    include = os.path.join(os.path.join(sys.exec_prefix, 'include'),
156                           'python'+version)
157
158  # Check existence of Python.h
159  #
160  headerfile = include + os.sep +'Python.h'
161  try:
162    open(headerfile, 'r')
163  except:
164    raise """Did not find Python header file %s.
165    Make sure files for Python C-extensions are installed.
166    In debian linux, for example, you need to install a
167    package called something like python2.3-dev""" %headerfile
168 
169 
170  # Check filename(s)
171  #
172  object_files = ''
173  for FN in FNs:       
174    root, ext = os.path.splitext(FN)
175    if ext == '':
176      FN = FN + '.c'
177    elif ext.lower() != '.c':
178      raise Exception, "Unrecognised extension: " + FN
179   
180    try:
181      open(FN,'r')
182    except:   
183      raise Exception, "Could not open: " + FN
184
185    if not object_files: root1 = root  #Remember first filename       
186    object_files += root + '.o ' 
187 
188 
189    # Compile
190    #
191   
192    s = "%s -c %s -I%s -o %s.o -Wall -O" %(compiler, FN, include, root)
193    if verbose:
194      print s
195    else:
196      s = s + ' 2> /dev/null' #Suppress errors
197 
198    try:
199      err = os.system(s)
200      if err != 0:
201          raise 'Attempting to compile %s failed - please try manually' %FN
202    except:
203      raise 'Could not compile %s - please try manually' %FN 
204
205 
206  # Make shared library (*.so or *.dll)
207 
208  s = "%s -%s %s -o %s.%s %s -lm" %(loader, sharedflag, object_files, root1, libext, libs)
209  if verbose:
210    print s
211  else:
212    s = s + ' 2> /dev/null' #Suppress warnings
213 
214  try: 
215    err=os.system(s)
216    if err != 0:       
217        raise 'Atempting to link %s failed - please try manually' %root1     
218  except:
219    raise 'Could not link %s - please try manually' %root1
220   
221
222
223
224if __name__ == '__main__':
225
226  import sys
227 
228  # Get file to compile
229  #
230  if len(sys.argv) < 2:
231    print "Usage:"
232    print "  python compile.py <filename>"
233    sys.exit()
234
235  filenames = []
236  for filename in sys.argv[1:]:
237    filenames.append(filename)
238   
239  compile(filenames, verbose=1)
240
Note: See TracBrowser for help on using the repository browser.