Changed to catch compile/link failures and raise CompileError, LibError,
or LinkError (exception classes defined in ccompiler.py).
diff --git a/Lib/distutils/ccompiler.py b/Lib/distutils/ccompiler.py
index 4222176..33caf86 100644
--- a/Lib/distutils/ccompiler.py
+++ b/Lib/distutils/ccompiler.py
@@ -15,6 +15,22 @@
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:
"""Abstract base class to define the interface that must be implemented
by real compiler abstraction classes. Might have some use as a
@@ -456,7 +472,9 @@
command line. On other platforms, consult the implementation
class documentation. In any event, they are intended as an
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
@@ -481,7 +499,9 @@
'debug' is a boolean; if true, debugging information will be
included in the library (note that on most platforms, it is the
compile step where this matters: the 'debug' flag is included
- here just for consistency)."""
+ here just for consistency).
+
+ Raises LibError on failure."""
pass
@@ -531,7 +551,9 @@
'extra_preargs' and 'extra_postargs' are as for 'compile()'
(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
@@ -552,7 +574,9 @@
is explicitly supplied as 'output_filename'. If 'output_dir' is
supplied, 'output_filename' is relative to it
(i.e. 'output_filename' can provide directory components if
- needed)."""
+ needed).
+
+ Raises LinkError on failure."""
pass
@@ -570,7 +594,9 @@
file. The "bunch of stuff" is as for 'link_shared_lib()'.
'output_progname' should be the base name of the executable
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
diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py
index b6ff432..06b415e 100644
--- a/Lib/distutils/msvccompiler.py
+++ b/Lib/distutils/msvccompiler.py
@@ -14,7 +14,8 @@
from types import *
from distutils.errors 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
@@ -261,9 +262,12 @@
output_opt = "/Fo" + obj
self.mkpath (os.path.dirname (obj))
- self.spawn ([self.cc] + compile_opts + pp_opts +
- [input_opt, output_opt] +
- extra_postargs)
+ try:
+ self.spawn ([self.cc] + compile_opts + pp_opts +
+ [input_opt, output_opt] +
+ extra_postargs)
+ except DistutilsExecError, msg:
+ raise CompileError, msg
return objects
@@ -290,7 +294,11 @@
lib_args[:0] = extra_preargs
if extra_postargs:
lib_args.extend (extra_postargs)
- self.spawn ([self.link] + ld_args)
+ try:
+ self.spawn ([self.link] + ld_args)
+ except DistutilsExecError, msg:
+ raise LibError, msg
+
else:
self.announce ("skipping %s (up-to-date)" % output_filename)
@@ -370,7 +378,10 @@
print " output_filename =", output_filename
print " mkpath'ing:", os.path.dirname (output_filename)
self.mkpath (os.path.dirname (output_filename))
- self.spawn ([self.link] + ld_args)
+ try:
+ self.spawn ([self.link] + ld_args)
+ except DistutilsExecError, msg:
+ raise LinkError, msg
else:
self.announce ("skipping %s (up-to-date)" % output_filename)
@@ -420,7 +431,10 @@
ld_args.extend (extra_postargs)
self.mkpath (os.path.dirname (output_filename))
- self.spawn ([self.link] + ld_args)
+ try:
+ self.spawn ([self.link] + ld_args)
+ except DistutilsExecError, msg:
+ raise LinkError, msg
else:
self.announce ("skipping %s (up-to-date)" % output_filename)
diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py
index 40f564a..c2f841f 100644
--- a/Lib/distutils/unixccompiler.py
+++ b/Lib/distutils/unixccompiler.py
@@ -21,7 +21,10 @@
from types import *
from copy import copy
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:
# * optimization/debug/warning flags; we just use whatever's in Python's
@@ -132,7 +135,12 @@
self.announce ("skipping %s (%s up-to-date)" % (src, obj))
else:
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 objects
@@ -164,7 +172,10 @@
# needed -- or maybe Python's configure script took care of
# it for us, hence the check for leading colon.
if self.ranlib[0] != ':':
- self.spawn ([self.ranlib, output_filename])
+ try:
+ self.spawn ([self.ranlib, output_filename])
+ except DistutilsExecError, msg:
+ raise LibError, msg
else:
self.announce ("skipping %s (up-to-date)" % output_filename)
@@ -229,7 +240,10 @@
if extra_postargs:
ld_args.extend (extra_postargs)
self.mkpath (os.path.dirname (output_filename))
- self.spawn ([self.ld_shared] + ld_args)
+ try:
+ self.spawn ([self.ld_shared] + ld_args)
+ except DistutilsExecError, msg:
+ raise LinkError, msg
else:
self.announce ("skipping %s (up-to-date)" % output_filename)
@@ -267,7 +281,10 @@
if extra_postargs:
ld_args.extend (extra_postargs)
self.mkpath (os.path.dirname (output_filename))
- self.spawn ([self.ld_exec] + ld_args)
+ try:
+ self.spawn ([self.ld_exec] + ld_args)
+ except DistutilsExecError, msg:
+ raise LinkError, msg
else:
self.announce ("skipping %s (up-to-date)" % output_filename)