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' ):
@@ -453,51 +469,9 @@ def python_factory(env: 'Environment', for_machine: 'MachineChoice',
453469 installation = BasicPythonExternalProgram ('python3' , mesonlib .python_command )
454470 installation .sanity ()
455471
456- if installation .build_config :
457- pkg_version = installation .build_config ['language' ]['version' ]
458- else :
459- pkg_version = installation .info ['variables' ].get ('LDVERSION' ) or installation .info ['version' ]
460-
461472 if DependencyMethods .PKGCONFIG in methods :
462473 if from_installation :
463- if installation .build_config :
464- pkg_libdir = installation .build_config ['c_api' ]['pkgconfig_path' ]
465- else :
466- pkg_libdir = installation .info ['variables' ].get ('LIBPC' )
467- pkg_embed = '-embed' if embed and mesonlib .version_compare (installation .info ['version' ], '>=3.8' ) else ''
468- pkg_name = f'python-{ pkg_version } { pkg_embed } '
469-
470- # If python-X.Y.pc exists in LIBPC, we will try to use it
471- def wrap_in_pythons_pc_dir (name : str , env : 'Environment' , kwargs : T .Dict [str , T .Any ],
472- installation : 'BasicPythonExternalProgram' ) -> 'ExternalDependency' :
473- if not pkg_libdir :
474- # there is no LIBPC, so we can't search in it
475- empty = ExternalDependency (DependencyTypeName ('pkgconfig' ), env , {})
476- empty .name = 'python'
477- return empty
478-
479- old_pkg_libdir = os .environ .pop ('PKG_CONFIG_LIBDIR' , None )
480- old_pkg_path = os .environ .pop ('PKG_CONFIG_PATH' , None )
481- os .environ ['PKG_CONFIG_LIBDIR' ] = pkg_libdir
482- try :
483- return PythonPkgConfigDependency (name , env , kwargs , installation , True )
484- finally :
485- def set_env (name : str , value : str ) -> None :
486- if value is not None :
487- os .environ [name ] = value
488- elif name in os .environ :
489- del os .environ [name ]
490- set_env ('PKG_CONFIG_LIBDIR' , old_pkg_libdir )
491- set_env ('PKG_CONFIG_PATH' , old_pkg_path )
492-
493- # Otherwise this doesn't fulfill the interface requirements
494- wrap_in_pythons_pc_dir .log_tried = PythonPkgConfigDependency .log_tried # type: ignore[attr-defined]
495-
496- candidates .append (functools .partial (wrap_in_pythons_pc_dir , pkg_name , env , kwargs , installation ))
497- # We only need to check both, if a python install has a LIBPC. It might point to the wrong location,
498- # e.g. relocated / cross compilation, but the presence of LIBPC indicates we should definitely look for something.
499- if pkg_libdir is not None :
500- candidates .append (functools .partial (PythonPkgConfigDependency , pkg_name , env , kwargs , installation ))
474+ candidates .append (functools .partial (PythonPkgConfigDependency , env , kwargs , installation , embed ))
501475 else :
502476 candidates .append (functools .partial (PkgConfigDependency , 'python3' , env , kwargs ))
503477
@@ -506,7 +480,7 @@ def set_env(name: str, value: str) -> None:
506480
507481 if DependencyMethods .EXTRAFRAMEWORK in methods :
508482 nkwargs = kwargs .copy ()
509- if mesonlib .version_compare (pkg_version , '>= 3' ):
483+ if mesonlib .version_compare (installation . version , '>= 3' ):
510484 # There is a python in /System/Library/Frameworks, but that's python 2.x,
511485 # Python 3 will always be in /Library
512486 nkwargs ['paths' ] = ['/Library/Frameworks' ]
0 commit comments