find_library: Add a cache for library searching

Otherwise we can end up searching for the same library tens of times,
because pkg-config does not de-duplicate -lfoo args before returning
them.

We use -Wl,--start-group/end-group, so we do not need to worry about
ordering issues in static libraries.
pull/3708/head
Nirbheek Chauhan 7 years ago committed by Nirbheek Chauhan
parent 6b7dba7f06
commit 186eed2dc6
  1. 24
      mesonbuild/compilers/c.py
  2. 10
      mesonbuild/compilers/fortran.py

@ -46,6 +46,7 @@ from .compilers import (
class CCompiler(Compiler):
library_dirs_cache = {}
program_dirs_cache = {}
find_library_cache = {}
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
# If a child ObjC or CPP class has already set it, don't set it ourselves
@ -837,13 +838,8 @@ class CCompiler(Compiler):
raise AssertionError('BUG: unknown libtype {!r}'.format(libtype))
return prefixes, suffixes
def find_library_impl(self, libname, env, extra_dirs, code, libtype='default'):
# These libraries are either built-in or invalid
if libname in self.ignore_libs:
return []
def find_library_real(self, libname, env, extra_dirs, code, libtype):
# First try if we can just add the library as -l.
if extra_dirs and isinstance(extra_dirs, str):
extra_dirs = [extra_dirs]
# Gcc + co seem to prefer builtin lib dirs to -L dirs.
# Only try to find std libs if no extra dirs specified.
if not extra_dirs and libtype == 'default':
@ -866,6 +862,22 @@ class CCompiler(Compiler):
return [trial]
return None
def find_library_impl(self, libname, env, extra_dirs, code, libtype):
# These libraries are either built-in or invalid
if libname in self.ignore_libs:
return []
if isinstance(extra_dirs, str):
extra_dirs = [extra_dirs]
key = (tuple(self.exelist), libname, tuple(extra_dirs), code, libtype)
if key not in self.find_library_cache:
value = self.find_library_real(libname, env, extra_dirs, code, libtype)
self.find_library_cache[key] = value
else:
value = self.find_library_cache[key]
if value is None:
return None
return value[:]
def find_library(self, libname, env, extra_dirs, libtype='default'):
code = 'int main(int argc, char **argv) { return 0; }'
return self.find_library_impl(libname, env, extra_dirs, code, libtype)

@ -23,6 +23,8 @@ from .compilers import (
class FortranCompiler(Compiler):
library_dirs_cache = CCompiler.library_dirs_cache
program_dirs_cache = CCompiler.library_dirs_cache
find_library_cache = CCompiler.library_dirs_cache
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
self.language = 'fortran'
@ -174,11 +176,17 @@ class FortranCompiler(Compiler):
def get_library_naming(self, env, libtype, strict=False):
return CCompiler.get_library_naming(self, env, libtype, strict)
def find_library_real(self, *args):
return CCompiler.find_library_real(self, *args)
def find_library_impl(self, *args):
return CCompiler.find_library_impl(self, *args)
def find_library(self, libname, env, extra_dirs, libtype='default'):
code = '''program main
call exit(0)
end program main'''
return CCompiler.find_library_impl(self, libname, env, extra_dirs, code, libtype)
return self.find_library_impl(libname, env, extra_dirs, code, libtype)
def thread_flags(self, env):
return CCompiler.thread_flags(self, env)

Loading…
Cancel
Save