diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2022-05-01 00:01:03 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-01 00:01:03 +0300 |
commit | bba588d8b03a9125bf5c4faaad31b70d39242b68 (patch) | |
tree | 63afdf87d9a5bfbb0953170ac89a46bedb02710d /mesonbuild/interpreter | |
parent | b30d04f52b5e13bf0c1047439465997184869c09 (diff) | |
parent | c181f2c70bd606f0100f74844fcf9697be16c217 (diff) | |
download | meson-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.py | 41 | ||||
-rw-r--r-- | mesonbuild/interpreter/interpreterobjects.py | 2 | ||||
-rw-r--r-- | mesonbuild/interpreter/primitives/__init__.py | 8 | ||||
-rw-r--r-- | mesonbuild/interpreter/primitives/string.py | 15 |
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) |