Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: grit/tool/build.py

Issue 757213003: Give build a --write-only-new option. (Closed) Base URL: http://grit-i18n.googlecode.com/svn/trunk/
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | grit/tool/build_unittest.py » ('j') | grit/tool/build_unittest.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 '''The 'grit build' tool along with integration for this tool with the 6 '''The 'grit build' tool along with integration for this tool with the
7 SCons build system. 7 SCons build system.
8 ''' 8 '''
9 9
10 import filecmp 10 import filecmp
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 -h HEADERFORMAT Custom format string to use for generating rc header files. 102 -h HEADERFORMAT Custom format string to use for generating rc header files.
103 The string should have two placeholders: {textual_id} 103 The string should have two placeholders: {textual_id}
104 and {numeric_id}. E.g. "#define {textual_id} {numeric_id}" 104 and {numeric_id}. E.g. "#define {textual_id} {numeric_id}"
105 Otherwise it will use the default "#define SYMBOL 1234" 105 Otherwise it will use the default "#define SYMBOL 1234"
106 106
107 --output-all-resource-defines 107 --output-all-resource-defines
108 --no-output-all-resource-defines If specified, overrides the value of the 108 --no-output-all-resource-defines If specified, overrides the value of the
109 output_all_resource_defines attribute of the root <grit> 109 output_all_resource_defines attribute of the root <grit>
110 element of the input .grd file. 110 element of the input .grd file.
111 111
112 --write-only-new flag
113 If flag is non-0, write output files to a temporary file
114 first, and copy it to the real output only if the new file
115 is different from the old file. This allows some build
116 systems to realize that dependent build steps might be
117 unnecessary, at the cost of comparing the output data at
118 grit time.
119
120
112 Conditional inclusion of resources only affects the output of files which 121 Conditional inclusion of resources only affects the output of files which
113 control which resources get linked into a binary, e.g. it affects .rc files 122 control which resources get linked into a binary, e.g. it affects .rc files
114 meant for compilation but it does not affect resource header files (that define 123 meant for compilation but it does not affect resource header files (that define
115 IDs). This helps ensure that values of IDs stay the same, that all messages 124 IDs). This helps ensure that values of IDs stay the same, that all messages
116 are exported to translation interchange files (e.g. XMB files), etc. 125 are exported to translation interchange files (e.g. XMB files), etc.
117 ''' 126 '''
118 127
119 def ShortDescription(self): 128 def ShortDescription(self):
120 return 'A tool that builds RC files for compilation.' 129 return 'A tool that builds RC files for compilation.'
121 130
122 def Run(self, opts, args): 131 def Run(self, opts, args):
123 self.output_directory = '.' 132 self.output_directory = '.'
124 first_ids_file = None 133 first_ids_file = None
125 whitelist_filenames = [] 134 whitelist_filenames = []
126 assert_output_files = [] 135 assert_output_files = []
127 target_platform = None 136 target_platform = None
128 depfile = None 137 depfile = None
129 depdir = None 138 depdir = None
130 rc_header_format = None 139 rc_header_format = None
131 output_all_resource_defines = None 140 output_all_resource_defines = None
141 write_only_new = False
132 (own_opts, args) = getopt.getopt(args, 'a:o:D:E:f:w:t:h:', 142 (own_opts, args) = getopt.getopt(args, 'a:o:D:E:f:w:t:h:',
133 ('depdir=','depfile=','assert-file-list=', 143 ('depdir=','depfile=','assert-file-list=',
134 'output-all-resource-defines', 144 'output-all-resource-defines',
135 'no-output-all-resource-defines',)) 145 'no-output-all-resource-defines',
146 'write-only-new='))
136 for (key, val) in own_opts: 147 for (key, val) in own_opts:
137 if key == '-a': 148 if key == '-a':
138 assert_output_files.append(val) 149 assert_output_files.append(val)
139 elif key == '--assert-file-list': 150 elif key == '--assert-file-list':
140 with open(val) as f: 151 with open(val) as f:
141 assert_output_files += f.read().splitlines() 152 assert_output_files += f.read().splitlines()
142 elif key == '-o': 153 elif key == '-o':
143 self.output_directory = val 154 self.output_directory = val
144 elif key == '-D': 155 elif key == '-D':
145 name, val = util.ParseDefine(val) 156 name, val = util.ParseDefine(val)
(...skipping 13 matching lines...) Expand all
159 elif key == '--no-output-all-resource-defines': 170 elif key == '--no-output-all-resource-defines':
160 output_all_resource_defines = False 171 output_all_resource_defines = False
161 elif key == '-t': 172 elif key == '-t':
162 target_platform = val 173 target_platform = val
163 elif key == '-h': 174 elif key == '-h':
164 rc_header_format = val 175 rc_header_format = val
165 elif key == '--depdir': 176 elif key == '--depdir':
166 depdir = val 177 depdir = val
167 elif key == '--depfile': 178 elif key == '--depfile':
168 depfile = val 179 depfile = val
180 elif key == '--write-only-new':
181 write_only_new = val != '0'
169 182
170 if len(args): 183 if len(args):
171 print 'This tool takes no tool-specific arguments.' 184 print 'This tool takes no tool-specific arguments.'
172 return 2 185 return 2
173 self.SetOptions(opts) 186 self.SetOptions(opts)
174 if self.scons_targets: 187 if self.scons_targets:
175 self.VerboseOut('Using SCons targets to identify files to output.\n') 188 self.VerboseOut('Using SCons targets to identify files to output.\n')
176 else: 189 else:
177 self.VerboseOut('Output directory: %s (absolute path: %s)\n' % 190 self.VerboseOut('Output directory: %s (absolute path: %s)\n' %
178 (self.output_directory, 191 (self.output_directory,
179 os.path.abspath(self.output_directory))) 192 os.path.abspath(self.output_directory)))
180 193
181 if whitelist_filenames: 194 if whitelist_filenames:
182 self.whitelist_names = set() 195 self.whitelist_names = set()
183 for whitelist_filename in whitelist_filenames: 196 for whitelist_filename in whitelist_filenames:
184 self.VerboseOut('Using whitelist: %s\n' % whitelist_filename); 197 self.VerboseOut('Using whitelist: %s\n' % whitelist_filename);
185 whitelist_contents = util.ReadFile(whitelist_filename, util.RAW_TEXT) 198 whitelist_contents = util.ReadFile(whitelist_filename, util.RAW_TEXT)
186 self.whitelist_names.update(whitelist_contents.strip().split('\n')) 199 self.whitelist_names.update(whitelist_contents.strip().split('\n'))
187 200
201 self.write_only_new = write_only_new
202
188 self.res = grd_reader.Parse(opts.input, 203 self.res = grd_reader.Parse(opts.input,
189 debug=opts.extra_verbose, 204 debug=opts.extra_verbose,
190 first_ids_file=first_ids_file, 205 first_ids_file=first_ids_file,
191 defines=self.defines, 206 defines=self.defines,
192 target_platform=target_platform) 207 target_platform=target_platform)
193 208
194 # If the output_all_resource_defines option is specified, override the value 209 # If the output_all_resource_defines option is specified, override the value
195 # found in the grd file. 210 # found in the grd file.
196 if output_all_resource_defines is not None: 211 if output_all_resource_defines is not None:
197 self.res.SetShouldOutputAllResourceDefines(output_all_resource_defines) 212 self.res.SetShouldOutputAllResourceDefines(output_all_resource_defines)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 244
230 # Set to a list of filenames for the output nodes that are relative 245 # Set to a list of filenames for the output nodes that are relative
231 # to the current working directory. They are in the same order as the 246 # to the current working directory. They are in the same order as the
232 # output nodes in the file. 247 # output nodes in the file.
233 self.scons_targets = None 248 self.scons_targets = None
234 249
235 # The set of names that are whitelisted to actually be included in the 250 # The set of names that are whitelisted to actually be included in the
236 # output. 251 # output.
237 self.whitelist_names = None 252 self.whitelist_names = None
238 253
254 # Whether to compare outputs to their old contents before writing.
255 self.write_only_new = False
256
239 @staticmethod 257 @staticmethod
240 def AddWhitelistTags(start_node, whitelist_names): 258 def AddWhitelistTags(start_node, whitelist_names):
241 # Walk the tree of nodes added attributes for the nodes that shouldn't 259 # Walk the tree of nodes added attributes for the nodes that shouldn't
242 # be written into the target files (skip markers). 260 # be written into the target files (skip markers).
243 from grit.node import include 261 from grit.node import include
244 from grit.node import message 262 from grit.node import message
245 from grit.node import structure 263 from grit.node import structure
246 for node in start_node: 264 for node in start_node:
247 # Same trick data_pack.py uses to see what nodes actually result in 265 # Same trick data_pack.py uses to see what nodes actually result in
248 # real items. 266 # real items.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 # Now copy from the temp file back to the real output, but on Windows, 352 # Now copy from the temp file back to the real output, but on Windows,
335 # only if the real output doesn't exist or the contents of the file 353 # only if the real output doesn't exist or the contents of the file
336 # changed. This prevents identical headers from being written and .cc 354 # changed. This prevents identical headers from being written and .cc
337 # files from recompiling (which is painful on Windows). 355 # files from recompiling (which is painful on Windows).
338 if not os.path.exists(output.GetOutputFilename()): 356 if not os.path.exists(output.GetOutputFilename()):
339 os.rename(output.GetOutputFilename() + '.tmp', 357 os.rename(output.GetOutputFilename() + '.tmp',
340 output.GetOutputFilename()) 358 output.GetOutputFilename())
341 else: 359 else:
342 # CHROMIUM SPECIFIC CHANGE. 360 # CHROMIUM SPECIFIC CHANGE.
343 # This clashes with gyp + vstudio, which expect the output timestamp 361 # This clashes with gyp + vstudio, which expect the output timestamp
344 # to change on a rebuild, even if nothing has changed. 362 # to change on a rebuild, even if nothing has changed, so only do
345 #files_match = filecmp.cmp(output.GetOutputFilename(), 363 # it when opted in.
346 # output.GetOutputFilename() + '.tmp') 364 if not self.write_only_new:
347 #if (output.GetType() != 'rc_header' or not files_match 365 write_file = True
348 # or sys.platform != 'win32'): 366 else:
349 shutil.copy2(output.GetOutputFilename() + '.tmp', 367 files_match = filecmp.cmp(output.GetOutputFilename(),
350 output.GetOutputFilename()) 368 output.GetOutputFilename() + '.tmp')
369 write_file = not files_match
370 if write_file:
371 shutil.copy2(output.GetOutputFilename() + '.tmp',
372 output.GetOutputFilename())
351 os.remove(output.GetOutputFilename() + '.tmp') 373 os.remove(output.GetOutputFilename() + '.tmp')
352 374
353 self.VerboseOut(' done.\n') 375 self.VerboseOut(' done.\n')
354 376
355 # Print warnings if there are any duplicate shortcuts. 377 # Print warnings if there are any duplicate shortcuts.
356 warnings = shortcuts.GenerateDuplicateShortcutsWarnings( 378 warnings = shortcuts.GenerateDuplicateShortcutsWarnings(
357 self.res.UberClique(), self.res.GetTcProject()) 379 self.res.UberClique(), self.res.GetTcProject())
358 if warnings: 380 if warnings:
359 print '\n'.join(warnings) 381 print '\n'.join(warnings)
360 382
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 self.MakeDirectoriesTo(depfile) 467 self.MakeDirectoriesTo(depfile)
446 outfile = self.fo_create(depfile, 'wb') 468 outfile = self.fo_create(depfile, 'wb')
447 outfile.writelines(depfile_contents) 469 outfile.writelines(depfile_contents)
448 470
449 @staticmethod 471 @staticmethod
450 def MakeDirectoriesTo(file): 472 def MakeDirectoriesTo(file):
451 '''Creates directories necessary to contain |file|.''' 473 '''Creates directories necessary to contain |file|.'''
452 dir = os.path.split(file)[0] 474 dir = os.path.split(file)[0]
453 if not os.path.exists(dir): 475 if not os.path.exists(dir):
454 os.makedirs(dir) 476 os.makedirs(dir)
OLDNEW
« no previous file with comments | « no previous file | grit/tool/build_unittest.py » ('j') | grit/tool/build_unittest.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698