aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz@archlinux.org>2022-11-20 17:26:44 -0500
committerEli Schwartz <eschwartz@archlinux.org>2022-12-04 17:56:03 -0500
commitda23630a97a2999faef42a68a631105a3556054c (patch)
tree83d305a75ba4b4c6029f0fdcc0295eef96f493e3
parent9074ad93c6675cdb603b85d85a8090100058f81b (diff)
downloadmeson-da23630a97a2999faef42a68a631105a3556054c.zip
meson-da23630a97a2999faef42a68a631105a3556054c.tar.gz
meson-da23630a97a2999faef42a68a631105a3556054c.tar.bz2
refactor pkg-config dependency to allow statically finding the program
The pkg-config dependency class has some interesting logic for finding a good pkg-config that will be used for dependency lookups. We sometimes need to use it, though, outside of the class. Make that possible.
-rw-r--r--mesonbuild/dependencies/pkgconfig.py68
-rw-r--r--unittests/linuxliketests.py2
2 files changed, 37 insertions, 33 deletions
diff --git a/mesonbuild/dependencies/pkgconfig.py b/mesonbuild/dependencies/pkgconfig.py
index 3905fc7..231ec51 100644
--- a/mesonbuild/dependencies/pkgconfig.py
+++ b/mesonbuild/dependencies/pkgconfig.py
@@ -47,36 +47,7 @@ class PkgConfigDependency(ExternalDependency):
self.is_libtool = False
# Store a copy of the pkg-config path on the object itself so it is
# stored in the pickled coredata and recovered.
- self.pkgbin: T.Union[None, bool, ExternalProgram] = None
-
- # Only search for pkg-config for each machine the first time and store
- # the result in the class definition
- if PkgConfigDependency.class_pkgbin[self.for_machine] is False:
- mlog.debug(f'Pkg-config binary for {self.for_machine} is cached as not found.')
- elif PkgConfigDependency.class_pkgbin[self.for_machine] is not None:
- mlog.debug(f'Pkg-config binary for {self.for_machine} is cached.')
- else:
- assert PkgConfigDependency.class_pkgbin[self.for_machine] is None
- mlog.debug(f'Pkg-config binary for {self.for_machine} is not cached.')
- for potential_pkgbin in find_external_program(
- self.env, self.for_machine, 'pkgconfig', 'Pkg-config',
- environment.default_pkgconfig, allow_default_for_cross=False):
- version_if_ok = self.check_pkgconfig(potential_pkgbin)
- if not version_if_ok:
- continue
- if not self.silent:
- mlog.log('Found pkg-config:', mlog.bold(potential_pkgbin.get_path()),
- f'({version_if_ok})')
- PkgConfigDependency.class_pkgbin[self.for_machine] = potential_pkgbin
- break
- else:
- if not self.silent:
- mlog.log('Found Pkg-config:', mlog.red('NO'))
- # Set to False instead of None to signify that we've already
- # searched for it and not found it
- PkgConfigDependency.class_pkgbin[self.for_machine] = False
-
- self.pkgbin = PkgConfigDependency.class_pkgbin[self.for_machine]
+ self.pkgbin = self._detect_pkgbin(self.silent, self.env, self.for_machine)
if self.pkgbin is False:
self.pkgbin = None
msg = f'Pkg-config binary for machine {self.for_machine} not found. Giving up.'
@@ -115,6 +86,38 @@ class PkgConfigDependency(ExternalDependency):
return s.format(self.__class__.__name__, self.name, self.is_found,
self.version_reqs)
+ @classmethod
+ def _detect_pkgbin(cls, silent: bool, env: Environment,
+ for_machine: MachineChoice) -> T.Union[None, bool, ExternalProgram]:
+ # Only search for pkg-config for each machine the first time and store
+ # the result in the class definition
+ if cls.class_pkgbin[for_machine] is False:
+ mlog.debug(f'Pkg-config binary for {for_machine} is cached as not found.')
+ elif cls.class_pkgbin[for_machine] is not None:
+ mlog.debug(f'Pkg-config binary for {for_machine} is cached.')
+ else:
+ assert cls.class_pkgbin[for_machine] is None, 'for mypy'
+ mlog.debug(f'Pkg-config binary for {for_machine} is not cached.')
+ for potential_pkgbin in find_external_program(
+ env, for_machine, 'pkgconfig', 'Pkg-config',
+ env.default_pkgconfig, allow_default_for_cross=False):
+ version_if_ok = cls.check_pkgconfig(env, potential_pkgbin)
+ if not version_if_ok:
+ continue
+ if not silent:
+ mlog.log('Found pkg-config:', mlog.bold(potential_pkgbin.get_path()),
+ f'({version_if_ok})')
+ cls.class_pkgbin[for_machine] = potential_pkgbin
+ break
+ else:
+ if not silent:
+ mlog.log('Found Pkg-config:', mlog.red('NO'))
+ # Set to False instead of None to signify that we've already
+ # searched for it and not found it
+ cls.class_pkgbin[for_machine] = False
+
+ return cls.class_pkgbin[for_machine]
+
def _call_pkgbin_real(self, args: T.List[str], env: T.Dict[str, str]) -> T.Tuple[int, str, str]:
assert isinstance(self.pkgbin, ExternalProgram)
cmd = self.pkgbin.get_command() + args
@@ -419,7 +422,8 @@ class PkgConfigDependency(ExternalDependency):
mlog.debug(f'Got pkgconfig variable {variable_name} : {variable}')
return variable
- def check_pkgconfig(self, pkgbin: ExternalProgram) -> T.Optional[str]:
+ @staticmethod
+ def check_pkgconfig(env: Environment, pkgbin: ExternalProgram) -> T.Optional[str]:
if not pkgbin.found():
mlog.log(f'Did not find pkg-config by name {pkgbin.name!r}')
return None
@@ -438,7 +442,7 @@ class PkgConfigDependency(ExternalDependency):
return None
except PermissionError:
msg = f'Found pkg-config {command_as_string!r} but didn\'t have permissions to run it.'
- if not self.env.machines.build.is_windows():
+ if not env.machines.build.is_windows():
msg += '\n\nOn Unix-like systems this is often caused by scripts that are not executable.'
mlog.warning(msg)
return None
diff --git a/unittests/linuxliketests.py b/unittests/linuxliketests.py
index 1e530b0..50c6b62 100644
--- a/unittests/linuxliketests.py
+++ b/unittests/linuxliketests.py
@@ -173,7 +173,7 @@ class LinuxlikeTests(BasePlatformTests):
self.assertEqual(libhello_nolib.get_compile_args(), [])
self.assertEqual(libhello_nolib.get_pkgconfig_variable('foo', [], None), 'bar')
self.assertEqual(libhello_nolib.get_pkgconfig_variable('prefix', [], None), self.prefix)
- if version_compare(libhello_nolib.check_pkgconfig(libhello_nolib.pkgbin),">=0.29.1"):
+ if version_compare(PkgConfigDependency.check_pkgconfig(env, libhello_nolib.pkgbin),">=0.29.1"):
self.assertEqual(libhello_nolib.get_pkgconfig_variable('escaped_var', [], None), r'hello\ world')
self.assertEqual(libhello_nolib.get_pkgconfig_variable('unescaped_var', [], None), 'hello world')