Commit f6fa85d4 authored by Dirk Pranke's avatar Dirk Pranke Committed by Commit Bot

Win tooling fixes for Python 3 compatibility.

Several of the toolchain support files in //build weren't
python3-compatible. This CL fixes those issues, at least for
the nothing-fails code path.

Also, the python2_action() wrapper script didn't handle the
case where the command line to pass to the python script
was greater than 8k limit (to cmd.exe) on windows we hit
by routing through the python.bat wrapper in depot_tools.
This CL changes how the python2_action wrapper works, to
mimic the way GN works by using python.bat to find
the path to the underlying python executable.

Bug: 1112471
Change-Id: Id628f0c46213f00f19ef2e7f58774448fe59f31d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2512387
Commit-Queue: Dirk Pranke <dpranke@google.com>
Reviewed-by: default avatarBruce Dawson <brucedawson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#822972}
parent 4d628b31
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
assert(is_win) assert(is_win)
import("//build/config/python.gni")
import("//build/config/win/visual_studio_version.gni") import("//build/config/win/visual_studio_version.gni")
# This template defines a rule to invoke the MS IDL compiler. The generated # This template defines a rule to invoke the MS IDL compiler. The generated
...@@ -88,7 +89,8 @@ template("midl") { ...@@ -88,7 +89,8 @@ template("midl") {
proxy_file = "{{source_name_part}}_p.c" proxy_file = "{{source_name_part}}_p.c"
type_library_file = "{{source_name_part}}.tlb" type_library_file = "{{source_name_part}}.tlb"
action_foreach(action_name) { # TODO(crbug.com/1112471): Get this working directly under Python 3.
python2_action_foreach(action_name) {
visibility = [ ":$source_set_name" ] visibility = [ ":$source_set_name" ]
script = "//build/toolchain/win/midl.py" script = "//build/toolchain/win/midl.py"
......
...@@ -36,7 +36,7 @@ class Struct(object): ...@@ -36,7 +36,7 @@ class Struct(object):
def Subtract(nt, **kwargs): def Subtract(nt, **kwargs):
"""Subtract(nt, f=2) returns a new namedtuple with 2 subtracted from nt.f""" """Subtract(nt, f=2) returns a new namedtuple with 2 subtracted from nt.f"""
return nt._replace(**{k: getattr(nt, k) - v for k, v in kwargs.iteritems()}) return nt._replace(**{k: getattr(nt, k) - v for k, v in kwargs.items()})
def MakeDeterministic(objdata): def MakeDeterministic(objdata):
...@@ -57,7 +57,7 @@ def MakeDeterministic(objdata): ...@@ -57,7 +57,7 @@ def MakeDeterministic(objdata):
# These seem to hold in practice; if they stop holding this script needs to # These seem to hold in practice; if they stop holding this script needs to
# become smarter. # become smarter.
objdata = array.array('c', objdata) # Writable, e.g. via struct.pack_into. objdata = array.array('b', objdata) # Writable, e.g. via struct.pack_into.
# Read coff header. # Read coff header.
COFFHEADER = Struct('COFFHEADER', COFFHEADER = Struct('COFFHEADER',
...@@ -91,10 +91,10 @@ def MakeDeterministic(objdata): ...@@ -91,10 +91,10 @@ def MakeDeterministic(objdata):
for i in range(0, coff_header.NumberOfSections): for i in range(0, coff_header.NumberOfSections):
section_header = SECTIONHEADER.unpack_from( section_header = SECTIONHEADER.unpack_from(
objdata, offset=COFFHEADER.size() + i * SECTIONHEADER.size()) objdata, offset=COFFHEADER.size() + i * SECTIONHEADER.size())
assert not section_header[0].startswith('/') # Support short names only. assert not section_header[0].startswith(b'/') # Support short names only.
section_headers.append(section_header) section_headers.append(section_header)
if section_header.Name == '.debug$S': if section_header.Name == b'.debug$S':
assert debug_section_index == -1 assert debug_section_index == -1
debug_section_index = i debug_section_index = i
assert debug_section_index != -1 assert debug_section_index != -1
...@@ -102,7 +102,7 @@ def MakeDeterministic(objdata): ...@@ -102,7 +102,7 @@ def MakeDeterministic(objdata):
data_start = COFFHEADER.size() + len(section_headers) * SECTIONHEADER.size() data_start = COFFHEADER.size() + len(section_headers) * SECTIONHEADER.size()
# Verify the .debug$S section looks like we expect. # Verify the .debug$S section looks like we expect.
assert section_headers[debug_section_index].Name == '.debug$S' assert section_headers[debug_section_index].Name == b'.debug$S'
assert section_headers[debug_section_index].VirtualSize == 0 assert section_headers[debug_section_index].VirtualSize == 0
assert section_headers[debug_section_index].VirtualAddress == 0 assert section_headers[debug_section_index].VirtualAddress == 0
debug_size = section_headers[debug_section_index].SizeOfRawData debug_size = section_headers[debug_section_index].SizeOfRawData
...@@ -174,7 +174,7 @@ def MakeDeterministic(objdata): ...@@ -174,7 +174,7 @@ def MakeDeterministic(objdata):
debug_sym = i debug_sym = i
# Make sure the .debug$S symbol looks like we expect. # Make sure the .debug$S symbol looks like we expect.
# In particular, it should have exactly one aux symbol. # In particular, it should have exactly one aux symbol.
assert sym.Name == '.debug$S' assert sym.Name == b'.debug$S'
assert sym.Value == 0 assert sym.Value == 0
assert sym.Type == 0 assert sym.Type == 0
assert sym.StorageClass == 3 assert sym.StorageClass == 3
...@@ -262,7 +262,10 @@ def MakeDeterministic(objdata): ...@@ -262,7 +262,10 @@ def MakeDeterministic(objdata):
COFFHEADER.size() + (debug_section_index + 1) * SECTIONHEADER.size()] COFFHEADER.size() + (debug_section_index + 1) * SECTIONHEADER.size()]
# All done! # All done!
if sys.version_info.major == 2:
return objdata.tostring() return objdata.tostring()
else:
return objdata.tobytes()
def main(): def main():
......
...@@ -158,7 +158,7 @@ class WinTool(object): ...@@ -158,7 +158,7 @@ class WinTool(object):
popen = subprocess.Popen(args, shell=True, env=env, popen = subprocess.Popen(args, shell=True, env=env,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, _ = popen.communicate() out, _ = popen.communicate()
for line in out.splitlines(): for line in out.decode('utf8').splitlines():
if not line.startswith(' Assembling: '): if not line.startswith(' Assembling: '):
print(line) print(line)
return popen.returncode return popen.returncode
......
...@@ -12,8 +12,13 @@ if sys.version_info.major == 2: ...@@ -12,8 +12,13 @@ if sys.version_info.major == 2:
exe = sys.executable exe = sys.executable
elif sys.executable.endswith('.exe'): elif sys.executable.endswith('.exe'):
# If we get here, we're a Python3 executable likely running on # If we get here, we're a Python3 executable likely running on
# Windows, so look for the Python2 wrapper in depot_tools. # Windows, so look for the Python2 wrapper in depot_tools. We
exe = 'python.bat' # can't invoke it directly because some command lines might exceed the
# 8K commamand line length limit in cmd.exe, but we can use it to
# find the underlying executable, which we can then safely call.
exe = subprocess.check_output(
['python.bat', '-c',
'import sys; print(sys.executable)']).decode('utf8').strip()
else: else:
# If we get here, we are a Python3 executable. Hope that we can find # If we get here, we are a Python3 executable. Hope that we can find
# a `python2.7` in path somewhere. # a `python2.7` in path somewhere.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment