aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/backend
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz@archlinux.org>2022-05-26 22:33:52 -0400
committerEli Schwartz <eschwartz@archlinux.org>2022-05-31 17:49:29 -0400
commitdd2f1c4c57874a0efcd9f6d331985c408101c30d (patch)
tree0af74e8a9eb283c2f457ba730716afa51a5a3e6e /mesonbuild/backend
parent40c69630df1057401a9ae3ec5584a9ff8d1bef46 (diff)
downloadmeson-dd2f1c4c57874a0efcd9f6d331985c408101c30d.zip
meson-dd2f1c4c57874a0efcd9f6d331985c408101c30d.tar.gz
meson-dd2f1c4c57874a0efcd9f6d331985c408101c30d.tar.bz2
ninja backend: simplify generation of phony targets
Every phony target has a special indirection rule created because ninja is bad at deleting generated outputs and tries to delete phony outputs too. Instead of invoking this as a separate helper post-creation function to create the alias, wrap NinjaBuildElement and create it behind the scenes. This simplifies target naming and means one less line at every single use site.
Diffstat (limited to 'mesonbuild/backend')
-rw-r--r--mesonbuild/backend/ninjabackend.py97
1 files changed, 33 insertions, 64 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 35c14ee..c6f82e3 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -434,18 +434,23 @@ class NinjaBackend(backends.Backend):
self.introspection_data = {}
self.created_llvm_ir_rule = PerMachine(False, False)
- def create_target_alias(self, to_target):
- # We need to use aliases for targets that might be used as directory
- # names to workaround a Ninja bug that breaks `ninja -t clean`.
- # This is used for 'reserved' targets such as 'test', 'install',
- # 'benchmark', etc, and also for RunTargets.
- # https://github.com/mesonbuild/meson/issues/1644
- if not to_target.startswith('meson-'):
- raise AssertionError(f'Invalid usage of create_target_alias with {to_target!r}')
- from_target = to_target[len('meson-'):]
- elem = NinjaBuildElement(self.all_outputs, from_target, 'phony', to_target)
+ def create_phony_target(self, all_outputs, dummy_outfile, rulename, phony_infilename, implicit_outs=None):
+ '''
+ We need to use aliases for targets that might be used as directory
+ names to workaround a Ninja bug that breaks `ninja -t clean`.
+ This is used for 'reserved' targets such as 'test', 'install',
+ 'benchmark', etc, and also for RunTargets.
+ https://github.com/mesonbuild/meson/issues/1644
+ '''
+ if dummy_outfile.startswith('meson-'):
+ raise AssertionError(f'Invalid usage of create_phony_target with {dummy_outfile!r}')
+
+ to_name = f'meson-{dummy_outfile}'
+ elem = NinjaBuildElement(all_outputs, dummy_outfile, 'phony', to_name)
self.add_build(elem)
+ return NinjaBuildElement(all_outputs, to_name, rulename, phony_infilename, implicit_outs)
+
def detect_vs_dep_prefix(self, tempfilename):
'''VS writes its dependency in a locale dependent format.
Detect the search prefix to use.'''
@@ -1050,13 +1055,10 @@ class NinjaBackend(backends.Backend):
env=target_env,
verbose=True)
cmd_type = f' (wrapped by meson {reason})' if reason else ''
- internal_target_name = f'meson-{target_name}'
- elem = NinjaBuildElement(self.all_outputs, internal_target_name, 'CUSTOM_COMMAND', [])
+ elem = self.create_phony_target(self.all_outputs, target_name, 'CUSTOM_COMMAND', [])
elem.add_item('COMMAND', meson_exe_cmd)
elem.add_item('description', f'Running external command {target.name}{cmd_type}')
elem.add_item('pool', 'console')
- # Alias that runs the target defined above with the name the user specified
- self.create_target_alias(internal_target_name)
deps = self.unwrap_dep_list(target)
deps += self.get_custom_target_depend_files(target)
elem.add_dep(deps)
@@ -1084,55 +1086,43 @@ class NinjaBackend(backends.Backend):
(['--use_llvm_cov'] if use_llvm_cov else []))
def generate_coverage_rules(self, gcovr_exe: T.Optional[str], gcovr_version: T.Optional[str]):
- e = NinjaBuildElement(self.all_outputs, 'meson-coverage', 'CUSTOM_COMMAND', 'PHONY')
+ e = self.create_phony_target(self.all_outputs, 'coverage', 'CUSTOM_COMMAND', 'PHONY')
self.generate_coverage_command(e, [])
e.add_item('description', 'Generates coverage reports')
self.add_build(e)
- # Alias that runs the target defined above
- self.create_target_alias('meson-coverage')
self.generate_coverage_legacy_rules(gcovr_exe, gcovr_version)
def generate_coverage_legacy_rules(self, gcovr_exe: T.Optional[str], gcovr_version: T.Optional[str]):
- e = NinjaBuildElement(self.all_outputs, 'meson-coverage-html', 'CUSTOM_COMMAND', 'PHONY')
+ e = self.create_phony_target(self.all_outputs, 'coverage-html', 'CUSTOM_COMMAND', 'PHONY')
self.generate_coverage_command(e, ['--html'])
e.add_item('description', 'Generates HTML coverage report')
self.add_build(e)
- # Alias that runs the target defined above
- self.create_target_alias('meson-coverage-html')
if gcovr_exe:
- e = NinjaBuildElement(self.all_outputs, 'meson-coverage-xml', 'CUSTOM_COMMAND', 'PHONY')
+ e = self.create_phony_target(self.all_outputs, 'coverage-xml', 'CUSTOM_COMMAND', 'PHONY')
self.generate_coverage_command(e, ['--xml'])
e.add_item('description', 'Generates XML coverage report')
self.add_build(e)
- # Alias that runs the target defined above
- self.create_target_alias('meson-coverage-xml')
- e = NinjaBuildElement(self.all_outputs, 'meson-coverage-text', 'CUSTOM_COMMAND', 'PHONY')
+ e = self.create_phony_target(self.all_outputs, 'coverage-text', 'CUSTOM_COMMAND', 'PHONY')
self.generate_coverage_command(e, ['--text'])
e.add_item('description', 'Generates text coverage report')
self.add_build(e)
- # Alias that runs the target defined above
- self.create_target_alias('meson-coverage-text')
if mesonlib.version_compare(gcovr_version, '>=4.2'):
- e = NinjaBuildElement(self.all_outputs, 'meson-coverage-sonarqube', 'CUSTOM_COMMAND', 'PHONY')
+ e = self.create_phony_target(self.all_outputs, 'coverage-sonarqube', 'CUSTOM_COMMAND', 'PHONY')
self.generate_coverage_command(e, ['--sonarqube'])
e.add_item('description', 'Generates Sonarqube XML coverage report')
self.add_build(e)
- # Alias that runs the target defined above
- self.create_target_alias('meson-coverage-sonarqube')
def generate_install(self):
self.create_install_data_files()
- elem = NinjaBuildElement(self.all_outputs, 'meson-install', 'CUSTOM_COMMAND', 'PHONY')
+ elem = self.create_phony_target(self.all_outputs, 'install', 'CUSTOM_COMMAND', 'PHONY')
elem.add_dep('all')
elem.add_item('DESC', 'Installing files.')
elem.add_item('COMMAND', self.environment.get_build_command() + ['install', '--no-rebuild'])
elem.add_item('pool', 'console')
self.add_build(elem)
- # Alias that runs the target defined above
- self.create_target_alias('meson-install')
def generate_tests(self):
self.serialize_tests()
@@ -1141,25 +1131,21 @@ class NinjaBackend(backends.Backend):
cmd += ['--no-stdsplit']
if self.environment.coredata.get_option(OptionKey('errorlogs')):
cmd += ['--print-errorlogs']
- elem = NinjaBuildElement(self.all_outputs, 'meson-test', 'CUSTOM_COMMAND', ['all', 'PHONY'])
+ elem = self.create_phony_target(self.all_outputs, 'test', 'CUSTOM_COMMAND', ['all', 'PHONY'])
elem.add_item('COMMAND', cmd)
elem.add_item('DESC', 'Running all tests.')
elem.add_item('pool', 'console')
self.add_build(elem)
- # Alias that runs the above-defined meson-test target
- self.create_target_alias('meson-test')
# And then benchmarks.
cmd = self.environment.get_build_command(True) + [
'test', '--benchmark', '--logbase',
'benchmarklog', '--num-processes=1', '--no-rebuild']
- elem = NinjaBuildElement(self.all_outputs, 'meson-benchmark', 'CUSTOM_COMMAND', ['all', 'PHONY'])
+ elem = self.create_phony_target(self.all_outputs, 'benchmark', 'CUSTOM_COMMAND', ['all', 'PHONY'])
elem.add_item('COMMAND', cmd)
elem.add_item('DESC', 'Running benchmark suite.')
elem.add_item('pool', 'console')
self.add_build(elem)
- # Alias that runs the above-defined meson-benchmark target
- self.create_target_alias('meson-benchmark')
def generate_rules(self):
self.rules = []
@@ -3170,33 +3156,27 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
mlog.debug("Library versioning disabled because we do not have symlink creation privileges.")
def generate_custom_target_clean(self, trees: T.List[str]) -> str:
- e = NinjaBuildElement(self.all_outputs, 'meson-clean-ctlist', 'CUSTOM_COMMAND', 'PHONY')
+ e = self.create_phony_target(self.all_outputs, 'clean-ctlist', 'CUSTOM_COMMAND', 'PHONY')
d = CleanTrees(self.environment.get_build_dir(), trees)
d_file = os.path.join(self.environment.get_scratch_dir(), 'cleantrees.dat')
e.add_item('COMMAND', self.environment.get_build_command() + ['--internal', 'cleantrees', d_file])
e.add_item('description', 'Cleaning custom target directories')
self.add_build(e)
- # Alias that runs the target defined above
- self.create_target_alias('meson-clean-ctlist')
# Write out the data file passed to the script
with open(d_file, 'wb') as ofile:
pickle.dump(d, ofile)
return 'clean-ctlist'
def generate_gcov_clean(self):
- gcno_elem = NinjaBuildElement(self.all_outputs, 'meson-clean-gcno', 'CUSTOM_COMMAND', 'PHONY')
+ gcno_elem = self.create_phony_target(self.all_outputs, 'clean-gcno', 'CUSTOM_COMMAND', 'PHONY')
gcno_elem.add_item('COMMAND', mesonlib.get_meson_command() + ['--internal', 'delwithsuffix', '.', 'gcno'])
gcno_elem.add_item('description', 'Deleting gcno files')
self.add_build(gcno_elem)
- # Alias that runs the target defined above
- self.create_target_alias('meson-clean-gcno')
- gcda_elem = NinjaBuildElement(self.all_outputs, 'meson-clean-gcda', 'CUSTOM_COMMAND', 'PHONY')
+ gcda_elem = self.create_phony_target(self.all_outputs, 'clean-gcda', 'CUSTOM_COMMAND', 'PHONY')
gcda_elem.add_item('COMMAND', mesonlib.get_meson_command() + ['--internal', 'delwithsuffix', '.', 'gcda'])
gcda_elem.add_item('description', 'Deleting gcda files')
self.add_build(gcda_elem)
- # Alias that runs the target defined above
- self.create_target_alias('meson-clean-gcda')
def get_user_option_args(self):
cmds = []
@@ -3209,13 +3189,11 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
return sorted(cmds)
def generate_dist(self):
- elem = NinjaBuildElement(self.all_outputs, 'meson-dist', 'CUSTOM_COMMAND', 'PHONY')
+ elem = self.create_phony_target(self.all_outputs, 'dist', 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('DESC', 'Creating source packages')
elem.add_item('COMMAND', self.environment.get_build_command() + ['dist'])
elem.add_item('pool', 'console')
self.add_build(elem)
- # Alias that runs the target defined above
- self.create_target_alias('meson-dist')
def generate_scanbuild(self):
if not environment.detect_scanbuild():
@@ -3225,12 +3203,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
cmd = self.environment.get_build_command() + \
['--internal', 'scanbuild', self.environment.source_dir, self.environment.build_dir] + \
self.environment.get_build_command() + self.get_user_option_args()
- elem = NinjaBuildElement(self.all_outputs, 'meson-scan-build', 'CUSTOM_COMMAND', 'PHONY')
+ elem = self.create_phony_target(self.all_outputs, 'scan-build', 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('COMMAND', cmd)
elem.add_item('pool', 'console')
self.add_build(elem)
- # Alias that runs the target defined above
- self.create_target_alias('meson-scan-build')
def generate_clangtool(self, name, extra_arg=None):
target_name = 'clang-' + name
@@ -3248,11 +3224,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
cmd = self.environment.get_build_command() + \
['--internal', 'clang' + name, self.environment.source_dir, self.environment.build_dir] + \
extra_args
- elem = NinjaBuildElement(self.all_outputs, 'meson-' + target_name, 'CUSTOM_COMMAND', 'PHONY')
+ elem = self.create_phony_target(self.all_outputs, target_name, 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('COMMAND', cmd)
elem.add_item('pool', 'console')
self.add_build(elem)
- self.create_target_alias('meson-' + target_name)
def generate_clangformat(self):
if not environment.detect_clangformat():
@@ -3276,12 +3251,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
return
cmd = self.environment.get_build_command() + \
['--internal', 'tags', tool, self.environment.source_dir]
- elem = NinjaBuildElement(self.all_outputs, 'meson-' + target_name, 'CUSTOM_COMMAND', 'PHONY')
+ elem = self.create_phony_target(self.all_outputs, target_name, 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('COMMAND', cmd)
elem.add_item('pool', 'console')
self.add_build(elem)
- # Alias that runs the target defined above
- self.create_target_alias('meson-' + target_name)
# For things like scan-build and other helper tools we might have.
def generate_utils(self):
@@ -3292,12 +3265,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
self.generate_tags('ctags', 'ctags')
self.generate_tags('cscope', 'cscope')
cmd = self.environment.get_build_command() + ['--internal', 'uninstall']
- elem = NinjaBuildElement(self.all_outputs, 'meson-uninstall', 'CUSTOM_COMMAND', 'PHONY')
+ elem = self.create_phony_target(self.all_outputs, 'uninstall', 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('COMMAND', cmd)
elem.add_item('pool', 'console')
self.add_build(elem)
- # Alias that runs the target defined above
- self.create_target_alias('meson-uninstall')
def generate_ending(self):
targetlist = []
@@ -3309,11 +3280,9 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
elem = NinjaBuildElement(self.all_outputs, 'all', 'phony', targetlist)
self.add_build(elem)
- elem = NinjaBuildElement(self.all_outputs, 'meson-clean', 'CUSTOM_COMMAND', 'PHONY')
+ elem = self.create_phony_target(self.all_outputs, 'clean', 'CUSTOM_COMMAND', 'PHONY')
elem.add_item('COMMAND', self.ninja_command + ['-t', 'clean'])
elem.add_item('description', 'Cleaning')
- # Alias that runs the above-defined meson-clean target
- self.create_target_alias('meson-clean')
# If we have custom targets in this project, add all their outputs to
# the list that is passed to the `cleantrees.py` script. The script