Changed to catch compile/link failures and raise CompileError, LibError,

or LinkError (exception classes defined in ccompiler.py).
This commit is contained in:
Greg Ward 2000-05-30 01:56:44 +00:00
parent adda156a13
commit d151711e66
3 changed files with 74 additions and 17 deletions

View File

@ -15,6 +15,22 @@ from distutils.spawn import spawn
from distutils.util import move_file, mkpath, newer_pairwise, newer_group from distutils.util import move_file, mkpath, newer_pairwise, newer_group
# Exception classes used by the CCompiler implementation classes
class CCompilerError (Exception):
"""Failure doing some compile/link operation."""
class CompileError (CCompilerError):
"""Failure to compile one or more C/C++ source files."""
class LibError (CCompilerError):
"""Failure to create a static library from one or more C/C++ object
files."""
class LinkError (CCompilerError):
"""Failure to link one or more C/C++ object files into an executable
or shared library file."""
class CCompiler: class CCompiler:
"""Abstract base class to define the interface that must be implemented """Abstract base class to define the interface that must be implemented
by real compiler abstraction classes. Might have some use as a by real compiler abstraction classes. Might have some use as a
@ -456,7 +472,9 @@ class CCompiler:
command line. On other platforms, consult the implementation command line. On other platforms, consult the implementation
class documentation. In any event, they are intended as an class documentation. In any event, they are intended as an
escape hatch for those occasions when the abstract compiler escape hatch for those occasions when the abstract compiler
framework doesn't cut the mustard.""" framework doesn't cut the mustard.
Raises CompileError on failure."""
pass pass
@ -481,7 +499,9 @@ class CCompiler:
'debug' is a boolean; if true, debugging information will be 'debug' is a boolean; if true, debugging information will be
included in the library (note that on most platforms, it is the included in the library (note that on most platforms, it is the
compile step where this matters: the 'debug' flag is included compile step where this matters: the 'debug' flag is included
here just for consistency).""" here just for consistency).
Raises LibError on failure."""
pass pass
@ -531,7 +551,9 @@ class CCompiler:
'extra_preargs' and 'extra_postargs' are as for 'compile()' 'extra_preargs' and 'extra_postargs' are as for 'compile()'
(except of course that they supply command-line arguments (except of course that they supply command-line arguments
for the particular linker being used).""" for the particular linker being used).
Raises LinkError on failure."""
pass pass
@ -552,7 +574,9 @@ class CCompiler:
is explicitly supplied as 'output_filename'. If 'output_dir' is is explicitly supplied as 'output_filename'. If 'output_dir' is
supplied, 'output_filename' is relative to it supplied, 'output_filename' is relative to it
(i.e. 'output_filename' can provide directory components if (i.e. 'output_filename' can provide directory components if
needed).""" needed).
Raises LinkError on failure."""
pass pass
@ -570,7 +594,9 @@ class CCompiler:
file. The "bunch of stuff" is as for 'link_shared_lib()'. file. The "bunch of stuff" is as for 'link_shared_lib()'.
'output_progname' should be the base name of the executable 'output_progname' should be the base name of the executable
program--e.g. on Unix the same as the output filename, but program--e.g. on Unix the same as the output filename, but
on DOS/Windows ".exe" will be appended.""" on DOS/Windows ".exe" will be appended.
Raises LinkError on failure."""
pass pass

View File

@ -14,7 +14,8 @@ import sys, os, string
from types import * from types import *
from distutils.errors import * from distutils.errors import *
from distutils.ccompiler import \ from distutils.ccompiler import \
CCompiler, gen_preprocess_options, gen_lib_options CCompiler, gen_preprocess_options, gen_lib_options, \
CompileError, LibError, LinkError
_can_read_reg = 0 _can_read_reg = 0
@ -261,9 +262,12 @@ class MSVCCompiler (CCompiler) :
output_opt = "/Fo" + obj output_opt = "/Fo" + obj
self.mkpath (os.path.dirname (obj)) self.mkpath (os.path.dirname (obj))
try:
self.spawn ([self.cc] + compile_opts + pp_opts + self.spawn ([self.cc] + compile_opts + pp_opts +
[input_opt, output_opt] + [input_opt, output_opt] +
extra_postargs) extra_postargs)
except DistutilsExecError, msg:
raise CompileError, msg
return objects return objects
@ -290,7 +294,11 @@ class MSVCCompiler (CCompiler) :
lib_args[:0] = extra_preargs lib_args[:0] = extra_preargs
if extra_postargs: if extra_postargs:
lib_args.extend (extra_postargs) lib_args.extend (extra_postargs)
try:
self.spawn ([self.link] + ld_args) self.spawn ([self.link] + ld_args)
except DistutilsExecError, msg:
raise LibError, msg
else: else:
self.announce ("skipping %s (up-to-date)" % output_filename) self.announce ("skipping %s (up-to-date)" % output_filename)
@ -370,7 +378,10 @@ class MSVCCompiler (CCompiler) :
print " output_filename =", output_filename print " output_filename =", output_filename
print " mkpath'ing:", os.path.dirname (output_filename) print " mkpath'ing:", os.path.dirname (output_filename)
self.mkpath (os.path.dirname (output_filename)) self.mkpath (os.path.dirname (output_filename))
try:
self.spawn ([self.link] + ld_args) self.spawn ([self.link] + ld_args)
except DistutilsExecError, msg:
raise LinkError, msg
else: else:
self.announce ("skipping %s (up-to-date)" % output_filename) self.announce ("skipping %s (up-to-date)" % output_filename)
@ -420,7 +431,10 @@ class MSVCCompiler (CCompiler) :
ld_args.extend (extra_postargs) ld_args.extend (extra_postargs)
self.mkpath (os.path.dirname (output_filename)) self.mkpath (os.path.dirname (output_filename))
try:
self.spawn ([self.link] + ld_args) self.spawn ([self.link] + ld_args)
except DistutilsExecError, msg:
raise LinkError, msg
else: else:
self.announce ("skipping %s (up-to-date)" % output_filename) self.announce ("skipping %s (up-to-date)" % output_filename)

View File

@ -21,7 +21,10 @@ import string, re, os
from types import * from types import *
from copy import copy from copy import copy
from distutils import sysconfig from distutils import sysconfig
from distutils.ccompiler import CCompiler, gen_preprocess_options, gen_lib_options from distutils.ccompiler import \
CCompiler, gen_preprocess_options, gen_lib_options, \
CompileError, LibError, LinkError
from distutils.errors import DistutilsExecError
# XXX Things not currently handled: # XXX Things not currently handled:
# * optimization/debug/warning flags; we just use whatever's in Python's # * optimization/debug/warning flags; we just use whatever's in Python's
@ -132,7 +135,12 @@ class UnixCCompiler (CCompiler):
self.announce ("skipping %s (%s up-to-date)" % (src, obj)) self.announce ("skipping %s (%s up-to-date)" % (src, obj))
else: else:
self.mkpath (os.path.dirname (obj)) self.mkpath (os.path.dirname (obj))
self.spawn ([self.cc] + cc_args + [src, '-o', obj] + extra_postargs) try:
self.spawn ([self.cc] + cc_args +
[src, '-o', obj] +
extra_postargs)
except DistutilsExecError, msg:
raise CompileError, msg
# Return *all* object filenames, not just the ones we just built. # Return *all* object filenames, not just the ones we just built.
return objects return objects
@ -164,7 +172,10 @@ class UnixCCompiler (CCompiler):
# needed -- or maybe Python's configure script took care of # needed -- or maybe Python's configure script took care of
# it for us, hence the check for leading colon. # it for us, hence the check for leading colon.
if self.ranlib[0] != ':': if self.ranlib[0] != ':':
try:
self.spawn ([self.ranlib, output_filename]) self.spawn ([self.ranlib, output_filename])
except DistutilsExecError, msg:
raise LibError, msg
else: else:
self.announce ("skipping %s (up-to-date)" % output_filename) self.announce ("skipping %s (up-to-date)" % output_filename)
@ -229,7 +240,10 @@ class UnixCCompiler (CCompiler):
if extra_postargs: if extra_postargs:
ld_args.extend (extra_postargs) ld_args.extend (extra_postargs)
self.mkpath (os.path.dirname (output_filename)) self.mkpath (os.path.dirname (output_filename))
try:
self.spawn ([self.ld_shared] + ld_args) self.spawn ([self.ld_shared] + ld_args)
except DistutilsExecError, msg:
raise LinkError, msg
else: else:
self.announce ("skipping %s (up-to-date)" % output_filename) self.announce ("skipping %s (up-to-date)" % output_filename)
@ -267,7 +281,10 @@ class UnixCCompiler (CCompiler):
if extra_postargs: if extra_postargs:
ld_args.extend (extra_postargs) ld_args.extend (extra_postargs)
self.mkpath (os.path.dirname (output_filename)) self.mkpath (os.path.dirname (output_filename))
try:
self.spawn ([self.ld_exec] + ld_args) self.spawn ([self.ld_exec] + ld_args)
except DistutilsExecError, msg:
raise LinkError, msg
else: else:
self.announce ("skipping %s (up-to-date)" % output_filename) self.announce ("skipping %s (up-to-date)" % output_filename)