From d1a07fec5cd6cdd65c0e8c5833547b1652c463be Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Thu, 21 Nov 2024 14:41:06 +0100 Subject: [PATCH] Ninja: set default pool depth for MS link.exe --- mesonbuild/backend/ninjabackend.py | 15 ++++++++++++--- mesonbuild/linkers/linkers.py | 13 +++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 5716ea29e351..558914fb8271 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -601,6 +601,15 @@ def detect_prefix(out): raise MesonException(f'Could not determine vs dep dependency prefix string. output: {stderr} {stdout}') + def get_link_pool_depth(self) -> int: + depth = self.environment.coredata.optstore.get_value('backend_max_links') + if depth == 0: + for compiler in self.environment.coredata.compilers.host.values(): + d = compiler.linker.get_default_pool_depth() + if d > 0 and (depth == 0 or d < depth): + depth = d + return depth; + def generate(self, capture: bool = False, vslite_ctx: T.Optional[T.Dict] = None) -> T.Optional[T.Dict]: if vslite_ctx: # We don't yet have a use case where we'd expect to make use of this, @@ -632,7 +641,7 @@ def generate(self, capture: bool = False, vslite_ctx: T.Optional[T.Dict] = None) outfile.write('# Do not edit by hand.\n\n') outfile.write('ninja_required_version = 1.8.2\n\n') - num_pools = self.environment.coredata.optstore.get_value('backend_max_links') + num_pools = self.get_link_pool_depth() if num_pools > 0: outfile.write(f'''pool link_pool depth = {num_pools} @@ -2305,7 +2314,7 @@ def _rsp_options(self, tool: T.Union['Compiler', 'StaticLinker', 'DynamicLinker' return options def generate_static_link_rules(self) -> None: - num_pools = self.environment.coredata.optstore.get_value('backend_max_links') + num_pools = self.get_link_pool_depth() if 'java' in self.environment.coredata.compilers.host: self.generate_java_link() for for_machine in MachineChoice: @@ -2353,7 +2362,7 @@ def generate_static_link_rules(self) -> None: self.add_rule(NinjaRule(rule, cmdlist, args, description, **options, extra=pool)) def generate_dynamic_link_rules(self) -> None: - num_pools = self.environment.coredata.optstore.get_value('backend_max_links') + num_pools = self.get_link_pool_depth() for for_machine in MachineChoice: complist = self.environment.coredata.compilers[for_machine] for langname, compiler in complist.items(): diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index d0ffc56182ee..22f1210b5bb8 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -298,6 +298,13 @@ def get_command_to_archive_shlib(self) -> T.List[str]: #Only used by AIX. return [] + def get_default_pool_depth(self): + # Returns the ideal number of concurrent invocations. + # Returning 0 means no limit, so the default concurrency + # value (tipically the number of logical processors) is + # used + return 0 + if T.TYPE_CHECKING: StaticLinkerBase = StaticLinker @@ -1368,6 +1375,12 @@ def get_win_subsystem_args(self, value: str) -> T.List[str]: def fatal_warnings(self) -> T.List[str]: return ['-WX'] + def get_default_pool_depth(self): + # MS link.exe is internally multithreaded and uses lots of memory. + # we might check the amount of physical memory here, but it's not + # clear if parallel invocations of the linker bring any advantage. + return 1 + class ClangClDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):