Skip to content

Commit 575d373

Browse files
committed
Added new distutils
1 parent 14db419 commit 575d373

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+8082
-0
lines changed

distutils/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
from __version__ import version as __version__
3+
# Must import local ccompiler ASAP in order to get
4+
# customized CCompiler.spawn effective.
5+
import ccompiler
6+
import unixccompiler

distutils/__version__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
major = 0
2+
minor = 4
3+
micro = 0
4+
version = '%(major)d.%(minor)d.%(micro)d' % (locals())

distutils/ccompiler.py

Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
2+
import re
3+
import os
4+
import sys
5+
import new
6+
7+
from distutils.ccompiler import *
8+
from distutils import ccompiler
9+
from distutils.sysconfig import customize_compiler
10+
from distutils.version import LooseVersion
11+
12+
import log
13+
from exec_command import exec_command
14+
from misc_util import cyg2win32
15+
from distutils.spawn import _nt_quote_args
16+
17+
# Using customized CCompiler.spawn.
18+
def CCompiler_spawn(self, cmd, display=None):
19+
if display is None:
20+
display = cmd
21+
if type(display) is type([]): display = ' '.join(display)
22+
log.info(display)
23+
if type(cmd) is type([]) and os.name == 'nt':
24+
cmd = _nt_quote_args(cmd)
25+
s,o = exec_command(cmd)
26+
if s:
27+
if type(cmd) is type([]):
28+
cmd = ' '.join(cmd)
29+
print o
30+
raise DistutilsExecError,\
31+
'Command "%s" failed with exit status %d' % (cmd, s)
32+
CCompiler.spawn = new.instancemethod(CCompiler_spawn,None,CCompiler)
33+
34+
def CCompiler_object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
35+
if output_dir is None:
36+
output_dir = ''
37+
obj_names = []
38+
for src_name in source_filenames:
39+
base, ext = os.path.splitext(os.path.normpath(src_name))
40+
base = os.path.splitdrive(base)[1] # Chop off the drive
41+
base = base[os.path.isabs(base):] # If abs, chop off leading /
42+
if base.startswith('..'):
43+
# Resolve starting relative path components, middle ones
44+
# (if any) have been handled by os.path.normpath above.
45+
i = base.rfind('..')+2
46+
d = base[:i]
47+
d = os.path.basename(os.path.abspath(d))
48+
base = d + base[i:]
49+
if ext not in self.src_extensions:
50+
raise UnknownFileError, \
51+
"unknown file type '%s' (from '%s')" % (ext, src_name)
52+
if strip_dir:
53+
base = os.path.basename(base)
54+
obj_name = os.path.join(output_dir,base + self.obj_extension)
55+
obj_names.append(obj_name)
56+
return obj_names
57+
58+
CCompiler.object_filenames = new.instancemethod(CCompiler_object_filenames,
59+
None,CCompiler)
60+
61+
def CCompiler_compile(self, sources, output_dir=None, macros=None,
62+
include_dirs=None, debug=0, extra_preargs=None,
63+
extra_postargs=None, depends=None):
64+
# This method is effective only with Python >=2.3 distutils.
65+
# Any changes here should be applied also to fcompiler.compile
66+
# method to support pre Python 2.3 distutils.
67+
if not sources:
68+
return []
69+
from fcompiler import FCompiler
70+
if isinstance(self, FCompiler):
71+
display = []
72+
for fc in ['f77','f90','fix']:
73+
fcomp = getattr(self,'compiler_'+fc)
74+
if fcomp is None:
75+
continue
76+
display.append("%s(%s) options: '%s'" % (os.path.basename(fcomp[0]),
77+
fc,
78+
' '.join(fcomp[1:])))
79+
display = '\n'.join(display)
80+
else:
81+
ccomp = self.compiler_so
82+
display = "%s options: '%s'" % (os.path.basename(ccomp[0]),
83+
' '.join(ccomp[1:]))
84+
log.info(display)
85+
macros, objects, extra_postargs, pp_opts, build = \
86+
self._setup_compile(output_dir, macros, include_dirs, sources,
87+
depends, extra_postargs)
88+
cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)
89+
display = "compile options: '%s'" % (' '.join(cc_args))
90+
if extra_postargs:
91+
display += "\nextra options: '%s'" % (' '.join(extra_postargs))
92+
log.info(display)
93+
94+
# build any sources in same order as they were originally specified
95+
# especially important for fortran .f90 files using modules
96+
if isinstance(self, FCompiler):
97+
objects_to_build = build.keys()
98+
for obj in objects:
99+
if obj in objects_to_build:
100+
src, ext = build[obj]
101+
if self.compiler_type=='absoft':
102+
obj = cyg2win32(obj)
103+
src = cyg2win32(src)
104+
self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
105+
else:
106+
for obj, (src, ext) in build.items():
107+
self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
108+
109+
# Return *all* object filenames, not just the ones we just built.
110+
return objects
111+
112+
CCompiler.compile = new.instancemethod(CCompiler_compile,None,CCompiler)
113+
114+
def CCompiler_customize_cmd(self, cmd):
115+
""" Customize compiler using distutils command.
116+
"""
117+
log.info('customize %s using %s' % (self.__class__.__name__,
118+
cmd.__class__.__name__))
119+
if getattr(cmd,'include_dirs',None) is not None:
120+
self.set_include_dirs(cmd.include_dirs)
121+
if getattr(cmd,'define',None) is not None:
122+
for (name,value) in cmd.define:
123+
self.define_macro(name, value)
124+
if getattr(cmd,'undef',None) is not None:
125+
for macro in cmd.undef:
126+
self.undefine_macro(macro)
127+
if getattr(cmd,'libraries',None) is not None:
128+
self.set_libraries(self.libraries + cmd.libraries)
129+
if getattr(cmd,'library_dirs',None) is not None:
130+
self.set_library_dirs(self.library_dirs + cmd.library_dirs)
131+
if getattr(cmd,'rpath',None) is not None:
132+
self.set_runtime_library_dirs(cmd.rpath)
133+
if getattr(cmd,'link_objects',None) is not None:
134+
self.set_link_objects(cmd.link_objects)
135+
return
136+
137+
CCompiler.customize_cmd = new.instancemethod(\
138+
CCompiler_customize_cmd,None,CCompiler)
139+
140+
def _compiler_to_string(compiler):
141+
props = []
142+
mx = 0
143+
keys = compiler.executables.keys()
144+
for key in ['version','libraries','library_dirs',
145+
'object_switch','compile_switch',
146+
'include_dirs','define','undef','rpath','link_objects']:
147+
if key not in keys:
148+
keys.append(key)
149+
for key in keys:
150+
if hasattr(compiler,key):
151+
v = getattr(compiler, key)
152+
mx = max(mx,len(key))
153+
props.append((key,`v`))
154+
lines = []
155+
format = '%-' +`mx+1`+ 's = %s'
156+
for prop in props:
157+
lines.append(format % prop)
158+
return '\n'.join(lines)
159+
160+
def CCompiler_show_customization(self):
161+
if 0:
162+
for attrname in ['include_dirs','define','undef',
163+
'libraries','library_dirs',
164+
'rpath','link_objects']:
165+
attr = getattr(self,attrname,None)
166+
if not attr:
167+
continue
168+
log.info("compiler '%s' is set to %s" % (attrname,attr))
169+
try: self.get_version()
170+
except: pass
171+
if log._global_log.threshold<2:
172+
print '*'*80
173+
print self.__class__
174+
print _compiler_to_string(self)
175+
print '*'*80
176+
177+
CCompiler.show_customization = new.instancemethod(\
178+
CCompiler_show_customization,None,CCompiler)
179+
180+
181+
def CCompiler_customize(self, dist, need_cxx=0):
182+
# See FCompiler.customize for suggested usage.
183+
log.info('customize %s' % (self.__class__.__name__))
184+
customize_compiler(self)
185+
if need_cxx:
186+
if hasattr(self,'compiler') and self.compiler[0].find('gcc')>=0:
187+
if sys.version[:3]>='2.3':
188+
if not self.compiler_cxx:
189+
self.compiler_cxx = [self.compiler[0].replace('gcc','g++')]\
190+
+ self.compiler[1:]
191+
else:
192+
self.compiler_cxx = [self.compiler[0].replace('gcc','g++')]\
193+
+ self.compiler[1:]
194+
else:
195+
log.warn('Missing compiler_cxx fix for '+self.__class__.__name__)
196+
return
197+
198+
CCompiler.customize = new.instancemethod(\
199+
CCompiler_customize,None,CCompiler)
200+
201+
def CCompiler_get_version(self, force=0, ok_status=[0]):
202+
""" Compiler version. Returns None if compiler is not available. """
203+
if not force and hasattr(self,'version'):
204+
return self.version
205+
if not (hasattr(self,'version_cmd') and
206+
hasattr(self,'version_pattern')):
207+
#log.warn('%s does not provide version_cmd and version_pattern attributes' \
208+
# % (self.__class__))
209+
return
210+
211+
cmd = ' '.join(self.version_cmd)
212+
status, output = exec_command(cmd,use_tee=0)
213+
version = None
214+
if status in ok_status:
215+
m = re.match(self.version_pattern,output)
216+
if m:
217+
version = m.group('version')
218+
assert version,`version`
219+
version = LooseVersion(version)
220+
self.version = version
221+
return version
222+
223+
CCompiler.get_version = new.instancemethod(\
224+
CCompiler_get_version,None,CCompiler)
225+
226+
#if sys.platform == 'win32':
227+
# compiler_class['mingw32'] = ('mingw32ccompiler', 'Mingw32CCompiler',
228+
# "Mingw32 port of GNU C Compiler for Win32"\
229+
# "(for MSC built Python)")
230+
# if os.environ.get('OSTYPE','')=='msys' or \
231+
# os.environ.get('MSYSTEM','')=='MINGW32':
232+
# # On windows platforms, we want to default to mingw32 (gcc)
233+
# # because msvc can't build blitz stuff.
234+
# log.info('Setting mingw32 as default compiler for nt.')
235+
# ccompiler._default_compilers = (('nt', 'mingw32'),) \
236+
# + ccompiler._default_compilers
237+
238+
239+
_distutils_new_compiler = new_compiler
240+
def new_compiler (plat=None,
241+
compiler=None,
242+
verbose=0,
243+
dry_run=0,
244+
force=0):
245+
# Try first C compilers from scipy.distutils.
246+
if plat is None:
247+
plat = os.name
248+
try:
249+
if compiler is None:
250+
compiler = get_default_compiler(plat)
251+
(module_name, class_name, long_description) = compiler_class[compiler]
252+
except KeyError:
253+
msg = "don't know how to compile C/C++ code on platform '%s'" % plat
254+
if compiler is not None:
255+
msg = msg + " with '%s' compiler" % compiler
256+
raise DistutilsPlatformError, msg
257+
module_name = "scipy.distutils." + module_name
258+
try:
259+
__import__ (module_name)
260+
except ImportError, msg:
261+
print msg,'in scipy.distutils, trying from distutils..'
262+
module_name = module_name[6:]
263+
try:
264+
__import__(module_name)
265+
except ImportError, msg:
266+
raise DistutilsModuleError, \
267+
"can't compile C/C++ code: unable to load module '%s'" % \
268+
module_name
269+
try:
270+
module = sys.modules[module_name]
271+
klass = vars(module)[class_name]
272+
except KeyError:
273+
raise DistutilsModuleError, \
274+
("can't compile C/C++ code: unable to find class '%s' " +
275+
"in module '%s'") % (class_name, module_name)
276+
compiler = klass(None, dry_run, force)
277+
log.debug('new_fcompiler returns %s' % (klass))
278+
return compiler
279+
280+
ccompiler.new_compiler = new_compiler
281+
282+
283+
_distutils_gen_lib_options = gen_lib_options
284+
def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries):
285+
r = _distutils_gen_lib_options(compiler, library_dirs,
286+
runtime_library_dirs, libraries)
287+
lib_opts = []
288+
for i in r:
289+
if type(i) is type([]):
290+
lib_opts.extend(i)
291+
else:
292+
lib_opts.append(i)
293+
return lib_opts
294+
ccompiler.gen_lib_options = gen_lib_options
295+
296+
297+
##Fix distutils.util.split_quoted:
298+
import re,string
299+
_wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace)
300+
_squote_re = re.compile(r"'(?:[^'\\]|\\.)*'")
301+
_dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"')
302+
_has_white_re = re.compile(r'\s')
303+
def split_quoted(s):
304+
s = string.strip(s)
305+
words = []
306+
pos = 0
307+
308+
while s:
309+
m = _wordchars_re.match(s, pos)
310+
end = m.end()
311+
if end == len(s):
312+
words.append(s[:end])
313+
break
314+
315+
if s[end] in string.whitespace: # unescaped, unquoted whitespace: now
316+
words.append(s[:end]) # we definitely have a word delimiter
317+
s = string.lstrip(s[end:])
318+
pos = 0
319+
320+
elif s[end] == '\\': # preserve whatever is being escaped;
321+
# will become part of the current word
322+
s = s[:end] + s[end+1:]
323+
pos = end+1
324+
325+
else:
326+
if s[end] == "'": # slurp singly-quoted string
327+
m = _squote_re.match(s, end)
328+
elif s[end] == '"': # slurp doubly-quoted string
329+
m = _dquote_re.match(s, end)
330+
else:
331+
raise RuntimeError, \
332+
"this can't happen (bad char '%c')" % s[end]
333+
334+
if m is None:
335+
raise ValueError, \
336+
"bad string (mismatched %s quotes?)" % s[end]
337+
338+
(beg, end) = m.span()
339+
if _has_white_re.search(s[beg+1:end-1]):
340+
s = s[:beg] + s[beg+1:end-1] + s[end:]
341+
pos = m.end() - 2
342+
else:
343+
# Keeping quotes when a quoted word does not contain
344+
# white-space. XXX: send a patch to distutils
345+
pos = m.end()
346+
347+
if pos >= len(s):
348+
words.append(s)
349+
break
350+
351+
return words
352+
ccompiler.split_quoted = split_quoted

distutils/command/__init__.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""distutils.command
2+
3+
Package containing implementation of all the standard Distutils
4+
commands."""
5+
6+
__revision__ = "$Id: __init__.py,v 1.3 2005/05/16 11:08:49 pearu Exp $"
7+
8+
distutils_all = [ 'build_py',
9+
'build_scripts',
10+
'clean',
11+
'install_lib',
12+
'install_scripts',
13+
'bdist',
14+
'bdist_dumb',
15+
'bdist_wininst',
16+
]
17+
18+
__import__('distutils.command',globals(),locals(),distutils_all)
19+
20+
__all__ = ['build',
21+
'config_compiler',
22+
'config',
23+
'build_src',
24+
'build_ext',
25+
'build_clib',
26+
'install',
27+
'install_data',
28+
'install_headers',
29+
'bdist_rpm',
30+
'sdist',
31+
] + distutils_all

0 commit comments

Comments
 (0)