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

Side by Side Diff: site_scons/site_tools/omaha_builders.py

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 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 | « site_scons/site_init.py ('k') | site_scons/site_tools/wix.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/python2.4
2 #
3 # Copyright 2009 Google Inc.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 # ========================================================================
17
18 """Omaha builders tool for SCons."""
19
20 import os.path
21 import SCons.Action
22 import SCons.Builder
23 import SCons.Tool
24
25
26 def EnablePrecompile(env, target_name):
27 """Enable use of precompiled headers for target_name.
28
29 Args:
30 env: The environment.
31 target_name: Name of component.
32
33 Returns:
34 The pch .obj file.
35 """
36 if env.Bit('use_precompiled_headers'):
37 # We enable all warnings on all levels. The goal is to fix the code that
38 # we have written and to programmatically disable the warnings for the
39 # code we do not control. This list of warnings should shrink as the code
40 # gets fixed.
41 env.FilterOut(CCFLAGS=['/W3'])
42 env.Append(
43 CCFLAGS=[
44 '/W4',
45 '/Wall',
46 ],
47 INCLUDES=[
48 '$MAIN_DIR/precompile/precompile.h'
49 ],
50 )
51
52 env['PCHSTOP'] = '$MAIN_DIR/precompile/precompile.h'
53
54 pch_env = env.Clone()
55 # Must manually force-include the header, as the precompilation step does
56 # not evaluate $INCLUDES
57 pch_env.Append(CCFLAGS=['/FI$MAIN_DIR/precompile/precompile.h'])
58 # Append '_pch' to the target base name to prevent target name collisions.
59 # One case where this might have occurred is when a .cc file has the same
60 # base name as the target program/library.
61 pch_output = pch_env.PCH(
62 target=target_name.replace('.', '_') + '_pch' + '.pch',
63 source='$MAIN_DIR/precompile/precompile.cc',
64 )
65
66 env['PCH'] = pch_output[0]
67
68 # Return the pch .obj file that is created, so it can be
69 # included with the inputs of a module
70 return [pch_output[1]]
71
72
73 def SignDotNetManifest(env, target, unsigned_manifest):
74 """Signs a .NET manifest.
75
76 Args:
77 env: The environment.
78 target: Name of signed manifest.
79 unsigned_manifest: Unsigned manifest.
80
81 Returns:
82 Output node list from env.Command().
83 """
84 sign_manifest_cmd = ('@mage -Sign $SOURCE -ToFile $TARGET -TimestampUri '
85 'http://timestamp.verisign.com/scripts/timstamp.dll ')
86
87 if env.Bit('build_server'):
88 # If signing fails with the following error, the hash may not match any
89 # certificates: "Internal error, please try again. Object reference not set
90 # to an instance of an object."
91 sign_manifest_cmd += ('-CertHash ' +
92 env['build_server_certificate_hash'])
93 else:
94 sign_manifest_cmd += '-CertFile %s -Password %s' % (
95 env.GetOption('authenticode_file'),
96 env.GetOption('authenticode_password'))
97
98 signed_manifest = env.Command(
99 target=target,
100 source=unsigned_manifest,
101 action=sign_manifest_cmd
102 )
103
104 return signed_manifest
105
106
107 #
108 # Custom Library and Program builders.
109 #
110 # These builders have additional cababilities, including enabling precompiled
111 # headers when appropriate and signing DLLs and EXEs.
112 #
113
114 # TODO(omaha): Make all build files use these builders instead of Hammer's.
115 # This will eliminate many lines in build.scons files related to enabling
116 # precompiled header and signing binaries.
117
118
119 def _ConditionallyEnablePrecompile(env, target_name, *args, **kwargs):
120 """Enables precompiled headers for target_name when appropriate.
121
122 Enables precompiled headers if they are enabled for the build unless
123 use_pch_default = False. This requires that the source files are specified in
124 sources or in a list as the first argument after target_name.
125
126 Args:
127 env: Environment in which we were called.
128 target_name: Name of the build target.
129 args: Positional arguments.
130 kwargs: Keyword arguments.
131 """
132 use_pch_default = kwargs.get('use_pch_default', True)
133
134 if use_pch_default and env.Bit('use_precompiled_headers'):
135 pch_output = env.EnablePrecompile(target_name)
136
137 # Search the keyworded list first.
138 for key in ['source', 'sources', 'input', 'inputs']:
139 if key in kwargs:
140 kwargs[key] += pch_output
141 return
142
143 # If the keyword was not found, assume the sources are the first argument in
144 # the non-keyworded list.
145 if args:
146 args[0].append(pch_output[0])
147
148
149 def ComponentStaticLibrary(env, lib_name, *args, **kwargs):
150 """Pseudo-builder for static library.
151
152 Enables precompiled headers if they are enabled for the build unless
153 use_pch_default = False. This requires that the source files are specified in
154 sources or in a list as the first argument after lib_name.
155
156 Args:
157 env: Environment in which we were called.
158 lib_name: Static library name.
159 args: Positional arguments.
160 kwargs: Keyword arguments.
161
162 Returns:
163 Output node list from env.ComponentLibrary().
164 """
165 _ConditionallyEnablePrecompile(env, lib_name, *args, **kwargs)
166
167 return env.ComponentLibrary(lib_name, *args, **kwargs)
168
169
170 # TODO(omaha): Add signing.
171 def ComponentDll(env, lib_name, *args, **kwargs):
172 """Pseudo-builder for DLL.
173
174 Enables precompiled headers if they are enabled for the build unless
175 use_pch_default = False. This requires that the source files are specified in
176 sources or in a list as the first argument after lib_name.
177
178 Args:
179 env: Environment in which we were called.
180 lib_name: DLL name.
181 args: Positional arguments.
182 kwargs: Keyword arguments.
183
184 Returns:
185 Output node list from env.ComponentLibrary().
186 """
187 env.Append(COMPONENT_STATIC=False)
188
189 _ConditionallyEnablePrecompile(env, lib_name, *args, **kwargs)
190
191 return env.ComponentLibrary(lib_name, *args, **kwargs)
192
193
194 # TODO(omaha): Add signing.
195 def ComponentSignedProgram(env, prog_name, *args, **kwargs):
196 """Pseudo-builder for signed EXEs.
197
198 Enables precompiled headers if they are enabled for the build unless
199 use_pch_default = False. This requires that the source files are specified in
200 sources or in a list as the first argument after prog_name.
201
202 Args:
203 env: Environment in which we were called.
204 prog_name: Executable name.
205 args: Positional arguments.
206 kwargs: Keyword arguments.
207
208 Returns:
209 Output node list from env.ComponentProgram().
210 """
211 _ConditionallyEnablePrecompile(env, prog_name, *args, **kwargs)
212
213 return env.ComponentProgram(prog_name, *args, **kwargs)
214
215
216 # TODO(omaha): Put these in a tools/ directory instead of staging.
217 def ComponentTool(env, prog_name, *args, **kwargs):
218 """Pseudo-builder for utility programs that do not need to be signed.
219
220 Enables precompiled headers if they are enabled for the build unless
221 use_pch_default = False. This requires that the source files are specified in
222 sources or in a list as the first argument after prog_name.
223
224 Args:
225 env: Environment in which we were called.
226 prog_name: Executable name.
227 args: Positional arguments.
228 kwargs: Keyword arguments.
229
230 Returns:
231 Output node list from env.ComponentProgram().
232 """
233 _ConditionallyEnablePrecompile(env, prog_name, *args, **kwargs)
234
235 return env.ComponentProgram(prog_name, *args, **kwargs)
236
237
238 #
239 # Unit Test Builders
240 #
241
242
243 def OmahaUnittest(env, # pylint: disable-msg=C6409
244 name,
245 source,
246 LIBS=None,
247 all_in_one=True,
248 COMPONENT_TEST_SIZE='large',
249 is_small_tests_using_resources=False):
250 """Declares a new unit test.
251
252 Args:
253 env: The environment.
254 name: Name of the unit test.
255 source: Sources for the unittest.
256 LIBS: Any libs required for the unit test.
257 all_in_one: If true, the test will be added to an executable containing
258 all tests.
259 COMPONENT_TEST_SIZE: small, medium, or large.
260 is_small_tests_using_resources: True if COMPONENT_TEST_SIZE='small' and
261 the test requires resources, such as strings.
262
263 If !all_in_one and COMPONENT_TEST_SIZE is 'small', a main is automatically
264 provided. Otherwise, one must be provided in source or LIBS. The small main
265 is selected based on is_small_tests_using_resources.
266
267 Returns:
268 Output node list from env.ComponentTestProgram().
269
270 Raises:
271 Exception: Invalid combination of arguments.
272 """
273 test_env = env.Clone()
274
275 source = test_env.Flatten(source)
276
277 if COMPONENT_TEST_SIZE != 'small' and is_small_tests_using_resources:
278 raise Exception('is_small_tests_using_resources set for non-small test.')
279
280 if all_in_one:
281 test_env['all_in_one_unittest_sources'].extend(test_env.File(source))
282 if LIBS:
283 test_env['all_in_one_unittest_libs'].update(
284 test_env.File(test_env.Flatten(LIBS)))
285 # TODO(omaha): Get the node list automatically.
286 if 'HAMMER_RUNS_TESTS' in os.environ.keys():
287 test_program_dir = '$TESTS_DIR'
288 else:
289 test_program_dir = '$STAGING_DIR'
290 output = [os.path.join(test_program_dir, 'omaha_unittest.exe'),
291 os.path.join(test_program_dir, 'omaha_unittest.pdb')]
292 else:
293 test_env.FilterOut(LINKFLAGS=['/NODEFAULTLIB', '/SUBSYSTEM:WINDOWS'])
294 if LIBS:
295 test_env.Append(
296 LIBS=test_env.Flatten(LIBS),
297 )
298 # TODO(omaha): Let's try to eliminate this giant list of Win32 .libs here.
299 # They are generally dependencies of Omaha base, common, or net; it makes
300 # more sense for unit test authors to stay aware of dependencies and pass
301 # them in as part of the LIBS argument.
302 test_env.Append(
303 CPPPATH=[
304 '$MAIN_DIR/third_party/gmock/include',
305 '$MAIN_DIR/third_party/gtest/include',
306 ],
307 LIBS=[
308 '$LIB_DIR/base',
309 '$LIB_DIR/gmock',
310 '$LIB_DIR/gtest',
311 ('atls', 'atlsd')[test_env.Bit('debug')],
312
313 # Required by base/process.h, which is used by unit_test.cc.
314 'psapi',
315
316 # Required by omaha_version.h, which is used by omaha_unittest.cc.
317 'version',
318
319 # Rquired if base/utils.h, which is used by several modules used by
320 # omaha_unittest.cc, is used.
321 'netapi32',
322 'rasapi32',
323 'shlwapi',
324 'wtsapi32',
325 ],
326 )
327
328 if COMPONENT_TEST_SIZE == 'small':
329 if is_small_tests_using_resources:
330 test_env.Append(LIBS=['$LIB_DIR/unittest_base_small_with_resources'])
331 else:
332 test_env.Append(LIBS=['$LIB_DIR/unittest_base_small'])
333
334 if env.Bit('use_precompiled_headers'):
335 source += test_env.EnablePrecompile(name)
336
337 # Set environment variables specific to the tests.
338 for env_var in os.environ:
339 if (not env_var in test_env['ENV'] and
340 (env_var.startswith('GTEST_') or env_var.startswith('OMAHA_TEST_'))):
341 test_env['ENV'][env_var] = os.environ[env_var]
342
343 output = test_env.ComponentTestProgram(
344 name,
345 source + ['$OBJ_ROOT/testing/run_as_invoker.res'],
346 COMPONENT_TEST_SIZE=COMPONENT_TEST_SIZE,
347 )
348
349 # Add a manual dependency on the resource file used by omaha_unittest.cc to
350 # ensure it is always available before the test runs, which could be during
351 # the build.
352 test_env.Depends(output, '$TESTS_DIR/goopdateres_en.dll')
353
354 return output
355
356
357 def GetAllInOneUnittestSources(env):
358 """Returns a list of source files for the all-in-one unit test.
359
360 Args:
361 env: The environment.
362
363 Returns:
364 A list of sources for the all-in-one unit test.
365 """
366 return env['all_in_one_unittest_sources']
367
368
369 def GetAllInOneUnittestLibs(env):
370 """Returns a list of libs to be linked into the all-in-one unit test.
371
372 Args:
373 env: The environment.
374
375 Returns:
376 A list of libs for the all-in-one unit test.
377 """
378 # Sort to prevent spurious rebuilds caused by indeterminate ordering of a set.
379 return sorted(env['all_in_one_unittest_libs'],
380 key=SCons.Node.FS.Base.get_abspath)
381
382
383 # If a .idl file does not result in any generated proxy code (no foo_p.c and
384 # no foo_data.c), the default TypeLibrary builder will mistakenly believe that
385 # the IDL needs to be run through midl.exe again to rebuild the missing files.
386 def _MidlEmitter(target, source, env):
387 def IsNonProxyGeneratedFile(x):
388 """Returns true if x is not generated proxy code, false otherwise."""
389 return not (str(x).endswith('_p.c') or str(x).endswith('_data.c'))
390
391 (t, source) = SCons.Tool.midl.midl_emitter(target, source, env)
392 return (filter(IsNonProxyGeneratedFile, t), source)
393
394
395 def IsCoverageBuild(env):
396 """Returns true if this is a coverage build.
397
398 Args:
399 env: The environment.
400
401 Returns:
402 whether this is a coverage build.
403 """
404 return 'coverage' in env.subst('$BUILD_TYPE')
405
406
407 def CopyFileToDirectory(env, target, source):
408 """Copies the file to the directory using the DOS copy command.
409
410 In general, Replicate() should be used, but there are specific cases where
411 an explicit copy is required.
412
413 Args:
414 env: The environment.
415 target: The target directory.
416 source: The full path to the source file.
417
418 Returns:
419 Output node list from env.Command().
420 """
421 (_, source_filename) = os.path.split(source)
422 return env.Command(target=os.path.join(target, source_filename),
423 source=source,
424 action='@copy /y $SOURCE $TARGET')
425
426
427 # NOTE: SCons requires the use of this name, which fails gpylint.
428 def generate(env): # pylint: disable-msg=C6409
429 """SCons entry point for this tool."""
430 env.AddMethod(EnablePrecompile)
431 env.AddMethod(SignDotNetManifest)
432 env.AddMethod(ComponentStaticLibrary)
433 env.AddMethod(ComponentDll)
434 env.AddMethod(ComponentSignedProgram)
435 env.AddMethod(ComponentTool)
436 env.AddMethod(OmahaUnittest)
437 env.AddMethod(GetAllInOneUnittestSources)
438 env.AddMethod(GetAllInOneUnittestLibs)
439 env.AddMethod(IsCoverageBuild)
440 env.AddMethod(CopyFileToDirectory)
441
442 env['MIDLNOPROXYCOM'] = ('$MIDL $MIDLFLAGS /tlb ${TARGETS[0]} '
443 '/h ${TARGETS[1]} /iid ${TARGETS[2]} '
444 '$SOURCE 2> NUL')
445 env['BUILDERS']['TypeLibraryWithNoProxy'] = SCons.Builder.Builder(
446 action=SCons.Action.Action('$MIDLNOPROXYCOM', '$MIDLNOPROXYCOMSTR'),
447 src_suffix='.idl',
448 suffix='.tlb',
449 emitter=_MidlEmitter,
450 source_scanner=SCons.Tool.midl.idl_scanner)
OLDNEW
« no previous file with comments | « site_scons/site_init.py ('k') | site_scons/site_tools/wix.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698