Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype support for PEP 739 #13945

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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 @@ -408,6 +408,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.7.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]:
'''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 @@ -256,7 +262,7 @@ def _check_pkgconfig(self, pkgbin: ExternalProgram) -> T.Optional[str]:
def _get_env(self, uninstalled: bool = False) -> EnvironmentVariables:
env = EnvironmentVariables()
key = OptionKey('pkg_config_path', machine=self.for_machine)
extra_paths: T.List[str] = self.env.coredata.optstore.get_value(key)[:]
extra_paths: T.List[str] = self.env.coredata.optstore.get_value(key)[:] + self.extra_paths
Comment on lines -259 to +265
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I see what you're doing here. You allow a PkgConfigDependency to take an additional PKG_CONFIG_PATH which is joined to the one in the cross file, which also means we don't need to push/pop os.environ.

On the flip side, the way we previously used it was via PKG_CONFIG_LIBDIR which was more narrowly scoped. I suspect this change means we can accidentally fall back to a different python than the one we were searching for (but still the same major.minor version at least)...

Copy link
Member

Choose a reason for hiding this comment

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

Ah hold on, we anyways fall back to checking for pkg-config without the internal LIBPC which means this is actually doing exactly what we want with one less check. Heh. :)

Copy link
Member

Choose a reason for hiding this comment

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

We don't need the cryptic copy of the first list anymore, right?

if uninstalled:
bpath = self.env.get_build_dir()
if bpath is not None:
Expand Down Expand Up @@ -295,11 +301,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
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