summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-01-08 14:33:51 +0100
committerEli Schwartz <eschwartz93@gmail.com>2025-01-08 13:45:26 -0500
commit5af3d3df0034d7ec3c159cc31f063558d5369df3 (patch)
tree9e05dfbcd50978b350a704ac59a3bd8c007a80e0
parent4151d09e262f48b3e06e6677581465758e08b79d (diff)
downloadmeson-5af3d3df0034d7ec3c159cc31f063558d5369df3.tar.gz
ninjabackend: avoid repeatedly building and analyzing rule commands
Two expensive parts of length_estimate() are executed for each target, but they are really always the same. Cache them in __init__, there will always be more targets than rules in cases where speed counts. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/backend/ninjabackend.py27
1 files changed, 14 insertions, 13 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 040f3add6..b4ec9ef00 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -226,6 +226,9 @@ class NinjaRule:
self.refcount = 0
self.rsprefcount = 0
self.rspfile_quote_style = rspfile_quote_style
+ self.command_str = ' '.join([self._quoter(x) for x in self.command + self.args])
+ self.var_refs = [m for m in re.finditer(r'(\${\w+}|\$\w+)?[^$]*', self.command_str)
+ if m.start(1) != -1]
if self.depfile == '$DEPFILE':
self.depfile += '_UNQUOTED'
@@ -262,7 +265,7 @@ class NinjaRule:
outfile.write(' rspfile = $out.rsp\n')
outfile.write(' rspfile_content = {}\n'.format(' '.join([self._quoter(x, rspfile_quote_func) for x in rspfile_args])))
else:
- outfile.write(' command = {}\n'.format(' '.join([self._quoter(x) for x in self.command + self.args])))
+ outfile.write(' command = {}\n'.format(self.command_str))
if self.deps:
outfile.write(f' deps = {self.deps}\n')
if self.depfile:
@@ -289,18 +292,16 @@ class NinjaRule:
ninja_vars['out'] = [outfiles]
# expand variables in command
- command = ' '.join([self._quoter(x) for x in self.command + self.args])
- estimate = len(command)
- for m in re.finditer(r'(\${\w+}|\$\w+)?[^$]*', command):
- if m.start(1) != -1:
- estimate -= m.end(1) - m.start(1)
- chunk = m.group(1)
- if chunk[1] == '{':
- chunk = chunk[2:-1]
- else:
- chunk = chunk[1:]
- chunk = ninja_vars.get(chunk, []) # undefined ninja variables are empty
- estimate += len(' '.join(chunk))
+ estimate = len(self.command_str)
+ for m in self.var_refs:
+ estimate -= m.end(1) - m.start(1)
+ chunk = m.group(1)
+ if chunk[1] == '{':
+ chunk = chunk[2:-1]
+ else:
+ chunk = chunk[1:]
+ chunk = ninja_vars.get(chunk, []) # undefined ninja variables are empty
+ estimate += len(' '.join(chunk))
# determine command length
return estimate