diff options
author | Charles Brunet <charles.brunet@optelgroup.com> | 2023-07-28 10:03:58 -0400 |
---|---|---|
committer | Eli Schwartz <eschwartz93@gmail.com> | 2023-08-02 01:32:27 -0400 |
commit | 947e0f819b942951dfc251da37ef4ae83b3ea9b7 (patch) | |
tree | 82f56901e7bfc5a117ce29e695f8f6123644bd66 | |
parent | ce5f2982e46fac866034a45558a82c337279fd6a (diff) | |
download | meson-947e0f819b942951dfc251da37ef4ae83b3ea9b7.zip meson-947e0f819b942951dfc251da37ef4ae83b3ea9b7.tar.gz meson-947e0f819b942951dfc251da37ef4ae83b3ea9b7.tar.bz2 |
Optimize extract_dll_paths in ninja backend
On my project, this function was a bottleneck in setup time.
By properly caching it, the cumtime for this function
went from 26s to 4.3s when I profiled it.
-rw-r--r-- | mesonbuild/backend/backends.py | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 3e6d652..2681924 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -1098,6 +1098,34 @@ class Backend: paths.update(cc.get_library_dirs(self.environment)) return list(paths) + @staticmethod + @lru_cache(maxsize=None) + def search_dll_path(link_arg: str) -> T.Optional[str]: + if link_arg.startswith(('-l', '-L')): + link_arg = link_arg[2:] + + p = Path(link_arg) + if not p.is_absolute(): + return None + + try: + p = p.resolve(strict=True) + except FileNotFoundError: + return None + + for f in p.parent.glob('*.dll'): + # path contains dlls + return str(p.parent) + + if p.is_file(): + p = p.parent + # Heuristic: replace *last* occurence of '/lib' + binpath = Path('/bin'.join(p.as_posix().rsplit('/lib', maxsplit=1))) + for _ in binpath.glob('*.dll'): + return str(binpath) + + return None + @classmethod @lru_cache(maxsize=None) def extract_dll_paths(cls, target: build.BuildTarget) -> T.Set[str]: @@ -1116,32 +1144,9 @@ class Backend: bindir = dep.get_pkgconfig_variable('bindir', [], default='') if bindir: results.add(bindir) - - for link_arg in dep.link_args: - if link_arg.startswith(('-l', '-L')): - link_arg = link_arg[2:] - p = Path(link_arg) - if not p.is_absolute(): - continue - - try: - p = p.resolve(strict=True) - except FileNotFoundError: continue - for _ in p.parent.glob('*.dll'): - # path contains dlls - results.add(str(p.parent)) - break - - else: - if p.is_file(): - p = p.parent - # Heuristic: replace *last* occurence of '/lib' - binpath = Path('/bin'.join(p.as_posix().rsplit('/lib', maxsplit=1))) - for _ in binpath.glob('*.dll'): - results.add(str(binpath)) - break + results.update(filter(None, map(cls.search_dll_path, dep.link_args))) # pylint: disable=bad-builtin for i in chain(target.link_targets, target.link_whole_targets): if isinstance(i, build.BuildTarget): |