diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 74033a8fc..cf06ac654 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -1225,6 +1225,10 @@ BUILTIN_CORE_OPTIONS: 'MutableKeyedOptionDictType' = OrderedDict([ (OptionKey('wrap_mode'), BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback', 'nopromote'])), (OptionKey('force_fallback_for'), BuiltinOption(UserArrayOption, 'Force fallback for those subprojects', [])), + # Pkgconfig module + (OptionKey('relocatable', module='pkgconfig'), + BuiltinOption(UserBooleanOption, 'Generate pkgconfig files as relocatable', False)), + # Python module (OptionKey('install_env', module='python'), BuiltinOption(UserComboOption, 'Which python environment to install to', 'prefix', choices=['auto', 'prefix', 'system', 'venv'])), diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index 0eac360f8..bbd3d0748 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -328,7 +328,8 @@ class PkgConfigModule(ExtensionModule): def _generate_pkgconfig_file(self, state, deps, subdirs, name, description, url, version, pcfile, conflicts, variables, - unescaped_variables, uninstalled=False, dataonly=False): + unescaped_variables, uninstalled=False, dataonly=False, + pkgroot=None): coredata = state.environment.get_coredata() referenced_vars = set() optnames = [x.name for x in BUILTIN_DIR_OPTIONS.keys()] @@ -374,6 +375,15 @@ class PkgConfigModule(ExtensionModule): else: outdir = state.environment.scratch_dir prefix = PurePath(coredata.get_option(mesonlib.OptionKey('prefix'))) + if pkgroot: + pkgroot = PurePath(pkgroot) + if not pkgroot.is_absolute(): + pkgroot = prefix / pkgroot + elif prefix not in pkgroot.parents: + raise mesonlib.MesonException('Pkgconfig prefix cannot be outside of the prefix ' + 'when pkgconfig.relocatable=true. ' + f'Pkgconfig prefix is {pkgroot.as_posix()}.') + prefix = PurePath('${pcfiledir}', os.path.relpath(prefix, pkgroot)) fname = os.path.join(outdir, pcfile) with open(fname, 'w', encoding='utf-8') as ofile: for optname in optnames: @@ -591,9 +601,11 @@ class PkgConfigModule(ExtensionModule): pkgroot_name = os.path.join('{libdir}', 'pkgconfig') if not isinstance(pkgroot, str): raise mesonlib.MesonException('Install_dir must be a string.') + relocatable = state.get_option('relocatable', module='pkgconfig') self._generate_pkgconfig_file(state, deps, subdirs, name, description, url, version, pcfile, conflicts, variables, - unescaped_variables, False, dataonly) + unescaped_variables, False, dataonly, + pkgroot=pkgroot if relocatable else None) res = build.Data([mesonlib.File(True, state.environment.get_scratch_dir(), pcfile)], pkgroot, pkgroot_name, None, state.subproject, install_tag='devel') variables = self.interpreter.extract_variables(kwargs, argname='uninstalled_variables', dict_new=True) variables = parse_variable_list(variables)