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

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 Write output files to a temporary file first, and copy
newt (away) 2014/12/04 22:09:42 Does this also need to be added to grit_info.py as
Nico 2014/12/04 22:33:07 I think policy_templates only passes the same defi
113 it to the real output only if the new file is different
114 from the old file. This allows some build systems to
115 realize that dependent build steps might be unnecessary,
116 at the cost of comparing the output data at grit time.
117
112 Conditional inclusion of resources only affects the output of files which 118 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 119 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 120 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 121 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. 122 are exported to translation interchange files (e.g. XMB files), etc.
117 ''' 123 '''
118 124
119 def ShortDescription(self): 125 def ShortDescription(self):
120 return 'A tool that builds RC files for compilation.' 126 return 'A tool that builds RC files for compilation.'
121 127
122 def Run(self, opts, args): 128 def Run(self, opts, args):
123 self.output_directory = '.' 129 self.output_directory = '.'
124 first_ids_file = None 130 first_ids_file = None
125 whitelist_filenames = [] 131 whitelist_filenames = []
126 assert_output_files = [] 132 assert_output_files = []
127 target_platform = None 133 target_platform = None
128 depfile = None 134 depfile = None
129 depdir = None 135 depdir = None
130 rc_header_format = None 136 rc_header_format = None
131 output_all_resource_defines = None 137 output_all_resource_defines = None
138 write_only_new = False
132 (own_opts, args) = getopt.getopt(args, 'a:o:D:E:f:w:t:h:', 139 (own_opts, args) = getopt.getopt(args, 'a:o:D:E:f:w:t:h:',
133 ('depdir=','depfile=','assert-file-list=', 140 ('depdir=','depfile=','assert-file-list=',
134 'output-all-resource-defines', 141 'output-all-resource-defines',
135 'no-output-all-resource-defines',)) 142 'no-output-all-resource-defines',
143 'write-only-new'))
136 for (key, val) in own_opts: 144 for (key, val) in own_opts:
137 if key == '-a': 145 if key == '-a':
138 assert_output_files.append(val) 146 assert_output_files.append(val)
139 elif key == '--assert-file-list': 147 elif key == '--assert-file-list':
140 with open(val) as f: 148 with open(val) as f:
141 assert_output_files += f.read().splitlines() 149 assert_output_files += f.read().splitlines()
142 elif key == '-o': 150 elif key == '-o':
143 self.output_directory = val 151 self.output_directory = val
144 elif key == '-D': 152 elif key == '-D':
145 name, val = util.ParseDefine(val) 153 name, val = util.ParseDefine(val)
(...skipping 13 matching lines...) Expand all
159 elif key == '--no-output-all-resource-defines': 167 elif key == '--no-output-all-resource-defines':
160 output_all_resource_defines = False 168 output_all_resource_defines = False
161 elif key == '-t': 169 elif key == '-t':
162 target_platform = val 170 target_platform = val
163 elif key == '-h': 171 elif key == '-h':
164 rc_header_format = val 172 rc_header_format = val
165 elif key == '--depdir': 173 elif key == '--depdir':
166 depdir = val 174 depdir = val
167 elif key == '--depfile': 175 elif key == '--depfile':
168 depfile = val 176 depfile = val
177 elif key == '--write-only-new':
178 write_only_new = True
169 179
170 if len(args): 180 if len(args):
171 print 'This tool takes no tool-specific arguments.' 181 print 'This tool takes no tool-specific arguments.'
172 return 2 182 return 2
173 self.SetOptions(opts) 183 self.SetOptions(opts)
174 if self.scons_targets: 184 if self.scons_targets:
175 self.VerboseOut('Using SCons targets to identify files to output.\n') 185 self.VerboseOut('Using SCons targets to identify files to output.\n')
176 else: 186 else:
177 self.VerboseOut('Output directory: %s (absolute path: %s)\n' % 187 self.VerboseOut('Output directory: %s (absolute path: %s)\n' %
178 (self.output_directory, 188 (self.output_directory,
179 os.path.abspath(self.output_directory))) 189 os.path.abspath(self.output_directory)))
180 190
181 if whitelist_filenames: 191 if whitelist_filenames:
182 self.whitelist_names = set() 192 self.whitelist_names = set()
183 for whitelist_filename in whitelist_filenames: 193 for whitelist_filename in whitelist_filenames:
184 self.VerboseOut('Using whitelist: %s\n' % whitelist_filename); 194 self.VerboseOut('Using whitelist: %s\n' % whitelist_filename);
185 whitelist_contents = util.ReadFile(whitelist_filename, util.RAW_TEXT) 195 whitelist_contents = util.ReadFile(whitelist_filename, util.RAW_TEXT)
186 self.whitelist_names.update(whitelist_contents.strip().split('\n')) 196 self.whitelist_names.update(whitelist_contents.strip().split('\n'))
187 197
198 self.write_only_new = write_only_new
199
188 self.res = grd_reader.Parse(opts.input, 200 self.res = grd_reader.Parse(opts.input,
189 debug=opts.extra_verbose, 201 debug=opts.extra_verbose,
190 first_ids_file=first_ids_file, 202 first_ids_file=first_ids_file,
191 defines=self.defines, 203 defines=self.defines,
192 target_platform=target_platform) 204 target_platform=target_platform)
193 205
194 # If the output_all_resource_defines option is specified, override the value 206 # If the output_all_resource_defines option is specified, override the value
195 # found in the grd file. 207 # found in the grd file.
196 if output_all_resource_defines is not None: 208 if output_all_resource_defines is not None:
197 self.res.SetShouldOutputAllResourceDefines(output_all_resource_defines) 209 self.res.SetShouldOutputAllResourceDefines(output_all_resource_defines)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 241
230 # Set to a list of filenames for the output nodes that are relative 242 # 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 243 # to the current working directory. They are in the same order as the
232 # output nodes in the file. 244 # output nodes in the file.
233 self.scons_targets = None 245 self.scons_targets = None
234 246
235 # The set of names that are whitelisted to actually be included in the 247 # The set of names that are whitelisted to actually be included in the
236 # output. 248 # output.
237 self.whitelist_names = None 249 self.whitelist_names = None
238 250
251 # Whether to compare outputs to their old contents before writing.
252 self.write_only_new = False
253
239 @staticmethod 254 @staticmethod
240 def AddWhitelistTags(start_node, whitelist_names): 255 def AddWhitelistTags(start_node, whitelist_names):
241 # Walk the tree of nodes added attributes for the nodes that shouldn't 256 # Walk the tree of nodes added attributes for the nodes that shouldn't
242 # be written into the target files (skip markers). 257 # be written into the target files (skip markers).
243 from grit.node import include 258 from grit.node import include
244 from grit.node import message 259 from grit.node import message
245 from grit.node import structure 260 from grit.node import structure
246 for node in start_node: 261 for node in start_node:
247 # Same trick data_pack.py uses to see what nodes actually result in 262 # Same trick data_pack.py uses to see what nodes actually result in
248 # real items. 263 # real items.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 348
334 # Now copy from the temp file back to the real output, but on Windows, 349 # 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 350 # 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 351 # changed. This prevents identical headers from being written and .cc
337 # files from recompiling (which is painful on Windows). 352 # files from recompiling (which is painful on Windows).
338 if not os.path.exists(output.GetOutputFilename()): 353 if not os.path.exists(output.GetOutputFilename()):
339 os.rename(output.GetOutputFilename() + '.tmp', 354 os.rename(output.GetOutputFilename() + '.tmp',
340 output.GetOutputFilename()) 355 output.GetOutputFilename())
341 else: 356 else:
342 # CHROMIUM SPECIFIC CHANGE. 357 # CHROMIUM SPECIFIC CHANGE.
343 # This clashes with gyp + vstudio, which expect the output timestamp 358 # This clashes with gyp + vstudio, which expect the output timestamp
newt (away) 2014/12/04 22:09:42 If this is still an issue when using visual studio
Nico 2014/12/04 22:33:07 We don't support visual studio anymore, but maybe
344 # to change on a rebuild, even if nothing has changed. 359 # to change on a rebuild, even if nothing has changed, so only do
345 #files_match = filecmp.cmp(output.GetOutputFilename(), 360 # it when opted in.
346 # output.GetOutputFilename() + '.tmp') 361 if not self.write_only_new:
347 #if (output.GetType() != 'rc_header' or not files_match 362 write_file = True
348 # or sys.platform != 'win32'): 363 else:
349 shutil.copy2(output.GetOutputFilename() + '.tmp', 364 files_match = filecmp.cmp(output.GetOutputFilename(),
350 output.GetOutputFilename()) 365 output.GetOutputFilename() + '.tmp')
366 write_file = not files_match
367 if write_file:
368 shutil.copy2(output.GetOutputFilename() + '.tmp',
newt (away) 2014/12/04 22:09:42 Seems like it would be quicker to delete output.h,
Nico 2014/12/04 22:33:07 That's the usual way of doing things so that if yo
369 output.GetOutputFilename())
351 os.remove(output.GetOutputFilename() + '.tmp') 370 os.remove(output.GetOutputFilename() + '.tmp')
352 371
353 self.VerboseOut(' done.\n') 372 self.VerboseOut(' done.\n')
354 373
355 # Print warnings if there are any duplicate shortcuts. 374 # Print warnings if there are any duplicate shortcuts.
356 warnings = shortcuts.GenerateDuplicateShortcutsWarnings( 375 warnings = shortcuts.GenerateDuplicateShortcutsWarnings(
357 self.res.UberClique(), self.res.GetTcProject()) 376 self.res.UberClique(), self.res.GetTcProject())
358 if warnings: 377 if warnings:
359 print '\n'.join(warnings) 378 print '\n'.join(warnings)
360 379
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 self.MakeDirectoriesTo(depfile) 464 self.MakeDirectoriesTo(depfile)
446 outfile = self.fo_create(depfile, 'wb') 465 outfile = self.fo_create(depfile, 'wb')
447 outfile.writelines(depfile_contents) 466 outfile.writelines(depfile_contents)
448 467
449 @staticmethod 468 @staticmethod
450 def MakeDirectoriesTo(file): 469 def MakeDirectoriesTo(file):
451 '''Creates directories necessary to contain |file|.''' 470 '''Creates directories necessary to contain |file|.'''
452 dir = os.path.split(file)[0] 471 dir = os.path.split(file)[0]
453 if not os.path.exists(dir): 472 if not os.path.exists(dir):
454 os.makedirs(dir) 473 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