pkgconfig: Set PKG_CONFIG in env for devenv and g-ir-scanner

pull/12227/head
Xavier Claessens 2 years ago committed by Xavier Claessens
parent 6a56f6d98f
commit f1c35b561f
  1. 56
      mesonbuild/dependencies/pkgconfig.py
  2. 9
      mesonbuild/modules/external_project.py
  3. 4
      mesonbuild/modules/gnome.py
  4. 4
      mesonbuild/modules/pkgconfig.py
  5. 4
      unittests/linuxliketests.py

@ -16,7 +16,7 @@ from __future__ import annotations
from pathlib import Path
from .base import ExternalDependency, DependencyException, sort_libpaths, DependencyTypeName
from ..mesonlib import EnvironmentVariables, OptionKey, OrderedSet, PerMachine, Popen_safe, Popen_safe_logged, MachineChoice
from ..mesonlib import EnvironmentVariables, OptionKey, OrderedSet, PerMachine, Popen_safe, Popen_safe_logged, MachineChoice, join_args
from ..programs import find_external_program, ExternalProgram
from .. import mlog
from pathlib import PurePath
@ -37,9 +37,11 @@ class PkgConfigInterface:
'''Base class wrapping a pkg-config implementation'''
class_impl: PerMachine[T.Union[Literal[False], T.Optional[PkgConfigInterface]]] = PerMachine(False, False)
class_cli_impl: PerMachine[T.Union[Literal[False], T.Optional[PkgConfigCLI]]] = PerMachine(False, False)
@staticmethod
def instance(env: Environment, for_machine: MachineChoice, silent: bool) -> 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:
@ -51,6 +53,35 @@ class PkgConfigInterface:
PkgConfigInterface.class_impl[for_machine] = impl
return impl
@staticmethod
def _cli(env: Environment, for_machine: MachineChoice, 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.
'''
for_machine = for_machine if env.is_cross_build() else MachineChoice.HOST
impl: T.Union[Literal[False], T.Optional[PkgConfigInterface]] # Help confused mypy
impl = PkgConfigInterface.instance(env, for_machine, silent)
if impl and not isinstance(impl, PkgConfigCLI):
impl = PkgConfigInterface.class_cli_impl[for_machine]
if impl is False:
impl = PkgConfigCLI(env, for_machine, silent)
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)
return cli._get_env(uninstalled) if cli else EnvironmentVariables()
@staticmethod
def setup_env(environ: EnvironOrDict, env: Environment, for_machine: MachineChoice,
uninstalled: bool = False) -> EnvironOrDict:
cli = PkgConfigInterface._cli(env, for_machine)
return cli._setup_env(environ, uninstalled) if cli else environ
def __init__(self, env: Environment, for_machine: MachineChoice) -> None:
self.env = env
self.for_machine = for_machine
@ -211,29 +242,26 @@ class PkgConfigCLI(PkgConfigInterface):
return None
return out.strip()
@staticmethod
def get_env(environment: Environment, for_machine: MachineChoice,
uninstalled: bool = False) -> EnvironmentVariables:
def _get_env(self, uninstalled: bool = False) -> EnvironmentVariables:
env = EnvironmentVariables()
key = OptionKey('pkg_config_path', machine=for_machine)
extra_paths: T.List[str] = environment.coredata.options[key].value[:]
key = OptionKey('pkg_config_path', machine=self.for_machine)
extra_paths: T.List[str] = self.env.coredata.options[key].value[:]
if uninstalled:
uninstalled_path = Path(environment.get_build_dir(), 'meson-uninstalled').as_posix()
uninstalled_path = Path(self.env.get_build_dir(), 'meson-uninstalled').as_posix()
if uninstalled_path not in extra_paths:
extra_paths.append(uninstalled_path)
env.set('PKG_CONFIG_PATH', extra_paths)
sysroot = environment.properties[for_machine].get_sys_root()
sysroot = self.env.properties[self.for_machine].get_sys_root()
if sysroot:
env.set('PKG_CONFIG_SYSROOT_DIR', [sysroot])
pkg_config_libdir_prop = environment.properties[for_machine].get_pkg_config_libdir()
pkg_config_libdir_prop = self.env.properties[self.for_machine].get_pkg_config_libdir()
if pkg_config_libdir_prop:
env.set('PKG_CONFIG_LIBDIR', pkg_config_libdir_prop)
env.set('PKG_CONFIG', [join_args(self.pkgbin.get_command())])
return env
@staticmethod
def setup_env(env: EnvironOrDict, environment: Environment, for_machine: MachineChoice,
uninstalled: bool = False) -> T.Dict[str, str]:
envvars = PkgConfigCLI.get_env(environment, for_machine, uninstalled)
def _setup_env(self, env: EnvironOrDict, uninstalled: bool = False) -> T.Dict[str, str]:
envvars = self._get_env(uninstalled)
env = envvars.get_env(env)
# Dump all PKG_CONFIG environment variables
for key, value in env.items():
@ -244,7 +272,7 @@ class PkgConfigCLI(PkgConfigInterface):
def _call_pkgbin(self, args: T.List[str], env: T.Optional[EnvironOrDict] = None) -> T.Tuple[int, str, str]:
assert isinstance(self.pkgbin, ExternalProgram)
env = env or os.environ
env = self.setup_env(env, self.env, self.for_machine)
env = self._setup_env(env)
cmd = self.pkgbin.get_command() + args
p, out, err = Popen_safe_logged(cmd, env=env)
return p.returncode, out.strip(), err.strip()

@ -24,7 +24,7 @@ from .. import mlog, build
from ..compilers.compilers import CFLAGS_MAPPING
from ..envconfig import ENV_VAR_PROG_MAP
from ..dependencies import InternalDependency
from ..dependencies.pkgconfig import PkgConfigCLI
from ..dependencies.pkgconfig import PkgConfigInterface
from ..interpreterbase import FeatureNew
from ..interpreter.type_checking import ENV_KW, DEPENDS_KW
from ..interpreterbase.decorators import ContainerTypeInfo, KwargInfo, typed_kwargs, typed_pos_args
@ -40,6 +40,7 @@ if T.TYPE_CHECKING:
from ..interpreter import Interpreter
from ..interpreterbase import TYPE_var
from ..mesonlib import EnvironmentVariables
from ..utils.core import EnvironOrDict
class Dependency(TypedDict):
@ -144,7 +145,7 @@ class ExternalProject(NewExtensionModule):
# Set common env variables like CFLAGS, CC, etc.
link_exelist: T.List[str] = []
link_args: T.List[str] = []
self.run_env = os.environ.copy()
self.run_env: EnvironOrDict = os.environ.copy()
for lang, compiler in self.env.coredata.compilers[MachineChoice.HOST].items():
if any(lang not in i for i in (ENV_VAR_PROG_MAP, CFLAGS_MAPPING)):
continue
@ -165,8 +166,8 @@ class ExternalProject(NewExtensionModule):
self.run_env['LDFLAGS'] = self._quote_and_join(link_args)
self.run_env = self.user_env.get_env(self.run_env)
self.run_env = PkgConfigCLI.setup_env(self.run_env, self.env, MachineChoice.HOST,
uninstalled=True)
self.run_env = PkgConfigInterface.setup_env(self.run_env, self.env, MachineChoice.HOST,
uninstalled=True)
self.build_dir.mkdir(parents=True, exist_ok=True)
self._run('configure', configure_cmd, workdir)

@ -34,7 +34,7 @@ from .. import mesonlib
from .. import mlog
from ..build import CustomTarget, CustomTargetIndex, Executable, GeneratedList, InvalidArguments
from ..dependencies import Dependency, InternalDependency
from ..dependencies.pkgconfig import PkgConfigDependency, PkgConfigCLI
from ..dependencies.pkgconfig import PkgConfigDependency, PkgConfigInterface
from ..interpreter.type_checking import DEPENDS_KW, DEPEND_FILES_KW, ENV_KW, INSTALL_DIR_KW, INSTALL_KW, NoneType, SOURCES_KW, in_set_validator
from ..interpreterbase import noPosargs, noKwargs, FeatureNew, FeatureDeprecated
from ..interpreterbase import typed_kwargs, KwargInfo, ContainerTypeInfo
@ -980,7 +980,7 @@ class GnomeModule(ExtensionModule):
# -uninstalled.pc files Meson generated. It also must respect pkgconfig
# settings user could have set in machine file, like PKG_CONFIG_LIBDIR,
# SYSROOT, etc.
run_env = PkgConfigCLI.get_env(state.environment, MachineChoice.HOST, uninstalled=True)
run_env = PkgConfigInterface.get_env(state.environment, MachineChoice.HOST, uninstalled=True)
# g-ir-scanner uses Python's distutils to find the compiler, which uses 'CC'
cc_exelist = state.environment.coredata.compilers.host['c'].get_exelist()
run_env.set('CC', [quote_arg(x) for x in cc_exelist], ' ')

@ -26,7 +26,7 @@ from .. import dependencies
from .. import mesonlib
from .. import mlog
from ..coredata import BUILTIN_DIR_OPTIONS
from ..dependencies.pkgconfig import PkgConfigDependency, PkgConfigCLI
from ..dependencies.pkgconfig import PkgConfigDependency, PkgConfigInterface
from ..interpreter.type_checking import D_MODULE_VERSIONS_KW, INSTALL_DIR_KW, VARIABLES_KW, NoneType
from ..interpreterbase import FeatureNew, FeatureDeprecated
from ..interpreterbase.decorators import ContainerTypeInfo, KwargInfo, typed_kwargs, typed_pos_args
@ -741,7 +741,7 @@ class PkgConfigModule(NewExtensionModule):
self._metadata[lib.get_id()] = MetaData(
filebase, name, state.current_node)
if self.devenv is None:
self.devenv = PkgConfigCLI.get_env(state.environment, mesonlib.MachineChoice.HOST, uninstalled=True)
self.devenv = PkgConfigInterface.get_env(state.environment, mesonlib.MachineChoice.HOST, uninstalled=True)
return ModuleReturnValue(res, [res])

@ -45,7 +45,7 @@ from mesonbuild.compilers.c import AppleClangCCompiler
from mesonbuild.compilers.cpp import AppleClangCPPCompiler
from mesonbuild.compilers.objc import AppleClangObjCCompiler
from mesonbuild.compilers.objcpp import AppleClangObjCPPCompiler
from mesonbuild.dependencies.pkgconfig import PkgConfigDependency, PkgConfigCLI
from mesonbuild.dependencies.pkgconfig import PkgConfigDependency, PkgConfigCLI, PkgConfigInterface
import mesonbuild.modules.pkgconfig
PKG_CONFIG = os.environ.get('PKG_CONFIG', 'pkg-config')
@ -1169,7 +1169,7 @@ class LinuxlikeTests(BasePlatformTests):
# Regression test: This used to modify the value of `pkg_config_path`
# option, adding the meson-uninstalled directory to it.
PkgConfigCLI.setup_env({}, env, MachineChoice.HOST, uninstalled=True)
PkgConfigInterface.setup_env({}, env, MachineChoice.HOST, uninstalled=True)
pkg_config_path = env.coredata.options[OptionKey('pkg_config_path')].value
self.assertEqual(pkg_config_path, [pkg_dir])

Loading…
Cancel
Save