2929 File , MachineChoice , MesonException , MesonBugException , OrderedSet ,
3030 ExecutableSerialisation , EnvironmentException ,
3131 classify_unity_sources , get_compiler_for_source ,
32- is_parent_path ,
32+ is_parent_path , get_rsp_threshold ,
3333)
3434from ..options import OptionKey
3535
@@ -533,6 +533,7 @@ def get_executable_serialisation(
533533 capture : T .Optional [str ] = None ,
534534 feed : T .Optional [str ] = None ,
535535 env : T .Optional [mesonlib .EnvironmentVariables ] = None ,
536+ can_use_rsp_file : bool = False ,
536537 tag : T .Optional [str ] = None ,
537538 verbose : bool = False ,
538539 installdir_map : T .Optional [T .Dict [str , str ]] = None ) -> 'ExecutableSerialisation' :
@@ -594,6 +595,21 @@ def get_executable_serialisation(
594595 exe_wrapper = None
595596
596597 workdir = workdir or self .environment .get_build_dir ()
598+
599+ # Must include separators as well
600+ needs_rsp_file = can_use_rsp_file and sum (len (i ) + 1 for i in cmd_args ) >= get_rsp_threshold ()
601+
602+ if needs_rsp_file :
603+ hasher = hashlib .sha1 ()
604+ args = ' ' .join (mesonlib .quote_arg (arg ) for arg in cmd_args )
605+ hasher .update (args .encode (encoding = 'utf-8' , errors = 'ignore' ))
606+ digest = hasher .hexdigest ()
607+ scratch_file = f'meson_rsp_{ digest } .rsp'
608+ rsp_file = os .path .join (self .environment .get_scratch_dir (), scratch_file )
609+ with open (rsp_file , 'w' , encoding = 'utf-8' , newline = '\n ' ) as f :
610+ f .write (args )
611+ cmd_args = [f'@{ rsp_file } ' ]
612+
597613 return ExecutableSerialisation (exe_cmd + cmd_args , env ,
598614 exe_wrapper , workdir ,
599615 extra_paths , capture , feed , tag , verbose , installdir_map )
@@ -606,14 +622,15 @@ def as_meson_exe_cmdline(self, exe: T.Union[str, mesonlib.File, build.BuildTarge
606622 feed : T .Optional [str ] = None ,
607623 force_serialize : bool = False ,
608624 env : T .Optional [mesonlib .EnvironmentVariables ] = None ,
625+ can_use_rsp_file : bool = False ,
609626 verbose : bool = False ) -> T .Tuple [T .List [str ], str ]:
610627 '''
611628 Serialize an executable for running with a generator or a custom target
612629 '''
613630 cmd : T .List [T .Union [str , mesonlib .File , build .BuildTarget , build .CustomTarget , programs .ExternalProgram ]] = []
614631 cmd .append (exe )
615632 cmd .extend (cmd_args )
616- es = self .get_executable_serialisation (cmd , workdir , extra_bdeps , capture , feed , env , verbose = verbose )
633+ es = self .get_executable_serialisation (cmd , workdir , extra_bdeps , capture , feed , env , can_use_rsp_file , verbose = verbose )
617634 reasons : T .List [str ] = []
618635 if es .extra_paths :
619636 reasons .append ('to set PATH' )
@@ -653,6 +670,9 @@ def as_meson_exe_cmdline(self, exe: T.Union[str, mesonlib.File, build.BuildTarge
653670 envlist .append (f'{ k } ={ v } ' )
654671 return ['env' ] + envlist + es .cmd_args , ', ' .join (reasons )
655672
673+ if any (a .startswith ('@' ) for a in es .cmd_args ):
674+ reasons .append ('because command is too long' )
675+
656676 if not force_serialize :
657677 if not capture and not feed :
658678 return es .cmd_args , ''
0 commit comments