windows: reduce chance of going over path limit in backend/vs

When building with vs2019 (not ninja), a path length error will be thrown
if the path to a resource file is even remotely deep within the tree.

This is largely because the target name includes the string "Windows
resource for file 'full path'", which is then expanded twice (once for
the .vcxproj itself, and once for IntDir) and added to the full path.
When combined with the tiny path limits on Windows, it is easy to exceed
path limits.

This error is largely avoided by the ninja back-end. Unlike the
vs back-end, the ninja back-end does not use target.get_id() as part of
the project file path, nor does it use target.get_id() as part of
get_target_private_dir().

Example error:

error MSB4184: The expression "[MSBuild]::NormalizePath(
C:\src\mesonbuild\Misc\FreeRDP-master\client\X11\xfreerdp\xfreerdp,
f3f7317@@Windows resource for file
'Misc_FreeRDP-master_client_X11_xfreerdp_xfreerdp_xfreerdp.rc'@cus\,
f3f7317@@Windows resource for file
'Misc_FreeRDP-master_client_X11_xfreerdp_xfreerdp_xfreerdp.rc'@cus.
vcxproj.CopyComplete)" cannot be evaluated. Path:
C:\src\mesonbuild\Misc\FreeRDP-master\client\X11\xfreerdp\xfreerdp\f3f7317
@@Windows resource for file
'Misc_FreeRDP-master_client_X11_xfreerdp_xfreerdp_xfreerdp.rc'@cus\f3f7317
@@Windows resource for file
'Misc_FreeRDP-master_client_X11_xfreerdp_xfreerdp_xfreerdp.rc'@cus.
vcxproj.CopyComplete exceeds the OS max path limit.
The fully qualified file name must be less than 260 characters.
pull/7754/head
Peter Harris 4 年之前 committed by Nirbheek Chauhan
父節點 deb1d7caba
當前提交 807f88739e
  1. 9
      mesonbuild/modules/windows.py

@ -119,22 +119,23 @@ class WindowsModule(ExtensionModule):
src = unholder(src)
if isinstance(src, str):
name_format = 'file {!r}'
name_formatted = src
name = os.path.join(state.subdir, src)
elif isinstance(src, mesonlib.File):
name_format = 'file {!r}'
name_formatted = src.fname
name = src.relative_name()
elif isinstance(src, build.CustomTarget):
if len(src.get_outputs()) > 1:
raise MesonException('windows.compile_resources does not accept custom targets with more than 1 output.')
name_format = 'target {!r}'
name_formatted = src.get_basename()
name = src.get_id()
else:
raise MesonException('Unexpected source type {!r}. windows.compile_resources accepts only strings, files, custom targets, and lists thereof.'.format(src))
# Path separators are not allowed in target names
name = name.replace('/', '_').replace('\\', '_')
name_formatted = name_formatted.replace('/', '_').replace('\\', '_')
res_kwargs = {
'output': name + '_@BASENAME@.' + suffix,
@ -149,7 +150,7 @@ class WindowsModule(ExtensionModule):
res_kwargs['depfile'] = res_kwargs['output'] + '.d'
res_kwargs['command'] += ['--preprocessor-arg=-MD', '--preprocessor-arg=-MQ@OUTPUT@', '--preprocessor-arg=-MF@DEPFILE@']
res_targets.append(build.CustomTarget('Windows resource for ' + name_format.format(name), state.subdir, state.subproject, res_kwargs))
res_targets.append(build.CustomTarget(name_formatted, state.subdir, state.subproject, res_kwargs))
add_target(args)

Loading…
取消
儲存