python module: cache dependency() lookup between invocations
Modeled similarly after the installations cache, but using the coredata dependency cache because it has a nice mechanism for handling the cache key.
This commit is contained in:
parent
ea952966b4
commit
43c60318fd
|
@ -11,6 +11,7 @@
|
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
import functools
|
||||
|
@ -26,6 +27,7 @@ from ..coredata import UserFeatureOption
|
|||
from ..build import known_shmod_kwargs
|
||||
from ..dependencies import DependencyMethods, PkgConfigDependency, NotFoundDependency, SystemDependency, ExtraFrameworkDependency
|
||||
from ..dependencies.base import process_method_kw
|
||||
from ..dependencies.detect import get_dep_identifier
|
||||
from ..environment import detect_cpu_family
|
||||
from ..interpreter import ExternalProgramHolder, extract_required_kwarg, permitted_dependency_kwargs
|
||||
from ..interpreter.type_checking import NoneType
|
||||
|
@ -539,31 +541,41 @@ class PythonInstallation(ExternalProgramHolder):
|
|||
|
||||
return self.interpreter.func_shared_module(None, args, kwargs)
|
||||
|
||||
def _dependency_method_impl(self, kwargs: TYPE_kwargs) -> Dependency:
|
||||
for_machine = self.interpreter.machine_from_native_kwarg(kwargs)
|
||||
identifier = get_dep_identifier(self._full_path(), kwargs)
|
||||
|
||||
dep = self.interpreter.coredata.deps[for_machine].get(identifier)
|
||||
if dep is not None:
|
||||
return dep
|
||||
|
||||
new_kwargs = kwargs.copy()
|
||||
new_kwargs['required'] = False
|
||||
methods = process_method_kw({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM}, kwargs)
|
||||
# it's theoretically (though not practically) possible to not bind dep, let's ensure it is.
|
||||
dep: Dependency = NotFoundDependency('python', self.interpreter.environment)
|
||||
for d in python_factory(self.interpreter.environment, for_machine, new_kwargs, methods, self):
|
||||
dep = d()
|
||||
if dep.found():
|
||||
break
|
||||
|
||||
self.interpreter.coredata.deps[for_machine].put(identifier, dep)
|
||||
return dep
|
||||
|
||||
@disablerIfNotFound
|
||||
@permittedKwargs(permitted_dependency_kwargs | {'embed'})
|
||||
@FeatureNewKwargs('python_installation.dependency', '0.53.0', ['embed'])
|
||||
@noPosargs
|
||||
def dependency_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> 'Dependency':
|
||||
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
|
||||
# it's theoretically (though not practically) possible for the else clse
|
||||
# to not bind dep, let's ensure it is.
|
||||
dep: 'Dependency' = NotFoundDependency('python', self.interpreter.environment)
|
||||
if disabled:
|
||||
mlog.log('Dependency', mlog.bold('python'), 'skipped: feature', mlog.bold(feature), 'disabled')
|
||||
return NotFoundDependency('python', self.interpreter.environment)
|
||||
else:
|
||||
new_kwargs = kwargs.copy()
|
||||
new_kwargs['required'] = False
|
||||
methods = process_method_kw({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM}, kwargs)
|
||||
for d in python_factory(self.interpreter.environment,
|
||||
MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST,
|
||||
new_kwargs, methods, self):
|
||||
dep = d()
|
||||
if dep.found():
|
||||
break
|
||||
dep = self._dependency_method_impl(kwargs)
|
||||
if required and not dep.found():
|
||||
raise mesonlib.MesonException('Python dependency not found')
|
||||
|
||||
return dep
|
||||
return dep
|
||||
|
||||
@typed_pos_args('install_data', varargs=(str, mesonlib.File))
|
||||
@typed_kwargs('python_installation.install_sources', _PURE_KW, _SUBDIR_KW,
|
||||
|
|
Loading…
Reference in New Issue