import os
import sys # FIXME: Shouldn't be needed.
import Arguments
import Jobs
import Phases
import Types
class Tool(object):
"""Tool - A concrete implementation of an action."""
eFlagsPipedInput = 1 << 0
eFlagsPipedOutput = 1 << 1
eFlagsIntegratedCPP = 1 << 2
def __init__(self, name, flags = 0):
self.name = name
self.flags = flags
def acceptsPipedInput(self):
return not not (self.flags & Tool.eFlagsPipedInput)
def canPipeOutput(self):
return not not (self.flags & Tool.eFlagsPipedOutput)
def hasIntegratedCPP(self):
return not not (self.flags & Tool.eFlagsIntegratedCPP)
class GCC_Common_Tool(Tool):
def getGCCExtraArgs(self):
return []
def constructJob(self, phase, arch, jobs, inputs,
output, outputType, arglist, linkingOutput):
cmd_args = []
for arg in arglist.args:
if arg.opt.forwardToGCC():
cmd_args.extend(arglist.render(arg))
cmd_args.extend(self.getGCCExtraArgs())
if arch:
cmd_args.extend(arglist.render(arch))
if isinstance(output, Jobs.PipedJob):
cmd_args.extend(['-o', '-'])
elif isinstance(phase.phase, Phases.SyntaxOnlyPhase):
cmd_args.append('-fsyntax-only')
else:
assert output
cmd_args.extend(arglist.render(output))
if (isinstance(self, GCC_LinkTool) and
linkingOutput):
cmd_args.append('-Wl,-arch_multiple')
cmd_args.append('-Wl,-final_output,' +
arglist.getValue(linkingOutput))
# Only pass -x if gcc will understand it; otherwise hope gcc
# understands the suffix correctly. The main use case this
# would go wrong in is for linker inputs if they happened to
# have an odd suffix; really the only way to get this to
# happen is a command like '-x foobar a.c' which will treat
# a.c like a linker input.
#
# FIXME: For the linker case specifically, can we safely
# convert inputs into '-Wl,' options?
for input in inputs:
if input.type.canBeUserSpecified:
cmd_args.extend(['-x', input.type.name])
if isinstance(input.source, Jobs.PipedJob):
cmd_args.append('-')
else:
assert isinstance(input.source, Arguments.Arg)
# If this is a linker input then assume we can forward
# just by rendering.
if input.source.opt.isLinkerInput:
cmd_args.extend(arglist.render(input.source))
else:
cmd_args.extend(arglist.renderAsInput(input.source))
jobs.addJob(Jobs.Command('gcc', cmd_args))
class GCC_PreprocessTool(GCC_Common_Tool):
def __init__(self):
super(GCC_PreprocessTool, self).__init__('gcc (cpp)',
(Tool.eFlagsPipedInput |
Tool.eFlagsPipedOutput))
def getGCCExtraArgs(self):
return ['-E']
class GCC_CompileTool(GCC_Common_Tool):
def __init__(self):
super(GCC_CompileTool, self).__init__('gcc (cc1)',
(Tool.eFlagsPipedInput |
Tool.eFlagsPipedOutput |
Tool.eFlagsIntegratedCPP))
def getGCCExtraArgs(self):
return ['-S']
class GCC_PrecompileTool(GCC_Common_Tool):
def __init__(self):
super(GCC_PrecompileTool, self).__init__('gcc (pch)',
(Tool.eFlagsPipedInput |
Tool.eFlagsIntegratedCPP))
def getGCCExtraArgs(self):
return []
class GCC_AssembleTool(GCC_Common_Tool):
def __init__(self):
# We can't generally assume the assembler can take or output
# on pipes.