From 26ffd4f8f2bca3f858cca829f4c356c6ce97c371 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 11 Dec 2020 23:35:24 +0200 Subject: [PATCH] Scan all C++ sources and ignore everything else. --- mesonbuild/backend/ninjabackend.py | 38 ++++++++++++++++++++++++++---- mesonbuild/mesonlib.py | 4 ++++ mesonbuild/scripts/depscan.py | 2 ++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index ea04079bd..159d6de02 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -689,7 +689,8 @@ int dummy; def generate_target(self, target): try: - os.makedirs(self.get_target_private_dir_abs(target)) + if isinstance(target, build.BuildTarget): + os.makedirs(self.get_target_private_dir_abs(target)) except FileExistsError: pass if isinstance(target, build.CustomTarget): @@ -871,21 +872,48 @@ int dummy; self.generate_shlib_aliases(target, self.get_target_dir(target)) self.add_build(elem) - def generate_dependency_scan_target(self, target, compiled_sources, source2object): + def should_scan_target(self, target): if 'cpp' not in target.compilers: + return False + # Currently only the preview version of Visual Studio is supported. + cpp = target.compilers['cpp'] + if cpp.get_id() != 'msvc': + return False + if not mesonlib.current_vs_supports_modules(): + return False + if mesonlib.version_compare(cpp.version, '<19.28.28617'): + return False + if mesonlib.version_compare(self.ninja_version, '<1.10.0'): + return False + return True + + def generate_dependency_scan_target(self, target, compiled_sources, source2object): + if not self.should_scan_target(target): return depscan_file = self.get_dep_scan_file_for(target) pickle_base = target.name + '.dat' pickle_file = os.path.join(self.get_target_private_dir(target), pickle_base).replace('\\', '/') pickle_abs = os.path.join(self.get_target_private_dir_abs(target), pickle_base).replace('\\', '/') rule_name = 'cppscan' - elem = NinjaBuildElement(self.all_outputs, depscan_file, rule_name, compiled_sources) + scan_sources = self.select_sources_to_scan(compiled_sources) + elem = NinjaBuildElement(self.all_outputs, depscan_file, rule_name, scan_sources) elem.add_item('picklefile', pickle_file) scaninfo = TargetDependencyScannerInfo(self.get_target_private_dir(target), source2object) with open(pickle_abs, 'wb') as p: pickle.dump(scaninfo, p) self.add_build(elem) + def select_sources_to_scan(self, compiled_sources): + # in practice pick up C++ and Fortran files. If some other language + # requires scanning (possibly Java to deal with inner class files) + # then add them here. + selected_sources = [] + for source in compiled_sources: + ext = os.path.splitext(source)[1][1:] + if ext in compilers.lang_suffixes['cpp']: + selected_sources.append(source) + return selected_sources + def process_target_dependencies(self, target): for t in target.get_dependencies(): if t.get_id() not in self.processed_targets: @@ -2011,7 +2039,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) if rulename in self.ruledict: # Scanning command is the same for native and cross compilation. continue - command = cmd = self.environment.get_build_command() + \ + command = self.environment.get_build_command() + \ ['--internal', 'depscan'] args = ['$picklefile', '$out', '$in'] description = 'Module scanner for {}.'.format(langname) @@ -2509,7 +2537,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) return (rel_obj, rel_src.replace('\\', '/')) def add_dependency_scanner_entries_to_element(self, target, compiler, element): - if compiler.get_language() != 'cpp': + if not self.should_scan_target(target): return dep_scan_file = self.get_dep_scan_file_for(target) element.add_item('dyndep', dep_scan_file) diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index d46dfcafa..e77314496 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -586,6 +586,10 @@ def detect_vcs(source_dir: T.Union[str, Path]) -> T.Optional[T.Dict[str, str]]: return vcs return None +def current_vs_supports_modules() -> bool: + vsver = os.environ.get('VSCMD_VER', '') + return vsver.startswith('16.9.0') and '-pre.' in vsver + # a helper class which implements the same version ordering as RPM class Version: def __init__(self, s: str) -> None: diff --git a/mesonbuild/scripts/depscan.py b/mesonbuild/scripts/depscan.py index 161faf81e..907ce5a27 100644 --- a/mesonbuild/scripts/depscan.py +++ b/mesonbuild/scripts/depscan.py @@ -17,6 +17,8 @@ import pickle import re import typing as T +from ..backend.ninjabackend import TargetDependencyScannerInfo + import_re = re.compile('\w*import ([a-zA-Z0-9]+);') export_re = re.compile('\w*export module ([a-zA-Z0-9]+);')