Skip to content

Commit

Permalink
build|interpreter: hold subprojects on a per-machine basis
Browse files Browse the repository at this point in the history
This doesn't actually enable per-machine subprojects, only set up the
storage to be per-machine
  • Loading branch information
dcbaker committed Jul 12, 2023
1 parent eb4bab5 commit 2fbc86c
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 22 deletions.
2 changes: 1 addition & 1 deletion mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def __init__(self, environment: environment.Environment):
self.data: T.List[Data] = []
self.symlinks: T.List[SymlinkData] = []
self.static_linker: PerMachine[StaticLinker] = PerMachine(None, None)
self.subprojects = {}
self.subprojects: PerMachine[T.Dict[str, str]] = PerMachine({}, {})
self.subproject_dir = ''
self.install_scripts: T.List['ExecutableSerialisation'] = []
self.postconf_scripts: T.List['ExecutableSerialisation'] = []
Expand Down
2 changes: 1 addition & 1 deletion mesonbuild/interpreter/dependencyfallbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def _do_subproject(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs
return self._get_subproject_dep(subp_name, varname, kwargs)

def _get_subproject(self, subp_name: str) -> T.Optional[SubprojectHolder]:
sub = self.interpreter.subprojects.get(subp_name)
sub = self.interpreter.subprojects.host.get(subp_name)
if sub and sub.found():
return sub
return None
Expand Down
36 changes: 18 additions & 18 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ def __init__(
self.processed_buildfiles = set() # type: T.Set[str]
self.project_args_frozen = False
self.global_args_frozen = False # implies self.project_args_frozen
self.subprojects: T.Dict[str, SubprojectHolder] = {}
self.subproject_stack: T.List[str] = []
self.subprojects: PerMachine[T.Dict[str, SubprojectHolder]] = PerMachine({}, {})
self.subproject_stack: PerMachine[T.List[str]] = PerMachine({}, {})
self.configure_file_outputs: T.Dict[str, int] = {}
# Passed from the outside, only used in subprojects.
if default_project_options:
Expand Down Expand Up @@ -882,7 +882,7 @@ def disabled_subproject(self, subp_name: str, disabled_feature: T.Optional[str]
exception: T.Optional[Exception] = None) -> SubprojectHolder:
sub = SubprojectHolder(NullSubprojectInterpreter(), os.path.join(self.subproject_dir, subp_name),
disabled_feature=disabled_feature, exception=exception)
self.subprojects[subp_name] = sub
self.subprojects.host[subp_name] = sub
return sub

def do_subproject(self, subp_name: str, method: Literal['meson', 'cmake'], kwargs: kwtypes.DoSubproject) -> SubprojectHolder:
Expand All @@ -904,16 +904,16 @@ def do_subproject(self, subp_name: str, method: Literal['meson', 'cmake'], kwarg
if has_path_sep(subp_name):
mlog.warning('Subproject name has a path separator. This may cause unexpected behaviour.',
location=self.current_node)
if subp_name in self.subproject_stack:
fullstack = self.subproject_stack + [subp_name]
if subp_name in self.subproject_stack.host:
fullstack = self.subproject_stack.host + [subp_name]
incpath = ' => '.join(fullstack)
raise InvalidCode(f'Recursive include of subprojects: {incpath}.')
if subp_name in self.subprojects:
subproject = self.subprojects[subp_name]
if subp_name in self.subprojects.host:
subproject = self.subprojects.host[subp_name]
if required and not subproject.found():
raise InterpreterException(f'Subproject "{subproject.subdir}" required but not found.')
if kwargs['version']:
pv = self.build.subprojects[subp_name]
pv = self.build.subprojects.host[subp_name]
wanted = kwargs['version']
if pv == 'undefined' or not mesonlib.version_compare_many(pv, wanted)[0]:
raise InterpreterException(f'Subproject {subp_name} version is {pv} but {wanted} required.')
Expand All @@ -933,7 +933,7 @@ def do_subproject(self, subp_name: str, method: Literal['meson', 'cmake'], kwarg
os.makedirs(os.path.join(self.build.environment.get_build_dir(), subdir), exist_ok=True)
self.global_args_frozen = True

stack = ':'.join(self.subproject_stack + [subp_name])
stack = ':'.join(self.subproject_stack.host + [subp_name])
m = ['\nExecuting subproject', mlog.bold(stack)]
if method != 'meson':
m += ['method', mlog.bold(method)]
Expand Down Expand Up @@ -981,7 +981,7 @@ def _do_subproject_meson(self, subp_name: str, subdir: str,
subi.bound_holder_map = self.bound_holder_map
subi.summary = self.summary

subi.subproject_stack = self.subproject_stack + [subp_name]
subi.subproject_stack.host = self.subproject_stack.host + [subp_name]
current_active = self.active_projectname
with mlog.nested_warnings():
subi.run()
Expand All @@ -996,17 +996,17 @@ def _do_subproject_meson(self, subp_name: str, subdir: str,
if pv == 'undefined' or not mesonlib.version_compare_many(pv, wanted)[0]:
raise InterpreterException(f'Subproject {subp_name} version is {pv} but {wanted} required.')
self.active_projectname = current_active
self.subprojects.update(subi.subprojects)
self.subprojects[subp_name] = SubprojectHolder(subi, subdir, warnings=subi_warnings,
callstack=self.subproject_stack)
self.subprojects.host.update(subi.subprojects)
self.subprojects.host[subp_name] = SubprojectHolder(subi, subdir, warnings=subi_warnings,
callstack=self.subproject_stack.host)
# Duplicates are possible when subproject uses files from project root
if build_def_files:
self.build_def_files.update(build_def_files)
# We always need the subi.build_def_files, to propagate sub-sub-projects
self.build_def_files.update(subi.build_def_files)
self.build.merge(subi.build)
self.build.subprojects[subp_name] = subi.project_version
return self.subprojects[subp_name]
self.build.subprojects.host[subp_name] = subi.project_version
return self.subprojects.host[subp_name]

def _do_subproject_cmake(self, subp_name: str, subdir: str, subdir_abs: str,
default_options: T.Dict[OptionKey, str],
Expand Down Expand Up @@ -1373,7 +1373,7 @@ def summary_impl(self, section: str, values, kwargs: 'kwtypes.Summary') -> None:
def _print_summary(self) -> None:
# Add automatic 'Subprojects' section in main project.
all_subprojects = collections.OrderedDict()
for name, subp in sorted(self.subprojects.items()):
for name, subp in sorted(self.subprojects.host.items()):
value = [subp.found()]
if subp.disabled_feature:
value += [f'Feature {subp.disabled_feature!r} disabled']
Expand Down Expand Up @@ -1405,7 +1405,7 @@ def _print_summary(self) -> None:
mlog.log('') # newline
main_summary = self.summary.pop('', None)
for subp_name, summary in sorted(self.summary.items()):
if self.subprojects[subp_name].found():
if self.subprojects.host[subp_name].found():
summary.dump()
if main_summary:
main_summary.dump()
Expand Down Expand Up @@ -1638,7 +1638,7 @@ def find_program_impl(self, args: T.List[mesonlib.FileOrString],
version = version_func(progobj)
elif isinstance(progobj, build.Executable):
if progobj.subproject:
interp = self.subprojects[progobj.subproject].held_object
interp = self.subprojects.host[progobj.subproject].held_object
else:
interp = self
assert isinstance(interp, Interpreter)
Expand Down
2 changes: 1 addition & 1 deletion mesonbuild/mdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ def run(options: argparse.Namespace) -> int:
extra_meson_args = []
if options.include_subprojects:
subproject_dir = os.path.join(src_root, b.subproject_dir)
for sub in b.subprojects:
for sub in b.subprojects.host:
directory = wrap.get_directory(subproject_dir, sub)
subprojects[sub] = os.path.join(b.subproject_dir, directory)
extra_meson_args.append('-Dwrap_mode=nodownload')
Expand Down
2 changes: 1 addition & 1 deletion mesonbuild/mintro.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ def list_projinfo(builddata: build.Build) -> T.Dict[str, T.Union[str, T.List[T.D
'descriptive_name': builddata.project_name,
'subproject_dir': builddata.subproject_dir} # type: T.Dict[str, T.Union[str, T.List[T.Dict[str, str]]]]
subprojects = []
for k, v in builddata.subprojects.items():
for k, v in builddata.subprojects.host.items():
c = {'name': k,
'version': v,
'descriptive_name': builddata.projects.get(k)} # type: T.Dict[str, str]
Expand Down

0 comments on commit 2fbc86c

Please sign in to comment.