From d151711e66d1077669025b3fda5616bf31935538 Mon Sep 17 00:00:00 2001 From: Greg Ward Date: Tue, 30 May 2000 01:56:44 +0000 Subject: [PATCH] Changed to catch compile/link failures and raise CompileError, LibError, or LinkError (exception classes defined in ccompiler.py). --- Lib/distutils/ccompiler.py | 36 +++++++++++++++++++++++++++++----- Lib/distutils/msvccompiler.py | 28 +++++++++++++++++++------- Lib/distutils/unixccompiler.py | 27 ++++++++++++++++++++----- 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/Lib/distutils/ccompiler.py b/Lib/distutils/ccompiler.py index 42221769e68..33caf86830c 100644 --- a/Lib/distutils/ccompiler.py +++ b/Lib/distutils/ccompiler.py @@ -15,6 +15,22 @@ from distutils.spawn import spawn 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 @@ class CCompiler: 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 @@ class CCompiler: '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 @@ class CCompiler: '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 @@ class CCompiler: 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 @@ class CCompiler: 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 b6ff432ce34..06b415ebde0 100644 --- a/Lib/distutils/msvccompiler.py +++ b/Lib/distutils/msvccompiler.py @@ -14,7 +14,8 @@ import sys, os, string 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 @@ class MSVCCompiler (CCompiler) : 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 @@ class MSVCCompiler (CCompiler) : 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 @@ class MSVCCompiler (CCompiler) : 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 @@ class MSVCCompiler (CCompiler) : 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 40f564ab885..c2f841ff67d 100644 --- a/Lib/distutils/unixccompiler.py +++ b/Lib/distutils/unixccompiler.py @@ -21,7 +21,10 @@ import string, re, os 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 @@ class UnixCCompiler (CCompiler): 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 @@ class UnixCCompiler (CCompiler): # 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 @@ class UnixCCompiler (CCompiler): 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 @@ class UnixCCompiler (CCompiler): 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)