aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/interpreter
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2022-05-01 00:01:03 +0300
committerGitHub <noreply@github.com>2022-05-01 00:01:03 +0300
commitbba588d8b03a9125bf5c4faaad31b70d39242b68 (patch)
tree63afdf87d9a5bfbb0953170ac89a46bedb02710d /mesonbuild/interpreter
parentb30d04f52b5e13bf0c1047439465997184869c09 (diff)
parentc181f2c70bd606f0100f74844fcf9697be16c217 (diff)
downloadmeson-bba588d8b03a9125bf5c4faaad31b70d39242b68.zip
meson-bba588d8b03a9125bf5c4faaad31b70d39242b68.tar.gz
meson-bba588d8b03a9125bf5c4faaad31b70d39242b68.tar.bz2
Merge pull request #10039 from eli-schwartz/wayland-protocols-subproject-files
dependencies: allow get_variable to expose files from subprojects
Diffstat (limited to 'mesonbuild/interpreter')
-rw-r--r--mesonbuild/interpreter/interpreter.py41
-rw-r--r--mesonbuild/interpreter/interpreterobjects.py2
-rw-r--r--mesonbuild/interpreter/primitives/__init__.py8
-rw-r--r--mesonbuild/interpreter/primitives/string.py15
4 files changed, 63 insertions, 3 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index d5e7dbd..6058838 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -420,6 +420,7 @@ class Interpreter(InterpreterBase, HoldableObject):
bool: P_OBJ.BooleanHolder,
str: P_OBJ.StringHolder,
P_OBJ.MesonVersionString: P_OBJ.MesonVersionStringHolder,
+ P_OBJ.DependencyVariableString: P_OBJ.DependencyVariableStringHolder,
# Meson types
mesonlib.File: OBJ.FileHolder,
@@ -669,6 +670,18 @@ class Interpreter(InterpreterBase, HoldableObject):
d_module_versions = extract_as_list(kwargs, 'd_module_versions')
d_import_dirs = self.extract_incdirs(kwargs, 'd_import_dirs')
final_deps = []
+ srcdir = Path(self.environment.source_dir)
+ # convert variables which refer to an -uninstalled.pc style datadir
+ for k, v in variables.items():
+ try:
+ p = Path(v)
+ except ValueError:
+ continue
+ else:
+ if not self.is_subproject() and srcdir / self.subproject_dir in p.parents:
+ continue
+ if p.is_absolute() and p.is_dir() and srcdir / self.root_subdir in p.resolve().parents:
+ variables[k] = P_OBJ.DependencyVariableString(v)
for d in deps:
if not isinstance(d, (dependencies.Dependency, dependencies.ExternalLibrary, dependencies.InternalDependency)):
raise InterpreterException('Dependencies must be external deps')
@@ -2721,7 +2734,13 @@ external dependencies (including libraries) must go to "dependencies".''')
@typed_pos_args('join_paths', varargs=str, min_varargs=1)
@noKwargs
def func_join_paths(self, node: mparser.BaseNode, args: T.Tuple[T.List[str]], kwargs: 'TYPE_kwargs') -> str:
- return os.path.join(*args[0]).replace('\\', '/')
+ parts = args[0]
+ other = os.path.join('', *parts[1:]).replace('\\', '/')
+ ret = os.path.join(*parts).replace('\\', '/')
+ if isinstance(parts[0], P_OBJ.DependencyVariableString) and '..' not in other:
+ return P_OBJ.DependencyVariableString(ret)
+ else:
+ return ret
def run(self) -> None:
super().run()
@@ -2763,6 +2782,26 @@ Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey
# declare_dependency).
def validate_within_subproject(self, subdir, fname):
srcdir = Path(self.environment.source_dir)
+ builddir = Path(self.environment.build_dir)
+ if isinstance(fname, P_OBJ.DependencyVariableString):
+ def validate_installable_file(fpath: Path) -> bool:
+ installablefiles: T.Set[Path] = set()
+ for d in self.build.data:
+ for s in d.sources:
+ installablefiles.add(Path(s.absolute_path(srcdir, builddir)))
+ installabledirs = [str(Path(srcdir, s.source_subdir)) for s in self.build.install_dirs]
+ if fpath in installablefiles:
+ return True
+ for d in installabledirs:
+ if str(fpath).startswith(d):
+ return True
+ return False
+
+ norm = Path(fname)
+ # variables built from a dep.get_variable are allowed to refer to
+ # subproject files, as long as they are scheduled to be installed.
+ if validate_installable_file(norm):
+ return
norm = Path(srcdir, subdir, fname).resolve()
if os.path.isdir(norm):
inputtype = 'directory'
diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py
index a07d548..e59ba6b 100644
--- a/mesonbuild/interpreter/interpreterobjects.py
+++ b/mesonbuild/interpreter/interpreterobjects.py
@@ -479,7 +479,7 @@ class DependencyHolder(ObjectHolder[Dependency]):
KwargInfo('default_value', (str, NoneType)),
KwargInfo('pkgconfig_define', ContainerTypeInfo(list, str, pairs=True), default=[], listify=True),
)
- def variable_method(self, args: T.Tuple[T.Optional[str]], kwargs: 'kwargs.DependencyGetVariable') -> T.Union[str, T.List[str]]:
+ def variable_method(self, args: T.Tuple[T.Optional[str]], kwargs: 'kwargs.DependencyGetVariable') -> str:
default_varname = args[0]
if default_varname is not None:
FeatureNew('Positional argument to dependency.get_variable()', '0.58.0').use(self.subproject, self.current_node)
diff --git a/mesonbuild/interpreter/primitives/__init__.py b/mesonbuild/interpreter/primitives/__init__.py
index b4fe621..1874d0d 100644
--- a/mesonbuild/interpreter/primitives/__init__.py
+++ b/mesonbuild/interpreter/primitives/__init__.py
@@ -10,6 +10,8 @@ __all__ = [
'StringHolder',
'MesonVersionString',
'MesonVersionStringHolder',
+ 'DependencyVariableString',
+ 'DependencyVariableStringHolder',
]
from .array import ArrayHolder
@@ -17,4 +19,8 @@ from .boolean import BooleanHolder
from .dict import DictHolder
from .integer import IntegerHolder
from .range import RangeHolder
-from .string import StringHolder, MesonVersionString, MesonVersionStringHolder
+from .string import (
+ StringHolder,
+ MesonVersionString, MesonVersionStringHolder,
+ DependencyVariableString, DependencyVariableStringHolder
+)
diff --git a/mesonbuild/interpreter/primitives/string.py b/mesonbuild/interpreter/primitives/string.py
index 9129303..1fd6e92 100644
--- a/mesonbuild/interpreter/primitives/string.py
+++ b/mesonbuild/interpreter/primitives/string.py
@@ -179,3 +179,18 @@ class MesonVersionStringHolder(StringHolder):
def version_compare_method(self, args: T.Tuple[str], kwargs: TYPE_kwargs) -> bool:
self.interpreter.tmp_meson_version = args[0]
return version_compare(self.held_object, args[0])
+
+# These special subclasses of string exist to cover the case where a dependency
+# exports a string variable interchangeable with a system dependency. This
+# matters because a dependency can only have string-type get_variable() return
+# values. If at any time dependencies start supporting additional variable
+# types, this class could be deprecated.
+class DependencyVariableString(str):
+ pass
+
+class DependencyVariableStringHolder(StringHolder):
+ def op_div(self, other: str) -> T.Union[str, DependencyVariableString]:
+ ret = super().op_div(other)
+ if '..' in other:
+ return ret
+ return DependencyVariableString(ret)