Skip to content

Commit b34dad8

Browse files
committed
build: move per-project data to a separate dataclass
This makes things easier to understand, with the project_args and project_link_args having the same structure as Build.global_args and Build.global_link_args. The difference is that the new member always includes an entry for the root project, so adjust those cases that need to look at subprojects only. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 87955a9 commit b34dad8

File tree

5 files changed

+37
-30
lines changed

5 files changed

+37
-30
lines changed

mesonbuild/build.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,14 @@ def to_json(self) -> T.Dict[str, T.Union[str, T.List[str]]]:
327327
}
328328

329329

330+
@dataclass(eq=False)
331+
class BuildProject:
332+
name: str
333+
version: str
334+
project_args: PerMachine[T.Dict[str, T.List[str]]] = field(default_factory=lambda: PerMachine({}, {}))
335+
project_link_args: PerMachine[T.Dict[str, T.List[str]]] = field(default_factory=lambda: PerMachine({}, {}))
336+
337+
330338
# literally everything isn't dataclass stuff
331339
class Build:
332340
"""A class that holds the status of one build including
@@ -339,13 +347,11 @@ def __init__(self, environment: Environment):
339347
self.project_name = 'name of master project'
340348
self.project_version: T.Optional[str] = None
341349
self.environment = environment
342-
self.projects: T.Dict[SubProject, str] = {}
350+
self.projects: T.Dict[SubProject, BuildProject] = {}
343351
self.targets: 'T.OrderedDict[str, T.Union[CustomTarget, BuildTarget]]' = OrderedDict()
344352
self.targetnames: T.Set[T.Tuple[str, str]] = set() # Set of executable names and their subdir
345353
self.global_args: PerMachine[T.Dict[str, T.List[str]]] = PerMachine({}, {})
346354
self.global_link_args: PerMachine[T.Dict[str, T.List[str]]] = PerMachine({}, {})
347-
self.projects_args: PerMachine[T.Dict[str, T.Dict[str, T.List[str]]]] = PerMachine({}, {})
348-
self.projects_link_args: PerMachine[T.Dict[str, T.Dict[str, T.List[str]]]] = PerMachine({}, {})
349355
self.tests: T.List['Test'] = []
350356
self.benchmarks: T.List['Test'] = []
351357
self.headers: T.List[Headers] = []
@@ -354,7 +360,6 @@ def __init__(self, environment: Environment):
354360
self.data: T.List[Data] = []
355361
self.symlinks: T.List[SymlinkData] = []
356362
self.static_linker: PerMachine[T.Optional[StaticLinker]] = PerMachine(None, None)
357-
self.subprojects: T.Dict[SubProject, str] = {}
358363
self.subproject_dir = ''
359364
self.install_scripts: T.List['ExecutableSerialisation'] = []
360365
self.postconf_scripts: T.List['ExecutableSerialisation'] = []
@@ -445,7 +450,7 @@ def ensure_static_linker(self, compiler: Compiler) -> None:
445450
self.static_linker[for_machine] = detect_static_linker(self.environment, compiler)
446451

447452
def get_project(self) -> str:
448-
return self.projects[SubProject('')]
453+
return self.projects[SubProject('')].name
449454

450455
def get_subproject_dir(self):
451456
return self.subproject_dir
@@ -482,8 +487,7 @@ def get_global_args(self, compiler: 'Compiler', for_machine: 'MachineChoice') ->
482487
return d.get(compiler.get_language(), [])
483488

484489
def get_project_args(self, compiler: 'Compiler', target: BuildTarget) -> T.List[str]:
485-
d = self.projects_args[target.for_machine]
486-
args = d.get(target.subproject)
490+
args = self.projects[target.subproject].project_args[target.for_machine]
487491
if not args:
488492
return []
489493
return args.get(compiler.get_language(), [])
@@ -493,9 +497,7 @@ def get_global_link_args(self, compiler: 'Compiler', for_machine: 'MachineChoice
493497
return d.get(compiler.get_language(), [])
494498

495499
def get_project_link_args(self, compiler: 'Compiler', target: BuildTarget) -> T.List[str]:
496-
d = self.projects_link_args[target.for_machine]
497-
498-
link_args = d.get(target.subproject)
500+
link_args = self.projects[target.subproject].project_link_args[target.for_machine]
499501
if not link_args:
500502
return []
501503

mesonbuild/interpreter/interpreter.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ def do_subproject(self, subp_name: SubProject, kwargs: kwtypes.DoSubproject, for
902902
if required and not subproject.found():
903903
raise InterpreterException(f'Subproject "{subproject.subdir}" required but not found.')
904904
if kwargs['version']:
905-
pv = self.build.subprojects[subp_name]
905+
pv = self.build.projects[subp_name].version
906906
wanted = kwargs['version']
907907
if pv == 'undefined' or not mesonlib.version_compare_many(pv, wanted)[0]:
908908
raise InterpreterException(f'Subproject {subp_name} version is {pv} but {wanted} required.')
@@ -1016,7 +1016,6 @@ def _do_subproject_meson(self, subp_name: SubProject, subdir: str,
10161016
# We always need the subi.build_def_files, to propagate sub-sub-projects
10171017
self.build_def_files.update(subi.get_build_def_files())
10181018
self.build.merge(subi.build)
1019-
self.build.subprojects[subp_name] = subi.project_version
10201019
return self.subprojects[subp_name]
10211020

10221021
def _do_subproject_cmake(self, subp_name: SubProject, subdir: str,
@@ -1276,7 +1275,7 @@ def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str
12761275
if self.cargo is None:
12771276
self.load_root_cargo_lock_file()
12781277

1279-
self.build.projects[self.subproject] = proj_name
1278+
self.build.projects[self.subproject] = build.BuildProject(proj_name, self.project_version)
12801279
mlog.log('Project name:', mlog.bold(proj_name))
12811280
mlog.log('Project version:', mlog.bold(self.project_version))
12821281

@@ -2934,12 +2933,17 @@ def func_add_global_link_arguments(self, node: mparser.FunctionNode, args: T.Tup
29342933
@typed_pos_args('add_project_arguments', varargs=str)
29352934
@typed_kwargs('add_project_arguments', NATIVE_KW, LANGUAGE_KW)
29362935
def func_add_project_arguments(self, node: mparser.FunctionNode, args: T.Tuple[T.List[str]], kwargs: 'kwtypes.FuncAddProjectArgs') -> None:
2937-
self._add_project_arguments(node, self.build.projects_args[kwargs['native']], args[0], kwargs)
2936+
self._add_project_arguments(node, self.current_build_project().project_args[kwargs['native']],
2937+
args[0], kwargs)
29382938

29392939
@typed_pos_args('add_project_link_arguments', varargs=str)
29402940
@typed_kwargs('add_global_arguments', NATIVE_KW, LANGUAGE_KW)
29412941
def func_add_project_link_arguments(self, node: mparser.FunctionNode, args: T.Tuple[T.List[str]], kwargs: 'kwtypes.FuncAddProjectArgs') -> None:
2942-
self._add_project_arguments(node, self.build.projects_link_args[kwargs['native']], args[0], kwargs)
2942+
self._add_project_arguments(node, self.current_build_project().project_link_args[kwargs['native']],
2943+
args[0], kwargs)
2944+
2945+
def current_build_project(self) -> build.BuildProject:
2946+
return self.build.projects[self.subproject]
29432947

29442948
@FeatureNew('add_project_dependencies', '0.63.0')
29452949
@typed_pos_args('add_project_dependencies', varargs=dependencies.Dependency)
@@ -2959,8 +2963,10 @@ def func_add_project_dependencies(self, node: mparser.FunctionNode, args: T.Tupl
29592963
for idir in i.to_string_list(self.environment.get_source_dir(), self.environment.get_build_dir()):
29602964
compile_args.extend(comp.get_include_args(idir, system_incdir))
29612965

2962-
self._add_project_arguments(node, self.build.projects_args[for_machine], compile_args, kwargs)
2963-
self._add_project_arguments(node, self.build.projects_link_args[for_machine], d.get_link_args(), kwargs)
2966+
self._add_project_arguments(node, self.current_build_project().project_args[for_machine],
2967+
compile_args, kwargs)
2968+
self._add_project_arguments(node, self.current_build_project().project_link_args[for_machine],
2969+
d.get_link_args(), kwargs)
29642970

29652971
def _warn_about_builtin_args(self, args: T.List[str]) -> None:
29662972
# -Wpedantic is deliberately not included, since some people want to use it but not use -Wextra
@@ -3005,10 +3011,7 @@ def _add_global_arguments(self, node: mparser.FunctionNode, argsdict: T.Dict[str
30053011

30063012
def _add_project_arguments(self, node: mparser.FunctionNode, argsdict: T.Dict[str, T.Dict[str, T.List[str]]],
30073013
args: T.List[str], kwargs: 'kwtypes.FuncAddProjectArgs') -> None:
3008-
if self.subproject not in argsdict:
3009-
argsdict[self.subproject] = {}
3010-
self._add_arguments(node, argsdict[self.subproject],
3011-
self.project_args_frozen, args, kwargs)
3014+
self._add_arguments(node, argsdict, self.project_args_frozen, args, kwargs)
30123015

30133016
def _add_arguments(self, node: mparser.FunctionNode, argsdict: T.Dict[str, T.List[str]],
30143017
args_frozen: bool, args: T.List[str], kwargs: 'kwtypes.FuncAddProjectArgs') -> None:

mesonbuild/mdist.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,9 +393,10 @@ def run(options: argparse.Namespace) -> int:
393393
extra_meson_args = []
394394
if options.include_subprojects:
395395
subproject_dir = os.path.join(src_root, b.subproject_dir)
396-
for sub in b.subprojects:
397-
directory = wrap.get_directory(subproject_dir, sub)
398-
subprojects[sub] = os.path.join(b.subproject_dir, directory)
396+
for sub in b.projects:
397+
if sub:
398+
directory = wrap.get_directory(subproject_dir, sub)
399+
subprojects[sub] = os.path.join(b.subproject_dir, directory)
399400
extra_meson_args.append('-Dwrap_mode=nodownload')
400401

401402
cls: T.Type[Dist]

mesonbuild/mintro.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from . import build, environment, mesonlib, options, coredata as cdata
2323
from .ast import IntrospectionInterpreter, AstConditionLevel, AstIDGenerator, AstIndentationGenerator, AstJSONPrinter
2424
from .backend import backends
25-
from .interpreterbase import SubProject, UnknownValue
25+
from .interpreterbase import UnknownValue
2626
from .options import OptionKey
2727

2828
if T.TYPE_CHECKING:
@@ -457,12 +457,13 @@ def list_projinfo(builddata: build.Build) -> T.Dict[str, T.Union[str, T.List[str
457457
'subproject_dir': builddata.subproject_dir,
458458
}
459459
subprojects = []
460-
for k, v in builddata.subprojects.items():
461-
subp = SubProject(k)
460+
for k, build_proj in builddata.projects.items():
461+
if not k:
462+
continue
462463
c: T.Dict[str, str] = {
463464
'name': k,
464-
'version': v,
465-
'descriptive_name': builddata.projects.get(subp),
465+
'version': build_proj.version,
466+
'descriptive_name': build_proj.name,
466467
}
467468
subprojects.append(c)
468469
result['subprojects'] = subprojects

mesonbuild/modules/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def __init__(self, interpreter: 'Interpreter') -> None:
5151
self.headers = interpreter.build.get_headers()
5252
self.man = interpreter.build.get_man()
5353
self.global_args = interpreter.build.global_args.host
54-
self.project_args = interpreter.build.projects_args.host.get(interpreter.subproject, {})
54+
self.project_args = interpreter.current_build_project().project_args.host
5555
self.current_node = interpreter.current_node
5656

5757
def get_include_args(self, include_dirs: T.Iterable[T.Union[str, build.IncludeDirs]], prefix: str = '-I') -> T.List[str]:

0 commit comments

Comments
 (0)