Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/markdown/Builtin-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ install prefix. For example: if the install prefix is `/usr` and the
| platlibdir | | Directory path | Directory for site-specific, platform-specific files (Since 0.60.0) |
| purelibdir | | Directory path | Directory for site-specific, non-platform-specific files (Since 0.60.0) |
| allow_limited_api | true | true, false | Disables project-wide use of the Python Limited API (Since 1.3.0) |
| build_config | | File path | Specifies the Python build configuration file (PEP 739) (Since 1.9.0) |

*Since 0.60.0* The `python.platlibdir` and `python.purelibdir` options are used
by the python module methods `python.install_sources()` and
Expand Down
28 changes: 18 additions & 10 deletions mesonbuild/dependencies/pkgconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ def set_program_override(pkg_bin: ExternalProgram, for_machine: MachineChoice) -
PkgConfigInterface.pkg_bin_per_machine[for_machine] = pkg_bin

@staticmethod
def instance(env: Environment, for_machine: MachineChoice, silent: bool) -> T.Optional[PkgConfigInterface]:
def instance(env: Environment, for_machine: MachineChoice, silent: bool,
extra_paths: T.Optional[T.List[str]] = None) -> T.Optional[PkgConfigInterface]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change of moving extra_paths into the instantiation breaks detection of Python on platforms where we need to search in a custom pkg-config path, such as on macOS.

You're caching the instances in the class_impl class variable, which means if you change extra_paths it gets ignored. The instances should probably be keyed with a tuple of extra_paths too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

project('testpy', 'c')

# Comment this out and the Python dependency below will be found
dependency('glib-2.0', required: false)
pymod = import('python')
python = pymod.find_installation('python3') 
python_dep = python.dependency(embed: true, include_type: 'system')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a macOS machine to reproduce. I'm going to try to build an artificial environment to reproduce this — but if you feel like writing a patch, that will probably be faster.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I didn't really reproduce a failure but I've reproduced the extra_paths mismatch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented your suggestion in #15001. I'm not particularly proud of that solution, so if anyone has a better idea…

'''Return a pkg-config implementation singleton'''
for_machine = for_machine if env.is_cross_build() else MachineChoice.HOST
impl = PkgConfigInterface.class_impl[for_machine]
if impl is False:
impl = PkgConfigCLI(env, for_machine, silent, PkgConfigInterface.pkg_bin_per_machine[for_machine])
impl = PkgConfigCLI(env, for_machine, silent, PkgConfigInterface.pkg_bin_per_machine[for_machine], extra_paths)
if not impl.found():
impl = None
if not impl and not silent:
Expand All @@ -55,7 +56,9 @@ def instance(env: Environment, for_machine: MachineChoice, silent: bool) -> T.Op
return impl

@staticmethod
def _cli(env: Environment, for_machine: MachineChoice, silent: bool = False) -> T.Optional[PkgConfigCLI]:
def _cli(env: Environment, for_machine: MachineChoice,
extra_paths: T.Optional[T.List[str]] = None,
silent: bool = False) -> T.Optional[PkgConfigCLI]:
'''Return the CLI pkg-config implementation singleton
Even when we use another implementation internally, external tools might
still need the CLI implementation.
Expand All @@ -66,15 +69,16 @@ def _cli(env: Environment, for_machine: MachineChoice, silent: bool = False) ->
if impl and not isinstance(impl, PkgConfigCLI):
impl = PkgConfigInterface.class_cli_impl[for_machine]
if impl is False:
impl = PkgConfigCLI(env, for_machine, silent, PkgConfigInterface.pkg_bin_per_machine[for_machine])
impl = PkgConfigCLI(env, for_machine, silent, PkgConfigInterface.pkg_bin_per_machine[for_machine], extra_paths)
if not impl.found():
impl = None
PkgConfigInterface.class_cli_impl[for_machine] = impl
return T.cast('T.Optional[PkgConfigCLI]', impl) # Trust me, mypy

@staticmethod
def get_env(env: Environment, for_machine: MachineChoice, uninstalled: bool = False) -> EnvironmentVariables:
cli = PkgConfigInterface._cli(env, for_machine)
def get_env(env: Environment, for_machine: MachineChoice, uninstalled: bool = False,
extra_paths: T.Optional[T.List[str]] = None) -> EnvironmentVariables:
cli = PkgConfigInterface._cli(env, for_machine, extra_paths)
return cli._get_env(uninstalled) if cli else EnvironmentVariables()

@staticmethod
Expand Down Expand Up @@ -123,11 +127,13 @@ class PkgConfigCLI(PkgConfigInterface):
'''pkg-config CLI implementation'''

def __init__(self, env: Environment, for_machine: MachineChoice, silent: bool,
pkgbin: T.Optional[ExternalProgram] = None) -> None:
pkgbin: T.Optional[ExternalProgram] = None,
extra_paths: T.Optional[T.List[str]] = None) -> None:
super().__init__(env, for_machine)
self._detect_pkgbin(pkgbin)
if self.pkgbin and not silent:
mlog.log('Found pkg-config:', mlog.green('YES'), mlog.bold(f'({self.pkgbin.get_path()})'), mlog.blue(self.pkgbin_version))
self.extra_paths = extra_paths or []

def found(self) -> bool:
return bool(self.pkgbin)
Expand Down Expand Up @@ -258,7 +264,7 @@ def _get_env(self, uninstalled: bool = False) -> EnvironmentVariables:
key = OptionKey('pkg_config_path', machine=self.for_machine)
pathlist = self.env.coredata.optstore.get_value_for(key)
assert isinstance(pathlist, list)
extra_paths: T.List[str] = pathlist[:]
extra_paths: T.List[str] = pathlist + self.extra_paths
if uninstalled:
bpath = self.env.get_build_dir()
if bpath is not None:
Expand Down Expand Up @@ -297,11 +303,13 @@ def _call_pkgbin(self, args: T.List[str], env: T.Optional[EnvironOrDict] = None)
class PkgConfigDependency(ExternalDependency):

def __init__(self, name: str, environment: Environment, kwargs: T.Dict[str, T.Any],
language: T.Optional[str] = None) -> None:
language: T.Optional[str] = None,
extra_paths: T.Optional[T.List[str]] = None) -> None:
super().__init__(DependencyTypeName('pkgconfig'), environment, kwargs, language=language)
self.name = name
self.is_libtool = False
pkgconfig = PkgConfigInterface.instance(self.env, self.for_machine, self.silent)
self.extra_paths = extra_paths or []
pkgconfig = PkgConfigInterface.instance(self.env, self.for_machine, self.silent, self.extra_paths)
if not pkgconfig:
msg = f'Pkg-config for machine {self.for_machine} not found. Giving up.'
if self.required:
Expand Down
Loading
Loading