mirror of
https://github.com/mesonbuild/meson.git
synced 2026-06-24 08:48:03 +00:00
nasm: use the correct flag for response file support, try 2
This commit reenables and implements correct response file support for Nasm. Fortified with the knowledge of #15867 and #15872, and with a quick chat with @nirbheek, I realised that the easiest way to fix this (since Ninja does not support custom argument spacing) is to do it the obvious way, with Meson's custom command support. This commit implements an abridged version of that: when a non-standard RspFileSyntax value is detected, the active NinjaBuildRule is temporarily resolved to the corresponding NinjaRule on the fly and if the latter says that a response file will be used, the NinjaBuildRule is immediately converted into a CUSTOM_COMMAND, completing the arguments with the bits for infile and outfile and triggering the executable serialization. That serializes the response file and pickles the command. Fixes building mpv with MSVC 2022+ and fdk-aac enabled.
This commit is contained in:
committed by
Paolo Bonzini
parent
d23570a90b
commit
739e86f3e4
@@ -549,10 +549,11 @@ class Backend:
|
||||
feed: T.Optional[str] = None,
|
||||
env: T.Optional[mesonlib.EnvironmentVariables] = None,
|
||||
can_use_rsp_file: bool = False,
|
||||
separator: str = ' ',
|
||||
rsp_file_flag: str = '@',
|
||||
tag: T.Optional[str] = None,
|
||||
verbose: bool = False,
|
||||
installdir_map: T.Optional[T.Dict[str, str]] = None) -> 'ExecutableSerialisation':
|
||||
|
||||
# XXX: cmd_args either need to be lowered to strings, or need to be checked for non-string arguments, right?
|
||||
exe, *raw_cmd_args = cmd
|
||||
if isinstance(exe, build.LocalProgram):
|
||||
@@ -618,14 +619,14 @@ class Backend:
|
||||
|
||||
if needs_rsp_file:
|
||||
hasher = hashlib.sha1()
|
||||
args = ' '.join(mesonlib.quote_arg(arg) for arg in cmd_args)
|
||||
args = separator.join(mesonlib.quote_arg(arg) for arg in cmd_args)
|
||||
hasher.update(args.encode(encoding='utf-8', errors='ignore'))
|
||||
digest = hasher.hexdigest()
|
||||
scratch_file = f'meson_rsp_{digest}.rsp'
|
||||
rsp_file = os.path.join(self.environment.get_scratch_dir(), scratch_file)
|
||||
with open(rsp_file, 'w', encoding='utf-8', newline='\n') as f:
|
||||
f.write(args)
|
||||
cmd_args = [f'@{rsp_file}']
|
||||
cmd_args = [f'{rsp_file_flag}{rsp_file}']
|
||||
|
||||
return ExecutableSerialisation(exe_cmd + cmd_args, env,
|
||||
exe_wrapper, workdir,
|
||||
@@ -640,6 +641,8 @@ class Backend:
|
||||
force_serialize: bool = False,
|
||||
env: T.Optional[mesonlib.EnvironmentVariables] = None,
|
||||
can_use_rsp_file: bool = False,
|
||||
separator: str = ' ',
|
||||
rsp_file_flag: str = '@',
|
||||
verbose: bool = False) -> T.Tuple[T.List[str], str]:
|
||||
'''
|
||||
Serialize an executable for running with a generator or a custom target
|
||||
@@ -647,7 +650,7 @@ class Backend:
|
||||
cmd: T.List[build.CommandTypes] = []
|
||||
cmd.append(exe)
|
||||
cmd.extend(cmd_args)
|
||||
es = self.get_executable_serialisation(cmd, workdir, extra_bdeps, capture, feed, env, can_use_rsp_file, verbose=verbose)
|
||||
es = self.get_executable_serialisation(cmd, workdir, extra_bdeps, capture, feed, env, can_use_rsp_file, separator=separator, rsp_file_flag=rsp_file_flag, verbose=verbose)
|
||||
reasons: T.List[str] = []
|
||||
if es.extra_paths:
|
||||
reasons.append('to set PATH')
|
||||
@@ -664,6 +667,9 @@ class Backend:
|
||||
if env and env.varnames:
|
||||
reasons.append('to set env')
|
||||
|
||||
if separator != ' ':
|
||||
reasons.append('to use a custom argument separator')
|
||||
|
||||
# force_serialize passed to this function means that the VS backend has
|
||||
# decided it absolutely cannot use real commands. This is "always",
|
||||
# because it's not clear what will work (other than compilers) and so
|
||||
@@ -673,7 +679,7 @@ class Backend:
|
||||
# It's also overridden for a few conditions that can't be handled
|
||||
# inside a command line
|
||||
|
||||
can_use_env = env.can_use_env and not force_serialize
|
||||
can_use_env = env and env.can_use_env and not force_serialize
|
||||
force_serialize = force_serialize or bool(reasons)
|
||||
|
||||
if capture:
|
||||
@@ -687,7 +693,7 @@ class Backend:
|
||||
envlist.append(f'{k}={v}')
|
||||
return ['env'] + envlist + es.cmd_args, ', '.join(reasons)
|
||||
|
||||
if any(a.startswith('@') for a in es.cmd_args):
|
||||
if can_use_rsp_file and any(a.startswith(rsp_file_flag) for a in es.cmd_args):
|
||||
reasons.append('because command is too long')
|
||||
|
||||
if not force_serialize:
|
||||
|
||||
@@ -365,6 +365,9 @@ class NinjaBuildElement:
|
||||
if self.rulename == 'phony':
|
||||
return False
|
||||
|
||||
if not self.rule:
|
||||
raise MesonBugException(f"build statement for {self.outfilenames} references unmapped rule {self.rulename}")
|
||||
|
||||
return self.rule.should_use_rspfile(self)
|
||||
|
||||
def count_rule_references(self) -> None:
|
||||
@@ -3370,7 +3373,27 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
|
||||
result += c
|
||||
return result
|
||||
element.add_item('CUDA_ESCAPED_TARGET', quote_make_target(rel_obj))
|
||||
element.add_item('ARGS', commands)
|
||||
if self.ninja.should_use_rspfile(element) and compiler.rsp_file_syntax() == RSPFileSyntax.NASM:
|
||||
exe = compiler.get_exelist()
|
||||
# Add to commands the args created by generate_compile_rule_for().
|
||||
# commands remain separate from exelist because they must stay
|
||||
# a CompilerArgs.
|
||||
if dep_file:
|
||||
commands += compiler.get_dependency_gen_args(rel_obj, dep_file)
|
||||
commands += [*compiler.get_output_args(rel_obj), *compiler.get_compile_only_args(), rel_src]
|
||||
|
||||
element.rulename = 'CUSTOM_COMMAND'
|
||||
meson_exe_cmd, reason = self.as_meson_exe_cmdline(exe[0],
|
||||
exe[1:] + commands.to_native(),
|
||||
separator='\n',
|
||||
rsp_file_flag='-@',
|
||||
can_use_rsp_file=True,
|
||||
verbose=True)
|
||||
cmd_type = f' (wrapped by meson {reason})' if reason else ''
|
||||
element.add_item('COMMAND', meson_exe_cmd)
|
||||
element.add_item('description', f'Compiling {compiler.get_display_language()} object {rel_obj}{cmd_type}')
|
||||
else:
|
||||
element.add_item('ARGS', commands)
|
||||
|
||||
self.add_dependency_scanner_entries_to_element(target, compiler, element, src)
|
||||
self.add_build(element)
|
||||
|
||||
@@ -6,6 +6,7 @@ import typing as T
|
||||
from ..mesonlib import EnvironmentException, get_meson_command
|
||||
from ..options import OptionKey
|
||||
from .compilers import Compiler
|
||||
from ..linkers import RSPFileSyntax
|
||||
from ..linkers.linkers import VisualStudioLikeLinkerMixin
|
||||
from .mixins.metrowerks import MetrowerksCompiler, mwasmarm_instruction_set_args, mwasmeppc_instruction_set_args
|
||||
from .mixins.ti import TICompiler
|
||||
@@ -159,11 +160,8 @@ class NasmCompiler(ASMCompiler):
|
||||
return []
|
||||
return self.crt_args[self.get_crt_val(crt_val)]
|
||||
|
||||
def can_linker_accept_rsp(self) -> bool:
|
||||
"""
|
||||
Determines whether the linker can accept arguments using the @rsp syntax.
|
||||
"""
|
||||
return False
|
||||
def rsp_file_syntax(self) -> RSPFileSyntax:
|
||||
return RSPFileSyntax.NASM
|
||||
|
||||
class YasmCompiler(NasmCompiler):
|
||||
id = 'yasm'
|
||||
|
||||
@@ -19,6 +19,7 @@ class RSPFileSyntax(enum.Enum):
|
||||
MSVC = enum.auto()
|
||||
GCC = enum.auto()
|
||||
TASKING = enum.auto()
|
||||
NASM = enum.auto()
|
||||
|
||||
|
||||
class ArLikeLinker:
|
||||
|
||||
Reference in New Issue
Block a user