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

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

Issue 25683011: Add the ability to generate a depfile when running grit build. (Closed) Base URL: https://chromium.googlesource.com/external/grit-i18n.git@master
Patch Set: add test, respond to comments Created 7 years, 2 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 ''' 91 '''
92 92
93 def ShortDescription(self): 93 def ShortDescription(self):
94 return 'A tool that builds RC files for compilation.' 94 return 'A tool that builds RC files for compilation.'
95 95
96 def Run(self, opts, args): 96 def Run(self, opts, args):
97 self.output_directory = '.' 97 self.output_directory = '.'
98 first_ids_file = None 98 first_ids_file = None
99 whitelist_filenames = [] 99 whitelist_filenames = []
100 target_platform = None 100 target_platform = None
101 (own_opts, args) = getopt.getopt(args, 'o:D:E:f:w:t:') 101 dep_dir = None
102 (own_opts, args) = getopt.getopt(args, 'o:D:E:f:w:t:', ('dep-dir=',))
102 for (key, val) in own_opts: 103 for (key, val) in own_opts:
103 if key == '-o': 104 if key == '-o':
104 self.output_directory = val 105 self.output_directory = val
105 elif key == '-D': 106 elif key == '-D':
106 name, val = util.ParseDefine(val) 107 name, val = util.ParseDefine(val)
107 self.defines[name] = val 108 self.defines[name] = val
108 elif key == '-E': 109 elif key == '-E':
109 (env_name, env_value) = val.split('=', 1) 110 (env_name, env_value) = val.split('=', 1)
110 os.environ[env_name] = env_value 111 os.environ[env_name] = env_value
111 elif key == '-f': 112 elif key == '-f':
112 # TODO(joi@chromium.org): Remove this override once change 113 # TODO(joi@chromium.org): Remove this override once change
113 # lands in WebKit.grd to specify the first_ids_file in the 114 # lands in WebKit.grd to specify the first_ids_file in the
114 # .grd itself. 115 # .grd itself.
115 first_ids_file = val 116 first_ids_file = val
116 elif key == '-w': 117 elif key == '-w':
117 whitelist_filenames.append(val) 118 whitelist_filenames.append(val)
118 elif key == '-t': 119 elif key == '-t':
119 target_platform = val 120 target_platform = val
121 elif key == '--dep-dir':
122 dep_dir = val
120 123
121 if len(args): 124 if len(args):
122 print 'This tool takes no tool-specific arguments.' 125 print 'This tool takes no tool-specific arguments.'
123 return 2 126 return 2
124 self.SetOptions(opts) 127 self.SetOptions(opts)
125 if self.scons_targets: 128 if self.scons_targets:
126 self.VerboseOut('Using SCons targets to identify files to output.\n') 129 self.VerboseOut('Using SCons targets to identify files to output.\n')
127 else: 130 else:
128 self.VerboseOut('Output directory: %s (absolute path: %s)\n' % 131 self.VerboseOut('Output directory: %s (absolute path: %s)\n' %
129 (self.output_directory, 132 (self.output_directory,
(...skipping 10 matching lines...) Expand all
140 debug=opts.extra_verbose, 143 debug=opts.extra_verbose,
141 first_ids_file=first_ids_file, 144 first_ids_file=first_ids_file,
142 defines=self.defines, 145 defines=self.defines,
143 target_platform=target_platform) 146 target_platform=target_platform)
144 # Set an output context so that conditionals can use defines during the 147 # Set an output context so that conditionals can use defines during the
145 # gathering stage; we use a dummy language here since we are not outputting 148 # gathering stage; we use a dummy language here since we are not outputting
146 # a specific language. 149 # a specific language.
147 self.res.SetOutputLanguage('en') 150 self.res.SetOutputLanguage('en')
148 self.res.RunGatherers() 151 self.res.RunGatherers()
149 self.Process() 152 self.Process()
153
154 if dep_dir:
155 self.GenerateDepfile(opts.input, dep_dir)
156
150 return 0 157 return 0
151 158
152 def __init__(self, defines=None): 159 def __init__(self, defines=None):
153 # Default file-creation function is built-in open(). Only done to allow 160 # Default file-creation function is built-in open(). Only done to allow
154 # overriding by unit test. 161 # overriding by unit test.
155 self.fo_create = open 162 self.fo_create = open
156 163
157 # key/value pairs of C-preprocessor like defines that are used for 164 # key/value pairs of C-preprocessor like defines that are used for
158 # conditional output of resources 165 # conditional output of resources
159 self.defines = defines or {} 166 self.defines = defines or {}
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 else: 251 else:
245 # TODO(gfeher) modify here to set utf-8 encoding for admx/adml 252 # TODO(gfeher) modify here to set utf-8 encoding for admx/adml
246 encoding = 'utf_16' 253 encoding = 'utf_16'
247 254
248 # Set the context, for conditional inclusion of resources 255 # Set the context, for conditional inclusion of resources
249 self.res.SetOutputLanguage(output.GetLanguage()) 256 self.res.SetOutputLanguage(output.GetLanguage())
250 self.res.SetOutputContext(output.GetContext()) 257 self.res.SetOutputContext(output.GetContext())
251 self.res.SetDefines(self.defines) 258 self.res.SetDefines(self.defines)
252 259
253 # Make the output directory if it doesn't exist. 260 # Make the output directory if it doesn't exist.
254 outdir = os.path.split(output.GetOutputFilename())[0] 261 self.MakeDirectoriesTo(output.GetOutputFilename())
255 if not os.path.exists(outdir):
256 os.makedirs(outdir)
257 262
258 # Write the results to a temporary file and only overwrite the original 263 # Write the results to a temporary file and only overwrite the original
259 # if the file changed. This avoids unnecessary rebuilds. 264 # if the file changed. This avoids unnecessary rebuilds.
260 outfile = self.fo_create(output.GetOutputFilename() + '.tmp', 'wb') 265 outfile = self.fo_create(output.GetOutputFilename() + '.tmp', 'wb')
261 266
262 if output.GetType() != 'data_package': 267 if output.GetType() != 'data_package':
263 outfile = util.WrapOutputStream(outfile, encoding) 268 outfile = util.WrapOutputStream(outfile, encoding)
264 269
265 # Iterate in-order through entire resource tree, calling formatters on 270 # Iterate in-order through entire resource tree, calling formatters on
266 # the entry into a node and on exit out of it. 271 # the entry into a node and on exit out of it.
(...skipping 30 matching lines...) Expand all
297 # Print out any fallback warnings, and missing translation errors, and 302 # Print out any fallback warnings, and missing translation errors, and
298 # exit with an error code if there are missing translations in a non-pseudo 303 # exit with an error code if there are missing translations in a non-pseudo
299 # and non-official build. 304 # and non-official build.
300 warnings = (self.res.UberClique().MissingTranslationsReport(). 305 warnings = (self.res.UberClique().MissingTranslationsReport().
301 encode('ascii', 'replace')) 306 encode('ascii', 'replace'))
302 if warnings: 307 if warnings:
303 self.VerboseOut(warnings) 308 self.VerboseOut(warnings)
304 if self.res.UberClique().HasMissingTranslations(): 309 if self.res.UberClique().HasMissingTranslations():
305 print self.res.UberClique().missing_translations_ 310 print self.res.UberClique().missing_translations_
306 sys.exit(-1) 311 sys.exit(-1)
312
313 def GenerateDepfile(self, input_filename, dep_dir):
314 '''Generate a depfile that contains the imlicit dependencies of the input
315 grd. The depfile will be in the same format as a makefile, and will contain
316 references to files relative to |dep_dir|. It will be put in the same
317 directory as the generated outputs.
318
319 For example, supposing we have three files in a directory src/
320
321 src/
322 blah.grd <- depends on input{1,2}.xtb
323 input1.xtb
324 input2.xtb
325
326 and we run
327
328 grit -i blah.grd -o ../out/gen --dep-dir ../out
329
330 from the directory src/ we will generate a depfile ../out/gen/blah.grd.d
331 that has the contents
332
333 gen/blah.grd.d: ../src/input1.xtb ../src/input2.xtb
334
335 Note that all paths in the depfile are relative to ../out, the dep-dir.
336 '''
337 depsfile_basename = os.path.basename(input_filename + '.d')
338 depfile = os.path.abspath(
339 os.path.join(self.output_directory, depsfile_basename))
340 dep_dir = os.path.abspath(dep_dir)
341 # The path prefix to prepend to dependencies in the depfile.
342 prefix = os.path.relpath(os.getcwd(), dep_dir)
343 # The path that the depfile refers to itself by.
344 self_ref_depfile = os.path.relpath(depfile, dep_dir)
345 infiles = self.res.GetInputFiles()
346 deps_text = ' '.join([os.path.join(prefix, i) for i in infiles])
347 depfile_contents = self_ref_depfile + ': ' + deps_text
348 self.MakeDirectoriesTo(depfile)
349 outfile = self.fo_create(depfile, 'wb')
350 outfile.writelines(depfile_contents)
Nico 2013/12/31 01:07:42 I'm currently looking at using this in gyp, and I'
351
352 @staticmethod
353 def MakeDirectoriesTo(file):
354 '''Creates directories necessary to contain |file|.'''
355 dir = os.path.split(file)[0]
356 if not os.path.exists(dir):
357 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