diff options
Diffstat (limited to 'mesonbuild/backend/backends.py')
-rw-r--r-- | mesonbuild/backend/backends.py | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index d0c3e0a..9a377d4 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -159,6 +159,7 @@ class Backend: self.processed_targets = {} self.build_to_src = mesonlib.relpath(self.environment.get_source_dir(), self.environment.get_build_dir()) + self.introspect_data_cache = None # Cache to speed up get_introspection_data def get_target_filename(self, t): if isinstance(t, build.CustomTarget): @@ -1165,20 +1166,10 @@ class Backend: This is a limited fallback / reference implementation. The backend should override this method. ''' - def include_dirs_to_path(inc_dirs, src_root, build_root): - result = [] - if isinstance(inc_dirs, build.IncludeDirs): - for i in inc_dirs.get_incdirs(): - abs_src = os.path.join(src_root, inc_dirs.get_curdir(), i) - abs_build = os.path.join(build_root, inc_dirs.get_curdir(), i) + if not self.introspect_data_cache: + self.introspect_data_cache = {'targets': {}, 'dependencies': {}} - if os.path.isdir(abs_src): - result += [abs_src] - - if os.path.isdir(abs_build): - result += [abs_build] - - return result + reg = re.compile(r'-I(.*)') def extract_dependency_infromation(dep): inc_dirs = [] @@ -1194,21 +1185,64 @@ class Backend: return inc_dirs, args - def climb_stack(tgt, inc_dirs, extra_args, dep_args): + def process_target(tgt, src_root, build_root): if isinstance(tgt, build.BuildTarget): + # First check if the target is cached + tgtid = tgt.get_id() + if tgtid in self.introspect_data_cache['targets']: + c_tgt = self.introspect_data_cache['targets'][tgtid] + return c_tgt['inc_dirs'], c_tgt['dep_args'], c_tgt['extra_args'] + # The build directory is always in the include directories absbase_src = os.path.join(src_root, tgt.subdir) absbase_build = os.path.join(build_root, tgt.subdir) - inc_dirs += [absbase_src, absbase_build] + inc_dirs = [absbase_src, absbase_build] + dep_args = [] + extra_args = {} + # Handle include directories for i in tgt.include_dirs: - inc_dirs += include_dirs_to_path(i, src_root, build_root) + if isinstance(i, build.IncludeDirs): + for j in i.get_incdirs(): + abs_src = os.path.join(absbase_src, i.get_curdir(), j) + abs_build = os.path.join(absbase_build, i.get_curdir(), j) + + if os.path.isdir(abs_src): + inc_dirs += [abs_src] + + if os.path.isdir(abs_build): + inc_dirs += [abs_build] + # Handle dependencies for i in tgt.external_deps: - dep_inc_dirs, args = extract_dependency_infromation(i) + if not isinstance(i, base.Dependency): + continue + + did = id(i) + if did in self.introspect_data_cache['dependencies']: + c_entry = self.introspect_data_cache['dependencies'][did] + inc_dirs += c_entry['dep_inc_dirs'] + dep_args += c_entry['dep_cur_args'] + continue + + dep_inc_dirs = [] + dep_cur_args = [] + + for i in i.get_compile_args(): + match = reg.match(i) + if match: + dep_inc_dirs += [match.group(1)] + else: + dep_cur_args += [i] + + self.introspect_data_cache['dependencies'][did] = { + 'dep_inc_dirs': dep_inc_dirs, + 'dep_cur_args': dep_cur_args + } inc_dirs += dep_inc_dirs - dep_args += args + dep_args += dep_cur_args + # Check for language specific extra args for i, comp in tgt.compilers.items(): if isinstance(comp, compilers.Compiler): if i not in extra_args: @@ -1218,19 +1252,32 @@ class Backend: extra_args[i] += self.build.get_global_args(comp, tgt.is_cross) extra_args[i] += self.build.get_project_args(comp, tgt.subproject, tgt.is_cross) + # Recursively check the other targets for i in tgt.link_targets: - climb_stack(i, inc_dirs, extra_args, dep_args) + t_inc_dirs, t_dep_args, t_extra_args = process_target(i, src_root, build_root) + inc_dirs += t_inc_dirs + dep_args += t_dep_args + for ind, arglist in t_extra_args.items(): + if ind in extra_args: + extra_args[ind] += arglist + else: + extra_args[ind] = arglist + + # Update the cache + self.introspect_data_cache['targets'][tgtid] = { + 'inc_dirs': inc_dirs, + 'dep_args': dep_args, + 'extra_args': extra_args + } + + return inc_dirs, dep_args, extra_args src_root = self.build.environment.get_source_dir() build_root = self.build.environment.get_build_dir() - - inc_dirs = [] - extra_args = {} - dep_args = [] sources = {} if isinstance(target, build.BuildTarget): - climb_stack(target, inc_dirs, extra_args, dep_args) + inc_dirs, dep_args, extra_args = process_target(target, src_root, build_root) # Add the dep_args, sort and remove duplicates for i in extra_args: |