def compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): ''' Enable parallel and incremental build. To do a clean build, please remove the "build" directory. ''' if os.getenv('DEBUG', ''): debug = 1 macros, objects, extra_postargs, pp_opts, build = self._setup_compile( output_dir, macros, include_dirs, sources, depends, extra_postargs) cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) compiler_so = self.compiler_so compiler_so_cxx = self.compiler_so_cxx if sys.platform == 'darwin' and _osx_support is not None: compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) compiler_so_cxx = _osx_support.compiler_fixup(compiler_so_cxx, cc_args + extra_postargs) def _single_compile(obj): try: src, ext = build[obj] except KeyError: return try: if not self.force and \ os.path.getmtime(obj) > \ os.path.getmtime(src): return except OSError: pass # _compile compiler = compiler_so_cxx \ if self.detect_language(src) == 'c++' \ else compiler_so try: self.spawn(compiler + cc_args + [src, '-o', obj] + extra_postargs) except distutils.errors.DistutilsExecError as msg: raise distutils.errors.CompileError(msg) for _ in pmap(_single_compile, objects): pass return objects
def compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): ''' Enable parallel and incremental build. To do a clean build, please remove the "build" directory. ''' macros, objects, extra_postargs, pp_opts, build = self._setup_compile( output_dir, macros, include_dirs, sources, depends, extra_postargs) cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) compiler_so = self.compiler_so compiler_so_cxx = self.compiler_so_cxx # strips non-existing -isysroot strip_broken_isysroot(compiler_so) strip_broken_isysroot(compiler_so_cxx) if sys.platform == 'darwin' and _osx_support is not None: # strips duplicated -isysroot compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) compiler_so_cxx = _osx_support.compiler_fixup(compiler_so_cxx, cc_args + extra_postargs) # generate dependency (.d) file cc_args.append('-MMD') def _single_compile(obj): src = build[obj][0] # _compile compiler = compiler_so_cxx \ if self.detect_language(src) == 'c++' \ else compiler_so try: self.spawn(compiler + cc_args + [src, '-o', obj] + extra_postargs) except distutils.errors.DistutilsExecError as msg: raise distutils.errors.CompileError(msg) incremental_parallel_compile(_single_compile, objects, self.force) return objects
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = \ self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def fixup_compiler(self, compiler_so, cc_args): if ismacos(): import _osx_support compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args) for token in ["-Wstrict-prototypes", "-O2"]: if token in compiler_so: del compiler_so[compiler_so.index(token)] return compiler_so
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so compiler_so_cxx = self.compiler_so_cxx if sys.platform == 'darwin': compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) compiler_so_cxx = _osx_support.compiler_fixup(compiler_so_cxx, cc_args + extra_postargs) try: if self.detect_language(src) == 'c++': self.spawn(compiler_so_cxx + cc_args + [src, '-o', obj] + extra_postargs) else: self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg)
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so if sys.platform == 'darwin': compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) try: self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError, msg
def link( self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ): objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = self._fix_lib_args( libraries, library_dirs, runtime_library_dirs ) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = objects + self.objects + lib_opts + ["-o", output_filename] if debug: ld_args[:0] = ["-g"] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: i = 0 if os.path.basename(linker[0]) == "env": i = 1 while "=" in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == "darwin": linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError, msg else: log.debug("skipping %s (up-to-date)", output_filename) return
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = self._fix_lib_args( libraries, library_dirs, runtime_library_dirs) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = objects + self.objects + lib_opts + [ '-o', output_filename ] if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == 'c++' and self.compiler_cxx: i = 0 if os.path.basename(linker[0]) == 'env': i = 1 while '=' in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError, msg else: log.debug('skipping %s (up-to-date)', output_filename) return
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = \ self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) # filter out standard library paths, which are not explicitely needed # for linking library_dirs = [dir for dir in library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] runtime_library_dirs = [dir for dir in runtime_library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i += 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) ld_args = ['-arch', 'x86_64'] + ld_args self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so if sys.platform == 'darwin': compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) try: raise DistutilsPlatformError( "clang not available on iOS for ", compiler_so + cc_args + [src, '-o', obj] + extra_postargs) # self.spawn(compiler_so + cc_args + [src, '-o', obj] + # extra_postargs) except DistutilsExecError as msg: raise CompileError(msg)
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so if sys.platform == 'darwin': compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) try: # @@JYM putting the -o obj before src for mvs # support , this should not hurt other unix c # compiler's implementations self.spawn(compiler_so + cc_args + ['-o', obj, src] + extra_postargs) except DistutilsExecError, msg: raise CompileError, msg
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so if sys.platform == 'darwin': compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) try: # iOS: since clang is not available, we send a nicer error message: if (sys.platform == 'darwin' and os.uname().machine.startswith('iP')): raise DistutilsExecError("There are no compilers available on iOS, sorry. Command was: ", cc_args) # self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_lang == "c++": if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe_cxx[:] else: linker = self.linker_so_cxx[:] else: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): ''' Enable parallel and incremental build. To do a clean build, please remove the "build" directory. ''' macros, objects, extra_postargs, pp_opts, build = self._setup_compile( output_dir, macros, include_dirs, sources, depends, extra_postargs) cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) compiler_so = self.compiler_so compiler_so_cxx = self.compiler_so_cxx if sys.platform == 'darwin' and _osx_support is not None: compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) compiler_so_cxx = _osx_support.compiler_fixup(compiler_so_cxx, cc_args + extra_postargs) mtimes = {} def need_compile(obj): try: src, ext = build[obj] except KeyError: return False if self.force: return True try: # parse .d file if it exists (Makefile syntax) deps = [] with open(os.path.splitext(obj)[0] + '.d') as handle: contents = handle.read().split(': ', 1)[-1] for line in contents.splitlines(): deps.extend(line.rstrip('\n\r\\').split()) except EnvironmentError: # no .d file, consider src the only dependency deps = [src] try: obj_mtime = os.path.getmtime(obj) for dep in deps: if dep not in mtimes: mtimes[dep] = os.path.getmtime(dep) if obj_mtime < mtimes[dep]: return True except OSError: return True return False def _single_compile(obj): src = build[obj][0] # _compile compiler = compiler_so_cxx \ if self.detect_language(src) == 'c++' \ else compiler_so try: self.spawn(compiler + cc_args + [src, '-o', obj] + extra_postargs) except distutils.errors.DistutilsExecError as msg: raise distutils.errors.CompileError(msg) for _ in pmap(_single_compile, filter(need_compile, objects)): pass return objects
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable Settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # Settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i += 1 if os.path.basename(linker[i]) == 'ld_so_aix': # AIX platforms prefix the compiler with the ld_so_aix # script, so we need to adjust our linker index offset = 1 else: offset = 0 linker[i+offset] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def update_event(self, inp=-1): self.set_output_val( 0, _osx_support.compiler_fixup(self.input(0), self.input(1)))
def _unix_piecemeal_link( self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ): """`link` externalized method taken almost verbatim from UnixCCompiler. Modifies the link command for unix-like compilers by using a command file so that long command line argument strings don't break the command shell's ARG_MAX character limit. """ objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) # filter out standard library paths, which are not explicitely needed # for linking library_dirs = [dir for dir in library_dirs if not dir in ("/lib", "/lib64", "/usr/lib", "/usr/lib64")] runtime_library_dirs = [ dir for dir in runtime_library_dirs if not dir in ("/lib", "/lib64", "/usr/lib", "/usr/lib64") ] lib_opts = ccompiler.gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not (isinstance(output_dir, str) or isinstance(output_dir, bytes)) and output_dir is not None: raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = objects + self.objects + lib_opts + ["-o", output_filename] if debug: ld_args[:0] = ["-g"] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == ccompiler.CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while "=" in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == "darwin": import _osx_support linker = _osx_support.compiler_fixup(linker, ld_args) temporary_directory = tempfile.mkdtemp() command_filename = os.path.abspath(os.path.join(temporary_directory, "command")) with open(command_filename, "w") as command_file: escaped_ld_args = [arg.replace("\\", "\\\\") for arg in ld_args] command_file.write(" ".join(escaped_ld_args)) self.spawn(linker + ["@{}".format(command_filename)]) except errors.DistutilsExecError: raise ccompiler.LinkError else: log.debug("skipping %s (up-to-date)", output_filename)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args # filter out standard library paths, which are not explicitely needed # for linking system_libdirs = ['/lib', '/lib64', '/usr/lib', '/usr/lib64'] multiarch = sysconfig.get_config_var("MULTIARCH") if multiarch: system_libdirs.extend(['/lib/%s' % multiarch, '/usr/lib/%s' % multiarch]) library_dirs = [dir for dir in library_dirs if not dir in system_libdirs] runtime_library_dirs = [dir for dir in runtime_library_dirs if not dir in system_libdirs] # filter out standard library paths, which are not explicitely needed # for linking library_dirs = [dir for dir in library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] runtime_library_dirs = [dir for dir in runtime_library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i += 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)