88import typing as T
99
1010from .. import mesonlib , mlog
11- from .base import process_method_kw , DependencyException , DependencyMethods , DependencyTypeName , ExternalDependency , SystemDependency
11+ from .base import process_method_kw , DependencyException , DependencyMethods , ExternalDependency , SystemDependency
1212from .configtool import ConfigToolDependency
1313from .detect import packages
1414from .factory import DependencyFactory
@@ -116,6 +116,15 @@ def __init__(self, name: str, command: T.Optional[T.List[str]] = None,
116116 }
117117 self .pure : bool = True
118118
119+ @property
120+ def version (self ) -> str :
121+ if self .build_config :
122+ value = self .build_config ['language' ]['version' ]
123+ else :
124+ value = self .info ['variables' ].get ('LDVERSION' ) or self .info ['version' ]
125+ assert isinstance (value , str )
126+ return value
127+
119128 def _check_version (self , version : str ) -> bool :
120129 if self .name == 'python2' :
121130 return mesonlib .version_compare (version , '< 3.0' )
@@ -357,19 +366,26 @@ def find_libpy_windows(self, env: 'Environment', limited_api: bool = False) -> N
357366
358367class PythonPkgConfigDependency (PkgConfigDependency , _PythonDependencyBase ):
359368
360- def __init__ (self , name : str , environment : 'Environment' ,
361- kwargs : T .Dict [str , T .Any ], installation : 'BasicPythonExternalProgram' ,
362- libpc : bool = False ):
363- if libpc :
364- mlog .debug (f'Searching for { name !r} via pkgconfig lookup in LIBPC' )
369+ def __init__ (self , environment : 'Environment' , kwargs : T .Dict [str , T .Any ],
370+ installation : 'BasicPythonExternalProgram' , embed : bool ):
371+ pkg_embed = '-embed' if embed and mesonlib .version_compare (installation .info ['version' ], '>=3.8' ) else ''
372+ pkg_name = f'python-{ installation .version } { pkg_embed } '
373+
374+ if installation .build_config :
375+ pkg_libdir = installation .build_config ['c_api' ]['pkgconfig_path' ]
376+ pkg_libdir_origin = 'c_api.pkgconfig_path from the Python build config'
365377 else :
366- mlog .debug (f'Searching for { name !r} via fallback pkgconfig lookup in default paths' )
378+ pkg_libdir = installation .info ['variables' ].get ('LIBPC' )
379+ pkg_libdir_origin = 'LIBPC' if pkg_libdir else 'the default paths'
380+ mlog .debug (f'Searching for { pkg_libdir !r} via pkgconfig lookup in { pkg_libdir_origin } ' )
381+ pkgconfig_paths = [pkg_libdir ] if pkg_libdir else []
367382
368- PkgConfigDependency .__init__ (self , name , environment , kwargs )
383+ PkgConfigDependency .__init__ (self , pkg_name , environment , kwargs , extra_paths = pkgconfig_paths )
369384 _PythonDependencyBase .__init__ (self , installation , kwargs .get ('embed' , False ))
370385
371- if libpc and not self .is_found :
372- mlog .debug (f'"python-{ self .version } " could not be found in LIBPC, this is likely due to a relocated python installation' )
386+ if pkg_libdir and not self .is_found :
387+ mlog .debug (f'{ pkg_name !r} could not be found in { pkg_libdir_origin } , '
388+ 'this is likely due to a relocated python installation' )
373389
374390 # pkg-config files are usually accurate starting with python 3.8
375391 if not self .link_libpython and mesonlib .version_compare (self .version , '< 3.8' ):
@@ -444,51 +460,9 @@ def python_factory(env: 'Environment', for_machine: 'MachineChoice',
444460 installation = BasicPythonExternalProgram ('python3' , mesonlib .python_command )
445461 installation .sanity ()
446462
447- if installation .build_config :
448- pkg_version = installation .build_config ['language' ]['version' ]
449- else :
450- pkg_version = installation .info ['variables' ].get ('LDVERSION' ) or installation .info ['version' ]
451-
452463 if DependencyMethods .PKGCONFIG in methods :
453464 if from_installation :
454- if installation .build_config :
455- pkg_libdir = installation .build_config ['c_api' ]['pkgconfig_path' ]
456- else :
457- pkg_libdir = installation .info ['variables' ].get ('LIBPC' )
458- pkg_embed = '-embed' if embed and mesonlib .version_compare (installation .info ['version' ], '>=3.8' ) else ''
459- pkg_name = f'python-{ pkg_version } { pkg_embed } '
460-
461- # If python-X.Y.pc exists in LIBPC, we will try to use it
462- def wrap_in_pythons_pc_dir (name : str , env : 'Environment' , kwargs : T .Dict [str , T .Any ],
463- installation : 'BasicPythonExternalProgram' ) -> 'ExternalDependency' :
464- if not pkg_libdir :
465- # there is no LIBPC, so we can't search in it
466- empty = ExternalDependency (DependencyTypeName ('pkgconfig' ), env , {})
467- empty .name = 'python'
468- return empty
469-
470- old_pkg_libdir = os .environ .pop ('PKG_CONFIG_LIBDIR' , None )
471- old_pkg_path = os .environ .pop ('PKG_CONFIG_PATH' , None )
472- os .environ ['PKG_CONFIG_LIBDIR' ] = pkg_libdir
473- try :
474- return PythonPkgConfigDependency (name , env , kwargs , installation , True )
475- finally :
476- def set_env (name : str , value : str ) -> None :
477- if value is not None :
478- os .environ [name ] = value
479- elif name in os .environ :
480- del os .environ [name ]
481- set_env ('PKG_CONFIG_LIBDIR' , old_pkg_libdir )
482- set_env ('PKG_CONFIG_PATH' , old_pkg_path )
483-
484- # Otherwise this doesn't fulfill the interface requirements
485- wrap_in_pythons_pc_dir .log_tried = PythonPkgConfigDependency .log_tried # type: ignore[attr-defined]
486-
487- candidates .append (functools .partial (wrap_in_pythons_pc_dir , pkg_name , env , kwargs , installation ))
488- # We only need to check both, if a python install has a LIBPC. It might point to the wrong location,
489- # e.g. relocated / cross compilation, but the presence of LIBPC indicates we should definitely look for something.
490- if pkg_libdir is not None :
491- candidates .append (functools .partial (PythonPkgConfigDependency , pkg_name , env , kwargs , installation ))
465+ candidates .append (functools .partial (PythonPkgConfigDependency , env , kwargs , installation , embed ))
492466 else :
493467 candidates .append (functools .partial (PkgConfigDependency , 'python3' , env , kwargs ))
494468
@@ -497,7 +471,7 @@ def set_env(name: str, value: str) -> None:
497471
498472 if DependencyMethods .EXTRAFRAMEWORK in methods :
499473 nkwargs = kwargs .copy ()
500- if mesonlib .version_compare (pkg_version , '>= 3' ):
474+ if mesonlib .version_compare (installation . version , '>= 3' ):
501475 # There is a python in /System/Library/Frameworks, but that's python 2.x,
502476 # Python 3 will always be in /Library
503477 nkwargs ['paths' ] = ['/Library/Frameworks' ]
0 commit comments