blob: 75d0a8b3527a7545342b2085af56d66862b61c05 [file] [log] [blame]
Ken Payson5998cd72016-08-10 15:39:43 -07001# Copyright 2016, Google Inc.
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met:
7#
8# * Redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer.
10# * Redistributions in binary form must reproduce the above
11# copyright notice, this list of conditions and the following disclaimer
12# in the documentation and/or other materials provided with the
13# distribution.
14# * Neither the name of Google Inc. nor the names of its
15# contributors may be used to endorse or promote products derived from
16# this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Ken Payson5998cd72016-08-10 15:39:43 -070029"""Patches the spawn() command for windows compilers.
30
31Windows has an 8191 character command line limit, but some compilers
32support an @command_file directive where command_file is a file
33containing the full command line.
34"""
35
36from distutils import ccompiler
37import os
38import os.path
39import shutil
40import sys
41import tempfile
42
43MAX_COMMAND_LENGTH = 8191
44
45_classic_spawn = ccompiler.CCompiler.spawn
46
Masood Malekghassemicc793702017-01-13 19:20:10 -080047
Ken Payson5998cd72016-08-10 15:39:43 -070048def _commandfile_spawn(self, command):
Masood Malekghassemicc793702017-01-13 19:20:10 -080049 command_length = sum([len(arg) for arg in command])
50 if os.name == 'nt' and command_length > MAX_COMMAND_LENGTH:
51 # Even if this command doesn't support the @command_file, it will
52 # fail as is so we try blindly
53 print('Command line length exceeded, using command file')
54 print(' '.join(command))
55 temporary_directory = tempfile.mkdtemp()
56 command_filename = os.path.abspath(
57 os.path.join(temporary_directory, 'command'))
58 with open(command_filename, 'w') as command_file:
59 escaped_args = [
60 '"' + arg.replace('\\', '\\\\') + '"' for arg in command[1:]
61 ]
62 command_file.write(' '.join(escaped_args))
63 modified_command = command[:1] + ['@{}'.format(command_filename)]
64 try:
65 _classic_spawn(self, modified_command)
66 finally:
67 shutil.rmtree(temporary_directory)
68 else:
69 _classic_spawn(self, command)
Ken Payson5998cd72016-08-10 15:39:43 -070070
71
72def monkeypatch_spawn():
Masood Malekghassemicc793702017-01-13 19:20:10 -080073 """Monkeypatching is dumb, but it's either that or we become maintainers of
Ken Payson5998cd72016-08-10 15:39:43 -070074 something much, much bigger."""
Masood Malekghassemicc793702017-01-13 19:20:10 -080075 ccompiler.CCompiler.spawn = _commandfile_spawn