Repository: mesonbuild/meson

Issue:
Support rspfile in ninja backend
On windows there is a command line limit, so longer calls from ninja with just fail with "CreateProcess: The parameter is incorrect."

To reproduce it just do :

```
 project('app', 'cpp')
 executable('app', 'test1.cpp', 'test2.cpp', ... , 'test1000.cpp')
```

And generate build.ninja file. In this case backend will generate one link build command with all 1000 object files. And total length of this command will be longer that maximum command line length on windows.

To fix it you need to use [rspfile in ninja](http://martine.github.io/ninja/manual.html#ref_rule)



Discussion:

Resolving patch:
diff --git a/ninjabackend.py b/ninjabackend.py
--- a/ninjabackend.py
+++ b/ninjabackend.py
@@ -85,6 +85,12 @@ def write(self, outfile):
         if len(self.orderdeps) > 0:
             line += ' || ' + ' '.join([ninja_quote(x) for x in self.orderdeps])
         line += '\n'
+        # This needs to be done to make these strings
+        # pass through arbitrary shells. Backslash is a
+        # quote character so it can break at any time.
+        # Because of this always use forward slashes,
+        # it is a path separator even on Windows.
+        line = line.replace('\\', '/')
         outfile.write(line)
 
         for e in self.elems:
@@ -104,6 +110,7 @@ def write(self, outfile):
                 newelems.append(templ % ninja_quote(i))
             line += ' '.join(newelems)
             line += '\n'
+            line = line.replace('\\', '/')
             outfile.write(line)
         outfile.write('\n')
 
@@ -857,7 +864,14 @@ def generate_static_link_rules(self, is_cross, outfile):
         if static_linker is None:
             return
         rule = 'rule STATIC%s_LINKER\n' % crstr
-        command = ' command = %s  $LINK_ARGS %s $in\n' % \
+        if mesonlib.is_windows():
+            command_templ = ''' command = %s @$out.rsp
+ rspfile = $out.rsp
+ rspfile_content = $LINK_ARGS %s $in
+'''
+        else:
+            command_templ = ' command = %s $LINK_ARGS %s $in\n'
+        command = command_templ %\
         (' '.join(static_linker.get_exelist()),
          ' '.join(static_linker.get_output_args('$out')))
         description = ' description = Static linking library $out\n\n'
@@ -890,7 +904,14 @@ def generate_dynamic_link_rules(self, outfile):
                     except KeyError:
                         pass
                 rule = 'rule %s%s_LINKER\n' % (langname, crstr)
-                command = ' command = %s %s $ARGS  %s $in $LINK_ARGS $aliasing\n' % \
+                if mesonlib.is_windows():
+                    command_template = ''' command = %s @$out.rsp
+ rspfile = $out.rsp
+ rspfile_content = %s $ARGS  %s $in $LINK_ARGS $aliasing
+'''
+                else:
+                    command_template = ' command = %s %s $ARGS  %s $in $LINK_ARGS $aliasing\n'
+                command = command_template % \
                 (' '.join(compiler.get_linker_exelist()),\
                  ' '.join(cross_args),\
                  ' '.join(compiler.get_linker_output_args('$out')))
@@ -1019,7 +1040,14 @@ def generate_compile_rule_for(self, langname, compiler, qstr, is_cross, outfile)
                 cross_args = self.environment.cross_info.config['properties'][langname + '_args']
             except KeyError:
                 pass
-        command = " command = %s %s $ARGS %s %s %s $in\n" % \
+        if mesonlib.is_windows():
+            command_template = ''' command = %s @$out.rsp
+ rspfile = $out.rsp
+ rspfile_content = %s $ARGS %s %s %s $in
+'''
+        else:
+            command_template = ' command = %s %s $ARGS %s %s %s $in\n'
+        command = command_template % \
             (' '.join(compiler.get_exelist()),\
              ' '.join(cross_args),
              ' '.join(quoted_depargs),\


Test patch: