ccc: Support arguments which behave like linker inputs.
- Support comma joined options which magically turn into multiple value arguments (e.g., -Wl,) - Split out separate Arg::render routine for when an argument is being rendered as an input (as opposed to in its original form). - Add option flag for options which should be rendered without the option when they are used as an input (e.g., -Xlinker or -o). - Support -weak-l..., -weak_framework, and -weak_library. llvm-svn: 62075
This commit is contained in:
parent
b2c42c648d
commit
02cd7e4070
|
|
@ -1,7 +1,10 @@
|
||||||
class Option(object):
|
class Option(object):
|
||||||
"""Root option class."""
|
"""Root option class."""
|
||||||
def __init__(self, name):
|
|
||||||
|
def __init__(self, name, isLinkerInput=False, noOptAsInput=False):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.isLinkerInput = isLinkerInput
|
||||||
|
self.noOptAsInput = noOptAsInput
|
||||||
|
|
||||||
def accept(self, index, arg, it):
|
def accept(self, index, arg, it):
|
||||||
"""accept(index, arg, iterator) -> Arg or None
|
"""accept(index, arg, iterator) -> Arg or None
|
||||||
|
|
@ -49,6 +52,15 @@ class JoinedOption(Option):
|
||||||
if arg.startswith(self.name):
|
if arg.startswith(self.name):
|
||||||
return JoinedValueArg(index, self)
|
return JoinedValueArg(index, self)
|
||||||
|
|
||||||
|
class CommaJoinedOption(Option):
|
||||||
|
"""An option which literally prefixs its argument, but which
|
||||||
|
conceptually may have an arbitrary number of arguments which are
|
||||||
|
separated by commas."""
|
||||||
|
|
||||||
|
def accept(self, index, arg, it):
|
||||||
|
if arg.startswith(self.name):
|
||||||
|
return CommaJoinedValuesArg(index, self)
|
||||||
|
|
||||||
class SeparateOption(Option):
|
class SeparateOption(Option):
|
||||||
"""An option which is followed by its value."""
|
"""An option which is followed by its value."""
|
||||||
|
|
||||||
|
|
@ -111,7 +123,7 @@ class Arg(object):
|
||||||
assert opt is not None
|
assert opt is not None
|
||||||
self.index = index
|
self.index = index
|
||||||
self.opt = opt
|
self.opt = opt
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s index=%r opt=%r>' % (self.__class__.__name__,
|
return '<%s index=%r opt=%r>' % (self.__class__.__name__,
|
||||||
self.index,
|
self.index,
|
||||||
|
|
@ -125,6 +137,9 @@ class Arg(object):
|
||||||
assert self.opt
|
assert self.opt
|
||||||
return [self.opt.name]
|
return [self.opt.name]
|
||||||
|
|
||||||
|
def renderAsInput(self, args):
|
||||||
|
return self.render(args)
|
||||||
|
|
||||||
class ValueArg(Arg):
|
class ValueArg(Arg):
|
||||||
"""ValueArg - An instance of an option which has an argument."""
|
"""ValueArg - An instance of an option which has an argument."""
|
||||||
|
|
||||||
|
|
@ -150,6 +165,11 @@ class JoinedValueArg(ValueArg):
|
||||||
def render(self, args):
|
def render(self, args):
|
||||||
return [self.opt.name + self.getValue(args)]
|
return [self.opt.name + self.getValue(args)]
|
||||||
|
|
||||||
|
def renderAsInput(self, args):
|
||||||
|
if self.opt.noOptAsInput:
|
||||||
|
return [self.getValue(args)]
|
||||||
|
return self.render(args)
|
||||||
|
|
||||||
class SeparateValueArg(ValueArg):
|
class SeparateValueArg(ValueArg):
|
||||||
"""SeparateValueArg - A single value argument where the value
|
"""SeparateValueArg - A single value argument where the value
|
||||||
follows the option in the argument vector."""
|
follows the option in the argument vector."""
|
||||||
|
|
@ -160,6 +180,11 @@ class SeparateValueArg(ValueArg):
|
||||||
def render(self, args):
|
def render(self, args):
|
||||||
return [self.opt.name, self.getValue(args)]
|
return [self.opt.name, self.getValue(args)]
|
||||||
|
|
||||||
|
def renderAsInput(self, args):
|
||||||
|
if self.opt.noOptAsInput:
|
||||||
|
return [self.getValue(args)]
|
||||||
|
return self.render(args)
|
||||||
|
|
||||||
class MultipleValuesArg(Arg):
|
class MultipleValuesArg(Arg):
|
||||||
"""MultipleValuesArg - An argument with multiple values which
|
"""MultipleValuesArg - An argument with multiple values which
|
||||||
follow the option in the argument vector."""
|
follow the option in the argument vector."""
|
||||||
|
|
@ -173,6 +198,23 @@ class MultipleValuesArg(Arg):
|
||||||
def render(self, args):
|
def render(self, args):
|
||||||
return [self.opt.name] + self.getValues(args)
|
return [self.opt.name] + self.getValues(args)
|
||||||
|
|
||||||
|
class CommaJoinedValuesArg(Arg):
|
||||||
|
"""CommaJoinedValuesArg - An argument with multiple values joined
|
||||||
|
by commas and joined (suffixed) to the option.
|
||||||
|
|
||||||
|
The key point of this arg is that it renders its values into
|
||||||
|
separate arguments, which allows it to be used as a generic
|
||||||
|
mechanism for passing arguments through to tools."""
|
||||||
|
|
||||||
|
def getValues(self, args):
|
||||||
|
return args.getInputString(self.index)[len(self.opt.name):].split(',')
|
||||||
|
|
||||||
|
def render(self, args):
|
||||||
|
return [self.opt.name + ','.join(self.getValues(args))]
|
||||||
|
|
||||||
|
def renderAsInput(self, args):
|
||||||
|
return self.getValues(args)
|
||||||
|
|
||||||
# FIXME: Man, this is lame. It is only used by -Xarch. Maybe easier to
|
# FIXME: Man, this is lame. It is only used by -Xarch. Maybe easier to
|
||||||
# just special case?
|
# just special case?
|
||||||
class JoinedAndSeparateValuesArg(Arg):
|
class JoinedAndSeparateValuesArg(Arg):
|
||||||
|
|
@ -299,6 +341,9 @@ class ArgList:
|
||||||
def render(self, arg):
|
def render(self, arg):
|
||||||
return arg.render(self)
|
return arg.render(self)
|
||||||
|
|
||||||
|
def renderAsInput(self, arg):
|
||||||
|
return arg.renderAsInput(self)
|
||||||
|
|
||||||
def getValue(self, arg):
|
def getValue(self, arg):
|
||||||
return arg.getValue(self)
|
return arg.getValue(self)
|
||||||
|
|
||||||
|
|
@ -367,7 +412,7 @@ class OptionParser:
|
||||||
self.addOption(FlagOption('-v'))
|
self.addOption(FlagOption('-v'))
|
||||||
|
|
||||||
# Input/output stuff
|
# Input/output stuff
|
||||||
self.oOption = self.addOption(JoinedOrSeparateOption('-o'))
|
self.oOption = self.addOption(JoinedOrSeparateOption('-o', noOptAsInput=True))
|
||||||
self.xOption = self.addOption(JoinedOrSeparateOption('-x'))
|
self.xOption = self.addOption(JoinedOrSeparateOption('-x'))
|
||||||
|
|
||||||
self.ObjCOption = self.addOption(FlagOption('-ObjC'))
|
self.ObjCOption = self.addOption(FlagOption('-ObjC'))
|
||||||
|
|
@ -385,14 +430,14 @@ class OptionParser:
|
||||||
|
|
||||||
# Blanket pass-through options.
|
# Blanket pass-through options.
|
||||||
|
|
||||||
self.addOption(JoinedOption('-Wa,'))
|
self.addOption(CommaJoinedOption('-Wa,'))
|
||||||
self.addOption(SeparateOption('-Xassembler'))
|
self.addOption(SeparateOption('-Xassembler'))
|
||||||
|
|
||||||
self.addOption(JoinedOption('-Wp,'))
|
self.addOption(CommaJoinedOption('-Wp,'))
|
||||||
self.addOption(SeparateOption('-Xpreprocessor'))
|
self.addOption(SeparateOption('-Xpreprocessor'))
|
||||||
|
|
||||||
self.addOption(JoinedOption('-Wl,'))
|
self.addOption(CommaJoinedOption('-Wl,', isLinkerInput=True))
|
||||||
self.addOption(SeparateOption('-Xlinker'))
|
self.addOption(SeparateOption('-Xlinker', isLinkerInput=True, noOptAsInput=True))
|
||||||
|
|
||||||
####
|
####
|
||||||
# Bring on the random garbage.
|
# Bring on the random garbage.
|
||||||
|
|
@ -456,6 +501,9 @@ class OptionParser:
|
||||||
self.addOption(FlagOption('-traditional'))
|
self.addOption(FlagOption('-traditional'))
|
||||||
self.addOption(FlagOption('--traditional'))
|
self.addOption(FlagOption('--traditional'))
|
||||||
self.addOption(FlagOption('-no_dead_strip_inits_and_terms'))
|
self.addOption(FlagOption('-no_dead_strip_inits_and_terms'))
|
||||||
|
self.addOption(JoinedOption('-weak-l', isLinkerInput=True))
|
||||||
|
self.addOption(SeparateOption('-weak_framework', isLinkerInput=True))
|
||||||
|
self.addOption(SeparateOption('-weak_library', isLinkerInput=True))
|
||||||
self.whyloadOption = self.addOption(FlagOption('-whyload'))
|
self.whyloadOption = self.addOption(FlagOption('-whyload'))
|
||||||
self.whatsloadedOption = self.addOption(FlagOption('-whatsloaded'))
|
self.whatsloadedOption = self.addOption(FlagOption('-whatsloaded'))
|
||||||
self.sectalignOption = self.addOption(MultiArgOption('-sectalign', numArgs=3))
|
self.sectalignOption = self.addOption(MultiArgOption('-sectalign', numArgs=3))
|
||||||
|
|
@ -496,10 +544,8 @@ class OptionParser:
|
||||||
self.Zunexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zunexported_symbols_list'))
|
self.Zunexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zunexported_symbols_list'))
|
||||||
self.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches'))
|
self.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches'))
|
||||||
|
|
||||||
# I dunno why these don't end up working when joined. Maybe
|
self.addOption(SeparateOption('-filelist', isLinkerInput=True))
|
||||||
# because of translation?
|
self.addOption(SeparateOption('-framework', isLinkerInput=True))
|
||||||
self.filelistOption = self.addOption(SeparateOption('-filelist'))
|
|
||||||
self.addOption(SeparateOption('-framework'))
|
|
||||||
# FIXME: Alias.
|
# FIXME: Alias.
|
||||||
self.addOption(SeparateOption('-install_name'))
|
self.addOption(SeparateOption('-install_name'))
|
||||||
self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name'))
|
self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name'))
|
||||||
|
|
@ -532,7 +578,7 @@ class OptionParser:
|
||||||
self.addOption(JoinedOrSeparateOption('-U'))
|
self.addOption(JoinedOrSeparateOption('-U'))
|
||||||
self.ZOption = self.addOption(JoinedOrSeparateOption('-Z'))
|
self.ZOption = self.addOption(JoinedOrSeparateOption('-Z'))
|
||||||
|
|
||||||
self.addOption(JoinedOrSeparateOption('-l'))
|
self.addOption(JoinedOrSeparateOption('-l', isLinkerInput=True))
|
||||||
self.uOption = self.addOption(JoinedOrSeparateOption('-u'))
|
self.uOption = self.addOption(JoinedOrSeparateOption('-u'))
|
||||||
self.tOption = self.addOption(JoinedOrSeparateOption('-t'))
|
self.tOption = self.addOption(JoinedOrSeparateOption('-t'))
|
||||||
self.yOption = self.addOption(JoinedOption('-y'))
|
self.yOption = self.addOption(JoinedOption('-y'))
|
||||||
|
|
|
||||||
|
|
@ -299,9 +299,8 @@ class Driver(object):
|
||||||
self.claim(inputTypeOpt)
|
self.claim(inputTypeOpt)
|
||||||
klass = inputType
|
klass = inputType
|
||||||
inputs.append((klass, a))
|
inputs.append((klass, a))
|
||||||
elif a.opt is self.parser.filelistOption:
|
elif a.opt.isLinkerInput:
|
||||||
# Treat as a linker input. Investigate how gcc is
|
# Treat as a linker input.
|
||||||
# handling this.
|
|
||||||
#
|
#
|
||||||
# FIXME: This might not be good enough. We may
|
# FIXME: This might not be good enough. We may
|
||||||
# need to introduce another type for this case, so
|
# need to introduce another type for this case, so
|
||||||
|
|
@ -528,15 +527,21 @@ class Driver(object):
|
||||||
args.getLastArg(self.parser.saveTempsOption2))
|
args.getLastArg(self.parser.saveTempsOption2))
|
||||||
hasNoIntegratedCPP = args.getLastArg(self.parser.noIntegratedCPPOption)
|
hasNoIntegratedCPP = args.getLastArg(self.parser.noIntegratedCPPOption)
|
||||||
hasPipe = args.getLastArg(self.parser.pipeOption)
|
hasPipe = args.getLastArg(self.parser.pipeOption)
|
||||||
|
|
||||||
|
# FIXME: forward will die, this isn't really how things are
|
||||||
|
# done, instead everything comes from the arglist. For this we
|
||||||
|
# need a DerivedArgList for handling -Xarch, and some way to
|
||||||
|
# still figure out what to forward to the generic gcc tool.
|
||||||
forward = []
|
forward = []
|
||||||
for a in args:
|
for a in args:
|
||||||
if a.opt is self.parser.inputOption:
|
if a.opt is self.parser.inputOption:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# FIXME: Needs to be part of option.
|
# FIXME: Needs to be part of option.
|
||||||
elif a.opt.name in ('-E', '-S', '-c',
|
elif (a.opt.name in ('-E', '-S', '-c',
|
||||||
'-arch', '-fsyntax-only', '-combine', '-x',
|
'-arch', '-fsyntax-only', '-combine', '-x',
|
||||||
'-###'):
|
'-###') or
|
||||||
|
a.opt.isLinkerInput):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
@ -648,10 +653,10 @@ class Driver(object):
|
||||||
#
|
#
|
||||||
# FIXME: gcc has some special case in here so that it doesn't
|
# FIXME: gcc has some special case in here so that it doesn't
|
||||||
# create output files if they would conflict with an input.
|
# create output files if they would conflict with an input.
|
||||||
inputName = args.getValue(baseInput)
|
|
||||||
if phase.type is Types.ImageType:
|
if phase.type is Types.ImageType:
|
||||||
namedOutput = "a.out"
|
namedOutput = "a.out"
|
||||||
else:
|
else:
|
||||||
|
inputName = args.getValue(baseInput)
|
||||||
base,_ = os.path.splitext(inputName)
|
base,_ = os.path.splitext(inputName)
|
||||||
assert phase.type.tempSuffix is not None
|
assert phase.type.tempSuffix is not None
|
||||||
namedOutput = base + '.' + phase.type.tempSuffix
|
namedOutput = base + '.' + phase.type.tempSuffix
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,13 @@ class GCC_Common_Tool(Tool):
|
||||||
if isinstance(input.source, Jobs.PipedJob):
|
if isinstance(input.source, Jobs.PipedJob):
|
||||||
cmd_args.append('-')
|
cmd_args.append('-')
|
||||||
else:
|
else:
|
||||||
cmd_args.append(arglist.getValue(input.source))
|
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))
|
jobs.addJob(Jobs.Command('gcc', cmd_args))
|
||||||
|
|
||||||
|
|
@ -113,7 +119,7 @@ class DarwinAssembleTool(Tool):
|
||||||
if isinstance(input.source, Jobs.PipedJob):
|
if isinstance(input.source, Jobs.PipedJob):
|
||||||
cmd_args.append('-')
|
cmd_args.append('-')
|
||||||
else:
|
else:
|
||||||
cmd_args.append(arglist.getValue(input.source))
|
cmd_args.extend(arglist.renderAsInput(input.source))
|
||||||
jobs.addJob(Jobs.Command('as', cmd_args))
|
jobs.addJob(Jobs.Command('as', cmd_args))
|
||||||
|
|
||||||
class GCC_AssembleTool(GCC_Common_Tool):
|
class GCC_AssembleTool(GCC_Common_Tool):
|
||||||
|
|
@ -471,7 +477,7 @@ class Darwin10_X86_LinkTool(Tool):
|
||||||
"-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.."])
|
"-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.."])
|
||||||
|
|
||||||
for input in inputs:
|
for input in inputs:
|
||||||
cmd_args.append(arglist.getValue(input.source))
|
cmd_args.extend(arglist.renderAsInput(input.source))
|
||||||
|
|
||||||
if (arglist.getLastArg(arglist.parser.f_profileArcsOption) or
|
if (arglist.getLastArg(arglist.parser.f_profileArcsOption) or
|
||||||
arglist.getLastArg(arglist.parser.f_profileGenerateOption) or
|
arglist.getLastArg(arglist.parser.f_profileGenerateOption) or
|
||||||
|
|
@ -548,5 +554,5 @@ class LipoTool(Tool):
|
||||||
cmd_args = ['-create']
|
cmd_args = ['-create']
|
||||||
cmd_args.extend(arglist.render(output))
|
cmd_args.extend(arglist.render(output))
|
||||||
for input in inputs:
|
for input in inputs:
|
||||||
cmd_args.append(arglist.getValue(input.source))
|
cmd_args.extend(arglist.renderAsInput(input.source))
|
||||||
jobs.addJob(Jobs.Command('lipo', cmd_args))
|
jobs.addJob(Jobs.Command('lipo', cmd_args))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue