From aa433c83821a8fbe029322c8e73df82fc705e932 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 5 Sep 2017 17:32:28 +0000 Subject: [PATCH] mc: Explicitly sort #define blocks. Some versions of mc.exe apparently don't do that, see chromium-dev "message_compiler.py build failure due to innocent enum ordering changes" Also print a slightly more detailed diff. Bug: 756607 Change-Id: I100891d0d1d06256448e568b9fa0ed8938d5957b Reviewed-on: https://chromium-review.googlesource.com/649768 Reviewed-by: Scott Graham Commit-Queue: Nico Weber Cr-Original-Commit-Position: refs/heads/master@{#499663} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 570a3b4c38a155a075e4370a37bf184c7d35bbd4 --- win/message_compiler.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/win/message_compiler.py b/win/message_compiler.py index 7edfe6e2a..3ee77c61b 100644 --- a/win/message_compiler.py +++ b/win/message_compiler.py @@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# Runs the Microsoft Message Compiler (mc.exe). This Python adapter is for the -# GN build, which can only run Python and not native binaries. +# Runs the Microsoft Message Compiler (mc.exe). # # Usage: message_compiler.py [*] +import difflib import distutils.dir_util import filecmp import os @@ -80,15 +80,27 @@ def main(): # it generates an ANSI header, and includes broken versions of the message # text in the comment before the value. To work around this, for any invalid # // comment lines, we simply drop the line in the header after building it. + # Also, mc.exe apparently doesn't always write #define lines in + # deterministic order, so manually sort each block of #defines. if header_dir: header_file = os.path.join( header_dir, os.path.splitext(os.path.basename(input_file))[0] + '.h') header_contents = [] with open(header_file, 'rb') as f: + define_block = [] # The current contiguous block of #defines. for line in f.readlines(): if line.startswith('//') and '?' in line: continue + if line.startswith('#define '): + define_block.append(line) + continue + # On the first non-#define line, emit the sorted preceding #define + # block. + header_contents += sorted(define_block, key=lambda s: s.split()[-1]) + define_block = [] header_contents.append(line) + # If the .h file ends with a #define block, flush the final block. + header_contents += sorted(define_block, key=lambda s: s.split()[-1]) with open(header_file, 'wb') as f: f.write(''.join(header_contents)) @@ -96,8 +108,16 @@ def main(): # in tmp_dir to the checked-in outputs. diff = filecmp.dircmp(tmp_dir, source) if diff.diff_files or set(diff.left_list) != set(diff.right_list): - print >>sys.stderr, 'mc.exe output different from files in %s, see %s' % ( - source, tmp_dir) + print 'mc.exe output different from files in %s, see %s' % (source, + tmp_dir) + diff.report() + for f in diff.diff_files: + if f.endswith('.bin'): continue + fromfile = os.path.join(source, f) + tofile = os.path.join(tmp_dir, f) + print ''.join(difflib.unified_diff(open(fromfile, 'U').readlines(), + open(tofile, 'U').readlines(), + fromfile, tofile)) delete_tmp_dir = False sys.exit(1) except subprocess.CalledProcessError as e: