OLD | NEW |
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 Loading... |
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 dep_dir = None | 101 depfile = None |
102 (own_opts, args) = getopt.getopt(args, 'o:D:E:f:w:t:', ('dep-dir=',)) | 102 depdir = None |
| 103 (own_opts, args) = getopt.getopt(args, 'o:D:E:f:w:t:', ('depdir=','depfile='
)) |
103 for (key, val) in own_opts: | 104 for (key, val) in own_opts: |
104 if key == '-o': | 105 if key == '-o': |
105 self.output_directory = val | 106 self.output_directory = val |
106 elif key == '-D': | 107 elif key == '-D': |
107 name, val = util.ParseDefine(val) | 108 name, val = util.ParseDefine(val) |
108 self.defines[name] = val | 109 self.defines[name] = val |
109 elif key == '-E': | 110 elif key == '-E': |
110 (env_name, env_value) = val.split('=', 1) | 111 (env_name, env_value) = val.split('=', 1) |
111 os.environ[env_name] = env_value | 112 os.environ[env_name] = env_value |
112 elif key == '-f': | 113 elif key == '-f': |
113 # TODO(joi@chromium.org): Remove this override once change | 114 # TODO(joi@chromium.org): Remove this override once change |
114 # lands in WebKit.grd to specify the first_ids_file in the | 115 # lands in WebKit.grd to specify the first_ids_file in the |
115 # .grd itself. | 116 # .grd itself. |
116 first_ids_file = val | 117 first_ids_file = val |
117 elif key == '-w': | 118 elif key == '-w': |
118 whitelist_filenames.append(val) | 119 whitelist_filenames.append(val) |
119 elif key == '-t': | 120 elif key == '-t': |
120 target_platform = val | 121 target_platform = val |
121 elif key == '--dep-dir': | 122 elif key == '--depdir': |
122 dep_dir = val | 123 depdir = val |
| 124 elif key == '--depfile': |
| 125 depfile = val |
123 | 126 |
124 if len(args): | 127 if len(args): |
125 print 'This tool takes no tool-specific arguments.' | 128 print 'This tool takes no tool-specific arguments.' |
126 return 2 | 129 return 2 |
127 self.SetOptions(opts) | 130 self.SetOptions(opts) |
128 if self.scons_targets: | 131 if self.scons_targets: |
129 self.VerboseOut('Using SCons targets to identify files to output.\n') | 132 self.VerboseOut('Using SCons targets to identify files to output.\n') |
130 else: | 133 else: |
131 self.VerboseOut('Output directory: %s (absolute path: %s)\n' % | 134 self.VerboseOut('Output directory: %s (absolute path: %s)\n' % |
132 (self.output_directory, | 135 (self.output_directory, |
(...skipping 11 matching lines...) Expand all Loading... |
144 first_ids_file=first_ids_file, | 147 first_ids_file=first_ids_file, |
145 defines=self.defines, | 148 defines=self.defines, |
146 target_platform=target_platform) | 149 target_platform=target_platform) |
147 # Set an output context so that conditionals can use defines during the | 150 # Set an output context so that conditionals can use defines during the |
148 # gathering stage; we use a dummy language here since we are not outputting | 151 # gathering stage; we use a dummy language here since we are not outputting |
149 # a specific language. | 152 # a specific language. |
150 self.res.SetOutputLanguage('en') | 153 self.res.SetOutputLanguage('en') |
151 self.res.RunGatherers() | 154 self.res.RunGatherers() |
152 self.Process() | 155 self.Process() |
153 | 156 |
154 if dep_dir: | 157 if depfile and depdir: |
155 self.GenerateDepfile(opts.input, dep_dir) | 158 self.GenerateDepfile(opts.input, depfile, depdir) |
156 | 159 |
157 return 0 | 160 return 0 |
158 | 161 |
159 def __init__(self, defines=None): | 162 def __init__(self, defines=None): |
160 # Default file-creation function is built-in open(). Only done to allow | 163 # Default file-creation function is built-in open(). Only done to allow |
161 # overriding by unit test. | 164 # overriding by unit test. |
162 self.fo_create = open | 165 self.fo_create = open |
163 | 166 |
164 # key/value pairs of C-preprocessor like defines that are used for | 167 # key/value pairs of C-preprocessor like defines that are used for |
165 # conditional output of resources | 168 # conditional output of resources |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 # exit with an error code if there are missing translations in a non-pseudo | 306 # exit with an error code if there are missing translations in a non-pseudo |
304 # and non-official build. | 307 # and non-official build. |
305 warnings = (self.res.UberClique().MissingTranslationsReport(). | 308 warnings = (self.res.UberClique().MissingTranslationsReport(). |
306 encode('ascii', 'replace')) | 309 encode('ascii', 'replace')) |
307 if warnings: | 310 if warnings: |
308 self.VerboseOut(warnings) | 311 self.VerboseOut(warnings) |
309 if self.res.UberClique().HasMissingTranslations(): | 312 if self.res.UberClique().HasMissingTranslations(): |
310 print self.res.UberClique().missing_translations_ | 313 print self.res.UberClique().missing_translations_ |
311 sys.exit(-1) | 314 sys.exit(-1) |
312 | 315 |
313 def GenerateDepfile(self, input_filename, dep_dir): | 316 def GenerateDepfile(self, input_filename, depfile, depdir): |
314 '''Generate a depfile that contains the imlicit dependencies of the input | 317 '''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 | 318 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 | 319 references to files relative to |depdir|. It will be put in |depfile|. |
317 directory as the generated outputs. | |
318 | 320 |
319 For example, supposing we have three files in a directory src/ | 321 For example, supposing we have three files in a directory src/ |
320 | 322 |
321 src/ | 323 src/ |
322 blah.grd <- depends on input{1,2}.xtb | 324 blah.grd <- depends on input{1,2}.xtb |
323 input1.xtb | 325 input1.xtb |
324 input2.xtb | 326 input2.xtb |
325 | 327 |
326 and we run | 328 and we run |
327 | 329 |
328 grit -i blah.grd -o ../out/gen --dep-dir ../out | 330 grit -i blah.grd -o ../out/gen --depdir ../out --depfile ../out/gen/blah.r
d.d |
329 | 331 |
330 from the directory src/ we will generate a depfile ../out/gen/blah.grd.d | 332 from the directory src/ we will generate a depfile ../out/gen/blah.grd.d |
331 that has the contents | 333 that has the contents |
332 | 334 |
333 gen/blah.grd.d: ../src/input1.xtb ../src/input2.xtb | 335 gen/blah.grd.d: ../src/input1.xtb ../src/input2.xtb |
334 | 336 |
335 Note that all paths in the depfile are relative to ../out, the dep-dir. | 337 Note that all paths in the depfile are relative to ../out, the depdir. |
336 ''' | 338 ''' |
337 depsfile_basename = os.path.basename(input_filename + '.d') | 339 depfile = os.path.abspath(depfile) |
338 depfile = os.path.abspath( | 340 depdir = os.path.abspath(depdir) |
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. | 341 # The path prefix to prepend to dependencies in the depfile. |
342 prefix = os.path.relpath(os.getcwd(), dep_dir) | 342 prefix = os.path.relpath(os.getcwd(), depdir) |
343 # The path that the depfile refers to itself by. | 343 # The path that the depfile refers to itself by. |
344 self_ref_depfile = os.path.relpath(depfile, dep_dir) | 344 self_ref_depfile = os.path.relpath(depfile, depdir) |
345 infiles = self.res.GetInputFiles() | 345 infiles = self.res.GetInputFiles() |
346 deps_text = ' '.join([os.path.join(prefix, i) for i in infiles]) | 346 deps_text = ' '.join([os.path.join(prefix, i) for i in infiles]) |
347 depfile_contents = self_ref_depfile + ': ' + deps_text | 347 depfile_contents = self_ref_depfile + ': ' + deps_text |
348 self.MakeDirectoriesTo(depfile) | 348 self.MakeDirectoriesTo(depfile) |
349 outfile = self.fo_create(depfile, 'wb') | 349 outfile = self.fo_create(depfile, 'wb') |
350 outfile.writelines(depfile_contents) | 350 outfile.writelines(depfile_contents) |
351 | 351 |
352 @staticmethod | 352 @staticmethod |
353 def MakeDirectoriesTo(file): | 353 def MakeDirectoriesTo(file): |
354 '''Creates directories necessary to contain |file|.''' | 354 '''Creates directories necessary to contain |file|.''' |
355 dir = os.path.split(file)[0] | 355 dir = os.path.split(file)[0] |
356 if not os.path.exists(dir): | 356 if not os.path.exists(dir): |
357 os.makedirs(dir) | 357 os.makedirs(dir) |
OLD | NEW |