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

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

Issue 997813004: Allow depfile to depend on a Stamp file instead of the default first input. (Closed) Base URL: https://chromium.googlesource.com/external/grit-i18n.git@master
Patch Set: +hack Created 5 years, 9 months 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
« no previous file with comments | « no previous file | grit/tool/build_unittest.py » ('j') | no next file with comments »
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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 112 --write-only-new flag
113 If flag is non-0, write output files to a temporary file 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 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 115 is different from the old file. This allows some build
116 systems to realize that dependent build steps might be 116 systems to realize that dependent build steps might be
117 unnecessary, at the cost of comparing the output data at 117 unnecessary, at the cost of comparing the output data at
118 grit time. 118 grit time.
119 119
120 --depend-on-stamp
121 If specified along with --depfile and --depdir, the depfile
122 generated will depend on a stampfile instead of the first
123 output in the input .grd file.
120 124
121 Conditional inclusion of resources only affects the output of files which 125 Conditional inclusion of resources only affects the output of files which
122 control which resources get linked into a binary, e.g. it affects .rc files 126 control which resources get linked into a binary, e.g. it affects .rc files
123 meant for compilation but it does not affect resource header files (that define 127 meant for compilation but it does not affect resource header files (that define
124 IDs). This helps ensure that values of IDs stay the same, that all messages 128 IDs). This helps ensure that values of IDs stay the same, that all messages
125 are exported to translation interchange files (e.g. XMB files), etc. 129 are exported to translation interchange files (e.g. XMB files), etc.
126 ''' 130 '''
127 131
128 def ShortDescription(self): 132 def ShortDescription(self):
129 return 'A tool that builds RC files for compilation.' 133 return 'A tool that builds RC files for compilation.'
130 134
131 def Run(self, opts, args): 135 def Run(self, opts, args):
132 self.output_directory = '.' 136 self.output_directory = '.'
133 first_ids_file = None 137 first_ids_file = None
134 whitelist_filenames = [] 138 whitelist_filenames = []
135 assert_output_files = [] 139 assert_output_files = []
136 target_platform = None 140 target_platform = None
137 depfile = None 141 depfile = None
138 depdir = None 142 depdir = None
139 rc_header_format = None 143 rc_header_format = None
140 output_all_resource_defines = None 144 output_all_resource_defines = None
141 write_only_new = False 145 write_only_new = False
146 depend_on_stamp = False
142 (own_opts, args) = getopt.getopt(args, 'a:o:D:E:f:w:t:h:', 147 (own_opts, args) = getopt.getopt(args, 'a:o:D:E:f:w:t:h:',
143 ('depdir=','depfile=','assert-file-list=', 148 ('depdir=','depfile=','assert-file-list=',
144 'output-all-resource-defines', 149 'output-all-resource-defines',
145 'no-output-all-resource-defines', 150 'no-output-all-resource-defines',
151 'depend-on-stamp',
146 'write-only-new=')) 152 'write-only-new='))
147 for (key, val) in own_opts: 153 for (key, val) in own_opts:
148 if key == '-a': 154 if key == '-a':
149 assert_output_files.append(val) 155 assert_output_files.append(val)
150 elif key == '--assert-file-list': 156 elif key == '--assert-file-list':
151 with open(val) as f: 157 with open(val) as f:
152 assert_output_files += f.read().splitlines() 158 assert_output_files += f.read().splitlines()
153 elif key == '-o': 159 elif key == '-o':
154 self.output_directory = val 160 self.output_directory = val
155 elif key == '-D': 161 elif key == '-D':
(...skipping 16 matching lines...) Expand all
172 elif key == '-t': 178 elif key == '-t':
173 target_platform = val 179 target_platform = val
174 elif key == '-h': 180 elif key == '-h':
175 rc_header_format = val 181 rc_header_format = val
176 elif key == '--depdir': 182 elif key == '--depdir':
177 depdir = val 183 depdir = val
178 elif key == '--depfile': 184 elif key == '--depfile':
179 depfile = val 185 depfile = val
180 elif key == '--write-only-new': 186 elif key == '--write-only-new':
181 write_only_new = val != '0' 187 write_only_new = val != '0'
188 elif key == '--depend-on-stamp':
189 depend_on_stamp = True
182 190
183 if len(args): 191 if len(args):
184 print 'This tool takes no tool-specific arguments.' 192 print 'This tool takes no tool-specific arguments.'
185 return 2 193 return 2
186 self.SetOptions(opts) 194 self.SetOptions(opts)
187 if self.scons_targets: 195 if self.scons_targets:
188 self.VerboseOut('Using SCons targets to identify files to output.\n') 196 self.VerboseOut('Using SCons targets to identify files to output.\n')
189 else: 197 else:
190 self.VerboseOut('Output directory: %s (absolute path: %s)\n' % 198 self.VerboseOut('Output directory: %s (absolute path: %s)\n' %
191 (self.output_directory, 199 (self.output_directory,
(...skipping 26 matching lines...) Expand all
218 if rc_header_format: 226 if rc_header_format:
219 self.res.AssignRcHeaderFormat(rc_header_format) 227 self.res.AssignRcHeaderFormat(rc_header_format)
220 self.res.RunGatherers() 228 self.res.RunGatherers()
221 self.Process() 229 self.Process()
222 230
223 if assert_output_files: 231 if assert_output_files:
224 if not self.CheckAssertedOutputFiles(assert_output_files): 232 if not self.CheckAssertedOutputFiles(assert_output_files):
225 return 2 233 return 2
226 234
227 if depfile and depdir: 235 if depfile and depdir:
228 self.GenerateDepfile(depfile, depdir, first_ids_file) 236 self.GenerateDepfile(depfile, depdir, first_ids_file, depend_on_stamp)
229 237
230 return 0 238 return 0
231 239
232 def __init__(self, defines=None): 240 def __init__(self, defines=None):
233 # Default file-creation function is built-in open(). Only done to allow 241 # Default file-creation function is built-in open(). Only done to allow
234 # overriding by unit test. 242 # overriding by unit test.
235 self.fo_create = open 243 self.fo_create = open
236 244
237 # key/value pairs of C-preprocessor like defines that are used for 245 # key/value pairs of C-preprocessor like defines that are used for
238 # conditional output of resources 246 # conditional output of resources
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 %s 425 %s
418 Extra output files: 426 Extra output files:
419 %s 427 %s
420 ''' 428 '''
421 print error % ('\n'.join(asserted), '\n'.join(actual), '\n'.join(missing), 429 print error % ('\n'.join(asserted), '\n'.join(actual), '\n'.join(missing),
422 '\n'.join(extra)) 430 '\n'.join(extra))
423 return False 431 return False
424 return True 432 return True
425 433
426 434
427 def GenerateDepfile(self, depfile, depdir, first_ids_file): 435 def GenerateDepfile(self, depfile, depdir, first_ids_file, depend_on_stamp):
428 '''Generate a depfile that contains the imlicit dependencies of the input 436 '''Generate a depfile that contains the imlicit dependencies of the input
429 grd. The depfile will be in the same format as a makefile, and will contain 437 grd. The depfile will be in the same format as a makefile, and will contain
430 references to files relative to |depdir|. It will be put in |depfile|. 438 references to files relative to |depdir|. It will be put in |depfile|.
431 439
432 For example, supposing we have three files in a directory src/ 440 For example, supposing we have three files in a directory src/
433 441
434 src/ 442 src/
435 blah.grd <- depends on input{1,2}.xtb 443 blah.grd <- depends on input{1,2}.xtb
436 input1.xtb 444 input1.xtb
437 input2.xtb 445 input2.xtb
438 446
439 and we run 447 and we run
440 448
441 grit -i blah.grd -o ../out/gen --depdir ../out --depfile ../out/gen/blah.r d.d 449 grit -i blah.grd -o ../out/gen --depdir ../out --depfile ../out/gen/blah.r d.d
442 450
443 from the directory src/ we will generate a depfile ../out/gen/blah.grd.d 451 from the directory src/ we will generate a depfile ../out/gen/blah.grd.d
444 that has the contents 452 that has the contents
445 453
446 gen/blah.h: ../src/input1.xtb ../src/input2.xtb 454 gen/blah.h: ../src/input1.xtb ../src/input2.xtb
447 455
448 Where "gen/blah.h" is the first output (Ninja expects the .d file to list 456 Where "gen/blah.h" is the first output (Ninja expects the .d file to list
449 the first output in cases where there is more than one). 457 the first output in cases where there is more than one). If the flag
458 --depend-on-stamp is specified, "gen/blah.rd.d.stamp" will be used that is
459 'touched' whenever a new depfile is generated.
450 460
451 Note that all paths in the depfile are relative to ../out, the depdir. 461 Note that all paths in the depfile are relative to ../out, the depdir.
452 ''' 462 '''
453 depfile = os.path.abspath(depfile) 463 depfile = os.path.abspath(depfile)
454 depdir = os.path.abspath(depdir) 464 depdir = os.path.abspath(depdir)
455 infiles = self.res.GetInputFiles() 465 infiles = self.res.GetInputFiles()
456 466
457 # We want to trigger a rebuild if the first ids change. 467 # We want to trigger a rebuild if the first ids change.
458 if first_ids_file is not None: 468 if first_ids_file is not None:
459 infiles.append(first_ids_file) 469 infiles.append(first_ids_file)
460 470
461 # Get the first output file relative to the depdir. 471 if (depend_on_stamp):
462 outputs = self.res.GetOutputFiles() 472 output_file = depfile + ".stamp"
463 output_file = os.path.relpath(os.path.join( 473 # Touch the stamp file before generating the depfile.
464 self.output_directory, outputs[0].GetFilename()), depdir) 474 with open(output_file, 'a'):
475 os.utime(output_file, None)
476 else:
477 # Get the first output file relative to the depdir.
478 outputs = self.res.GetOutputFiles()
479 output_file = os.path.join(self.output_directory,
480 outputs[0].GetFilename())
465 481
482 output_file = os.path.relpath(output_file, depdir)
466 # The path prefix to prepend to dependencies in the depfile. 483 # The path prefix to prepend to dependencies in the depfile.
467 prefix = os.path.relpath(os.getcwd(), depdir) 484 prefix = os.path.relpath(os.getcwd(), depdir)
468 deps_text = ' '.join([os.path.join(prefix, i) for i in infiles]) 485 deps_text = ' '.join([os.path.join(prefix, i) for i in infiles])
469 486
470 depfile_contents = output_file + ': ' + deps_text 487 depfile_contents = output_file + ': ' + deps_text
471 self.MakeDirectoriesTo(depfile) 488 self.MakeDirectoriesTo(depfile)
472 outfile = self.fo_create(depfile, 'wb') 489 outfile = self.fo_create(depfile, 'wb')
473 outfile.writelines(depfile_contents) 490 outfile.writelines(depfile_contents)
474 491
475 @staticmethod 492 @staticmethod
476 def MakeDirectoriesTo(file): 493 def MakeDirectoriesTo(file):
477 '''Creates directories necessary to contain |file|.''' 494 '''Creates directories necessary to contain |file|.'''
478 dir = os.path.split(file)[0] 495 dir = os.path.split(file)[0]
479 if not os.path.exists(dir): 496 if not os.path.exists(dir):
480 os.makedirs(dir) 497 os.makedirs(dir)
OLDNEW
« no previous file with comments | « no previous file | grit/tool/build_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698