ninja: Specifically implement gcc rspfile style quoting

This differs from sh-quoting in that a backslash *always* escapes the
following character, even inside single quotes.  Yes, really.

https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libiberty/argv.c#l176
This commit is contained in:
Jon Turney 2019-05-02 14:11:42 +01:00 committed by Dan Kegel
parent aca93df184
commit abf8bf488e
1 changed files with 18 additions and 8 deletions

View File

@ -65,6 +65,16 @@ def cmd_quote(s):
return s return s
def gcc_rsp_quote(s):
# see: the function buildargv() in libiberty
#
# this differs from sh-quoting in that a backslash *always* escapes the
# following character, even inside single quotes.
s = s.replace('\\', '\\\\')
return shlex.quote(s)
# How ninja executes command lines differs between Unix and Windows # How ninja executes command lines differs between Unix and Windows
# (see https://ninja-build.org/manual.html#ref_rule_command) # (see https://ninja-build.org/manual.html#ref_rule_command)
if mesonlib.is_windows(): if mesonlib.is_windows():
@ -134,7 +144,7 @@ class NinjaComment:
class NinjaRule: class NinjaRule:
def __init__(self, rule, command, args, description, def __init__(self, rule, command, args, description,
rspable = False, deps = None, depfile = None, extra = None, rspable = False, deps = None, depfile = None, extra = None,
rspfile_quote_style = 'sh'): rspfile_quote_style = 'gcc'):
def strToCommandArg(c): def strToCommandArg(c):
if isinstance(c, NinjaCommandArg): if isinstance(c, NinjaCommandArg):
@ -168,7 +178,7 @@ class NinjaRule:
self.rspable = rspable # if a rspfile can be used self.rspable = rspable # if a rspfile can be used
self.refcount = 0 self.refcount = 0
self.rsprefcount = 0 self.rsprefcount = 0
self.rspfile_quote_style = rspfile_quote_style # rspfile quoting style is 'sh' or 'cl' self.rspfile_quote_style = rspfile_quote_style # rspfile quoting style is 'gcc' or 'cl'
@staticmethod @staticmethod
def _quoter(x, qf = quote_func): def _quoter(x, qf = quote_func):
@ -186,7 +196,7 @@ class NinjaRule:
if self.rspfile_quote_style == 'cl': if self.rspfile_quote_style == 'cl':
rspfile_quote_func = cmd_quote rspfile_quote_func = cmd_quote
else: else:
rspfile_quote_func = shlex.quote rspfile_quote_func = gcc_rsp_quote
def rule_iter(): def rule_iter():
if self.refcount: if self.refcount:
@ -334,7 +344,7 @@ class NinjaBuildElement:
if self.rule.rspfile_quote_style == 'cl': if self.rule.rspfile_quote_style == 'cl':
qf = cmd_quote qf = cmd_quote
else: else:
qf = shlex.quote qf = gcc_rsp_quote
else: else:
qf = quote_func qf = quote_func
@ -1725,7 +1735,7 @@ int dummy;
pool = None pool = None
self.add_rule(NinjaRule(rule, cmdlist, args, description, self.add_rule(NinjaRule(rule, cmdlist, args, description,
rspable=static_linker.can_linker_accept_rsp(), rspable=static_linker.can_linker_accept_rsp(),
rspfile_quote_style='cl' if isinstance(static_linker, VisualStudioLinker) else 'sh', rspfile_quote_style='cl' if isinstance(static_linker, VisualStudioLinker) else 'gcc',
extra=pool)) extra=pool))
def generate_dynamic_link_rules(self): def generate_dynamic_link_rules(self):
@ -1749,7 +1759,7 @@ int dummy;
self.add_rule(NinjaRule(rule, command, args, description, self.add_rule(NinjaRule(rule, command, args, description,
rspable=compiler.can_linker_accept_rsp(), rspable=compiler.can_linker_accept_rsp(),
rspfile_quote_style='cl' if (compiler.get_argument_syntax() == 'msvc' or rspfile_quote_style='cl' if (compiler.get_argument_syntax() == 'msvc' or
isinstance(compiler, DmdDCompiler)) else 'sh', isinstance(compiler, DmdDCompiler)) else 'gcc',
extra=pool)) extra=pool))
args = self.environment.get_build_command() + \ args = self.environment.get_build_command() + \
@ -1778,7 +1788,7 @@ int dummy;
description = 'Compiling C Sharp target $out' description = 'Compiling C Sharp target $out'
self.add_rule(NinjaRule(rule, command, args, description, self.add_rule(NinjaRule(rule, command, args, description,
rspable=mesonlib.is_windows(), rspable=mesonlib.is_windows(),
rspfile_quote_style='cl' if isinstance(compiler, VisualStudioCsCompiler) else 'sh')) rspfile_quote_style='cl' if isinstance(compiler, VisualStudioCsCompiler) else 'gcc'))
def generate_vala_compile_rules(self, compiler): def generate_vala_compile_rules(self, compiler):
rule = self.compiler_to_rule_name(compiler) rule = self.compiler_to_rule_name(compiler)
@ -1865,7 +1875,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
self.add_rule(NinjaRule(rule, command, args, description, self.add_rule(NinjaRule(rule, command, args, description,
rspable=compiler.can_linker_accept_rsp(), rspable=compiler.can_linker_accept_rsp(),
rspfile_quote_style='cl' if (compiler.get_argument_syntax() == 'msvc' or rspfile_quote_style='cl' if (compiler.get_argument_syntax() == 'msvc' or
isinstance(compiler, DmdDCompiler)) else 'sh', isinstance(compiler, DmdDCompiler)) else 'gcc',
deps=deps, depfile=depfile)) deps=deps, depfile=depfile))
def generate_pch_rule_for(self, langname, compiler): def generate_pch_rule_for(self, langname, compiler):