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

Side by Side Diff: grit/scons.py

Issue 1442863002: Remove contents of grit's SVN repository. (Closed) Base URL: http://grit-i18n.googlecode.com/svn/trunk/
Patch Set: Created 5 years, 1 month 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 | « grit/pseudo_unittest.py ('k') | grit/shortcuts.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
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
4 # found in the LICENSE file.
5
6 '''SCons integration for GRIT.
7 '''
8
9 # NOTE: DO NOT IMPORT ANY GRIT STUFF HERE - we import lazily so that
10 # grit and its dependencies aren't imported until actually needed.
11
12 import os
13 import types
14
15 def _IsDebugEnabled():
16 return 'GRIT_DEBUG' in os.environ and os.environ['GRIT_DEBUG'] == '1'
17
18 def _SourceToFile(source):
19 '''Return the path to the source file, given the 'source' argument as provided
20 by SCons to the _Builder or _Emitter functions.
21 '''
22 # Get the filename of the source. The 'source' parameter can be a string,
23 # a "node", or a list of strings or nodes.
24 if isinstance(source, types.ListType):
25 source = str(source[0])
26 else:
27 source = str(source)
28 return source
29
30
31 def _ParseRcFlags(flags):
32 """Gets a mapping of defines.
33
34 Args:
35 flags: env['RCFLAGS']; the input defines.
36
37 Returns:
38 A tuple of (defines, res_file):
39 defines: A mapping of {name: val}
40 res_file: None, or the specified res file for static file dependencies.
41 """
42 from grit import util
43
44 defines = {}
45 res_file = None
46 # Get the CPP defines from the environment.
47 res_flag = '--res_file='
48 for flag in flags:
49 if flag.startswith(res_flag):
50 res_file = flag[len(res_flag):]
51 continue
52 if flag.startswith('/D'):
53 flag = flag[2:]
54 name, val = util.ParseDefine(flag)
55 # Only apply to first instance of a given define
56 if name not in defines:
57 defines[name] = val
58 return (defines, res_file)
59
60
61 def _Builder(target, source, env):
62 print _SourceToFile(source)
63
64 from grit import grit_runner
65 from grit.tool import build
66 options = grit_runner.Options()
67 # This sets options to default values
68 options.ReadOptions([])
69 options.input = _SourceToFile(source)
70
71 # TODO(joi) Check if we can get the 'verbose' option from the environment.
72
73 builder = build.RcBuilder(defines=_ParseRcFlags(env['RCFLAGS'])[0])
74
75 # To ensure that our output files match what we promised SCons, we
76 # use the list of targets provided by SCons and update the file paths in
77 # our .grd input file with the targets.
78 builder.scons_targets = [str(t) for t in target]
79 builder.Run(options, [])
80 return None # success
81
82
83 def _GetOutputFiles(grd, base_dir):
84 """Processes outputs listed in the grd into rc_headers and rc_alls.
85
86 Note that anything that's not an rc_header is classified as an rc_all.
87
88 Args:
89 grd: An open GRD reader.
90
91 Returns:
92 A tuple of (rc_headers, rc_alls, lang_folders):
93 rc_headers: Outputs marked as rc_header.
94 rc_alls: All other outputs.
95 lang_folders: The output language folders.
96 """
97 rc_headers = []
98 rc_alls = []
99 lang_folders = {}
100
101 # Explicit output files.
102 for output in grd.GetOutputFiles():
103 path = os.path.join(base_dir, output.GetFilename())
104 if (output.GetType() == 'rc_header'):
105 rc_headers.append(path)
106 else:
107 rc_alls.append(path)
108 if _IsDebugEnabled():
109 print 'GRIT: Added target %s' % path
110 if output.attrs['lang'] != '':
111 lang_folders[output.attrs['lang']] = os.path.dirname(path)
112
113 return (rc_headers, rc_alls, lang_folders)
114
115
116 def _ProcessNodes(grd, base_dir, lang_folders):
117 """Processes the GRD nodes to figure out file dependencies.
118
119 Args:
120 grd: An open GRD reader.
121 base_dir: The base directory for filenames.
122 lang_folders: THe output language folders.
123
124 Returns:
125 A tuple of (structure_outputs, translated_files, static_files):
126 structure_outputs: Structures marked as sconsdep.
127 translated_files: Files that are structures or skeletons, and get
128 translated by GRIT.
129 static_files: Files that are includes, and are used directly by res files.
130 """
131 structure_outputs = []
132 translated_files = []
133 static_files = []
134
135 # Go through nodes, figuring out resources. Also output certain resources
136 # as build targets, based on the sconsdep flag.
137 for node in grd.ActiveDescendants():
138 with node:
139 file = node.ToRealPath(node.GetInputPath())
140 if node.name == 'structure':
141 translated_files.append(os.path.abspath(file))
142 # TODO(joi) Should remove the "if sconsdep is true" thing as it is a
143 # hack - see grit/node/structure.py
144 if node.HasFileForLanguage() and node.attrs['sconsdep'] == 'true':
145 for lang in lang_folders:
146 path = node.FileForLanguage(lang, lang_folders[lang],
147 create_file=False,
148 return_if_not_generated=False)
149 if path:
150 structure_outputs.append(path)
151 if _IsDebugEnabled():
152 print 'GRIT: Added target %s' % path
153 elif (node.name == 'skeleton' or (node.name == 'file' and node.parent and
154 node.parent.name == 'translations')):
155 translated_files.append(os.path.abspath(file))
156 elif node.name == 'include':
157 # If it's added by file name and the file isn't easy to find, don't make
158 # it a dependency. This could add some build flakiness, but it doesn't
159 # work otherwise.
160 if node.attrs['filenameonly'] != 'true' or os.path.exists(file):
161 static_files.append(os.path.abspath(file))
162 # If it's output from mk, look in the output directory.
163 elif node.attrs['mkoutput'] == 'true':
164 static_files.append(os.path.join(base_dir, os.path.basename(file)))
165
166 return (structure_outputs, translated_files, static_files)
167
168
169 def _SetDependencies(env, base_dir, res_file, rc_alls, translated_files,
170 static_files):
171 """Sets dependencies in the environment.
172
173 Args:
174 env: The SCons environment.
175 base_dir: The base directory for filenames.
176 res_file: The res_file specified in the RC flags.
177 rc_alls: All non-rc_header outputs.
178 translated_files: Files that are structures or skeletons, and get
179 translated by GRIT.
180 static_files: Files that are includes, and are used directly by res files.
181 """
182 if res_file:
183 env.Depends(os.path.join(base_dir, res_file), static_files)
184 else:
185 # Make a best effort dependency setup when no res file is specified.
186 translated_files.extend(static_files)
187
188 for rc_all in rc_alls:
189 env.Depends(rc_all, translated_files)
190
191
192 def _Emitter(target, source, env):
193 """Modifies the list of targets to include all outputs.
194
195 Note that this also sets up the dependencies, even though it's an emitter
196 rather than a scanner. This is so that the resource header file doesn't show
197 as having dependencies.
198
199 Args:
200 target: The list of targets to emit for.
201 source: The source or list of sources for the target.
202 env: The SCons environment.
203
204 Returns:
205 A tuple of (targets, sources).
206 """
207 from grit import grd_reader
208 from grit import util
209
210 (defines, res_file) = _ParseRcFlags(env['RCFLAGS'])
211
212 grd = grd_reader.Parse(_SourceToFile(source), debug=_IsDebugEnabled())
213 # TODO(jperkins): This is a hack to get an output context set for the reader.
214 # This should really be smarter about the language.
215 grd.SetOutputLanguage('en')
216 grd.SetDefines(defines)
217
218 base_dir = util.dirname(str(target[0]))
219 (rc_headers, rc_alls, lang_folders) = _GetOutputFiles(grd, base_dir)
220 (structure_outputs, translated_files, static_files) = _ProcessNodes(grd,
221 base_dir, lang_folders)
222
223 rc_alls.extend(structure_outputs)
224 _SetDependencies(env, base_dir, res_file, rc_alls, translated_files,
225 static_files)
226
227 targets = rc_headers
228 targets.extend(rc_alls)
229
230 # Return target and source lists.
231 return (targets, source)
232
233
234 # Function name is mandated by newer versions of SCons.
235 def generate(env):
236 # Importing this module should be possible whenever this function is invoked
237 # since it should only be invoked by SCons.
238 import SCons.Builder
239 import SCons.Action
240
241 # The varlist parameter tells SCons that GRIT needs to be invoked again
242 # if RCFLAGS has changed since last compilation.
243 build_action = SCons.Action.FunctionAction(_Builder, varlist=['RCFLAGS'])
244 emit_action = SCons.Action.FunctionAction(_Emitter, varlist=['RCFLAGS'])
245
246 builder = SCons.Builder.Builder(action=build_action, emitter=emit_action,
247 src_suffix='.grd')
248
249 # Add our builder and scanner to the environment.
250 env.Append(BUILDERS = {'GRIT': builder})
251
252
253 # Function name is mandated by newer versions of SCons.
254 def exists(env):
255 return 1
OLDNEW
« no previous file with comments | « grit/pseudo_unittest.py ('k') | grit/shortcuts.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698