mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.58k stars 1.62k forks source link

VS backend: avoid creating files with forbidden characters #10937

Open lb90 opened 2 years ago

lb90 commented 2 years ago

The VS backend creates files or directories using the names given to custom targets, etc. Anyway Windows is more strict than Unix in that a few characters cannot be used in file or directory names.

The issue can be experienced with that meson.build sample:

project('test-issue', 'c')

main_obj = custom_target('compile with cl: ',
                         input : 'main.c',
                         output : 'main.obj',
                         command : ['cl', '/c', '@INPUT@'])

libfoo = static_library('foo', [main_obj])

And main.c:

#include <stdlib.h>

int main()
{
  return 0;
}

When running Meson we get:

D:\meson-issue>python D:\meson\meson.py vs --backend=vs
The Meson build system
Version: 0.63.99
Source dir: D:\meson-issue
Build dir: D:\meson-issue\vs
Build type: native build
Project name: test-issue
Project version: undefined
C compiler for the host machine: cl (msvc 19.33.31630 "Microsoft (R) C/C++ Optimizing Compiler Version 19.33.31630 for x64")
C linker for the host machine: link link 14.33.31630.0
Auto detected Visual Studio backend: vs2022
Host machine cpu family: x86_64
Host machine cpu: x86_64
Build targets in project: 2

test-issue undefined

  User defined options
    backend: vs

Traceback (most recent call last):
  File "D:\meson\mesonbuild\mesonmain.py", line 194, in run
    return options.run_func(options)
  File "D:\meson\mesonbuild\msetup.py", line 307, in run
    app.generate()
  File "D:\meson\mesonbuild\msetup.py", line 186, in generate
    self._generate(env)
  File "D:\meson\mesonbuild\msetup.py", line 248, in _generate
    intr.backend.generate()
  File "D:\meson\mesonbuild\backend\vs2010backend.py", line 233, in generate
    projlist = self.generate_projects()
  File "D:\meson\mesonbuild\backend\vs2010backend.py", line 485, in generate_projects
    self.gen_vcxproj(target, str(projfile_path), proj_uuid)
  File "D:\meson\mesonbuild\backend\vs2010backend.py", line 876, in gen_vcxproj
    return self.gen_custom_target_vcxproj(target, ofname, guid)
  File "D:\meson\mesonbuild\backend\vs2010backend.py", line 684, in gen_custom_target_vcxproj
    self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
  File "D:\meson\mesonbuild\backend\vs2010backend.py", line 856, in _prettyprint_vcxproj_xml
    replace_if_different(ofname, ofname_tmp)
  File "D:\meson\mesonbuild\utils\universal.py", line 1283, in replace_if_different
    os.replace(dst_tmp, dst)
OSError: [WinError 87] The parameter is incorrect: 'D:\\meson-issue\\vs\\compile with cl: @cus.vcxproj~' -> 'D:\\meson-issue\\vs\\compile with cl: @cus.vcxproj'

ERROR: Unhandled python OSError. This is probably not a Meson bug, but an issue with your build environment.
WARNING: Running the setup command as `meson [options]` instead of `meson setup [options]` is ambiguous and deprecated.

Note that there's no issue with using spaces in filenames, as MSBuild / Visual Studio can handle spaces just fine. The problem is in the use of the colon character. CreateFile interprets the colon as a file stream specifier.

See https://gitlab.gnome.org/GNOME/gtk/-/issues/5280

eli-schwartz commented 2 years ago

I really have to wonder why the custom_target description field is being used for something other than the log descriptions (for the ninja backend this is only used to control the "generating XXX with a custom command" message).

lb90 commented 2 years ago

Hi! I believe it's because in MSBuild every target is usually defined in its own project file (.proj, .vcxproj, etc.) and those project files are all referenced by the main solution file (.sln), whereas ninja uses a single build.ninja file.

For the custom target, a .proj file has to be created, but then we have to solve the issue of allowed filename characters

eli-schwartz commented 2 years ago

That sounds so painful... is it not possible to use the output filename instead of the description?

lb90 commented 2 years ago

is it not possible to use the output filename instead of the description?

Looks like a great idea to me!