Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bde1c23

Browse files
committed
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`
1 parent f3d9a71 commit bde1c23

10 files changed

Lines changed: 22 additions & 36 deletions

File tree

mesonbuild/build.py

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from .mesonlib import (
2323
HoldableObject, SecondLevelHolder,
2424
File, MesonException, MachineChoice, PerMachine, OrderedSet, listify,
25-
extract_as_list, classify_unity_sources,
25+
classify_unity_sources,
2626
get_filenames_templates_dict, substitute_values, has_path_sep,
2727
is_parent_path, relpath, PerMachineDefaultable,
2828
MesonBugException, EnvironmentVariables, pickle_load, lazy_property,
@@ -1287,8 +1287,7 @@ def process_kwargs(self, kwargs: BuildTargetKeywordArguments) -> None:
12871287
# internal deps (added inside self.add_deps()) to override them.
12881288
self.add_include_dirs(kwargs.get('include_directories', []))
12891289
# Add dependencies (which also have include_directories)
1290-
deplist = extract_as_list(kwargs, 'dependencies')
1291-
self.add_deps(deplist)
1290+
self.add_deps(kwargs.get('dependencies', []))
12921291
# If an item in this list is False, the output corresponding to
12931292
# the list index of that item will not be installed
12941293
self.install_dir = kwargs.get('install_dir', [])
@@ -1418,8 +1417,7 @@ def has_pch(self) -> bool:
14181417
def get_include_dirs(self) -> T.List['IncludeDirs']:
14191418
return self.include_dirs
14201419

1421-
def add_deps(self, deps):
1422-
deps = listify(deps)
1420+
def add_deps(self, deps: T.List[dependencies.Dependency]) -> None:
14231421
for dep in deps:
14241422
if dep in self.added_deps:
14251423
# Prefer to add dependencies to added_deps which have a name
@@ -1447,29 +1445,11 @@ def add_deps(self, deps):
14471445
self.external_deps.append(extpart)
14481446
# Deps of deps.
14491447
self.add_deps(dep.ext_deps)
1450-
elif isinstance(dep, dependencies.Dependency):
1448+
else:
14511449
if dep not in self.external_deps:
14521450
self.external_deps.append(dep)
14531451
self.process_sourcelist(dep.get_sources())
14541452
self.add_deps(dep.ext_deps)
1455-
elif isinstance(dep, BuildTarget):
1456-
raise InvalidArguments(f'Tried to use a build target {dep.name} as a dependency of target {self.name}.\n'
1457-
'You probably should put it in link_with instead.')
1458-
else:
1459-
# This is a bit of a hack. We do not want Build to know anything
1460-
# about the interpreter so we can't import it and use isinstance.
1461-
# This should be reliable enough.
1462-
if hasattr(dep, 'held_object'):
1463-
# FIXME: subproject is not a real ObjectHolder so we have to do this by hand
1464-
dep = dep.held_object
1465-
if hasattr(dep, 'project_args_frozen') or hasattr(dep, 'global_args_frozen'):
1466-
raise InvalidArguments('Tried to use subproject object as a dependency.\n'
1467-
'You probably wanted to use a dependency declared in it instead.\n'
1468-
'Access it by calling get_variable() on the subproject object.')
1469-
raise InvalidArguments(f'Argument is of an unacceptable type {type(dep).__name__!r}.\nMust be '
1470-
'either an external dependency (returned by find_library() or '
1471-
'dependency()) or an internal dependency (returned by '
1472-
'declare_dependency()).')
14731453

14741454
dep_d_features = dep.d_features
14751455

mesonbuild/interpreter/interpreter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3559,7 +3559,7 @@ def add_stdlib_info(self, target):
35593559
for l in target.compilers.keys():
35603560
dep = self.build.stdlibs[target.for_machine].get(l, None)
35613561
if dep:
3562-
target.add_deps(dep)
3562+
target.add_deps([dep])
35633563

35643564
def check_sources_exist(self, subdir, sources):
35653565
for s in sources:

mesonbuild/interpreter/kwargs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ class _BaseBuildTarget(TypedDict):
337337

338338
build_by_default: bool
339339
build_rpath: str
340+
dependencies: T.List[Dependency]
340341
extra_files: T.List[FileOrString]
341342
gnu_symbol_visibility: str
342343
include_directories: T.List[build.IncludeDirs]

mesonbuild/interpreter/type_checking.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ def _default_options_convertor(raw: T.Union[str, T.List[str], T.Dict[str, Elemen
426426
ContainerTypeInfo(list, (Dependency, InternalDependency)),
427427
listify=True,
428428
default=[],
429+
extra_types={
430+
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.',
431+
},
429432
)
430433

431434
D_MODULE_VERSIONS_KW: KwargInfo[T.List[T.Union[str, int]]] = KwargInfo(
@@ -721,6 +724,7 @@ def _pch_convertor(args: T.List[str]) -> T.Optional[T.Tuple[str, T.Optional[str]
721724
*_LANGUAGE_KWS,
722725
BT_SOURCES_KW,
723726
INCLUDE_DIRECTORIES.evolve(since_values={ContainerTypeInfo(list, str): '0.50.0'}),
727+
DEPENDENCIES_KW,
724728
INCLUDE_DIRECTORIES.evolve(name='d_import_dirs'),
725729
_NAME_PREFIX_KW,
726730
_NAME_PREFIX_KW.evolve(name='name_suffix', validator=_name_suffix_validator),
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int func(void) { return 0; }

test cases/failing/124 subproject object as a dependency/main.c renamed to test cases/common/287 invalid dependency arguments/main.c

File renamed without changes.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
project('test', 'c')
2+
3+
testcase expect_error('executable keyword argument \'dependencies\' was of type array[SubprojectHolder] but should have been array[Dependency | InternalDependency]')
4+
executable('main', 'main.c', dependencies: subproject('sub'))
5+
endtestcase
6+
7+
lib = static_library('lib', 'lib.c')
8+
9+
testcase expect_error('executable keyword argument \'dependencies\' was of type array[StaticLibrary] but should have been array[Dependency | InternalDependency]. Tried to use a build_target "lib" as a dependency. This should be in `link_with` or `link_whole` instead.')
10+
executable('main', 'main.c', dependencies : lib)
11+
endtestcase

test cases/failing/124 subproject object as a dependency/subprojects/sub/meson.build renamed to test cases/common/287 invalid dependency arguments/subprojects/sub/meson.build

File renamed without changes.

test cases/failing/124 subproject object as a dependency/meson.build

Lines changed: 0 additions & 4 deletions
This file was deleted.

test cases/failing/124 subproject object as a dependency/test.json

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)