diff options
| author | Dylan Baker <dylan@pnwbakers.com> | 2025-12-08 10:53:08 -0800 |
|---|---|---|
| committer | Dylan Baker <dylan@pnwbakers.com> | 2025-12-17 12:46:50 -0800 |
| commit | bde1c23b4f3eb9eb63e835b722bb9bbcccc4c8c1 (patch) | |
| tree | 3f7ef84071483aa7cdca5337615ea2259180b172 /mesonbuild | |
| parent | f3d9a71a1bea661495c1d3c6004b26b4497fb1c9 (diff) | |
| download | meson-bde1c23b4f3eb9eb63e835b722bb9bbcccc4c8c1.tar.gz | |
interpreter|build: Use typed_kwargs for build_target(dependencies)
What is basically impossible is to handle `SubprojectHolder`, because
it's not a true holder but an interpreter object. Well, impossible
without changing SubprojectHolder into a true holder, because it's
avoiding the circular import becomes extremely convoluted otherwise, and
refactoring is difficult because the held object is itself an
Interpreter. It's a rather complex problem to solve gracefully. I've
punted to avoid the complexity, it does mean that the error message is
somewhat less exact.
I don't think this is actually a huge problem because we've really
guided people away from using `subproject()` and to instead use
dependency fallbacks, which don't have this problem to begin with.
This removes validation from the build layer, and puts it in
interpreter. For code sharing reasons this means that
`internal_dependency` also gets more fine grained error messages.
The test case for this has been modified to use the `testcase
expect_error` construct, and thus has been moved to the common tests
directory. It's also been extended to cover both the library case, which
gives coverage for the `extra_types` in `KwargInfo`
Diffstat (limited to 'mesonbuild')
| -rw-r--r-- | mesonbuild/build.py | 28 | ||||
| -rw-r--r-- | mesonbuild/interpreter/interpreter.py | 2 | ||||
| -rw-r--r-- | mesonbuild/interpreter/kwargs.py | 1 | ||||
| -rw-r--r-- | mesonbuild/interpreter/type_checking.py | 4 |
4 files changed, 10 insertions, 25 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 37a437812..ae6770be2 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -22,7 +22,7 @@ from . import programs from .mesonlib import ( HoldableObject, SecondLevelHolder, File, MesonException, MachineChoice, PerMachine, OrderedSet, listify, - extract_as_list, classify_unity_sources, + classify_unity_sources, get_filenames_templates_dict, substitute_values, has_path_sep, is_parent_path, relpath, PerMachineDefaultable, MesonBugException, EnvironmentVariables, pickle_load, lazy_property, @@ -1287,8 +1287,7 @@ class BuildTarget(Target): # internal deps (added inside self.add_deps()) to override them. self.add_include_dirs(kwargs.get('include_directories', [])) # Add dependencies (which also have include_directories) - deplist = extract_as_list(kwargs, 'dependencies') - self.add_deps(deplist) + self.add_deps(kwargs.get('dependencies', [])) # If an item in this list is False, the output corresponding to # the list index of that item will not be installed self.install_dir = kwargs.get('install_dir', []) @@ -1418,8 +1417,7 @@ class BuildTarget(Target): def get_include_dirs(self) -> T.List['IncludeDirs']: return self.include_dirs - def add_deps(self, deps): - deps = listify(deps) + def add_deps(self, deps: T.List[dependencies.Dependency]) -> None: for dep in deps: if dep in self.added_deps: # Prefer to add dependencies to added_deps which have a name @@ -1447,29 +1445,11 @@ class BuildTarget(Target): self.external_deps.append(extpart) # Deps of deps. self.add_deps(dep.ext_deps) - elif isinstance(dep, dependencies.Dependency): + else: if dep not in self.external_deps: self.external_deps.append(dep) self.process_sourcelist(dep.get_sources()) self.add_deps(dep.ext_deps) - elif isinstance(dep, BuildTarget): - raise InvalidArguments(f'Tried to use a build target {dep.name} as a dependency of target {self.name}.\n' - 'You probably should put it in link_with instead.') - else: - # This is a bit of a hack. We do not want Build to know anything - # about the interpreter so we can't import it and use isinstance. - # This should be reliable enough. - if hasattr(dep, 'held_object'): - # FIXME: subproject is not a real ObjectHolder so we have to do this by hand - dep = dep.held_object - if hasattr(dep, 'project_args_frozen') or hasattr(dep, 'global_args_frozen'): - raise InvalidArguments('Tried to use subproject object as a dependency.\n' - 'You probably wanted to use a dependency declared in it instead.\n' - 'Access it by calling get_variable() on the subproject object.') - raise InvalidArguments(f'Argument is of an unacceptable type {type(dep).__name__!r}.\nMust be ' - 'either an external dependency (returned by find_library() or ' - 'dependency()) or an internal dependency (returned by ' - 'declare_dependency()).') dep_d_features = dep.d_features diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 3a0cae041..3b87f48ea 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -3559,7 +3559,7 @@ class Interpreter(InterpreterBase, HoldableObject): for l in target.compilers.keys(): dep = self.build.stdlibs[target.for_machine].get(l, None) if dep: - target.add_deps(dep) + target.add_deps([dep]) def check_sources_exist(self, subdir, sources): for s in sources: diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index c08ceb759..1dee9a65c 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -337,6 +337,7 @@ class _BaseBuildTarget(TypedDict): build_by_default: bool build_rpath: str + dependencies: T.List[Dependency] extra_files: T.List[FileOrString] gnu_symbol_visibility: str include_directories: T.List[build.IncludeDirs] diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py index 478924828..7515cbcef 100644 --- a/mesonbuild/interpreter/type_checking.py +++ b/mesonbuild/interpreter/type_checking.py @@ -426,6 +426,9 @@ DEPENDENCIES_KW: KwargInfo[T.List[Dependency]] = KwargInfo( ContainerTypeInfo(list, (Dependency, InternalDependency)), listify=True, default=[], + extra_types={ + BuildTarget: lambda arg: f'Tried to use a build_target "{T.cast("BuildTarget", arg).name}" as a dependency. This should be in `link_with` or `link_whole` instead.', + }, ) D_MODULE_VERSIONS_KW: KwargInfo[T.List[T.Union[str, int]]] = KwargInfo( @@ -721,6 +724,7 @@ _BUILD_TARGET_KWS: T.List[KwargInfo] = [ *_LANGUAGE_KWS, BT_SOURCES_KW, INCLUDE_DIRECTORIES.evolve(since_values={ContainerTypeInfo(list, str): '0.50.0'}), + DEPENDENCIES_KW, INCLUDE_DIRECTORIES.evolve(name='d_import_dirs'), _NAME_PREFIX_KW, _NAME_PREFIX_KW.evolve(name='name_suffix', validator=_name_suffix_validator), |
