2 # Copyright 2008, Google Inc.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 sys
.path
.append("./common")
41 Dir('gtest').addRepository(Dir('../third_party/gtest/files'))
46 # ----------------------------------------------------------
47 # Base environment for both nacl and non-nacl variants.
48 pre_base_env
= Environment(
49 tools
= ['component_setup'],
50 # Makes SOURCE_ROOT independent of site_init.
51 SOURCE_ROOT
= Dir('#/../..').abspath
,
52 # Publish dlls as final products (to staging).
53 COMPONENT_LIBRARY_PUBLISH
= True,
55 pre_base_env
.Append(BUILD_GROUPS
=['most'])
56 # ----------------------------------------------------------
57 # Small tests are usually unit tests
59 def AddNodeToSmallTestsSuite(env
, node
):
60 Alias('small_tests', node
)
62 pre_base_env
.AddMethod(AddNodeToSmallTestsSuite
)
64 # ----------------------------------------------------------
66 Alias('unit_tests', 'small_tests')
68 # ----------------------------------------------------------
69 # Medium tests are usually larger than unit tests, but don't take as much time
71 def AddNodeToMediumTestsSuite(env
, node
):
72 Alias('medium_tests', node
)
74 pre_base_env
.AddMethod(AddNodeToMediumTestsSuite
)
76 # ----------------------------------------------------------
77 # Large tests are usually long tests
79 def AddNodeToLargeTestsSuite(env
, node
):
80 Alias('large_tests', node
)
82 pre_base_env
.AddMethod(AddNodeToLargeTestsSuite
)
84 # ----------------------------------------------------------
86 def AddNodeToSmokeTestSuite(env
, node
):
87 env
.Alias('smoke_test', node
)
89 pre_base_env
.AddMethod(AddNodeToSmokeTestSuite
)
91 def _SmokeTestIntro(**args
):
92 Banner("Running Smoke Test")
94 node
= pre_base_env
.Command(target
='dummy',
96 action
=_SmokeTestIntro
)
99 pre_base_env
.AddNodeToSmokeTestSuite(node
)
101 # ----------------------------------------------------------
107 pre_base_env
.AddMethod(Banner
)
110 def FindLikelySelLdr(directory
):
112 if (nacl_util
.GetSelLdr('opt')):
113 candidates
.append(nacl_util
.GetSelLdr('opt'))
114 if (nacl_util
.GetSelLdr('dbg')):
115 candidates
.append(nacl_util
.GetSelLdr('dbg'))
118 mtime
= os
.stat(c
)[stat
.ST_MTIME
]
119 if mtime
> latest
[1]:
124 def CommandSelLdrTestNacl(env
, name
, exe
, guess_sel_ldr
=False, flags
='" "',
125 stdin
='None', stdout
='None', filter='""',
127 stderr_filter
=('"^(NeverMatched AlwaysIgnoreStderr)'
130 log_golden
='None', log_filter
='".*"',
132 # TODO: retire the sel_ldr_tester.py script in favor of command_tester.py
134 # the default for stderr_filter is a heuristic: it should only
135 # match the phrase "NeverMatched AlwaysIgnoreStderr" repeated 999
136 # times, so should serve as a filter that ignores all stderr
137 # output. (There is, AFAIK, no regexp that always fails to match.)
138 # Since for non-death tests we had been ignoring stderr output,
139 # this way we get (approximately) the same behavior.
140 script
= '${SCONSTRUCT_DIR}/tools/sel_ldr_tester.py'
143 sel_ldr
= FindLikelySelLdr(env
.subst('$DESTINATION_ROOT'))
144 # Bail out if sel_ldr can't be found.
145 if not sel_ldr
: return []
147 sel_ldr
= '$STAGING_DIR/${PROGPREFIX}sel_ldr${PROGSUFFIX}'
148 deps
= [script
, sel_ldr
, exe
]
149 if stdin
!= 'None': deps
.append(stdin
)
150 if stdout
!= 'None': deps
.append(stdout
)
152 if log_golden
!= 'None':
153 log_output
= '${TARGET}.log'
154 # TODO: consider redirecting output into tests/results
155 return env
.Command(name
, deps
,
156 '$PYTHON ${SOURCES[0].abspath} '
157 '${SOURCES[1].abspath} '
158 '${SOURCES[2].abspath} '
159 '%s %s %s %s %s %s %d %s %s %d %s > $TARGET' % (
160 flags
, stdin
, stdout
, filter,
161 stderr
, stderr_filter
, exit_status
,
162 log_golden
, log_filter
, log_verbosity
, log_output
))
164 pre_base_env
.AddMethod(CommandSelLdrTestNacl
)
166 # ----------------------------------------------------------
168 TEST_EXTRA_ARGS
= ['stdin', 'stdout', 'stderr', 'log',
169 're_stdout', 're_stderr', 're_log']
170 TEST_SCRIPT
= '${SCONSTRUCT_DIR}/tools/command_tester.py'
172 def CommandTestAgainstGoldenOuput(env
, name
, command
, **extra
):
173 script_flags
= ['--name', name
]
176 for n
, c
in enumerate(command
):
179 command
[n
] = '${SOURCES[%d].abspath}' % (len(deps
) - 1)
182 assert e
in TEST_EXTRA_ARGS
183 if type(extra
[e
]) != str:
184 deps
.append(extra
[e
])
185 extra
[e
] = '${SOURCES[%d].abspath}' % (len(deps
) - 1)
186 script_flags
.append('--' + e
)
187 script_flags
.append(extra
[e
])
189 # NOTE: "SOURCES[X]" references the scons object in deps[x]
190 command
= ['${PYTHON}',
191 '${SOURCES[0].abspath}',
192 ' '.join(script_flags
),
197 # TODO: consider redirecting output into tests/results
198 return env
.Command(name
, deps
, " ".join(command
))
200 pre_base_env
.AddMethod(CommandTestAgainstGoldenOuput
)
201 # ----------------------------------------------------------
202 if ARGUMENTS
.get('pp', 0):
203 def CommandPrettyPrinter(cmd
, targets
, source
, env
):
204 prefix
= env
.subst('$SOURCE_ROOT') + '/googleclient/'
206 cmd_tokens
= cmd
.split()
207 if "python" in cmd_tokens
[0]:
208 cmd_name
= cmd_tokens
[1]
210 cmd_name
= cmd_tokens
[0].split('(')[0]
211 if cmd_name
.startswith(prefix
):
212 cmd_name
= cmd_name
[len(prefix
):]
213 env_name
= env
.subst('${BUILD_TYPE}${BUILD_SUBTYPE}')
214 print '[%s] [%s] %s' % (cmd_name
, env_name
, target
.get_path())
215 pre_base_env
.Append(PRINT_CMD_LINE_FUNC
= CommandPrettyPrinter
)
217 # ----------------------------------------------------------
218 base_env
= pre_base_env
.Clone()
221 BUILD_SCONSCRIPTS
= [
222 # NOTE: this dir also has a nacl.scons
223 'tests/npapi_bridge/build.scons',
225 'platform_qual_test/build.scons',
226 'service_runtime/build.scons',
227 'service_runtime/nrd_xfer_lib/build.scons',
228 'tools/libsrpc/build.scons',
229 'tools/npapi_runtime/build.scons',
230 'intermodule_comm/build.scons',
231 'npapi_plugin/build.scons',
232 'npapi_plugin/install.scons',
234 'nonnacl_util/build.scons',
235 # 'nacl_ie_plugin/build.scons',
238 ['NACL_BLOCK_SHIFT', '5'],
239 ['NACL_BLOCK_SIZE', '32'],
241 GEN2_FLAGS
= '-c -f "Video|Audio|Multimedia"',
244 SDL_HERMETIC_LINUX_DIR
='$MAIN_DIR/../third_party/sdl/linux/v1_2_13',
245 SDL_HERMETIC_MAC_DIR
='$MAIN_DIR/../third_party/sdl/osx/v1_2_13',
246 SDL_HERMETIC_WINDOWS_DIR
='$MAIN_DIR/../third_party/sdl/win/v1_2_13',
251 # Optionally ignore the build process.
252 DeclareBit('prebuilt', 'Disable all build steps, only support install steps')
253 base_env
.SetBitFromOption('prebuilt', False)
254 if base_env
.Bit('prebuilt'):
255 base_env
.Replace(BUILD_SCONSCRIPTS
= ['npapi_plugin/install.scons'])
257 # Add the sdk root path (without setting up the tools).
258 base_env
['NACL_SDK_ROOT_ONLY'] = True
259 base_env
.Tool('naclsdk')
263 ======================================================================
265 ======================================================================
272 * + nacl: scons -c MODE=most
273 * + doc and more: scons -c MODE=all
274 * just the doc: scons MODE=doc
275 * build mandel: scons MODE=most mandel.nexe
276 * some unittests: scons small_tests
277 * a smoke test: scons -k pp=1 smoke_test
278 * 2nd smoke test: scons -k pp=1 MODE=nacl smoke_test
279 * firefox plugin: scons MODE=opt-linux npGoogleNaClPlugin
280 * sel_ldr: scons MODE=opt-linux sel_ldr
281 * firefox install: scons firefox_install
282 * firefox install pre-built copy: scons firefox_install --prebuilt
286 pp=1 use command line pretty printing (more concise output)
287 sdl=<mode> where <mode>:
288 'none': don't use SDL (default)
289 'local': use locally installed SDL
290 'hermetic': use the hermetic SDL copy
291 naclsdk_mode=<mode> where <mode>:
292 'local': use locally installed sdk kit
293 'download': use the download copy (default)
294 'custom:<path>': use kit at <path>
296 --prebuilt Do not build things, just do install steps
298 Automagically generated help:
299 -----------------------------
302 # ----------------------------------------------------------
303 windows_env
= base_env
.Clone(
304 tools
= ['target_platform_windows'],
305 ASCOM
= '$ASPPCOM /E | as -o $TARGET',
306 PDB
= '${TARGET.base}.pdb',
310 ['NACL_WINDOWS', '1'],
313 ['_WIN32_WINNT', '0x0501']
315 NACL_PLATFORM
= 'win',
316 LIBS
= ['wsock32', 'advapi32'],
317 CCFLAGS
= ['/EHsc', '/WX'],
320 windows_debug_env
= windows_env
.Clone(
321 tools
= ['target_debug'],
322 BUILD_TYPE
= 'dbg-win',
323 BUILD_TYPE_DESCRIPTION
= 'Windows debug build',
326 windows_debug_env
.Append(BUILD_GROUPS
= ['default'])
327 environment_list
.append(windows_debug_env
)
329 windows_optimized_env
= windows_env
.Clone(
330 tools
= ['target_optimized'],
331 BUILD_TYPE
= 'opt-win',
332 BUILD_TYPE_DESCRIPTION
= 'Windows optimized build',
334 environment_list
.append(windows_optimized_env
)
336 if ARGUMENTS
.get('sdl', 'hermetic') != 'none':
337 # These will only apply to sdl!=none builds!
338 windows_debug_env
.Append(
342 windows_optimized_env
.Append(
347 if '/MT' in windows_optimized_env
['CCFLAGS']:
348 windows_optimized_env
.FilterOut(CCFLAGS
=['/MT']);
349 windows_optimized_env
.Append(CCFLAGS
=['/MD']);
350 if '/MTd' in windows_debug_env
['CCFLAGS']:
351 windows_debug_env
.FilterOut(CCFLAGS
=['/MTd']);
352 windows_debug_env
.Append(CCFLAGS
=['/MDd']);
353 # this doesn't feel right, but fixes dbg-win
354 windows_debug_env
.Append(LINKFLAGS
= ['/NODEFAULTLIB:msvcrt'])
355 # make source level debugging a little easier
356 if '/Z7' not in windows_debug_env
['CCFLAGS']:
357 if '/Zi' not in windows_debug_env
['CCFLAGS']:
358 windows_debug_env
.Append(CCFLAGS
=['/Z7'])
360 # ----------------------------------------------------------
362 unix_like_env
= base_env
.Clone()
363 unix_like_env
.Append(
369 '-fvisibility=hidden',
370 '-Wno-unused-variable',
373 CFLAGS
= ['-std=gnu99'],
374 LIBS
= ['pthread', 'ssl', 'crypto'],
377 # ----------------------------------------------------------
379 mac_env
= unix_like_env
.Clone(
380 tools
= ['target_platform_mac'],
381 # TODO: this should really be able to live in unix_like_env
382 # but can't due to what the target_platform_x module is
385 PLUGIN_SUFFIX
= '.bundle',
389 ['NACL_WINDOWS', '0'],
392 ['MAC_OS_X_VERSION_MIN_REQUIRED', 'MAC_OS_X_VERSION_10_4'],
394 NACL_PLATFORM
= 'osx',
395 CCFLAGS
= ['-mmacosx-version-min=10.4']
398 mac_debug_env
= mac_env
.Clone(
399 tools
= ['target_debug'],
400 BUILD_TYPE
= 'dbg-mac',
401 BUILD_TYPE_DESCRIPTION
= 'MacOS debug build',
403 mac_debug_env
.Append(BUILD_GROUPS
= ['default'])
404 environment_list
.append(mac_debug_env
)
406 mac_optimized_env
= mac_env
.Clone(
407 tools
= ['target_optimized'],
408 BUILD_TYPE
= 'opt-mac',
409 BUILD_TYPE_DESCRIPTION
= 'MacOS optimized build',
411 environment_list
.append(mac_optimized_env
)
413 # ----------------------------------------------------------
415 linux_env
= unix_like_env
.Clone(
416 tools
= ['target_platform_linux'],
417 # TODO: this should really be able to live in unix_like_env
418 # but can't due to what the target_platform_x module is
423 # -m32 and -L/usr/lib32 are needed to do 32-bit builds on 64-bit
424 # user-space machines; requires ia32-libs-dev to be installed; or,
425 # failing that, ia32-libs and symbolic links *manually* created for
426 # /usr/lib32/libssl.so and /usr/lib32/libcrypto.so to the current
427 # /usr/lib32/lib*.so.version (tested with ia32-libs 2.2ubuntu11; no
428 # ia32-libs-dev was available for testing).
429 # Additional symlinks of this sort are needed for gtk,
430 # see nonnacl_util/build.scons.
432 linux_env
.SetDefault(
433 # NOTE: look into http://www.scons.org/wiki/DoxygenBuilder
434 DOXYGEN
= ARGUMENTS
.get('DOXYGEN', '/usr/bin/doxygen'),
438 ASFLAGS
= [ '-m32', ],
439 CFLAGS
= [ '-m32', ],
440 CCFLAGS
= [ '-m32', ],
442 ['NACL_WINDOWS', '0'],
447 LINKFLAGS
= [ '-m32', '-L/usr/lib32', ],
448 NACL_PLATFORM
= 'linux',
452 linux_debug_env
= linux_env
.Clone(
453 tools
= ['target_debug'],
454 BUILD_TYPE
= 'dbg-linux',
455 BUILD_TYPE_DESCRIPTION
= 'Linux debug build',
457 linux_debug_env
.Append(BUILD_GROUPS
= ['default'])
458 environment_list
.append(linux_debug_env
)
460 linux_optimized_env
= linux_env
.Clone(
461 tools
= ['target_optimized'],
462 BUILD_TYPE
= 'opt-linux',
463 BUILD_TYPE_DESCRIPTION
= 'Linux optimized build',
465 environment_list
.append(linux_optimized_env
)
468 # ----------------------------------------------------------
469 # The nacl_env is used to build native_client modules
470 # using a special tool chain which produces platform
471 # independent binaries
472 # ----------------------------------------------------------
473 nacl_env
= pre_base_env
.Clone(
476 BUILD_TYPE_DESCRIPTION
= 'NaCl module build',
479 # TODO: This doesn't work at the moment due to a scons
480 # limitation. Commented out until scons is fixed.
481 # hook for app to specify extra libraries
482 #LIBS = "$EXTRA_LIBS",
484 CCFLAGS
= ['-O2', '-mfpmath=sse', '-msse', '-fomit-frame-pointer'],
486 CPPPATH
= ['$SOURCE_ROOT/googleclient'],
489 Banner('Building nexe binaries using sdk at [%s]' %
490 nacl_env
.subst('$NACL_SDK_ROOT'))
494 BUILD_SCONSCRIPTS
= [
495 #### ALPHABETICALLY SORTED ####
496 'intermodule_comm/nacl.scons',
499 'tests/app_lib/nacl.scons',
500 'tests/contest_issues/nacl.scons',
501 'tests/cloudfs/nacl.scons',
502 'tests/earth/nacl.scons',
503 'tests/fib/nacl.scons',
504 'tests/file/nacl.scons',
505 'tests/hello_world/nacl.scons',
506 'tests/imc_shm_mmap/nacl.scons',
507 'tests/life/nacl.scons',
508 'tests/mandel/nacl.scons',
509 'tests/mandel_nav/nacl.scons',
510 'tests/many/nacl.scons',
511 'tests/mmap/nacl.scons',
512 'tests/noop/nacl.scons',
513 'tests/npapi_bridge/nacl.scons',
514 'tests/npapi_hw/nacl.scons',
515 'tests/npapi_pi/nacl.scons',
516 'tests/nrd_xfer/nacl.scons',
517 'tests/null/nacl.scons',
518 'tests/nullptr/nacl.scons',
519 'tests/srpc/nacl.scons',
520 'tests/srpc_hw/nacl.scons',
521 'tests/syscalls/nacl.scons',
522 'tests/threads/nacl.scons',
523 'tests/tone/nacl.scons',
524 'tests/voronoi/nacl.scons',
526 'tools/stubs/nacl.scons',
527 'tools/libnacl/nacl.scons',
528 'tools/libsrpc/nacl.scons',
529 'tools/nc_threads/nacl.scons',
530 'tools/libav/nacl.scons',
531 'tools/libunimpl/nacl.scons',
532 'tools/npapi_runtime/nacl.scons',
533 #### ALPHABETICALLY SORTED ####
537 # Uncomment this if you want the nacl stuff to be build by default.
538 #nacl_env.Append(BUILD_GROUPS = ['default'])
539 environment_list
.append(nacl_env
)
541 # ----------------------------------------------------------
543 # ----------------------------------------------------------
544 # ----------------------------------------------------------
546 # ----------------------------------------------------------
548 doc_env
= pre_base_env
.Clone(
550 BUILD_TYPE_DESCRIPTION
= 'Documentation build',
551 HOST_PLATFORMS
= '*',
553 doc_env
.FilterOut(BUILD_GROUPS
=['most'])
554 environment_list
.append(doc_env
)
556 BUILD_SCONSCRIPTS
= [
562 # ----------------------------------------------------------
564 # Blank out defaults.
567 BuildComponents(environment_list
)
569 # Change default to build everything, but not run tests.
570 Default(['all_programs', 'all_bundles', 'all_test_programs', 'all_libraries'])
572 # ----------------------------------------------------------
575 # Generate a solution, defer to the end.
576 solution_env
= base_env
.Clone(tools
= ['visual_studio_solution'])
577 solution
= solution_env
.Solution(
578 'nacl', environment_list
,
579 exclude_pattern
= '.*third_party.*',
580 extra_build_targets
= {
581 'Firefox': 'c:/Program Files/Mozilla FireFox/firefox.exe',
584 solution_env
.Alias('solution', solution
)