2 # Copyright (c) 2012 The Native Client 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.
13 sys.path.append("./common")
14 sys.path.append('../third_party')
16 from SCons.Errors import UserError
17 from SCons.Script import GetBuildFailures
22 SCons.Warnings.warningAsException()
24 sys.path.append("tools")
28 # NOTE: Underlay for src/third_party_mod/gtest
29 # TODO: try to eliminate this hack
30 Dir('src/third_party_mod/gtest').addRepository(
31 Dir('#/../testing/gtest'))
33 # turning garbage collection off reduces startup time by 10%
40 def PrintFinalReport():
41 """This function is run just before scons exits and dumps various reports.
43 # Note, these global declarations are not strictly necessary
48 if pre_base_env.Bit('target_stats'):
51 print 'COMMAND EXECUTION REPORT'
53 for k in sorted(CMD_COUNTER.keys()):
54 print "%4d %s" % (CMD_COUNTER[k], k)
58 print 'ENVIRONMENT USAGE REPORT'
60 for k in sorted(ENV_COUNTER.keys()):
61 print "%4d %s" % (ENV_COUNTER[k], k)
63 failures = GetBuildFailures()
69 print 'ERROR REPORT: %d failures' % len(failures)
73 for node in Flatten(f.node):
74 test_name = GetTestName(node)
75 raw_name = str(node.path)
76 # If this wasn't a test, "GetTestName" will return raw_name.
77 if test_name != raw_name:
78 test_name = '%s (%s)' % (test_name, raw_name)
79 print "%s failed: %s\n" % (test_name, f.errstr)
81 atexit.register(PrintFinalReport)
84 def VerboseConfigInfo(env):
85 "Should we print verbose config information useful for bug reports"
86 if '--help' in sys.argv: return False
87 if env.Bit('prebuilt') or env.Bit('built_elsewhere'): return False
88 return env.Bit('sysinfo')
93 # NOTE BitFromArgument(...) implicitly defines additional ACCEPTABLE_ARGUMENTS.
94 ACCEPTABLE_ARGUMENTS = set([
95 # TODO: add comments what these mean
96 # TODO: check which ones are obsolete
97 #### ASCII SORTED ####
98 # Use a destination directory other than the default "scons-out".
102 # Limit bandwidth of browser tester
104 # Location to download Chromium binaries to and/or read them from.
105 'chrome_binaries_dir',
106 # used for chrome_browser_tests: path to the browser
107 'chrome_browser_path',
108 # A comma-separated list of test names to disable by excluding the
109 # tests from a test suite. For example, 'small_tests
110 # disable_tests=run_hello_world_test' will run small_tests without
111 # including hello_world_test. Note that if a test listed here
112 # does not exist you will not get an error or a warning.
114 # used for chrome_browser_tests: path to a pre-built browser plugin.
115 'force_ppapi_plugin',
116 # force emulator use by tests
118 # force sel_ldr use by tests
120 # force irt image used by tests
122 # Replacement memcheck command for overriding the DEPS-in memcheck
123 # script. May have commas to separate separate shell args. There
124 # is no quoting, so this implies that this mechanism will fail if
125 # the args actually need to have commas. See
126 # http://code.google.com/p/nativeclient/issues/detail?id=3158 for
127 # the discussion of why this argument is needed.
129 # If the replacement memcheck command only works for trusted code,
130 # set memcheck_trusted_only to non-zero.
131 'memcheck_trusted_only',
132 # colon-separated list of linker flags, e.g. "-lfoo:-Wl,-u,bar".
134 # colon-separated list of pnacl bcld flags, e.g. "-lfoo:-Wl,-u,bar".
135 # Not using nacl_linkflags since that gets clobbered in some tests.
140 # Run tests under this tool (e.g. valgrind, tsan, strace, etc).
141 # If the tool has options, pass them after comma: 'tool,--opt1,--opt2'.
142 # NB: no way to use tools the names or the args of
143 # which contains a comma.
145 # More args for the tool.
146 'run_under_extra_args',
147 # Multiply timeout values by this number.
149 # test_wrapper specifies a wrapper program such as
150 # tools/run_test_via_ssh.py, which runs tests on a remote host
151 # using rsync and SSH. Example usage:
152 # ./scons run_hello_world_test platform=arm force_emulator= \
153 # test_wrapper="./tools/run_test_via_ssh.py --host=armbox --subdir=tmp"
155 # Replacement tsan command for overriding the DEPS-in tsan
156 # script. May have commas to separate separate shell args. There
157 # is no quoting, so this implies that this mechanism will fail if
158 # the args actually need to have commas. See
159 # http://code.google.com/p/nativeclient/issues/detail?id=3158 for
160 # the discussion of why this argument is needed.
162 # Run browser tests under this tool. See
163 # tools/browser_tester/browsertester/browserlauncher.py for tool names.
165 # activates buildbot-specific presets
167 # Where to install header files for public consumption.
169 # Where to install libraries for public consumption.
171 # Where to install trusted-code binaries for public (SDK) consumption.
173 # Where a Breakpad build output directory is for optional Breakpad testing.
174 'breakpad_tools_dir',
178 # Overly general to provide compatibility with existing build bots, etc.
179 # In the future it might be worth restricting the values that are accepted.
180 _TRUE_STRINGS = set(['1', 'true', 'yes'])
181 _FALSE_STRINGS = set(['0', 'false', 'no'])
184 # Converts a string representing a Boolean value, of some sort, into an actual
185 # Boolean value. Python's built in type coercion does not work because
186 # bool('False') == True
187 def StringValueToBoolean(value):
188 # ExpandArguments may stick non-string values in ARGUMENTS. Be accommodating.
189 if isinstance(value, bool):
192 if not isinstance(value, basestring):
193 raise Exception("Expecting a string but got a %s" % repr(type(value)))
195 if value.lower() in _TRUE_STRINGS:
197 elif value.lower() in _FALSE_STRINGS:
200 raise Exception("Cannot convert '%s' to a Boolean value" % value)
203 def GetBinaryArgumentValue(arg_name, default):
204 if not isinstance(default, bool):
205 raise Exception("Default value for '%s' must be a Boolean" % arg_name)
206 if arg_name not in ARGUMENTS:
208 return StringValueToBoolean(ARGUMENTS[arg_name])
211 # name is the name of the bit
212 # arg_name is the name of the command-line argument, if it differs from the bit
213 def BitFromArgument(env, name, default, desc, arg_name=None):
214 # In most cases the bit name matches the argument name
218 DeclareBit(name, desc)
219 assert arg_name not in ACCEPTABLE_ARGUMENTS, repr(arg_name)
220 ACCEPTABLE_ARGUMENTS.add(arg_name)
222 if GetBinaryArgumentValue(arg_name, default):
228 # SetUpArgumentBits declares binary command-line arguments and converts them to
229 # bits. For example, one of the existing declarations would result in the
230 # argument "bitcode=1" causing env.Bit('bitcode') to evaluate to true.
231 # NOTE Command-line arguments are a SCons-ism that is separate from
232 # command-line options. Options are prefixed by "-" or "--" whereas arguments
233 # are not. The function SetBitFromOption can be used for options.
234 # NOTE This function must be called before the bits are used
235 # NOTE This function must be called after all modifications of ARGUMENTS have
236 # been performed. See: ExpandArguments
237 def SetUpArgumentBits(env):
238 BitFromArgument(env, 'bitcode', default=False,
239 desc='We are building bitcode')
241 BitFromArgument(env, 'translate_fast', default=False,
242 desc='When using pnacl TC (bitcode=1) use accelerated translation step')
244 BitFromArgument(env, 'built_elsewhere', default=False,
245 desc='The programs have already been built by another system')
247 BitFromArgument(env, 'skip_trusted_tests', default=False,
248 desc='Only run untrusted tests - useful for translator testing'
249 ' (also skips tests of the IRT itself')
251 BitFromArgument(env, 'nacl_pic', default=False,
252 desc='generate position indepent code for (P)NaCl modules')
254 BitFromArgument(env, 'nacl_static_link', default=not env.Bit('nacl_glibc'),
255 desc='Whether to use static linking instead of dynamic linking '
256 'for building NaCl executables during tests. '
257 'For nacl-newlib, the default is 1 (static linking). '
258 'For nacl-glibc, the default is 0 (dynamic linking).')
260 BitFromArgument(env, 'nacl_disable_shared', default=not env.Bit('nacl_glibc'),
261 desc='Do not build shared versions of libraries. '
262 'For nacl-newlib, the default is 1 (static libraries only). '
263 'For nacl-glibc, the default is 0 (both static and shared libraries).')
265 # Defaults on when --verbose is specified.
266 # --verbose sets 'brief_comstr' to False, so this looks a little strange
267 BitFromArgument(env, 'target_stats', default=not GetOption('brief_comstr'),
268 desc='Collect and display information about which commands are executed '
269 'during the build process')
271 BitFromArgument(env, 'werror', default=True,
272 desc='Treat warnings as errors (-Werror)')
274 BitFromArgument(env, 'disable_nosys_linker_warnings', default=False,
275 desc='Disable warning mechanism in src/untrusted/nosys/warning.h')
277 BitFromArgument(env, 'naclsdk_validate', default=True,
278 desc='Verify the presence of the SDK')
280 BitFromArgument(env, 'running_on_valgrind', default=False,
281 desc='Compile and test using valgrind')
283 BitFromArgument(env, 'enable_tmpfs_redirect_var', default=False,
284 desc='Allow redirecting tmpfs location for shared memory '
285 '(by default, /dev/shm is used)')
287 BitFromArgument(env, 'pp', default=False,
288 desc='Enable pretty printing')
290 # By default SCons does not use the system's environment variables when
291 # executing commands, to help isolate the build process.
292 BitFromArgument(env, 'use_environ', arg_name='USE_ENVIRON',
293 default=False, desc='Expose existing environment variables to the build')
295 # Defaults on when --verbose is specified
296 # --verbose sets 'brief_comstr' to False, so this looks a little strange
297 BitFromArgument(env, 'sysinfo', default=not GetOption('brief_comstr'),
298 desc='Print verbose system information')
300 BitFromArgument(env, 'disable_flaky_tests', default=False,
301 desc='Do not run potentially flaky tests - used on Chrome bots')
303 BitFromArgument(env, 'use_sandboxed_translator', default=False,
304 desc='use pnacl sandboxed translator for linking (not available for arm)')
306 BitFromArgument(env, 'pnacl_generate_pexe', default=env.Bit('bitcode'),
307 desc='use pnacl to generate pexes and translate in a separate step')
309 BitFromArgument(env, 'translate_in_build_step', default=True,
310 desc='Run translation during build phase (e.g. if do_not_run_tests=1)')
312 BitFromArgument(env, 'pnacl_unsandboxed', default=False,
313 desc='Translate pexe to an unsandboxed, host executable')
315 BitFromArgument(env, 'browser_headless', default=False,
316 desc='Where possible, set up a dummy display to run the browser on '
317 'when running browser tests. On Linux, this runs the browser through '
318 'xvfb-run. This Scons does not need to be run with an X11 display '
319 'and we do not open a browser window on the user\'s desktop. '
320 'Unfortunately there is no equivalent on Mac OS X.')
322 BitFromArgument(env, 'disable_crash_dialog', default=True,
323 desc='Disable Windows\' crash dialog box, which Windows pops up when a '
324 'process exits with an unhandled fault. Windows enables this by '
325 'default for processes launched from the command line or from the '
326 'GUI. Our default is to disable it, because the dialog turns crashes '
327 'into hangs on Buildbot, and our test suite includes various crash '
330 BitFromArgument(env, 'do_not_run_tests', default=False,
331 desc='Prevents tests from running. This lets SCons build the files needed '
332 'to run the specified test(s) without actually running them. This '
333 'argument is a counterpart to built_elsewhere.')
335 BitFromArgument(env, 'validator_ragel', default=True,
336 desc='Use the R-DFA validator instead of the original validators.')
338 # TODO(shcherbina): add support for other golden-based tests, not only
339 # run_x86_*_validator_testdata_tests.
340 BitFromArgument(env, 'regenerate_golden', default=False,
341 desc='When running golden-based tests, instead of comparing results '
342 'save actual output as golden data.')
344 BitFromArgument(env, 'x86_64_zero_based_sandbox', default=False,
345 desc='Use the zero-address-based x86-64 sandbox model instead of '
346 'the r15-based model.')
348 BitFromArgument(env, 'android', default=False,
349 desc='Build for Android target')
351 BitFromArgument(env, 'arm_hard_float', default=True,
352 desc='Build for hard float ARM ABI')
354 BitFromArgument(env, 'skip_nonstable_bitcode', default=False,
355 desc='Skip tests involving non-stable bitcode')
357 #########################################################################
359 # This is for generating a testing library for use within private test
360 # enuminsts, where we want to compare and test different validators.
362 BitFromArgument(env, 'ncval_testing', default=False,
363 desc='EXPERIMENTAL: Compile validator code for testing within enuminsts')
365 # PNaCl sanity checks
366 if ((env.Bit('pnacl_generate_pexe') or env.Bit('use_sandboxed_translator'))
367 and not env.Bit('bitcode')):
368 raise ValueError("pnacl_generate_pexe and use_sandboxed_translator"
369 "don't make sense without bitcode")
371 # Sandboxed translator only accepts stable bitcode. Hence we must disallow
372 # nonstable bitcodes.
373 if env.Bit('use_sandboxed_translator'):
374 env.SetBits('skip_nonstable_bitcode')
376 def CheckArguments():
377 for key in ARGUMENTS:
378 if key not in ACCEPTABLE_ARGUMENTS:
379 raise UserError('bad argument: %s' % key)
382 # Sets a command line argument. Dies if an argument with this name is already
384 def SetArgument(key, value):
385 print ' %s=%s' % (key, str(value))
387 print 'ERROR: %s redefined' % (key, )
390 ARGUMENTS[key] = value
392 # Expands "macro" command line arguments.
393 def ExpandArguments():
394 if ARGUMENTS.get('buildbot') == 'memcheck':
395 print 'buildbot=memcheck expands to the following arguments:'
396 SetArgument('run_under',
397 ARGUMENTS.get('memcheck_command',
398 'src/third_party/valgrind/memcheck.sh') +
399 ',--error-exitcode=1')
400 SetArgument('scale_timeout', 20)
401 SetArgument('running_on_valgrind', True)
402 elif ARGUMENTS.get('buildbot') == 'tsan':
403 print 'buildbot=tsan expands to the following arguments:'
404 SetArgument('run_under',
405 ARGUMENTS.get('tsan_command',
406 'src/third_party/valgrind/tsan.sh') +
407 ',--nacl-untrusted,--error-exitcode=1,' +
408 '--suppressions=src/third_party/valgrind/tests.supp')
409 SetArgument('scale_timeout', 20)
410 SetArgument('running_on_valgrind', True)
411 elif ARGUMENTS.get('buildbot') == 'tsan-trusted':
412 print 'buildbot=tsan-trusted expands to the following arguments:'
413 SetArgument('run_under',
414 ARGUMENTS.get('tsan_command',
415 'src/third_party/valgrind/tsan.sh') +
416 ',--error-exitcode=1,' +
417 '--suppressions=src/third_party/valgrind/tests.supp')
418 SetArgument('scale_timeout', 20)
419 SetArgument('running_on_valgrind', True)
420 elif ARGUMENTS.get('buildbot') == 'memcheck-browser-tests':
421 print 'buildbot=memcheck-browser-tests expands to the following arguments:'
422 SetArgument('browser_test_tool', 'memcheck')
423 SetArgument('scale_timeout', 20)
424 SetArgument('running_on_valgrind', True)
425 elif ARGUMENTS.get('buildbot') == 'tsan-browser-tests':
426 print 'buildbot=tsan-browser-tests expands to the following arguments:'
427 SetArgument('browser_test_tool', 'tsan')
428 SetArgument('scale_timeout', 20)
429 SetArgument('running_on_valgrind', True)
430 elif ARGUMENTS.get('buildbot'):
431 print 'ERROR: unexpected argument buildbot="%s"' % (
432 ARGUMENTS.get('buildbot'), )
437 environment_list = []
439 # Base environment for both nacl and non-nacl variants.
441 if ARGUMENTS.get('DESTINATION_ROOT') is not None:
442 kwargs['DESTINATION_ROOT'] = ARGUMENTS.get('DESTINATION_ROOT')
443 pre_base_env = Environment(
444 tools = ['component_setup'],
445 # SOURCE_ROOT is one leave above the native_client directory.
446 SOURCE_ROOT = Dir('#/..').abspath,
447 # Publish dlls as final products (to staging).
448 COMPONENT_LIBRARY_PUBLISH = True,
450 # Use workaround in special scons version.
452 LIBS_DO_SUBST = True,
454 # Select where to find coverage tools.
455 COVERAGE_MCOV = '../third_party/lcov/bin/mcov',
456 COVERAGE_GENHTML = '../third_party/lcov/bin/genhtml',
461 breakpad_tools_dir = ARGUMENTS.get('breakpad_tools_dir')
462 if breakpad_tools_dir is not None:
463 pre_base_env['BREAKPAD_TOOLS_DIR'] = pre_base_env.Dir(
464 os.path.abspath(breakpad_tools_dir))
468 DeclareBit('clang', 'Use clang to build trusted code')
469 pre_base_env.SetBitFromOption('clang', False)
472 'Use AddressSanitizer to build trusted code (implies --clang)')
473 pre_base_env.SetBitFromOption('asan', False)
474 if pre_base_env.Bit('asan'):
475 pre_base_env.SetBits('clang')
479 DeclareBit('coverage_enabled', 'The build should be instrumented to generate'
480 'coverage information')
482 # If the environment variable BUILDBOT_BUILDERNAME is set, we can determine
483 # if we are running in a VM by the lack of a '-bare-' (aka bare metal) in the
484 # bot name. Otherwise if the builder name is not set, then assume real HW.
485 DeclareBit('running_on_vm', 'Returns true when environment is running in a VM')
486 builder = os.environ.get('BUILDBOT_BUILDERNAME')
487 if builder and builder.find('-bare-') == -1:
488 pre_base_env.SetBits('running_on_vm')
490 pre_base_env.ClearBits('running_on_vm')
492 DeclareBit('nacl_glibc', 'Use nacl-glibc for building untrusted code')
493 pre_base_env.SetBitFromOption('nacl_glibc', False)
495 # This function should be called ASAP after the environment is created, but
496 # after ExpandArguments.
497 SetUpArgumentBits(pre_base_env)
499 def DisableCrashDialog():
500 if sys.platform == 'win32':
503 # The double call is to preserve existing flags, as discussed at
504 # http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx
505 new_flags = win32con.SEM_NOGPFAULTERRORBOX
506 existing_flags = win32api.SetErrorMode(new_flags)
507 win32api.SetErrorMode(existing_flags | new_flags)
509 if pre_base_env.Bit('disable_crash_dialog'):
512 # Scons normally wants to scrub the environment. However, sometimes
513 # we want to allow PATH and other variables through so that Scons
514 # scripts can find nacl-gcc without needing a Scons-specific argument.
515 if pre_base_env.Bit('use_environ'):
516 pre_base_env['ENV'] = os.environ.copy()
518 # We want to pull CYGWIN setup in our environment or at least set flag
519 # nodosfilewarning. It does not do anything when CYGWIN is not involved
520 # so let's do it in all cases.
521 pre_base_env['ENV']['CYGWIN'] = os.environ.get('CYGWIN', 'nodosfilewarning')
523 # Note: QEMU_PREFIX_HOOK may influence test runs and sb translator invocations
524 pre_base_env['ENV']['QEMU_PREFIX_HOOK'] = os.environ.get('QEMU_PREFIX_HOOK', '')
526 # Allow the zero-based sandbox model to run insecurely.
527 # TODO(arbenson): remove this once binutils bug is fixed (see
528 # src/trusted/service_runtime/arch/x86_64/sel_addrspace_posix_x86_64.c)
529 if pre_base_env.Bit('x86_64_zero_based_sandbox'):
530 pre_base_env['ENV']['NACL_ENABLE_INSECURE_ZERO_BASED_SANDBOX'] = 1
532 if pre_base_env.Bit('werror'):
533 werror_flags = ['-Werror']
537 # Allow variadic macros
538 werror_flags = werror_flags + ['-Wno-variadic-macros']
540 if pre_base_env.Bit('clang'):
541 # Allow 'default' label in switch even when all enumeration cases
543 werror_flags += ['-Wno-covered-switch-default']
544 # Allow C++11 extensions (for "override")
545 werror_flags += ['-Wno-c++11-extensions']
548 # Method to make sure -pedantic, etc, are not stripped from the
549 # default env, since occasionally an engineer will be tempted down the
550 # dark -- but wide and well-trodden -- path of expediency and stray
551 # from the path of correctness.
553 def EnsureRequiredBuildWarnings(env):
554 if env.Bit('linux') or env.Bit('mac'):
555 required_env_flags = set(['-pedantic', '-Wall'] + werror_flags)
556 ccflags = set(env.get('CCFLAGS'))
558 if not required_env_flags.issubset(ccflags):
559 raise UserError('required build flags missing: '
560 + ' '.join(required_env_flags.difference(ccflags)))
562 # windows get a pass for now
565 pre_base_env.AddMethod(EnsureRequiredBuildWarnings)
567 # Expose MakeTempDir and MakeTempFile to scons scripts
568 pre_base_env.AddMethod(test_lib.MakeTempDir)
569 pre_base_env.AddMethod(test_lib.MakeTempFile)
571 # Method to add target suffix to name.
572 def NaClTargetArchSuffix(env, name):
573 return name + '_' + env['TARGET_FULLARCH'].replace('-', '_')
575 pre_base_env.AddMethod(NaClTargetArchSuffix)
578 # Generic Test Wrapper
580 # Add list of Flaky or Bad tests to skip per platform. A
581 # platform is defined as build type
582 # <BUILD_TYPE>-<SUBARCH>
587 # This is a list of tests that do not yet pass when using nacl-glibc.
588 # TODO(mseaborn): Enable more of these tests!
589 nacl_glibc_skiplist = set([
590 # Struct layouts differ.
592 # Syscall wrappers not implemented yet.
595 # Fails because clock() is not hooked up.
596 'run_timefuncs_test',
597 # Needs further investigation.
599 # run_srpc_sysv_shm_test fails because:
600 # 1) it uses fstat(), while we only have an fstat64() wrapper;
601 # 2) the test needs an explicit fflush(stdout) call because the
602 # process is killed without exit() being called.
603 'run_srpc_sysv_shm_test',
604 # This test fails with nacl-glibc: glibc reports an internal
605 # sanity check failure in free().
606 # TODO(robertm): This needs further investigation.
607 'run_ppapi_event_test',
608 'run_srpc_ro_file_test',
609 'run_ppapi_geturl_valid_test',
610 'run_ppapi_geturl_invalid_test',
611 # http://code.google.com/p/chromium/issues/detail?id=108131
612 # we would need to list all of the glibc components as
613 # web accessible resources in the extensions's manifest.json,
614 # not just the nexe and nmf file.
615 'run_ppapi_extension_mime_handler_browser_test',
617 # This test need more investigation.
620 nacl_glibc_skiplist.update(['%s_irt' % test for test in nacl_glibc_skiplist])
623 # If a test is not in one of these suites, it will probally not be run on a
624 # regular basis. These are the suites that will be run by the try bot or that
625 # a large number of users may run by hand.
626 MAJOR_TEST_SUITES = set([
630 # Tests using the pepper plugin, only run with chrome
631 # TODO(ncbray): migrate pepper_browser_tests to chrome_browser_tests
632 'pepper_browser_tests',
633 # Lightweight browser tests
634 'chrome_browser_tests',
636 'memcheck_bot_tests',
638 # Special testing environment for testing comparing x86 validators.
640 # Environment for validator difference testing
641 'validator_diff_tests',
644 # These are the test suites we know exist, but aren't run on a regular basis.
645 # These test suites are essentially shortcuts that run a specific subset of the
647 ACCEPTABLE_TEST_SUITES = set([
649 'dynamic_load_tests',
657 'sel_ldr_sled_tests',
660 'validator_modeling',
662 # Special testing of the decoder for the ARM validator.
666 # Under --mode=nacl_irt_test we build variants of numerous tests normally
667 # built under --mode=nacl. The test names and suite names for these
668 # variants are set (in IrtTestAddNodeToTestSuite, below) by appending _irt
669 # to the names used for the --mode=nacl version of the same tests.
670 MAJOR_TEST_SUITES |= set([name + '_irt'
671 for name in MAJOR_TEST_SUITES])
672 ACCEPTABLE_TEST_SUITES |= set([name + '_irt'
673 for name in ACCEPTABLE_TEST_SUITES])
675 # The major test suites are also acceptable names. Suite names are checked
676 # against this set in order to catch typos.
677 ACCEPTABLE_TEST_SUITES.update(MAJOR_TEST_SUITES)
680 def ValidateTestSuiteNames(suite_name, node_name):
681 if node_name is None:
682 node_name = '<unknown>'
684 # Prevent a silent failiure - strings are iterable!
685 if not isinstance(suite_name, (list, tuple)):
686 raise Exception("Test suites for %s should be specified as a list, "
687 "not as a %s: %s" % (node_name, type(suite_name).__name__,
691 raise Exception("No test suites are specified for %s. Set the 'broken' "
692 "parameter on AddNodeToTestSuite in the cases where there's a known "
693 "issue and you don't want the test to run" % (node_name,))
695 # Make sure each test is in at least one test suite we know will run
696 major_suites = set(suite_name).intersection(MAJOR_TEST_SUITES)
698 raise Exception("None of the test suites %s for %s are run on a "
699 "regular basis" % (repr(suite_name), node_name))
701 # Make sure a wierd test suite hasn't been inadvertantly specified
703 if s not in ACCEPTABLE_TEST_SUITES:
704 raise Exception("\"%s\" is not a known test suite. Either this is "
705 "a typo for %s, or it should be added to ACCEPTABLE_TEST_SUITES in "
706 "SConstruct" % (s, node_name))
708 BROKEN_TEST_COUNT = 0
711 def GetPlatformString(env):
712 build = env['BUILD_TYPE']
714 # If we are testing 'NACL' we really need the trusted info
715 if build=='nacl' and 'TRUSTED_ENV' in env:
716 trusted_env = env['TRUSTED_ENV']
717 build = trusted_env['BUILD_TYPE']
718 subarch = trusted_env['BUILD_SUBARCH']
720 subarch = env['BUILD_SUBARCH']
722 # Build the test platform string
723 return build + '-' + subarch
725 pre_base_env.AddMethod(GetPlatformString)
728 tests_to_disable_qemu = set([
729 # These tests do not work under QEMU but do work on ARM hardware.
731 # You should use the is_broken argument in preference to adding
732 # tests to this list.
734 # TODO(dschuff) some of these tests appear to work with the new QEMU.
736 # http://code.google.com/p/nativeclient/issues/detail?id=2437
737 # Note, for now these tests disable both the irt and non-irt variants
738 'run_atomic_ops_test', # still broken with qemu 2012/06/12
739 'run_atomic_ops_nexe_test',
740 # The debug stub test is not set up to insert QEMU at the right
741 # point, and service_runtime's thread suspension does not work
743 'run_debug_stub_test',
744 'run_egyptian_cotton_test', # still broken with qemu 2012/06/12
745 'run_faulted_thread_queue_test',
746 'run_many_threads_sequential_test',
747 'run_mmap_atomicity_test', # still broken with qemu 2012/06/12
748 # http://code.google.com/p/nativeclient/issues/detail?id=2142
749 'run_nacl_semaphore_test',
750 'run_nacl_tls_unittest',
751 # subprocess needs to also have qemu prefix, which isn't supported
752 'run_subprocess_test',
753 # The next 2 tests seem flaky on QEMU
754 'run_srpc_manifest_file_test',
755 'run_srpc_message_untrusted_test',
756 'run_thread_stack_alloc_test',
757 'run_thread_suspension_test',
759 'run_dynamic_modify_test',
760 # qemu has bugs that make TestCatchingFault flaky (see
761 # http://code.google.com/p/nativeclient/issues/detail?id=3239), and
762 # we don't particularly need to measure performance under qemu.
763 'run_performance_test',
766 tests_to_disable = set()
767 if ARGUMENTS.get('disable_tests', '') != '':
768 tests_to_disable.update(ARGUMENTS['disable_tests'].split(','))
771 def ShouldSkipTest(env, node_name):
772 if (env.Bit('skip_trusted_tests')
773 and (env['NACL_BUILD_FAMILY'] == 'TRUSTED'
774 or env['NACL_BUILD_FAMILY'] == 'UNTRUSTED_IRT')):
777 if env.Bit('do_not_run_tests'):
778 # This hack is used for pnacl testing where we might build tests
779 # without running them on one bot and then transfer and run them on another.
780 # The skip logic only takes the first bot into account e.g. qemu
781 # restrictions, while it really should be skipping based on the second
782 # bot. By simply disabling the skipping completely we work around this.
785 # There are no known-to-fail tests any more, but this code is left
786 # in so that if/when we port to a new architecture or add a test
787 # that is known to fail on some platform(s), we can continue to have
788 # a central location to disable tests from running. NB: tests that
789 # don't *build* on some platforms need to be omitted in another way.
791 if node_name in tests_to_disable:
794 if env.UsingEmulator():
795 if node_name in tests_to_disable_qemu:
797 # For now also disable the irt variant
798 if node_name.endswith('_irt') and node_name[:-4] in tests_to_disable_qemu:
801 # Retrieve list of tests to skip on this platform
802 skiplist = bad_build_lists.get(env.GetPlatformString(), [])
803 if node_name in skiplist:
806 if env.Bit('nacl_glibc') and node_name in nacl_glibc_skiplist:
811 pre_base_env.AddMethod(ShouldSkipTest)
814 def AddNodeToTestSuite(env, node, suite_name, node_name, is_broken=False,
816 global BROKEN_TEST_COUNT
818 # CommandTest can return an empty list when it silently discards a test
822 assert node_name is not None
823 test_name_regex = r'run_.*_(unit)?test.*$'
824 assert re.match(test_name_regex, node_name), (
825 'test %r does not match "run_..._test" naming convention '
826 '(precise regex is %s)' % (node_name, test_name_regex))
828 ValidateTestSuiteNames(suite_name, node_name)
832 if is_broken or is_flaky and env.Bit('disable_flaky_tests'):
833 # Only print if --verbose is specified
834 if not GetOption('brief_comstr'):
835 print '*** BROKEN ', node_name
836 BROKEN_TEST_COUNT += 1
837 env.Alias('broken_tests', node)
838 elif env.ShouldSkipTest(node_name):
839 print '*** SKIPPING ', env.GetPlatformString(), ':', node_name
840 env.Alias('broken_tests', node)
842 env.Alias('all_tests', node)
848 env.ComponentTestOutput(node_name, node)
849 test_name = node_name
851 # This is rather shady, but the tests need a name without dots so they match
853 # TODO(ncbray) node_name should not be optional.
854 test_name = os.path.basename(str(node[0].path))
855 if test_name.endswith('.out'):
856 test_name = test_name[:-4]
857 test_name = test_name.replace('.', '_')
858 SetTestName(node, test_name)
860 pre_base_env.AddMethod(AddNodeToTestSuite)
863 def TestBindsFixedTcpPort(env, node):
864 # This tells Scons that tests that bind a fixed TCP port should not
865 # run concurrently, because they would interfere with each other.
866 # These tests are typically tests for NaCl's GDB debug stub. The
867 # dummy filename used below is an arbitrary token that just has to
868 # match across the tests.
869 SideEffect(env.File('${SCONSTRUCT_DIR}/test_binds_fixed_tcp_port'), node)
871 pre_base_env.AddMethod(TestBindsFixedTcpPort)
874 # Convenient testing aliases
875 # NOTE: work around for scons non-determinism in the following two lines
876 Alias('sel_ldr_sled_tests', [])
878 Alias('small_tests', [])
879 Alias('medium_tests', [])
880 Alias('large_tests', [])
882 Alias('small_tests_irt', [])
883 Alias('medium_tests_irt', [])
884 Alias('large_tests_irt', [])
886 Alias('pepper_browser_tests', [])
887 Alias('chrome_browser_tests', [])
889 Alias('unit_tests', 'small_tests')
890 Alias('smoke_tests', ['small_tests', 'medium_tests'])
892 if pre_base_env.Bit('nacl_glibc'):
893 Alias('memcheck_bot_tests', ['small_tests'])
894 Alias('tsan_bot_tests', ['small_tests'])
896 Alias('memcheck_bot_tests', ['small_tests', 'medium_tests', 'large_tests'])
897 Alias('tsan_bot_tests', [])
905 pre_base_env.AddMethod(Banner)
909 # Define the platforms, and use them to define the path for the
910 # scons-out directory (aka TARGET_ROOT)
912 # Various variables in the scons environment are related to this, e.g.
914 # BUILD_ARCH: (arm, mips, x86)
915 # BUILD_SUBARCH: (32, 64)
917 # This dictionary is used to translate from a platform name to a
918 # (arch, subarch) pair
919 AVAILABLE_PLATFORMS = {
920 'x86-32' : { 'arch' : 'x86' , 'subarch' : '32' },
921 'x86-64' : { 'arch' : 'x86' , 'subarch' : '64' },
922 'mips32' : { 'arch' : 'mips', 'subarch' : '32' },
923 'arm' : { 'arch' : 'arm' , 'subarch' : '32' },
924 'arm-thumb2' : { 'arch' : 'arm' , 'subarch' : '32' }
927 # Look up the platform name from the command line arguments.
928 def GetPlatform(self):
929 return ARGUMENTS.get('platform', 'x86-32')
931 pre_base_env.AddMethod(GetPlatform)
933 # Decode platform into list [ ARCHITECTURE , EXEC_MODE ].
934 def DecodePlatform(platform):
935 if platform in AVAILABLE_PLATFORMS:
936 return AVAILABLE_PLATFORMS[platform]
937 raise Exception('Unrecognized platform: %s' % platform)
940 DeclareBit('build_x86_32', 'Building binaries for the x86-32 architecture',
941 exclusive_groups='build_arch')
942 DeclareBit('build_x86_64', 'Building binaries for the x86-64 architecture',
943 exclusive_groups='build_arch')
944 DeclareBit('build_mips32', 'Building binaries for the MIPS architecture',
945 exclusive_groups='build_arch')
946 DeclareBit('build_arm_arm', 'Building binaries for the ARM architecture',
947 exclusive_groups='build_arch')
948 DeclareBit('build_arm_thumb2',
949 'Building binaries for the ARM architecture (thumb2 ISA)',
950 exclusive_groups='build_arch')
951 DeclareBit('target_x86_32', 'Tools being built will process x86-32 binaries',
952 exclusive_groups='target_arch')
953 DeclareBit('target_x86_64', 'Tools being built will process x86-36 binaries',
954 exclusive_groups='target_arch')
955 DeclareBit('target_mips32', 'Tools being built will process MIPS binaries',
956 exclusive_groups='target_arch')
957 DeclareBit('target_arm_arm', 'Tools being built will process ARM binaries',
958 exclusive_groups='target_arch')
959 DeclareBit('target_arm_thumb2',
960 'Tools being built will process ARM binaries (thumb2 ISA)',
961 exclusive_groups='target_arch')
963 # Shorthand for either the 32 or 64 bit version of x86.
964 DeclareBit('build_x86', 'Building binaries for the x86 architecture')
965 DeclareBit('target_x86', 'Tools being built will process x86 binaries')
967 # Shorthand for either arm or thumb2 versions of ARM
968 DeclareBit('build_arm', 'Building binaries for the arm architecture')
969 DeclareBit('target_arm', 'Tools being built will process arm binaries')
972 def MakeArchSpecificEnv():
973 env = pre_base_env.Clone()
974 platform = env.GetPlatform()
975 info = DecodePlatform(platform)
977 env.Replace(BUILD_FULLARCH=platform)
978 env.Replace(BUILD_ARCHITECTURE=info['arch'])
979 env.Replace(BUILD_SUBARCH=info['subarch'])
980 env.Replace(TARGET_FULLARCH=platform)
981 env.Replace(TARGET_ARCHITECTURE=info['arch'])
982 env.Replace(TARGET_SUBARCH=info['subarch'])
984 # Example: PlatformBit('build', 'x86-32') -> build_x86_32
985 def PlatformBit(prefix, platform):
986 return "%s_%s" % (prefix, platform.replace('-', '_'))
988 env.SetBits(PlatformBit('build', platform))
989 env.SetBits(PlatformBit('target', platform))
991 if env.Bit('build_x86_32') or env.Bit('build_x86_64'):
992 env.SetBits('build_x86')
993 if env.Bit('build_arm_arm') or env.Bit('build_arm_thumb2'):
994 env.SetBits('build_arm')
996 if env.Bit('target_x86_32') or env.Bit('target_x86_64'):
997 env.SetBits('target_x86')
998 if env.Bit('target_arm_arm') or env.Bit('target_arm_thumb2'):
999 env.SetBits('target_arm')
1001 env.Replace(BUILD_ISA_NAME=env.GetPlatform())
1003 if env.Bit('target_mips32'):
1004 # This is a silent default on MIPS.
1005 env.SetBits('bitcode')
1007 # Determine where the object files go
1008 env.Replace(BUILD_TARGET_NAME=platform)
1009 # This may be changed later; see target_variant_map, below.
1010 env.Replace(TARGET_VARIANT='')
1011 env.Replace(TARGET_ROOT=
1012 '${DESTINATION_ROOT}/${BUILD_TYPE}-${BUILD_TARGET_NAME}${TARGET_VARIANT}')
1017 pre_base_env.AddMethod(lambda self: ARGUMENTS.get('running_on_valgrind'),
1018 'IsRunningUnderValgrind')
1020 DeclareBit('with_leakcheck', 'Running under Valgrind leak checker')
1022 def RunningUnderLeakCheck():
1023 run_under = ARGUMENTS.get('run_under')
1025 extra_args = ARGUMENTS.get('run_under_extra_args')
1027 run_under += extra_args
1028 if run_under.find('leak-check=full') > 0:
1032 if RunningUnderLeakCheck():
1033 pre_base_env.SetBits('with_leakcheck')
1036 def HasSuffix(item, suffix):
1037 if isinstance(item, str):
1038 return item.endswith(suffix)
1039 elif hasattr(item, '__getitem__'):
1040 return HasSuffix(item[0], suffix)
1042 return item.path.endswith(suffix)
1045 def StripSuffix(string, suffix):
1046 assert string.endswith(suffix)
1047 return string[:-len(suffix)]
1050 def DualLibrary(env, lib_name, *args, **kwargs):
1051 """Builder to build both .a and _shared.a library in one step.
1054 env: Environment in which we were called.
1055 lib_name: Library name.
1056 args: Positional arguments.
1057 kwargs: Keyword arguments.
1059 static_objs = [i for i in Flatten(args[0]) if not HasSuffix(i, '.os')]
1060 shared_objs = [i for i in Flatten(args[0]) if not HasSuffix(i, '.o')]
1061 # Built static library as ususal.
1062 env.ComponentLibrary(lib_name, static_objs, **kwargs)
1063 # For coverage bots, we only want one object file since two versions would
1064 # write conflicting information to the same .gdca/.gdna files.
1065 if env.Bit('coverage_enabled'): return
1066 # Build a static library using -fPIC for the .o's.
1067 if env.Bit('linux'):
1068 env_shared = env.Clone(OBJSUFFIX='.os')
1069 env_shared.Append(CCFLAGS=['-fPIC'])
1070 # -fPIE overrides -fPIC, and shared libraries should not be linked
1072 env_shared.FilterOut(CCFLAGS=['-fPIE'])
1073 env_shared.ComponentLibrary(lib_name + '_shared', shared_objs, **kwargs)
1074 # for arm trusted we usually build -static
1075 env_shared.FilterOut(LINKFLAGS=['-static'])
1077 def DualObject(env, *args, **kwargs):
1078 """Builder to build both .o and .os in one step.
1081 env: Environment in which we were called.
1082 args: Positional arguments.
1083 kwargs: Keyword arguments.
1085 # Built static library as ususal.
1086 ret = env.ComponentObject(*args, **kwargs)
1087 # For coverage bots, we only want one object file since two versions would
1088 # write conflicting information to the same .gdca/.gdna files.
1089 if env.Bit('coverage_enabled'): return ret
1090 # Build a static library using -fPIC for the .o's.
1091 if env.Bit('linux'):
1092 env_shared = env.Clone(OBJSUFFIX='.os')
1093 env_shared.Append(CCFLAGS=['-fPIC'])
1094 ret += env_shared.ComponentObject(*args, **kwargs)
1098 def AddDualLibrary(env):
1099 env.AddMethod(DualLibrary)
1100 env.AddMethod(DualObject)
1101 # For coverage bots we only build one set of objects and we always set
1102 # '-fPIC' so we do not need a "special" library.
1103 if env.Bit('coverage_enabled'):
1104 env['SHARED_LIBS_SPECIAL'] = False
1106 env['SHARED_LIBS_SPECIAL'] = env.Bit('linux')
1109 # In prebuild mode we ignore the dependencies so that stuff does
1110 # NOT get build again
1111 # Optionally ignore the build process.
1112 DeclareBit('prebuilt', 'Disable all build steps, only support install steps')
1113 pre_base_env.SetBitFromOption('prebuilt', False)
1116 # HELPERS FOR TEST INVOLVING TRUSTED AND UNTRUSTED ENV
1117 def GetEmulator(env):
1118 emulator = ARGUMENTS.get('force_emulator')
1119 if emulator is None and 'TRUSTED_ENV' in env:
1120 emulator = env['TRUSTED_ENV'].get('EMULATOR')
1123 pre_base_env.AddMethod(GetEmulator)
1125 def UsingEmulator(env):
1126 return bool(env.GetEmulator())
1128 pre_base_env.AddMethod(UsingEmulator)
1131 def GetValidator(env, validator):
1132 # NOTE: that the variable TRUSTED_ENV is set by ExportSpecialFamilyVars()
1133 if 'TRUSTED_ENV' not in env:
1136 if validator is None:
1137 if env.Bit('build_arm'):
1138 validator = 'arm-ncval-core'
1139 elif env.Bit('build_mips32'):
1140 validator = 'mips-ncval-core'
1142 if env.Bit('validator_ragel'):
1143 validator = 'ncval_new'
1147 trusted_env = env['TRUSTED_ENV']
1148 return trusted_env.File('${STAGING_DIR}/${PROGPREFIX}%s${PROGSUFFIX}' %
1151 pre_base_env.AddMethod(GetValidator)
1154 # Perform os.path.abspath rooted at the directory SConstruct resides in.
1155 def SConstructAbsPath(env, path):
1156 return os.path.normpath(os.path.join(env['MAIN_DIR'], path))
1158 pre_base_env.AddMethod(SConstructAbsPath)
1162 sel_ldr = ARGUMENTS.get('force_sel_ldr')
1164 return env.File(env.SConstructAbsPath(sel_ldr))
1166 # NOTE: that the variable TRUSTED_ENV is set by ExportSpecialFamilyVars()
1167 if 'TRUSTED_ENV' not in env:
1170 trusted_env = env['TRUSTED_ENV']
1171 return trusted_env.File('${STAGING_DIR}/${PROGPREFIX}sel_ldr${PROGSUFFIX}')
1173 pre_base_env.AddMethod(GetSelLdr)
1176 def GetSelLdrSeccomp(env):
1177 # NOTE: that the variable TRUSTED_ENV is set by ExportSpecialFamilyVars()
1178 if 'TRUSTED_ENV' not in env:
1181 if not (env.Bit('linux') and env.Bit('build_x86_64')):
1184 trusted_env = env['TRUSTED_ENV']
1185 return trusted_env.File('${STAGING_DIR}/${PROGPREFIX}'
1186 'sel_ldr_seccomp${PROGSUFFIX}')
1188 pre_base_env.AddMethod(GetSelLdrSeccomp)
1191 def SupportsSeccompBpfSandbox(env):
1192 if not (env.Bit('linux') and env.Bit('build_x86_64')):
1195 # The gcov runtime does some extra calls (such as 'access') that
1196 # are not permitted by the policy.
1197 if env.Bit('coverage_enabled'):
1200 # This is a lame detection if seccomp bpf filters are supported by the kernel.
1201 # We suppose that any Linux kernel v3.2+ supports it, but it is only true
1202 # for Ubuntu kernels. Seccomp BPF filters reached the mainline at 3.5,
1203 # so this check will be wrong on some relatively old non-Ubuntu Linux distros.
1204 kernel_version = map(int, platform.release().split('.', 2)[:2])
1205 return kernel_version >= [3, 2]
1207 pre_base_env.AddMethod(SupportsSeccompBpfSandbox)
1210 def GetBootstrap(env):
1211 if 'TRUSTED_ENV' in env:
1212 trusted_env = env['TRUSTED_ENV']
1213 if trusted_env.Bit('linux'):
1214 template_digits = 'X' * 16
1215 return (trusted_env.File('${STAGING_DIR}/nacl_helper_bootstrap'),
1216 ['--r_debug=0x' + template_digits,
1217 '--reserved_at_zero=0x' + template_digits])
1220 pre_base_env.AddMethod(GetBootstrap)
1222 def AddBootstrap(env, executable, args):
1223 bootstrap, bootstrap_args = env.GetBootstrap()
1224 if bootstrap is None:
1225 return [executable] + args
1227 return [bootstrap, executable] + bootstrap_args + args
1229 pre_base_env.AddMethod(AddBootstrap)
1232 def GetIrtNexe(env, chrome_irt=False):
1233 image = ARGUMENTS.get('force_irt')
1235 return env.SConstructAbsPath(image)
1238 return nacl_irt_env.File('${STAGING_DIR}/irt.nexe')
1240 return nacl_irt_env.File('${STAGING_DIR}/irt_core.nexe')
1242 pre_base_env.AddMethod(GetIrtNexe)
1245 def CommandValidatorTestNacl(env, name, image,
1246 validator_flags=None,
1250 validator = env.GetValidator(validator)
1251 if validator is None:
1252 print 'WARNING: no validator found. Skipping test %s' % name
1255 if validator_flags is None:
1256 validator_flags = []
1258 if env.Bit('pnacl_generate_pexe'):
1261 command = [validator] + validator_flags + [image]
1262 return env.CommandTest(name, command, size, **extra)
1264 pre_base_env.AddMethod(CommandValidatorTestNacl)
1267 def ExtractPublishedFiles(env, target_name):
1268 run_files = ['$STAGING_DIR/' + os.path.basename(published_file.path)
1269 for published_file in env.GetPublished(target_name, 'run')]
1270 nexe = '$STAGING_DIR/%s${PROGSUFFIX}' % target_name
1271 return [env.File(file) for file in run_files + [nexe]]
1273 pre_base_env.AddMethod(ExtractPublishedFiles)
1276 # Only include the chrome side of the build if present.
1277 if os.path.exists(pre_base_env.File(
1278 '#/../ppapi/native_client/chrome_main.scons').abspath):
1279 SConscript('#/../ppapi/native_client/chrome_main.scons',
1280 exports=['pre_base_env'])
1281 enable_chrome = True
1283 def AddChromeFilesFromGroup(env, file_group):
1285 pre_base_env.AddMethod(AddChromeFilesFromGroup)
1286 enable_chrome = False
1287 DeclareBit('enable_chrome_side',
1288 'Is the chrome side present.')
1289 pre_base_env.SetBitFromOption('enable_chrome_side', enable_chrome)
1291 def ProgramNameForNmf(env, basename):
1292 """ Create an architecture-specific filename that can be used in an NMF URL.
1294 if env.Bit('pnacl_generate_pexe'):
1297 return '%s_%s' % (basename, env.get('TARGET_FULLARCH'))
1299 pre_base_env.AddMethod(ProgramNameForNmf)
1302 def SelUniversalTest(env, name, nexe, sel_universal_flags=None, **kwargs):
1303 # The dynamic linker's ability to receive arguments over IPC at
1304 # startup currently requires it to reject the plugin's first
1305 # connection, but this interferes with the sel_universal-based
1306 # testing because sel_universal does not retry the connection.
1307 # TODO(mseaborn): Fix by retrying the connection or by adding an
1308 # option to ld.so to disable its argv-over-IPC feature.
1309 if env.Bit('nacl_glibc') and not env.Bit('nacl_static_link'):
1312 # TODO(petarj): Sel_universal hangs on qemu-mips. Enable when fixed.
1313 if env.Bit('target_mips32') and env.UsingEmulator():
1316 if sel_universal_flags is None:
1317 sel_universal_flags = []
1319 # When run under qemu, sel_universal must sneak in qemu to the execv
1320 # call that spawns sel_ldr.
1321 if env.UsingEmulator():
1322 sel_universal_flags.append('--command_prefix')
1323 sel_universal_flags.append(env.GetEmulator())
1325 if 'TRUSTED_ENV' not in env:
1327 sel_universal = env['TRUSTED_ENV'].File(
1328 '${STAGING_DIR}/${PROGPREFIX}sel_universal${PROGSUFFIX}')
1330 # Point to sel_ldr using an environment variable.
1331 sel_ldr = env.GetSelLdr()
1333 print 'WARNING: no sel_ldr found. Skipping test %s' % name
1335 kwargs.setdefault('osenv', []).append('NACL_SEL_LDR=' + sel_ldr.abspath)
1336 bootstrap, _ = env.GetBootstrap()
1337 if bootstrap is not None:
1338 kwargs['osenv'].append('NACL_SEL_LDR_BOOTSTRAP=%s' % bootstrap.abspath)
1340 node = CommandSelLdrTestNacl(env,
1343 loader=sel_universal,
1344 sel_ldr_flags=sel_universal_flags,
1345 skip_bootstrap=True,
1347 if not env.Bit('built_elsewhere'):
1348 env.Depends(node, sel_ldr)
1349 if bootstrap is not None:
1350 env.Depends(node, bootstrap)
1353 pre_base_env.AddMethod(SelUniversalTest)
1356 def MakeNaClLogOption(env, target):
1357 """ Make up a filename related to the [target], for use with NACLLOG.
1358 The file should end up in the build directory (scons-out/...).
1360 # NOTE: to log to the source directory use file.srcnode().abspath instead.
1361 # See http://www.scons.org/wiki/File%28%29
1362 return env.File(target + '.nacllog').abspath
1364 pre_base_env.AddMethod(MakeNaClLogOption)
1366 def MakeVerboseExtraOptions(env, target, log_verbosity, extra):
1367 """ Generates **extra options that will give access to service runtime logs,
1368 at a given log_verbosity. Slips the options into the given extra dict. """
1369 log_file = env.MakeNaClLogOption(target)
1370 extra['log_file'] = log_file
1371 extra_env = ['NACLLOG=%s' % log_file,
1372 'NACLVERBOSITY=%d' % log_verbosity]
1373 extra['osenv'] = extra.get('osenv', []) + extra_env
1375 pre_base_env.AddMethod(MakeVerboseExtraOptions)
1377 def ShouldUseVerboseOptions(env, extra):
1378 """ Heuristic for setting up Verbose NACLLOG options. """
1379 return ('process_output_single' in extra or
1380 'log_golden' in extra)
1382 pre_base_env.AddMethod(ShouldUseVerboseOptions)
1385 DeclareBit('tests_use_irt', 'Non-browser tests also load the IRT image', False)
1387 # Bit to be set by individual test/nacl.scons files that need to opt out.
1388 DeclareBit('nonstable_bitcode', 'Tests use non-stable bitcode features', False)
1391 def GetFinalizedPexe(env, pexe):
1392 """ Prep and finalize the ABI for a given pexe if needed.
1394 if not env.Bit('pnacl_generate_pexe') or env.Bit('nonstable_bitcode'):
1397 # We can remove this once we move all CommandSelLdrTestNacl to a nacl.scons
1398 # file instead. There are currently some canned nexe tests in build.scons.
1399 if env['NACL_BUILD_FAMILY'] == 'TRUSTED':
1402 # Otherwise, finalize during the build step, since there is no finalize tool
1403 # that can run on triggered bots such as the ARM HW bots.
1404 pexe_name = pexe.abspath
1405 final_name = StripSuffix(pexe_name, '.nonfinal.pexe') + '.final.pexe'
1406 # Make sure the pexe doesn't get removed by the fake builders when
1409 node = env.Command(target=final_name, source=[pexe_name],
1410 action=[Action('${PNACLFINALIZECOM}',
1411 '${PNACLFINALIZECOMSTR}')])
1412 assert len(node) == 1, node
1416 # Translate the given pexe.
1417 def GetTranslatedNexe(env, pexe):
1418 # First finalize the pexe.
1419 pexe = GetFinalizedPexe(env, pexe)
1421 # Then check if we need to translate.
1422 # Check if we started with a pexe, so there is actually a translation step.
1423 if not env.Bit('pnacl_generate_pexe'):
1426 # We can remove this once we move all CommandSelLdrTestNacl to a nacl.scons
1427 # file instead. There are currently some canned nexe tests in build.scons.
1428 if env['NACL_BUILD_FAMILY'] == 'TRUSTED':
1431 # Often there is a build step (do_not_run_tests=1) and a test step
1432 # (which is run with -j1). Normally we want to translate in the build step
1433 # so we can translate in parallel. However when we do sandboxed translation
1434 # on arm hw, we do the build step on x86 and translation on arm, so we have
1435 # to force the translation to be done in the test step. Hence,
1436 # we check the bit 'translate_in_build_step' / check if we are
1438 if not env.Bit('translate_in_build_step') and env.Bit('do_not_run_tests'):
1441 pexe_name = pexe.abspath
1442 # Tidy up the suffix (remove the .final.pexe or .nonfinal.pexe),
1443 # depending on whether or not the pexe was finalized.
1444 suffix_to_strip = '.final.pexe'
1445 if not pexe_name.endswith(suffix_to_strip):
1446 suffix_to_strip = '.nonfinal.pexe'
1447 nexe_name = StripSuffix(pexe_name, suffix_to_strip) + '.nexe'
1448 # Make sure the pexe doesn't get removed by the fake builders when
1451 if env.Bit('nonstable_bitcode'):
1452 env.Append(TRANSLATEFLAGS=['--allow-llvm-bitcode-input'])
1453 node = env.Command(target=nexe_name, source=[pexe_name],
1454 action=[Action('${TRANSLATECOM}', '${TRANSLATECOMSTR}')])
1455 assert len(node) == 1, node
1458 pre_base_env.AddMethod(GetTranslatedNexe)
1461 def CommandTestFileDumpCheck(env,
1466 """Create a test that disassembles a binary (|target|) and checks for
1467 patterns in the |check_file|. Disassembly is done using |objdump_flags|.
1470 # Do not try to run OBJDUMP if 'built_elsewhere', since that *might* mean
1471 # that a toolchain is not even present. E.g., the arm hw buildbots do
1472 # not have the pnacl toolchain. We should be able to look for the host
1473 # ARM objdump though... a TODO(jvoung) for when there is time.
1474 if env.Bit('built_elsewhere'):
1476 target = env.GetTranslatedNexe(target)
1477 return env.CommandTestFileCheck(name,
1478 ['${OBJDUMP}', objdump_flags, target],
1481 pre_base_env.AddMethod(CommandTestFileDumpCheck)
1484 def CommandTestFileCheck(env, name, cmd, check_file):
1485 """Create a test that runs a |cmd| (array of strings),
1486 which is expected to print to stdout. The results
1487 of stdout will then be piped to the file_check.py tool which
1488 will search for the regexes specified in |check_file|. """
1490 return env.CommandTest(name,
1492 env.File('${SCONSTRUCT_DIR}/tools/file_check.py'),
1494 # don't run ${PYTHON} under the emulator.
1495 direct_emulation=False)
1497 pre_base_env.AddMethod(CommandTestFileCheck)
1499 def CommandSelLdrTestNacl(env, name, nexe,
1505 # True for *.nexe statically linked with glibc
1507 skip_bootstrap=False,
1508 wrapper_program_prefix=None,
1509 # e.g., [ 'python', 'time_check.py', '--' ]
1511 # Disable all sel_ldr tests for windows under coverage.
1512 # Currently several .S files block sel_ldr from being instrumented.
1513 # See http://code.google.com/p/nativeclient/issues/detail?id=831
1514 if ('TRUSTED_ENV' in env and
1515 env['TRUSTED_ENV'].Bit('coverage_enabled') and
1516 env['TRUSTED_ENV'].Bit('windows')):
1519 # The nexe might be a pexe that needs finalization, and translation.
1520 nexe = env.GetTranslatedNexe(nexe)
1523 if args is not None:
1526 if env.Bit('pnacl_unsandboxed'):
1527 # Run unsandboxed executable directly, without sel_ldr.
1528 return env.CommandTest(name, command, size, **extra)
1531 loader = env.GetSelLdr()
1533 print 'WARNING: no sel_ldr found. Skipping test %s' % name
1536 # Avoid problems with [] as default arguments
1537 if sel_ldr_flags is None:
1540 # Avoid modifying original list
1541 sel_ldr_flags = list(sel_ldr_flags)
1543 # Disable the validator if running a GLibC test under Valgrind.
1544 # http://code.google.com/p/nativeclient/issues/detail?id=1799
1545 if env.IsRunningUnderValgrind() and env.Bit('nacl_glibc'):
1546 sel_ldr_flags += ['-cc']
1547 # https://code.google.com/p/nativeclient/issues/detail?id=3158
1548 # We don't currently have valgrind.so for LD_PRELOAD to use. That .so
1549 # is not used for newlib.
1550 # TODO(sehr): add valgrind.so built for NaCl.
1553 # Skip platform qualification checks on configurations with known issues.
1554 if env.GetEmulator() or env.IsRunningUnderValgrind():
1555 sel_ldr_flags += ['-Q']
1557 # Skip validation if we are using the x86-64 zero-based sandbox.
1558 # TODO(arbenson): remove this once the validator supports the x86-64
1559 # zero-based sandbox model.
1560 if env.Bit('x86_64_zero_based_sandbox'):
1561 sel_ldr_flags += ['-c']
1563 # The glibc modifications only make sense for nacl_env tests.
1564 # But this function gets used by some base_env (i.e. src/trusted/...)
1565 # tests too. Don't add the --nacl_glibc changes to the command
1566 # line for those cases.
1567 if env.Bit('nacl_glibc') and env['NACL_BUILD_FAMILY'] != 'TRUSTED':
1568 if not glibc_static and not env.Bit('nacl_static_link'):
1569 command = ['${NACL_SDK_LIB}/runnable-ld.so',
1570 # Locally-built shared libraries come from ${LIB_DIR}
1571 # while toolchain-provided ones come from ${NACL_SDK_LIB}.
1572 '--library-path', '${LIB_DIR}:${NACL_SDK_LIB}'] + command
1573 # Enable file access.
1574 sel_ldr_flags += ['-a']
1576 # Turn off sandbox for mac so coverage files can be written out.
1577 if ('TRUSTED_ENV' in env and
1578 env['TRUSTED_ENV'].Bit('coverage_enabled') and
1579 env.Bit('host_mac') and
1580 '-a' not in sel_ldr_flags):
1581 sel_ldr_flags += ['-a']
1583 if env.Bit('tests_use_irt'):
1584 sel_ldr_flags += ['-B', nacl_env.GetIrtNexe()]
1587 loader_cmd = [loader]
1589 loader_cmd = env.AddBootstrap(loader, [])
1591 command = loader_cmd + sel_ldr_flags + ['--'] + command
1593 if env.Bit('host_linux'):
1594 extra['using_nacl_signal_handler'] = True
1596 if env.ShouldUseVerboseOptions(extra):
1597 env.MakeVerboseExtraOptions(name, log_verbosity, extra)
1599 node = env.CommandTest(name, command, size, posix_path=True,
1600 wrapper_program_prefix=wrapper_program_prefix, **extra)
1601 if env.Bit('tests_use_irt'):
1602 env.Alias('irt_tests', node)
1605 pre_base_env.AddMethod(CommandSelLdrTestNacl)
1608 TEST_EXTRA_ARGS = ['stdin', 'log_file',
1609 'stdout_golden', 'stderr_golden', 'log_golden',
1610 'filter_regex', 'filter_inverse', 'filter_group_only',
1611 'osenv', 'arch', 'subarch', 'exit_status', 'track_cmdtime',
1612 'num_runs', 'process_output_single',
1613 'process_output_combined', 'using_nacl_signal_handler',
1614 'declares_exit_status', 'time_warning', 'time_error']
1616 TEST_TIME_THRESHOLD = {
1623 # Valgrind handles SIGSEGV in a way our testing tools do not expect.
1624 UNSUPPORTED_VALGRIND_EXIT_STATUS = ['trusted_sigabrt',
1625 'untrusted_sigill' ,
1626 'untrusted_segfault',
1627 'untrusted_sigsegv_or_equivalent',
1629 'trusted_sigsegv_or_equivalent']
1632 def GetPerfEnvDescription(env):
1633 """ Return a string describing architecture, library, etc. options that may
1636 NOTE: If any of these labels are changed, be sure to update the graph
1637 labels used in tools/nacl_perf_expectations/nacl_perf_expectations.json,
1638 after a few data-points have been collected. """
1639 description_list = [env['TARGET_FULLARCH']]
1640 # Using a list to keep the order consistent.
1641 bit_to_description = [ ('bitcode', ('pnacl', 'nnacl')),
1642 ('translate_fast', ('fast', '')),
1643 ('nacl_glibc', ('glibc', 'newlib')),
1644 ('nacl_static_link', ('static', 'dynamic')),
1646 for (bit, (descr_yes, descr_no)) in bit_to_description:
1648 additional = descr_yes
1650 additional = descr_no
1652 description_list.append(additional)
1653 return '_'.join(description_list)
1655 pre_base_env.AddMethod(GetPerfEnvDescription)
1660 def GetTestName(target):
1661 key = str(target.path)
1662 return TEST_NAME_MAP.get(key, key)
1664 pre_base_env['GetTestName'] = GetTestName
1667 def SetTestName(node, name):
1668 for target in Flatten(node):
1669 TEST_NAME_MAP[str(target.path)] = name
1672 def ApplyTestWrapperCommand(command_args, extra_deps):
1673 new_args = ARGUMENTS['test_wrapper'].split()
1674 for input_file in extra_deps:
1675 new_args.extend(['-F', input_file])
1676 for arg in command_args:
1677 if isinstance(arg, str):
1678 new_args.extend(['-a', arg])
1680 new_args.extend(['-f', arg])
1684 def CommandTest(env, name, command, size='small', direct_emulation=True,
1685 extra_deps=[], posix_path=False, capture_output=True,
1686 wrapper_program_prefix=None, scale_timeout=None,
1688 if not name.endswith('.out') or name.startswith('$'):
1689 raise Exception('ERROR: bad test filename for test output %r' % name)
1691 if env.IsRunningUnderValgrind():
1693 elif env.Bit('asan'):
1694 skip = 'AddressSanitizer'
1697 # Valgrind tends to break crash tests by changing the exit status.
1698 # So far, tests using declares_exit_status are crash tests. If this
1699 # changes, we will have to find a way to make declares_exit_status
1700 # work with Valgrind.
1701 if (skip is not None and
1702 (extra.get('exit_status') in UNSUPPORTED_VALGRIND_EXIT_STATUS or
1703 bool(int(extra.get('declares_exit_status', 0))))):
1704 print 'Skipping death test "%s" under %s' % (name, skip)
1708 extra.setdefault('osenv', [])
1709 # Ensure that 'osenv' is a list.
1710 if isinstance(extra['osenv'], str):
1711 extra['osenv'] = [extra['osenv']]
1712 # ASan normally intercepts SIGSEGV and disables our SIGSEGV signal
1713 # handler, which interferes with various NaCl tests, including the
1714 # platform qualification test built into sel_ldr. We fix this by
1715 # telling ASan not to mess with SIGSEGV.
1716 asan_options = ['handle_segv=0']
1717 if env.Bit('host_mac') and int(platform.mac_ver()[0].split('.')[1]) < 7:
1718 # MacOS 10.6 has a bug in the libsandbox system library where it
1719 # makes a memcmp call that reads off the end of a malloc'd block.
1720 # The bug appears to be harmless, but trips an ASan report. So
1721 # tell ASan to suppress memcmp checks.
1722 asan_options.append('strict_memcmp=0')
1723 # Note that the ASan runtime doesn't use : specifically as a separator.
1724 # It actually just looks for "foo=" anywhere in the string with strstr,
1725 # so any separator will do. The most obvious choices, ' ', ',', and ';'
1726 # all cause command_tester.py to split things up and get confused.
1727 extra['osenv'].append('ASAN_OPTIONS=' + ':'.join(asan_options))
1729 name = '${TARGET_ROOT}/test_results/' + name
1730 # NOTE: using the long version of 'name' helps distinguish opt vs dbg
1731 max_time = TEST_TIME_THRESHOLD[size]
1732 if 'scale_timeout' in ARGUMENTS:
1733 max_time = max_time * int(ARGUMENTS['scale_timeout'])
1735 max_time = max_time * scale_timeout
1737 if env.Bit('nacl_glibc'):
1738 suite = 'nacl_glibc'
1740 suite = 'nacl_newlib'
1741 if env.Bit('bitcode'):
1744 script_flags = ['--name', '%s.${GetTestName(TARGET)}' % suite,
1745 '--time_warning', str(max_time),
1746 '--time_error', str(10 * max_time),
1749 run_under = ARGUMENTS.get('run_under')
1751 run_under_extra_args = ARGUMENTS.get('run_under_extra_args')
1752 if run_under_extra_args:
1753 run_under = run_under + ',' + run_under_extra_args
1754 script_flags.append('--run_under')
1755 script_flags.append(run_under)
1757 emulator = env.GetEmulator()
1758 if emulator and direct_emulation:
1759 command = [emulator] + command
1761 # test wrapper should go outside of emulators like qemu, since the
1762 # test wrapper code is not emulated.
1763 if wrapper_program_prefix is not None:
1764 command = wrapper_program_prefix + command
1766 script_flags.append('--perf_env_description')
1767 script_flags.append(env.GetPerfEnvDescription())
1769 # Add architecture info.
1770 extra['arch'] = env['BUILD_ARCHITECTURE']
1771 extra['subarch'] = env['BUILD_SUBARCH']
1773 for flag_name, flag_value in extra.iteritems():
1774 assert flag_name in TEST_EXTRA_ARGS, repr(flag_name)
1775 if isinstance(flag_value, list):
1776 # Options to command_tester.py which are actually lists must not be
1777 # separated by whitespace. This stringifies the lists with a separator
1778 # char to satisfy command_tester.
1779 flag_value = command_tester.StringifyList(flag_value)
1780 # do not add --flag + |flag_name| |flag_value| if
1781 # |flag_value| is false (empty).
1783 script_flags.append('--' + flag_name)
1784 # Make sure flag values are strings (or SCons objects) when building
1785 # up the command. Right now, this only means convert ints to strings.
1786 if isinstance(flag_value, int):
1787 flag_value = str(flag_value)
1788 script_flags.append(flag_value)
1791 if not capture_output:
1792 script_flags.extend(['--capture_output', '0'])
1794 # Set command_tester.py's output filename. We skip this when using
1795 # test_wrapper because the run_test_via_ssh.py wrapper does not have
1796 # the ability to copy result files back from the remote host.
1797 if 'test_wrapper' not in ARGUMENTS:
1798 script_flags.extend(['--report', name])
1800 test_script = env.File('${SCONSTRUCT_DIR}/tools/command_tester.py')
1801 extra_deps = extra_deps + [env.File('${SCONSTRUCT_DIR}/tools/test_lib.py')]
1802 command = ['${PYTHON}', test_script] + script_flags + command
1803 if 'test_wrapper' in ARGUMENTS:
1804 command = ApplyTestWrapperCommand(command, extra_deps)
1805 return env.AutoDepsCommand(name, command,
1806 extra_deps=extra_deps, posix_path=posix_path,
1807 disabled=env.Bit('do_not_run_tests'))
1809 pre_base_env.AddMethod(CommandTest)
1812 def FileSizeTest(env, name, envFile, max_size=None):
1813 """FileSizeTest() returns a scons node like the other XYZTest generators.
1814 It logs the file size of envFile in a perf-buildbot-recognizable format.
1815 Optionally, it can cause a test failure if the file is larger than max_size.
1817 def doSizeCheck(target, source, env):
1818 filepath = source[0].abspath
1819 actual_size = os.stat(filepath).st_size
1820 command_tester.LogPerfResult(name,
1821 env.GetPerfEnvDescription(),
1822 '%.3f' % (actual_size / 1024.0),
1824 # Also get zipped size.
1825 nexe_file = open(filepath, 'rb')
1826 zipped_size = len(zlib.compress(nexe_file.read()))
1828 command_tester.LogPerfResult(name,
1829 'ZIPPED_' + env.GetPerfEnvDescription(),
1830 '%.3f' % (zipped_size / 1024.0),
1832 # Finally, do the size check.
1833 if max_size is not None and actual_size > max_size:
1834 # NOTE: this exception only triggers a failure for this particular test,
1835 # just like any other test failure.
1836 raise Exception("File %s larger than expected: expected up to %i, got %i"
1837 % (filepath, max_size, actual_size))
1838 # If 'built_elsewhere', the file should should have already been built.
1839 # Do not try to built it and/or its pieces.
1840 if env.Bit('built_elsewhere'):
1841 env.Ignore(name, envFile)
1842 return env.Command(name, envFile, doSizeCheck)
1844 pre_base_env.AddMethod(FileSizeTest)
1846 def StripExecutable(env, name, exe):
1847 """StripExecutable returns a node representing the stripped version of |exe|.
1848 The stripped version will be given the basename |name|.
1849 NOTE: for now this only works with the untrusted toolchain.
1850 STRIP does not appear to be a first-class citizen in SCons and
1851 STRIP has only been set to point at the untrusted toolchain.
1856 action=[Action('${STRIPCOM} ${SOURCES} -o ${TARGET}', '${STRIPCOMSTR}')])
1858 pre_base_env.AddMethod(StripExecutable)
1861 # TODO(ncbray): pretty up the log output when running this builder.
1862 def DisabledCommand(target, source, env):
1865 pre_base_env['BUILDERS']['DisabledCommand'] = Builder(action=DisabledCommand)
1868 def AutoDepsCommand(env, name, command, extra_deps=[], posix_path=False,
1870 """AutoDepsCommand() takes a command as an array of arguments. Each
1871 argument may either be:
1874 * a Scons file object, e.g. one created with env.File() or as the
1875 result of another build target.
1877 In the second case, the file is automatically declared as a
1878 dependency of this command.
1880 command = list(command)
1882 for index, arg in enumerate(command):
1883 if not isinstance(arg, str):
1884 if len(Flatten(arg)) != 1:
1885 # Do not allow this, because it would cause "deps" to get out
1886 # of sync with the indexes in "command".
1887 # See http://code.google.com/p/nativeclient/issues/detail?id=1086
1888 raise AssertionError('Argument to AutoDepsCommand() actually contains '
1889 'multiple (or zero) arguments: %r' % arg)
1891 command[index] = '${SOURCES[%d].posix}' % len(deps)
1893 command[index] = '${SOURCES[%d].abspath}' % len(deps)
1896 # If built_elsewhere, build commands are replaced by no-ops, so make sure
1897 # the targets don't get removed first
1898 if env.Bit('built_elsewhere'):
1900 env.Depends(name, extra_deps)
1903 return env.DisabledCommand(name, deps)
1905 return env.Command(name, deps, ' '.join(command))
1908 pre_base_env.AddMethod(AutoDepsCommand)
1911 def GetPrintableCommandName(cmd):
1912 """Look at the first few elements of cmd to derive a suitable command name."""
1913 cmd_tokens = cmd.split()
1914 if "python" in cmd_tokens[0] and len(cmd_tokens) >= 2:
1915 cmd_name = cmd_tokens[1]
1917 cmd_name = cmd_tokens[0].split('(')[0]
1919 # undo some pretty printing damage done by hammer
1920 cmd_name = cmd_name.replace('________','')
1921 # use file name part of a path
1922 return cmd_name.split('/')[-1]
1925 def GetPrintableEnvironmentName(env):
1926 # use file name part of a obj root path as env name
1927 return env.subst('${TARGET_ROOT}').split('/')[-1]
1929 pre_base_env.AddMethod(GetPrintableEnvironmentName)
1932 def CustomCommandPrinter(cmd, targets, source, env):
1933 # Abuse the print hook to count the commands that are executed
1934 if env.Bit('target_stats'):
1935 cmd_name = GetPrintableCommandName(cmd)
1936 env_name = env.GetPrintableEnvironmentName()
1937 CMD_COUNTER[cmd_name] = CMD_COUNTER.get(cmd_name, 0) + 1
1938 ENV_COUNTER[env_name] = ENV_COUNTER.get(env_name, 0) + 1
1941 # Our pretty printer
1943 cmd_name = GetPrintableCommandName(cmd)
1944 env_name = env.GetPrintableEnvironmentName()
1945 sys.stdout.write('[%s] [%s] %s\n' % (cmd_name, env_name,
1946 targets[0].get_path()))
1948 # The SCons default (copied from print_cmd_line in Action.py)
1949 sys.stdout.write(cmd + u'\n')
1951 pre_base_env.Append(PRINT_CMD_LINE_FUNC=CustomCommandPrinter)
1954 def GetAbsDirArg(env, argument, target):
1955 """Fetch the named command-line argument and turn it into an absolute
1956 directory name. If the argument is missing, raise a UserError saying
1957 that the given target requires that argument be given."""
1958 dir = ARGUMENTS.get(argument)
1960 raise UserError('%s must be set when invoking %s' % (argument, target))
1961 return os.path.join(env.Dir('$MAIN_DIR').abspath, dir)
1963 pre_base_env.AddMethod(GetAbsDirArg)
1966 pre_base_env.Append(
1968 ['NACL_BUILD_ARCH', '${BUILD_ARCHITECTURE}' ],
1969 ['NACL_BUILD_SUBARCH', '${BUILD_SUBARCH}' ],
1973 def MakeGTestEnv(env):
1974 # Create an environment to run unit tests using Gtest.
1975 gtest_env = env.Clone()
1977 # This became necessary for the arm cross TC v4.6
1978 # but probable applies to all new gcc TCs
1979 gtest_env.Append(LINKFLAGS=['-pthread'])
1981 # Define compile-time flag that communicates that we are compiling in the test
1982 # environment (rather than for the TCB).
1983 if gtest_env['NACL_BUILD_FAMILY'] == 'TRUSTED':
1984 gtest_env.Append(CCFLAGS=['-DNACL_TRUSTED_BUT_NOT_TCB'])
1986 # This is necessary for unittest_main.c which includes gtest/gtest.h
1987 # The problem is that gtest.h includes other files expecting the
1988 # include path to be set.
1989 gtest_env.Prepend(CPPPATH=['${SOURCE_ROOT}/testing/gtest/include'])
1991 # gtest does not compile with our stringent settings.
1992 if gtest_env.Bit('linux') or gtest_env.Bit('mac'):
1993 # "-pedantic" is because of: gtest-typed-test.h:236:46: error:
1994 # anonymous variadic macros were introduced in C99
1995 # Also, gtest does not compile successfully with "-Wundef".
1996 gtest_env.FilterOut(CCFLAGS=['-pedantic', '-Wundef'])
1997 gtest_env.FilterOut(CXXFLAGS=['-fno-rtti', '-Weffc++'])
1999 # gtest is incompatible with static linking due to obscure libstdc++
2000 # linking interactions.
2001 # See http://code.google.com/p/nativeclient/issues/detail?id=1987
2002 gtest_env.FilterOut(LINKFLAGS=['-static'])
2004 gtest_env.Prepend(LIBS=['gtest'])
2007 pre_base_env.AddMethod(MakeGTestEnv)
2009 def MakeUntrustedNativeEnv(env):
2010 native_env = nacl_env.Clone()
2011 if native_env.Bit('bitcode') and not native_env.Bit('target_mips32'):
2012 native_env = native_env.PNaClGetNNaClEnv()
2015 pre_base_env.AddMethod(MakeUntrustedNativeEnv)
2017 def MakeBaseTrustedEnv():
2018 base_env = MakeArchSpecificEnv()
2022 ['NACL_TARGET_ARCH', '${TARGET_ARCHITECTURE}' ],
2023 ['NACL_TARGET_SUBARCH', '${TARGET_SUBARCH}' ],
2030 EXTRA_CXXFLAGS = [],
2032 CFLAGS = ['${EXTRA_CFLAGS}'],
2033 CXXFLAGS = ['${EXTRA_CXXFLAGS}'],
2035 if base_env.Bit('ncval_testing'):
2036 base_env.Append(CPPDEFINES = ['NCVAL_TESTING'])
2037 if base_env.Bit('target_arm_thumb2'):
2038 base_env.Append(CPPDEFINES = ['NACL_TARGET_ARM_THUMB2_MODE=1'])
2040 base_env.Append(BUILD_SCONSCRIPTS = [
2041 # KEEP THIS SORTED PLEASE
2042 'build/build.scons',
2043 'toolchain_build/build.scons',
2044 'src/shared/gio/build.scons',
2045 'src/shared/imc/build.scons',
2046 'src/shared/ldr/build.scons',
2047 'src/shared/platform/build.scons',
2048 'src/shared/serialization/build.scons',
2049 'src/shared/srpc/build.scons',
2050 'src/shared/utils/build.scons',
2051 'src/third_party_mod/gtest/build.scons',
2052 'src/tools/validator_tools/build.scons',
2053 'src/trusted/cpu_features/build.scons',
2054 'src/trusted/debug_stub/build.scons',
2055 'src/trusted/desc/build.scons',
2056 'src/trusted/fault_injection/build.scons',
2057 'src/trusted/generic_container/build.scons',
2058 'src/trusted/gio/build.scons',
2059 'src/trusted/interval_multiset/build.scons',
2060 'src/trusted/manifest_name_service_proxy/build.scons',
2061 'src/trusted/nacl_base/build.scons',
2062 'src/trusted/nonnacl_util/build.scons',
2063 'src/trusted/perf_counter/build.scons',
2064 'src/trusted/platform_qualify/build.scons',
2065 'src/trusted/python_bindings/build.scons',
2066 'src/trusted/reverse_service/build.scons',
2067 'src/trusted/seccomp_bpf/build.scons',
2068 'src/trusted/sel_universal/build.scons',
2069 'src/trusted/service_runtime/build.scons',
2070 'src/trusted/simple_service/build.scons',
2071 'src/trusted/threading/build.scons',
2072 'src/trusted/validator/build.scons',
2073 'src/trusted/validator/driver/build.scons',
2074 'src/trusted/validator/x86/32/build.scons',
2075 'src/trusted/validator/x86/64/build.scons',
2076 'src/trusted/validator/x86/build.scons',
2077 'src/trusted/validator/x86/decoder/build.scons',
2078 'src/trusted/validator/x86/decoder/generator/build.scons',
2079 'src/trusted/validator/x86/ncval_reg_sfi/build.scons',
2080 'src/trusted/validator/x86/ncval_seg_sfi/build.scons',
2081 'src/trusted/validator/x86/ncval_seg_sfi/generator/build.scons',
2082 'src/trusted/validator/x86/testing/enuminsts/build.scons',
2083 'src/trusted/validator_arm/build.scons',
2084 'src/trusted/validator_ragel/build.scons',
2085 'src/trusted/validator_x86/build.scons',
2086 'src/trusted/weak_ref/build.scons',
2087 'tests/common/build.scons',
2088 'tests/lock_manager/build.scons',
2089 'tests/performance/build.scons',
2090 'tests/python_version/build.scons',
2091 'tests/sel_ldr_seccomp/build.scons',
2092 'tests/srpc_message/build.scons',
2093 'tests/tools/build.scons',
2094 'tests/unittests/shared/srpc/build.scons',
2095 'tests/unittests/shared/imc/build.scons',
2096 'tests/unittests/shared/platform/build.scons',
2097 'tests/unittests/trusted/asan/build.scons',
2098 'tests/unittests/trusted/bits/build.scons',
2099 'tests/unittests/trusted/platform_qualify/build.scons',
2100 'tests/unittests/trusted/service_runtime/build.scons',
2103 base_env.AddMethod(SDKInstallBin)
2105 # The ARM and MIPS validators can be built for any target that doesn't use
2107 if not base_env.Bit('target_x86_64'):
2109 BUILD_SCONSCRIPTS = [
2110 'src/trusted/validator_mips/build.scons',
2113 base_env.AddChromeFilesFromGroup('trusted_scons_files')
2116 NACL_BUILD_FAMILY = 'TRUSTED',
2119 # Add optional scons files if present in the directory tree.
2120 if os.path.exists(pre_base_env.subst('${MAIN_DIR}/supplement/build.scons')):
2121 base_env.Append(BUILD_SCONSCRIPTS=['${MAIN_DIR}/supplement/build.scons'])
2126 # Select tests to run under coverage build.
2127 pre_base_env['COVERAGE_TARGETS'] = [
2128 'small_tests', 'medium_tests', 'large_tests',
2129 'chrome_browser_tests']
2132 pre_base_env.Help("""\
2133 ======================================================================
2135 ======================================================================
2140 * cleaning: scons -c
2142 * build mandel: scons --mode=nacl mandel.nexe
2143 * smoke test: scons --mode=nacl,opt-linux -k pp=1 smoke_tests
2145 * sel_ldr: scons --mode=opt-linux sel_ldr
2147 * build the plugin: scons --mode=opt-linux ppNaClPlugin
2148 * or: scons --mode=opt-linux src/trusted/plugin
2150 Targets to build trusted code destined for the SDK:
2151 * build trusted-code tools: scons build_bin
2152 * install trusted-code tools: scons install_bin bindir=...
2153 * These default to opt build, or add --mode=dbg-host for debug build.
2155 Targets to build untrusted code destined for the SDK:
2156 * build just libraries: scons build_lib
2157 * install just headers: scons install_headers includedir=...
2158 * install just libraries: scons install_lib libdir=...
2159 * install headers and libraries:scons install includedir=... libdir=...
2161 * dump system info: scons --mode=nacl,opt-linux dummy
2166 naclsdk_mode=<mode> where <mode>:
2168 'local': use locally installed sdk kit
2169 'download': use the download copy (default)
2170 'custom:<path>': use kit at <path>
2171 'manual': use settings from env vars NACL_SDK_xxx
2173 pnaclsdk_mode=<mode> where <mode:
2174 'default': use the default (typically the downloaded copy)
2175 'custom:<path>': use kit from <path>
2177 --prebuilt Do not build things, just do install steps
2179 --verbose Full command line logging before command execution
2181 pp=1 Use command line pretty printing (more concise output)
2183 sysinfo=1 Verbose system info printing
2185 naclsdk_validate=0 Suppress presence check of sdk
2189 Automagically generated help:
2190 -----------------------------
2194 def SetupClang(env):
2195 env['CLANG_DIR'] = '${SOURCE_ROOT}/third_party/llvm-build/Release+Asserts/bin'
2196 env['CLANG_OPTS'] = []
2198 if not (env.Bit('host_linux') or env.Bit('host_mac')):
2199 print "ERROR: ASan is only available for Linux and Mac"
2201 env['CLANG_OPTS'].append('-fsanitize=address')
2202 if env.Bit('host_mac'):
2203 # The built executables will try to find this library at runtime
2204 # in the directory containing the executable itself. In the
2205 # Chromium build, the library just gets copied into that
2206 # directory. Here, there isn't a single directory from which
2207 # all the test binaries are run (sel_ldr is run from staging/
2208 # but other trusted test binaries are run from their respective
2209 # obj/.../ directories). So instead just point the dynamic linker
2210 # at the right directory using an environment variable.
2211 clang_lib_dir = '${CLANG_DIR}/../lib/clang/*/lib/darwin'
2212 env['ENV']['DYLD_LIBRARY_PATH'] = ':'.join([dir.abspath for dir in
2213 env.Glob(clang_lib_dir)])
2214 if 'PROPAGATE_ENV' not in env:
2215 env['PROPAGATE_ENV'] = []
2216 env['PROPAGATE_ENV'].append('DYLD_LIBRARY_PATH')
2218 env['CC'] = '${CLANG_DIR}/clang ${CLANG_OPTS}'
2219 env['CXX'] = '${CLANG_DIR}/clang++ ${CLANG_OPTS}'
2220 # Make sure we find Clang-supplied libraries like -lprofile_rt
2221 # in the Clang build we use, rather than from the system.
2222 # The system-installed versions go with the system-installed Clang
2223 # and might not be compatible with the Clang we're running.
2224 env.Append(LIBPATH=['${CLANG_DIR}/../lib'])
2226 def GenerateOptimizationLevels(env):
2227 if env.Bit('clang'):
2230 # Generate debug variant.
2231 debug_env = env.Clone(tools = ['target_debug'])
2232 debug_env['OPTIMIZATION_LEVEL'] = 'dbg'
2233 debug_env['BUILD_TYPE'] = debug_env.subst('$BUILD_TYPE')
2234 debug_env['BUILD_DESCRIPTION'] = debug_env.subst('$BUILD_DESCRIPTION')
2235 AddDualLibrary(debug_env)
2236 # Add to the list of fully described environments.
2237 environment_list.append(debug_env)
2239 # Generate opt variant.
2240 opt_env = env.Clone(tools = ['target_optimized'])
2241 opt_env['OPTIMIZATION_LEVEL'] = 'opt'
2242 opt_env['BUILD_TYPE'] = opt_env.subst('$BUILD_TYPE')
2243 opt_env['BUILD_DESCRIPTION'] = opt_env.subst('$BUILD_DESCRIPTION')
2244 AddDualLibrary(opt_env)
2245 # Add to the list of fully described environments.
2246 environment_list.append(opt_env)
2248 return (debug_env, opt_env)
2251 def SDKInstallBin(env, name, node, target=None):
2252 """Add the given node to the build_bin and install_bin targets.
2253 It will be installed under the given name with the build target appended.
2254 The optional target argument overrides the setting of what that target is."""
2255 env.Alias('build_bin', node)
2256 if 'install_bin' in COMMAND_LINE_TARGETS:
2257 dir = env.GetAbsDirArg('bindir', 'install_bin')
2259 target = env['TARGET_FULLARCH'].replace('-', '_')
2260 file_name, file_ext = os.path.splitext(name)
2261 output_name = file_name + '_' + target + file_ext
2262 install_node = env.InstallAs(os.path.join(dir, output_name), node)
2263 env.Alias('install_bin', install_node)
2266 def MakeWindowsEnv():
2267 base_env = MakeBaseTrustedEnv()
2268 windows_env = base_env.Clone(
2269 BUILD_TYPE = '${OPTIMIZATION_LEVEL}-win',
2270 BUILD_TYPE_DESCRIPTION = 'Windows ${OPTIMIZATION_LEVEL} build',
2271 tools = ['target_platform_windows'],
2272 # Windows /SAFESEH linking requires either an .sxdata section be
2273 # present or that @feat.00 be defined as a local, absolute symbol
2274 # with an odd value.
2275 ASCOM = ('$ASPPCOM /E /D__ASSEMBLER__ | '
2276 '$WINASM -defsym @feat.00=1 -o $TARGET'),
2277 PDB = '${TARGET.base}.pdb',
2278 # Strict doesn't currently work for Windows since some of the system
2279 # libraries like wsock32 are magical.
2280 LIBS_STRICT = False,
2281 TARGET_ARCH='x86_64' if base_env.Bit('build_x86_64') else 'x86',
2286 ['NACL_WINDOWS', '1'],
2288 ['NACL_LINUX', '0'],
2289 ['NACL_ANDROID', '0'],
2290 ['_WIN32_WINNT', '0x0501'],
2291 ['__STDC_LIMIT_MACROS', '1'],
2293 # WIN32 is used by ppapi
2295 # WIN32_LEAN_AND_MEAN tells windows.h to omit obsolete and rarely
2296 # used #include files. This allows use of Winsock 2.0 which otherwise
2297 # would conflict with Winsock 1.x included by windows.h.
2298 ['WIN32_LEAN_AND_MEAN', ''],
2300 LIBS = ['ws2_32', 'advapi32'],
2301 # TODO(bsy) remove 4355 once cross-repo
2302 # NACL_ALLOW_THIS_IN_INITIALIZER_LIST changes go in.
2303 CCFLAGS = ['/EHsc', '/WX', '/wd4355', '/wd4800'],
2306 # This linker option allows us to ensure our builds are compatible with
2307 # Chromium, which uses it.
2308 if windows_env.Bit('build_x86_32'):
2309 windows_env.Append(LINKFLAGS = "/safeseh")
2311 # We use the GNU assembler (gas) on Windows so that we can use the
2312 # same .S assembly files on all platforms. Microsoft's assembler uses
2313 # a completely different syntax for x86 code.
2314 if windows_env.Bit('build_x86_64'):
2315 # This assembler only works for x86-64 code.
2316 windows_env['WINASM'] = \
2317 windows_env.File('$SOURCE_ROOT/third_party/mingw-w64/mingw/bin/'
2318 'x86_64-w64-mingw32-as.exe').abspath
2320 # This assembler only works for x86-32 code.
2321 windows_env['WINASM'] = \
2322 windows_env.File('$SOURCE_ROOT/third_party/gnu_binutils/files/'
2327 windows_optimized_env) = GenerateOptimizationLevels(MakeWindowsEnv())
2329 def MakeUnixLikeEnv():
2330 unix_like_env = MakeBaseTrustedEnv()
2331 # -Wdeclaration-after-statement is desirable because MS studio does
2332 # not allow declarations after statements in a block, and since much
2333 # of our code is portable and primarily initially tested on Linux,
2334 # it'd be nice to get the build error earlier rather than later
2335 # (building and testing on Linux is faster).
2336 # TODO(nfullagar): should we consider switching to -std=c99 ?
2337 unix_like_env.Prepend(
2340 '-Wdeclaration-after-statement',
2341 # Require defining functions as "foo(void)" rather than
2342 # "foo()" because, in C (but not C++), the latter defines a
2343 # function with unspecified arguments rather than no
2345 '-Wstrict-prototypes',
2356 '-fdiagnostics-show-option',
2357 '-fvisibility=hidden',
2358 '-fstack-protector',
2360 CXXFLAGS=['-std=c++98'],
2361 # NOTE: pthread is only neeeded for libppNaClPlugin.so and on arm
2363 CPPDEFINES = [['__STDC_LIMIT_MACROS', '1'],
2364 ['__STDC_FORMAT_MACROS', '1'],
2368 if not unix_like_env.Bit('clang'):
2369 unix_like_env.Append(CCFLAGS=['--param', 'ssp-buffer-size=4'])
2371 if unix_like_env.Bit('enable_tmpfs_redirect_var'):
2372 unix_like_env.Append(CPPDEFINES=[['NACL_ENABLE_TMPFS_REDIRECT_VAR', '1']])
2374 unix_like_env.Append(CPPDEFINES=[['NACL_ENABLE_TMPFS_REDIRECT_VAR', '0']])
2375 return unix_like_env
2379 mac_env = MakeUnixLikeEnv().Clone(
2380 BUILD_TYPE = '${OPTIMIZATION_LEVEL}-mac',
2381 BUILD_TYPE_DESCRIPTION = 'MacOS ${OPTIMIZATION_LEVEL} build',
2382 tools = ['target_platform_mac'],
2383 # TODO(bradnelson): this should really be able to live in unix_like_env
2384 # but can't due to what the target_platform_x module is
2387 PLUGIN_SUFFIX = '.bundle',
2390 # This should be kept in synch with mac_deployment_target
2391 # in build/common.gypi, which in turn should be kept in synch
2392 # with chromium/src/build/common.gypi.
2393 mac_deployment_target = '10.6'
2396 CCFLAGS=['-mmacosx-version-min=' + mac_deployment_target],
2397 LINKFLAGS=['-mmacosx-version-min=' + mac_deployment_target])
2399 subarch_flag = '-m%s' % mac_env['BUILD_SUBARCH']
2401 CCFLAGS=[subarch_flag, '-fPIC'],
2402 ASFLAGS=[subarch_flag],
2403 LINKFLAGS=[subarch_flag, '-fPIC'],
2404 CPPDEFINES = [['NACL_WINDOWS', '0'],
2406 ['NACL_LINUX', '0'],
2407 ['NACL_ANDROID', '0'],
2408 # defining _DARWIN_C_SOURCE breaks 10.4
2409 #['_DARWIN_C_SOURCE', '1'],
2410 #['__STDC_LIMIT_MACROS', '1']
2415 (mac_debug_env, mac_optimized_env) = GenerateOptimizationLevels(MakeMacEnv())
2418 def which(cmd, paths=os.environ.get('PATH', '').split(os.pathsep)):
2420 if os.access(os.path.join(p, cmd), os.X_OK):
2425 def SetupLinuxEnvArm(env):
2426 jail = '${SCONSTRUCT_DIR}/toolchain/linux_arm-trusted'
2427 if env.Bit('arm_hard_float'):
2428 arm_abi = 'gnueabihf'
2431 if not platform.machine().startswith('arm'):
2432 # Allow emulation on non-ARM hosts.
2433 env.Replace(EMULATOR=jail + '/run_under_qemu_arm')
2434 if env.Bit('built_elsewhere'):
2435 def FakeInstall(dest, source, env):
2436 print 'Not installing', dest
2437 # Replace build commands with no-ops
2438 env.Replace(CC='true', CXX='true', LD='true',
2439 AR='true', RANLIB='true', INSTALL=FakeInstall)
2442 for suffix in ['', '-4.5', '-4.6']:
2443 if which('arm-linux-%s-g++%s' % (arm_abi, suffix)):
2446 if arm_suffix is None:
2447 # This doesn't bail out completely here because we cannot
2448 # tell whether scons was run with just --mode=nacl, where
2449 # none of these settings will actually be used.
2450 print 'NOTE: arm trusted TC is not installed'
2451 bad = 'ERROR-missing-arm-trusted-toolchain'
2452 env.Replace(CC=bad, CXX=bad, LD=bad)
2455 env.Replace(CC='arm-linux-%s-gcc%s' % (arm_abi, arm_suffix),
2456 CXX='arm-linux-%s-g++%s' % (arm_abi, arm_suffix),
2457 LD='arm-linux-%s-ld%s' % (arm_abi, arm_suffix),
2459 LIBPATH=['${LIB_DIR}',
2460 '%s/usr/lib' % jail,
2462 '%s/usr/lib/arm-linux-%s' % (jail, arm_abi),
2463 '%s/lib/arm-linux-%s' % (jail, arm_abi),
2465 LINKFLAGS=['-Wl,-rpath-link=' + jail +
2466 '/lib/arm-linux-' + arm_abi]
2468 env.Prepend(CCFLAGS=['-march=armv7-a',
2469 '-marm', # force arm32
2471 if not env.Bit('android'):
2472 env.Prepend(CCFLAGS=['-isystem', jail + '/usr/include'])
2473 # /usr/lib makes sense for most configuration except this one
2474 # No ARM compatible libs can be found there.
2475 # So this just makes the command lines longer and sometimes results
2476 # in linker warnings referring to this directory.
2477 env.FilterOut(LIBPATH=['/usr/lib'])
2479 # get_plugin_dirname.cc has a dependency on dladdr
2480 env.Append(LIBS=['dl'])
2482 def SetupAndroidEnv(env):
2483 env.FilterOut(CPPDEFINES=[['NACL_ANDROID', '0']])
2484 env.Prepend(CPPDEFINES=[['NACL_ANDROID', '1']])
2485 ndk = os.environ.get('ANDROID_NDK_ROOT')
2486 sdk = os.environ.get('ANDROID_SDK_ROOT')
2488 if env.Bit('build_arm'):
2489 ndk_target = 'arm-linux-androideabi'
2490 ndk_tctarget = ndk_target
2492 libarch = 'armeabi-v7a'
2493 arch_cflags += ['-march=armv7-a', '-mfloat-abi=softfp']
2494 elif env.Bit('build_mips32'):
2495 ndk_target = 'mipsel-linux-android'
2496 ndk_tctarget = ndk_target
2500 ndk_target = 'i686-linux-android'
2501 # x86 toolchain has strange location, not using GNU triplet
2502 ndk_tctarget = 'x86'
2506 if not ndk or not sdk:
2507 print 'Please define ANDROID_NDK_ROOT and ANDROID_SDK_ROOT'
2509 tc = '%s/toolchains/%s-%s/prebuilt/linux-x86/bin/' \
2510 % (ndk, ndk_tctarget, ndk_version)
2511 tc_prefix = '%s/%s-' % (tc, ndk_target)
2512 platform_prefix = '%s/platforms/android-14/arch-%s' % (ndk, arch)
2513 stl_path = '%s/sources/cxx-stl/gnu-libstdc++/%s' % (ndk, ndk_version)
2514 env.Replace(CC=tc_prefix + 'gcc',
2515 CXX=tc_prefix + 'g++',
2516 LD=tc_prefix + 'g++',
2517 EMULATOR=sdk + '/tools/emulator',
2518 LIBPATH=['${LIB_DIR}',
2519 '%s/libs/%s' % (stl_path, libarch),
2520 '%s/usr/lib' % (platform_prefix),
2522 LIBS=['gnustl_static', # Yes, that stdc++.
2527 # Second time, to have mutual libgcc<->libc deps resolved.
2531 env.Append(CCFLAGS=['--sysroot='+ platform_prefix,
2532 '-isystem='+ platform_prefix + '/usr/include',
2535 # Due to bogus warnings on uintptr_t formats.
2538 CXXFLAGS=['-I%s/include' % (stl_path),
2539 '-I%s/libs/%s/include' % (stl_path, libarch),
2543 LINKFLAGS=['-Wl,-rpath-link=' + platform_prefix + '/usr/lib',
2544 '-Wl,-Ttext-segment,0x50000000',
2547 '-L%s/../lib/gcc/%s/%s' \
2548 % (tc, ndk_target, ndk_version),
2549 # Note that we have to use crtbegin_static.o
2550 # if compile -static, and crtbegin_dynamic.o
2551 # otherwise. Also, this apporach skips
2552 # all static initializers invocations.
2553 # TODO(olonho): implement proper static
2554 # initializers solution.
2555 platform_prefix + '/usr/lib/crtbegin_static.o',
2556 platform_prefix + '/usr/lib/crtend_android.o',
2559 # As we want static binary, not PIE.
2560 env.FilterOut(LINKFLAGS=['-pie'])
2563 def SetupLinuxEnvMips(env):
2564 jail = '${SCONSTRUCT_DIR}/toolchain/linux_mips-trusted'
2565 if not platform.machine().startswith('mips'):
2566 # Allow emulation on non-MIPS hosts.
2567 env.Replace(EMULATOR=jail + '/run_under_qemu_mips32')
2568 if env.Bit('built_elsewhere'):
2569 def FakeInstall(dest, source, env):
2570 print 'Not installing', dest
2571 # Replace build commands with no-ops
2572 env.Replace(CC='true', CXX='true', LD='true',
2573 AR='true', RANLIB='true', INSTALL=FakeInstall)
2575 tc_dir = os.path.join(os.getcwd(), 'toolchain', 'linux_mips-trusted',
2577 if not which(os.path.join(tc_dir, 'mipsel-linux-gnu-gcc')):
2578 print ("\nERRROR: MIPS trusted TC is not installed - try running:\n"
2579 "tools/trusted_cross_toolchains/trusted-toolchain-creator"
2580 ".mipsel.squeeze.sh nacl_sdk")
2582 env.Replace(CC=os.path.join(tc_dir, 'mipsel-linux-gnu-gcc'),
2583 CXX=os.path.join(tc_dir, 'mipsel-linux-gnu-g++'),
2584 LD=os.path.join(tc_dir, 'mipsel-linux-gnu-ld'),
2586 LIBPATH=['${LIB_DIR}',
2587 jail + '/sysroot/usr/lib'],
2589 os.path.join(jail, 'ld_script_mips_trusted')]
2592 env.Append(LIBS=['rt', 'dl', 'pthread'],
2593 CCFLAGS=['-march=mips32r2'])
2597 linux_env = MakeUnixLikeEnv().Clone(
2598 BUILD_TYPE = '${OPTIMIZATION_LEVEL}-linux',
2599 BUILD_TYPE_DESCRIPTION = 'Linux ${OPTIMIZATION_LEVEL} build',
2600 tools = ['target_platform_linux'],
2601 # TODO(bradnelson): this should really be able to live in unix_like_env
2602 # but can't due to what the target_platform_x module is
2607 # Prepend so we can disable warnings via Append
2609 CPPDEFINES = [['NACL_WINDOWS', '0'],
2611 ['NACL_LINUX', '1'],
2612 ['NACL_ANDROID', '0'],
2613 ['_BSD_SOURCE', '1'],
2614 ['_POSIX_C_SOURCE', '199506'],
2615 ['_XOPEN_SOURCE', '600'],
2616 ['_GNU_SOURCE', '1'],
2617 ['_LARGEFILE64_SOURCE', '1'],
2622 if linux_env.Bit('build_x86_32'):
2625 LINKFLAGS = ['-m32'],
2627 elif linux_env.Bit('build_x86_64'):
2630 LINKFLAGS = ['-m64'],
2632 elif linux_env.Bit('build_arm'):
2633 SetupLinuxEnvArm(linux_env)
2634 elif linux_env.Bit('build_mips32'):
2635 SetupLinuxEnvMips(linux_env)
2637 Banner('Strange platform: %s' % env.GetPlatform())
2639 # These are desireable options for every Linux platform:
2640 # _FORTIFY_SOURCE: general paranoia "hardening" option for library functions
2641 # -fPIE/-pie: create a position-independent executable
2642 # relro/now: "hardening" options for linking
2643 # noexecstack: ensure that the executable does not get a PT_GNU_STACK
2644 # header that causes the kernel to set the READ_IMPLIES_EXEC
2645 # personality flag, which disables NX page protection.
2647 CPPDEFINES=[['-D_FORTIFY_SOURCE', '2']],
2648 LINKFLAGS=['-pie', '-Wl,-z,relro', '-Wl,-z,now', '-Wl,-z,noexecstack'],
2650 # The ARM toolchain has a linker that doesn't handle the code its
2651 # compiler generates under -fPIE.
2652 if linux_env.Bit('build_arm') or linux_env.Bit('build_mips32'):
2653 linux_env.Prepend(CCFLAGS=['-fPIC'])
2654 # TODO(mcgrathr): Temporarily punt _FORTIFY_SOURCE for ARM because
2655 # it causes a libc dependency newer than the old bots have installed.
2656 linux_env.FilterOut(CPPDEFINES=[['-D_FORTIFY_SOURCE', '2']])
2658 linux_env.Prepend(CCFLAGS=['-fPIE'])
2660 # We always want to use the same flags for .S as for .c because
2661 # code-generation flags affect the predefines we might test there.
2662 linux_env.Replace(ASFLAGS=['${CCFLAGS}'])
2664 if linux_env.Bit('android'):
2665 SetupAndroidEnv(linux_env)
2669 (linux_debug_env, linux_optimized_env) = \
2670 GenerateOptimizationLevels(MakeLinuxEnv())
2673 # Do this before the site_scons/site_tools/naclsdk.py stuff to pass it along.
2674 pre_base_env.Append(
2675 PNACL_BCLDFLAGS = ARGUMENTS.get('pnacl_bcldflags', '').split(':'))
2678 # The nacl_env is used to build native_client modules
2679 # using a special tool chain which produces platform
2680 # independent binaries
2681 # NOTE: this loads stuff from: site_scons/site_tools/naclsdk.py
2682 nacl_env = MakeArchSpecificEnv().Clone(
2683 tools = ['naclsdk'],
2684 NACL_BUILD_FAMILY = 'UNTRUSTED',
2685 BUILD_TYPE = 'nacl',
2686 BUILD_TYPE_DESCRIPTION = 'NaCl module build',
2690 # ${SOURCE_ROOT} for #include <ppapi/...>
2696 EXTRA_CXXFLAGS = [],
2698 EXTRA_LINKFLAGS = ARGUMENTS.get('nacl_linkflags', '').split(':'),
2700 # always optimize binaries
2703 '-fomit-frame-pointer',
2706 '-fdiagnostics-show-option',
2711 CFLAGS = ['-std=gnu99',
2713 CXXFLAGS = ['-std=gnu++98',
2717 # This magic is copied from scons-2.0.1/engine/SCons/Defaults.py
2718 # where this pattern is used for _LIBDIRFLAGS, which produces -L
2719 # switches. Here we are producing a -Wl,-rpath-link,DIR for each
2720 # element of LIBPATH, i.e. for each -LDIR produced.
2721 RPATH_LINK_FLAGS = '$( ${_concat(RPATHLINKPREFIX, LIBPATH, RPATHLINKSUFFIX,'
2722 '__env__, RDirs, TARGET, SOURCE)} $)',
2723 RPATHLINKPREFIX = '-Wl,-rpath-link,',
2724 RPATHLINKSUFFIX = '',
2727 LINKFLAGS = ['${RPATH_LINK_FLAGS}'],
2729 # These are settings for in-tree, non-browser tests to use.
2730 # They use libraries that circumvent the IRT-based implementations
2731 # in the public libraries.
2732 NONIRT_LIBS = ['nacl_sys_private'],
2733 PTHREAD_LIBS = ['pthread_private'],
2734 DYNCODE_LIBS = ['nacl_dyncode_private'],
2735 EXCEPTION_LIBS = ['nacl_exception_private'],
2736 LIST_MAPPINGS_LIBS = ['nacl_list_mappings_private'],
2739 def IsNewLinker(env):
2740 """Return True if using a new-style linker with the new-style layout.
2741 That means the linker supports the -Trodata-segment switch."""
2742 return env.Bit('target_arm') or env.Bit('bitcode')
2744 nacl_env.AddMethod(IsNewLinker)
2746 def UnderWindowsCoverage(env):
2747 """Return True if using running on coverage under windows."""
2748 if 'TRUSTED_ENV' not in env:
2750 return env['TRUSTED_ENV'].Bit('coverage_enabled') and env.Bit('host_windows')
2752 nacl_env.AddMethod(UnderWindowsCoverage)
2754 def RodataSwitch(env, value, via_compiler=True):
2755 """Return string of arguments to place the rodata segment at |value|.
2756 If |via_compiler| is False, this is going directly to the linker, rather
2757 than via the compiler driver."""
2758 if env.IsNewLinker():
2759 args = ['-Trodata-segment=' + value]
2761 # With the --build-id option (which the compiler will pass, but pass it
2762 # here to be doubly sure), the rodata segment starts with the
2763 # .note.gnu.build-id section; without --build-id it starts with .rodata.
2765 args = ['--build-id', '--section-start', '.note.gnu.build-id=' + value]
2767 # If file is linked directly then it's probably some kind of low-level
2768 # test so don't use build id and move .rodata to the desired position.
2769 args = ['--section-start', '.rodata=' + value]
2771 if env.Bit('bitcode'):
2772 # The -Wn flag passes arguments to PNaCl's native linker (as opposed
2773 # to the bitcode linker, which gets the -Wl arguments)
2774 args = ','.join(['-Wn'] + args)
2776 args = ','.join(['-Wl'] + args)
2778 args = ' '.join(args)
2781 nacl_env.AddMethod(RodataSwitch)
2783 def TextSwitch(env, value):
2784 """ Return a string of arguments to place the text segment at |value|.
2785 Assume the string is going to the compiler driver, rather than directly
2787 # TODO(dschuff): just replace uses of this with the flag directly.
2788 return '-Wl,-Ttext-segment=' + value
2790 nacl_env.AddMethod(TextSwitch)
2792 def AllowNonStableBitcode(env):
2793 """ This modifies the environment to allow features that aren't part
2794 of PNaCl's stable ABI. If tests using these features should be
2795 skipped entirely, this returns False. Otherwise, on success, it
2798 if env.Bit('bitcode'):
2799 env.SetBits('nonstable_bitcode')
2800 return not env.Bit('skip_nonstable_bitcode')
2802 nacl_env.AddMethod(AllowNonStableBitcode)
2805 def AllowInlineAssembly(env):
2806 """ This modifies the environment to allow inline assembly in
2807 untrusted code. If the environment cannot be modified to allow
2808 inline assembly, it returns False. Otherwise, on success, it
2811 if env.Bit('bitcode'):
2812 # For each architecture, we only attempt to make our inline
2813 # assembly code work with one untrusted-code toolchain. For x86,
2814 # we target GCC, but not PNaCl/Clang, because the latter's
2815 # assembly support has various quirks that we don't want to have
2816 # to debug. For ARM, we target PNaCl/Clang, because that is the
2817 # only current ARM toolchain. One day, we will have an ARM GCC
2818 # toolchain, and we will no longer need to use inline assembly
2819 # with PNaCl/Clang at all.
2820 if not (env.Bit('target_arm') or env.Bit('target_mips32')):
2822 # Inline assembly does not work in pexes.
2823 if env.Bit('pnacl_generate_pexe'):
2825 env.AddBiasForPNaCl()
2826 env.PNaClForceNative()
2829 nacl_env.AddMethod(AllowInlineAssembly)
2832 # TODO(mseaborn): Enable this unconditionally once the C code on the
2833 # Chromium side compiles successfully with this warning.
2834 if not enable_chrome:
2835 nacl_env.Append(CFLAGS=['-Wstrict-prototypes'])
2837 if nacl_env.Bit('target_arm') and not nacl_env.Bit('bitcode'):
2838 # arm-nacl-gcc is based on GCC>=4.7, where -Wall includes this new warning.
2839 # The COMPILE_ASSERT macro in base/basictypes.h and
2840 # gpu/command_buffer/common/types.h triggers this warning and it's proven too
2841 # painful to find a formulation that doesn't and also doesn't break any of
2842 # the other compilers.
2843 # TODO(mcgrathr): Get the chromium code cleaned up so it doesn't trigger this
2844 # warning one day, perhaps by just compiling with -std=c++0x and
2845 # using static_assert.
2846 # See https://code.google.com/p/chromium/issues/detail?id=132339
2847 nacl_env.Append(CCFLAGS=['-Wno-unused-local-typedefs'])
2849 # This is the address at which a user executable is expected to place its
2850 # data segment in order to be compatible with the integrated runtime (IRT)
2851 # library. This address should not be changed lightly.
2852 irt_compatible_rodata_addr = 0x10000000
2853 # This is the address at which the IRT's own code will be located.
2854 # It must be below irt_compatible_rodata and leave enough space for
2855 # the code segment of the IRT. It should be as close as possible to
2856 # irt_compatible_rodata so as to leave the maximum contiguous area
2857 # available for the dynamic code loading area that falls below it.
2858 # This can be adjusted as necessary for the actual size of the IRT code.
2859 irt_code_addr = irt_compatible_rodata_addr - (6 << 20) # max 6M IRT code
2860 # This is the address at which the IRT's own data will be located. The
2861 # 32-bit sandboxes limit the address space to 1GB; the initial thread's
2862 # stack sits at the top of the address space and extends down for
2863 # NACL_DEFAULT_STACK_MAX (src/trusted/service_runtime/sel_ldr.h) below.
2864 # So this must be below there, and leave enough space for the IRT's own
2865 # data segment. It should be as high as possible so as to leave the
2866 # maximum contiguous area available for the user's data and break below.
2867 # This can be adjusted as necessary for the actual size of the IRT data
2868 # (that is RODATA, rounded up to 64k, plus writable data).
2869 # 1G (address space) - 16M (NACL_DEFAULT_STACK_MAX) - 1MB (IRT rodata+data)
2870 irt_data_addr = (1 << 30) - (16 << 20) - (1 << 20)
2873 IRT_DATA_REGION_START = '%#.8x' % irt_compatible_rodata_addr,
2874 # Load addresses of the IRT's code and data segments.
2875 IRT_BLOB_CODE_START = '%#.8x' % irt_code_addr,
2876 IRT_BLOB_DATA_START = '%#.8x' % irt_data_addr,
2879 def TestsUsePublicListMappingsLib(env):
2880 """Use the public list_mappings library for in-tree tests."""
2881 env.Replace(LIST_MAPPINGS_LIBS=['nacl_list_mappings'])
2883 def TestsUsePublicLibs(env):
2884 """Change the environment so it uses public libraries for in-tree tests."""
2885 env.Replace(NONIRT_LIBS=[],
2886 PTHREAD_LIBS=['pthread'],
2887 DYNCODE_LIBS=['nacl_dyncode', 'nacl'],
2888 EXCEPTION_LIBS=['nacl_exception', 'nacl'])
2890 # glibc is incompatible with libpthread_private and libnacl_sys_private.
2891 if nacl_env.Bit('nacl_glibc'):
2892 nacl_env.Replace(NONIRT_LIBS=[],
2893 PTHREAD_LIBS=['pthread'])
2895 # These add on to those set in pre_base_env, above.
2898 # This ensures that UINT32_MAX gets defined.
2899 ['__STDC_LIMIT_MACROS', '1'],
2900 # This ensures that PRId64 etc. get defined.
2901 ['__STDC_FORMAT_MACROS', '1'],
2902 # _GNU_SOURCE ensures that strtof() gets declared.
2904 # strdup, and other common stuff
2905 ['_BSD_SOURCE', '1'],
2906 ['_POSIX_C_SOURCE', '199506'],
2907 ['_XOPEN_SOURCE', '600'],
2909 ['DYNAMIC_ANNOTATIONS_ENABLED', '1' ],
2910 ['DYNAMIC_ANNOTATIONS_PREFIX', 'NACL_' ],
2912 ['NACL_WINDOWS', '0'],
2914 ['NACL_LINUX', '0'],
2915 ['NACL_ANDROID', '0'],
2919 def FixWindowsAssembler(env):
2920 if env.Bit('host_windows'):
2921 # NOTE: This is needed because Windows builds are case-insensitive.
2922 # Without this we use nacl-as, which doesn't handle include directives, etc.
2923 env.Replace(ASCOM='${CCCOM}')
2925 FixWindowsAssembler(nacl_env)
2927 # Look in the local include and lib directories before the toolchain's.
2928 nacl_env['INCLUDE_DIR'] = '${TARGET_ROOT}/include'
2929 # Remove the default $LIB_DIR element so that we prepend it without duplication.
2930 # Using PrependUnique alone would let it stay last, where we want it first.
2931 nacl_env.FilterOut(LIBPATH=['${LIB_DIR}'])
2932 nacl_env.PrependUnique(
2933 CPPPATH = ['${INCLUDE_DIR}'],
2934 LIBPATH = ['${LIB_DIR}'],
2937 if nacl_env.Bit('bitcode'):
2938 # passing -O when linking requests LTO, which does additional global
2939 # optimizations at link time
2940 nacl_env.Append(LINKFLAGS=['-O3'])
2941 if not nacl_env.Bit('nacl_glibc'):
2942 nacl_env.Append(LINKFLAGS=['-static'])
2944 if nacl_env.Bit('translate_fast'):
2945 nacl_env.Append(LINKFLAGS=['-Xlinker', '-translate-fast'])
2946 nacl_env.Append(TRANSLATEFLAGS=['-translate-fast'])
2948 # With pnacl's clang base/ code uses the "override" keyword.
2949 nacl_env.Append(CXXFLAGS=['-Wno-c++11-extensions'])
2950 # Allow extraneous semicolons. (Until these are removed.)
2951 # http://code.google.com/p/nativeclient/issues/detail?id=2861
2952 nacl_env.Append(CCFLAGS=['-Wno-extra-semi'])
2953 # Allow unused private fields. (Until these are removed.)
2954 # http://code.google.com/p/nativeclient/issues/detail?id=2861
2955 nacl_env.Append(CCFLAGS=['-Wno-unused-private-field'])
2957 # We use a special environment for building the IRT image because it must
2958 # always use the newlib toolchain, regardless of --nacl_glibc. We clone
2959 # it from nacl_env here, before too much other cruft has been added.
2960 # We do some more magic below to instantiate it the way we need it.
2961 nacl_irt_env = nacl_env.Clone(
2962 BUILD_TYPE = 'nacl_irt',
2963 BUILD_TYPE_DESCRIPTION = 'NaCl IRT build',
2964 NACL_BUILD_FAMILY = 'UNTRUSTED_IRT',
2967 # Provide access to the IRT build environment from the default environment
2968 # which is needed when compiling custom IRT for testing purposes.
2969 nacl_env['NACL_IRT_ENV'] = nacl_irt_env
2971 # Since we don't build src/untrusted/pthread/nacl.scons in
2972 # nacl_irt_env, we must tell the IRT how to find the pthread.h header.
2973 nacl_irt_env.Append(CPPPATH='${MAIN_DIR}/src/untrusted/pthread')
2975 # Map certain flag bits to suffices on the build output. This needs to
2976 # happen pretty early, because it affects any concretized directory names.
2977 target_variant_map = [
2978 ('bitcode', 'pnacl'),
2979 ('translate_fast', 'fast'),
2980 ('nacl_pic', 'pic'),
2981 ('use_sandboxed_translator', 'sbtc'),
2982 ('nacl_glibc', 'glibc'),
2983 ('pnacl_generate_pexe', 'pexe'),
2985 for variant_bit, variant_suffix in target_variant_map:
2986 if nacl_env.Bit(variant_bit):
2987 nacl_env['TARGET_VARIANT'] += '-' + variant_suffix
2989 if nacl_env.Bit('bitcode'):
2990 nacl_env['TARGET_VARIANT'] += '-clang'
2992 nacl_env.Replace(TESTRUNNER_LIBS=['testrunner'])
2993 # TODO(mseaborn): Drop this once chrome side has inlined this.
2994 nacl_env.Replace(PPAPI_LIBS=['ppapi'])
2996 # TODO(mseaborn): Make nacl-glibc-based static linking work with just
2997 # "-static", without specifying a linker script.
2998 # See http://code.google.com/p/nativeclient/issues/detail?id=1298
2999 def GetLinkerScriptBaseName(env):
3000 if env.Bit('build_x86_64'):
3005 if (nacl_env.Bit('nacl_glibc') and
3006 nacl_env.Bit('nacl_static_link')):
3007 if nacl_env.IsNewLinker():
3008 nacl_env.Append(LINKFLAGS=['-static'])
3010 # The "-lc" is necessary because libgcc_eh depends on libc but for
3011 # some reason nacl-gcc is not linking with "--start-group/--end-group".
3012 nacl_env.Append(LINKFLAGS=[
3014 '-T', 'ldscripts/%s.x.static' % GetLinkerScriptBaseName(nacl_env),
3017 if nacl_env.Bit('running_on_valgrind'):
3018 nacl_env.Append(CCFLAGS = ['-g', '-Wno-overlength-strings',
3019 '-fno-optimize-sibling-calls'],
3020 CPPDEFINES = [['DYNAMIC_ANNOTATIONS_ENABLED', '1' ],
3021 ['DYNAMIC_ANNOTATIONS_PREFIX', 'NACL_' ]])
3022 # With GLibC, libvalgrind.so is preloaded at runtime.
3023 # With Newlib, it has to be linked in.
3024 if not nacl_env.Bit('nacl_glibc'):
3025 nacl_env.Append(LINKFLAGS = ['-Wl,-u,have_nacl_valgrind_interceptors'],
3026 LIBS = ['valgrind'])
3028 environment_list.append(nacl_env)
3030 if not nacl_env.Bit('nacl_glibc'):
3031 # These are all specific to nacl-newlib so we do not include them
3032 # when building against nacl-glibc. The functionality of
3033 # pthread/startup/stubs/nosys is provided by glibc. The valgrind
3034 # code currently assumes nc_threads.
3036 BUILD_SCONSCRIPTS = [
3037 #### ALPHABETICALLY SORTED ####
3038 'src/untrusted/pthread/nacl.scons',
3039 'src/untrusted/stubs/nacl.scons',
3040 'src/untrusted/nosys/nacl.scons',
3041 #### ALPHABETICALLY SORTED ####
3044 BUILD_SCONSCRIPTS = [
3045 #### ALPHABETICALLY SORTED ####
3046 'src/shared/gio/nacl.scons',
3047 'src/shared/imc/nacl.scons',
3048 'src/shared/ldr/nacl.scons',
3049 'src/shared/platform/nacl.scons',
3050 'src/shared/srpc/nacl.scons',
3051 'src/trusted/service_runtime/nacl.scons',
3052 'src/trusted/validator_x86/nacl.scons',
3053 'src/trusted/weak_ref/nacl.scons',
3054 'src/untrusted/crash_dump/nacl.scons',
3055 'src/untrusted/minidump_generator/nacl.scons',
3056 'src/untrusted/nacl/nacl.scons',
3057 'src/untrusted/valgrind/nacl.scons',
3058 #### ALPHABETICALLY SORTED ####
3060 nacl_env.AddChromeFilesFromGroup('untrusted_scons_files')
3062 # These are tests that are worthwhile to run in IRT variant only.
3064 #### ALPHABETICALLY SORTED ####
3065 'tests/irt/nacl.scons',
3066 'tests/irt_compatibility/nacl.scons',
3067 'tests/random/nacl.scons',
3068 'tests/sbrk/nacl.scons',
3069 'tests/translator_size_limits/nacl.scons',
3072 # These are tests that are worthwhile to run in both IRT and non-IRT variants.
3073 # The nacl_irt_test mode runs them in the IRT variants.
3074 irt_variant_tests = [
3075 #### ALPHABETICALLY SORTED ####
3076 'tests/app_lib/nacl.scons',
3077 'tests/bigalloc/nacl.scons',
3078 'tests/bundle_size/nacl.scons',
3079 'tests/callingconv/nacl.scons',
3080 'tests/callingconv_ppapi/nacl.scons',
3081 'tests/callingconv_case_by_case/nacl.scons',
3082 'tests/clock/nacl.scons',
3083 'tests/common/nacl.scons',
3084 'tests/compiler_thread_suspension/nacl.scons',
3085 'tests/computed_gotos/nacl.scons',
3086 'tests/data_below_data_start/nacl.scons',
3087 'tests/data_not_executable/nacl.scons',
3088 'tests/dup/nacl.scons',
3089 'tests/dynamic_code_loading/nacl.scons',
3090 'tests/dynamic_linking/nacl.scons',
3091 'tests/egyptian_cotton/nacl.scons',
3092 'tests/environment_variables/nacl.scons',
3093 'tests/exception_test/nacl.scons',
3094 'tests/fib/nacl.scons',
3095 'tests/file/nacl.scons',
3096 'tests/fixedfeaturecpu/nacl.scons',
3097 'tests/futexes/nacl.scons',
3098 'tests/gc_instrumentation/nacl.scons',
3099 'tests/gdb/nacl.scons',
3100 'tests/glibc_file64_test/nacl.scons',
3101 'tests/glibc_static_test/nacl.scons',
3102 'tests/glibc_syscall_wrappers/nacl.scons',
3103 'tests/glibc_socket_wrappers/nacl.scons',
3104 'tests/hello_world/nacl.scons',
3105 'tests/imc_shm_mmap/nacl.scons',
3106 'tests/infoleak/nacl.scons',
3107 'tests/libc/nacl.scons',
3108 'tests/libc_free_hello_world/nacl.scons',
3109 'tests/list_mappings/nacl.scons',
3110 'tests/longjmp/nacl.scons',
3111 'tests/loop/nacl.scons',
3112 'tests/mandel/nacl.scons',
3113 'tests/manifest_file/nacl.scons',
3114 'tests/math/nacl.scons',
3115 'tests/memcheck_test/nacl.scons',
3116 'tests/mmap/nacl.scons',
3117 'tests/mmap_main_nexe/nacl.scons',
3118 'tests/mmap_prot_exec/nacl.scons',
3119 'tests/mmap_race_protect/nacl.scons',
3120 'tests/nacl_log/nacl.scons',
3121 'tests/nameservice/nacl.scons',
3122 'tests/nanosleep/nacl.scons',
3123 'tests/noop/nacl.scons',
3124 'tests/nrd_xfer/nacl.scons',
3125 'tests/nthread_nice/nacl.scons',
3126 'tests/null/nacl.scons',
3127 'tests/nullptr/nacl.scons',
3128 'tests/pagesize/nacl.scons',
3129 'tests/performance/nacl.scons',
3130 'tests/pnacl_abi/nacl.scons',
3131 'tests/pnacl_native_objects/nacl.scons',
3132 'tests/redir/nacl.scons',
3133 'tests/rodata_not_writable/nacl.scons',
3134 'tests/sel_ldr/nacl.scons',
3135 'tests/sel_ldr_seccomp/nacl.scons',
3136 'tests/sel_main_chrome/nacl.scons',
3137 'tests/signal_handler/nacl.scons',
3138 'tests/sleep/nacl.scons',
3139 'tests/srpc/nacl.scons',
3140 'tests/srpc_hw/nacl.scons',
3141 'tests/srpc_message/nacl.scons',
3142 'tests/stack_alignment/nacl.scons',
3143 'tests/stubout_mode/nacl.scons',
3144 'tests/subprocess/nacl.scons',
3145 'tests/sysbasic/nacl.scons',
3146 'tests/syscall_return_regs/nacl.scons',
3147 'tests/syscall_return_sandboxing/nacl.scons',
3148 'tests/syscalls/nacl.scons',
3149 'tests/thread_capture/nacl.scons',
3150 'tests/threads/nacl.scons',
3151 'tests/time/nacl.scons',
3152 'tests/tls/nacl.scons',
3153 'tests/tls_perf/nacl.scons',
3154 'tests/tls_segment_x86_32/nacl.scons',
3155 'tests/toolchain/nacl.scons',
3156 'tests/toolchain/arm/nacl.scons',
3157 'tests/toolchain/mips/nacl.scons',
3158 'tests/unittests/shared/platform/nacl.scons',
3159 'tests/untrusted_check/nacl.scons',
3160 'tests/unwind_restores_regs/nacl.scons',
3161 #### ALPHABETICALLY SORTED ####
3162 # NOTE: The following tests are really IRT-only tests, but they
3163 # are in this category so that they can generate libraries (which
3164 # works in nacl_env but not in nacl_irt_test_env) while also
3165 # adding tests to nacl_irt_test_env.
3166 'tests/inbrowser_test_runner/nacl.scons',
3167 'tests/untrusted_crash_dump/nacl.scons',
3168 'tests/untrusted_minidump/nacl.scons',
3171 # These are tests that are NOT worthwhile to run in an IRT variant.
3172 # In some cases, that's because they are browser tests which always
3173 # use the IRT. In others, it's because they are special-case tests
3174 # that are incompatible with having an IRT loaded.
3175 nonvariant_tests = [
3176 #### ALPHABETICALLY SORTED ####
3177 'tests/barebones/nacl.scons',
3178 'tests/chrome_extension/nacl.scons',
3179 'tests/custom_desc/nacl.scons',
3180 'tests/debug_stub/nacl.scons',
3181 'tests/faulted_thread_queue/nacl.scons',
3182 'tests/imc_sockets/nacl.scons',
3183 'tests/minnacl/nacl.scons',
3184 'tests/multiple_sandboxes/nacl.scons',
3185 # Potential issue with running them:
3186 # http://code.google.com/p/nativeclient/issues/detail?id=2092
3187 # See also the comment in "buildbot/buildbot_standard.py"
3188 'tests/pnacl_shared_lib_test/nacl.scons',
3189 'tests/signal_handler_single_step/nacl.scons',
3190 'tests/thread_suspension/nacl.scons',
3191 'tests/trusted_crash/crash_in_syscall/nacl.scons',
3192 'tests/trusted_crash/osx_crash_filter/nacl.scons',
3193 'tests/trusted_crash/osx_crash_forwarding/nacl.scons',
3194 'tests/unittests/shared/imc/nacl.scons',
3195 'tests/unittests/shared/srpc/nacl.scons',
3196 #### ALPHABETICALLY SORTED ####
3199 nacl_env.Append(BUILD_SCONSCRIPTS=nonvariant_tests)
3200 nacl_env.AddChromeFilesFromGroup('nonvariant_test_scons_files')
3201 nacl_env.Append(BUILD_SCONSCRIPTS=irt_variant_tests)
3202 nacl_env.AddChromeFilesFromGroup('irt_variant_test_scons_files')
3204 # Defines TESTS_TO_RUN_INBROWSER.
3205 SConscript('tests/inbrowser_test_runner/selection.scons',
3206 exports=['nacl_env'])
3208 # Possibly install a toolchain by downloading it
3209 # TODO: explore using a less heavy weight mechanism
3210 # NOTE: this uses stuff from: site_scons/site_tools/naclsdk.py
3213 SCons.Script.AddOption('--download',
3217 action='store_true',
3218 help='deprecated - allow tools to download')
3220 if nacl_env.GetOption('download'):
3221 print '@@@@ --download is deprecated, use gclient runhooks --force'
3222 nacl_sync_env = nacl_env.Clone()
3223 nacl_sync_env['ENV'] = os.environ
3224 nacl_sync_env.Execute('gclient runhooks --force')
3227 def NaClSharedLibrary(env, lib_name, *args, **kwargs):
3228 env_shared = env.Clone(COMPONENT_STATIC=False)
3229 soname = SCons.Util.adjustixes(lib_name, 'lib', '.so')
3230 env_shared.AppendUnique(SHLINKFLAGS=['-Wl,-soname,%s' % (soname)])
3231 return env_shared.ComponentLibrary(lib_name, *args, **kwargs)
3233 nacl_env.AddMethod(NaClSharedLibrary)
3235 def NaClSdkLibrary(env, lib_name, *args, **kwargs):
3236 n = [env.ComponentLibrary(lib_name, *args, **kwargs)]
3237 if not env.Bit('nacl_disable_shared'):
3238 n.append(env.NaClSharedLibrary(lib_name, *args, **kwargs))
3241 nacl_env.AddMethod(NaClSdkLibrary)
3244 # Special environment for untrusted test binaries that use raw syscalls
3245 def RawSyscallObjects(env, sources):
3246 raw_syscall_env = env.Clone()
3247 raw_syscall_env.Append(
3249 ['USE_RAW_SYSCALLS', '1'],
3250 ['NACL_BUILD_ARCH', '${BUILD_ARCHITECTURE}' ],
3251 ['NACL_BUILD_SUBARCH', '${BUILD_SUBARCH}' ],
3252 ['NACL_TARGET_ARCH', '${TARGET_ARCHITECTURE}' ],
3253 ['NACL_TARGET_SUBARCH', '${TARGET_SUBARCH}' ],
3257 for source_file in sources:
3258 target_name = 'raw_' + os.path.basename(source_file).rstrip('.c')
3259 object = raw_syscall_env.ComponentObject(target_name,
3261 objects.append(object)
3264 nacl_env.AddMethod(RawSyscallObjects)
3267 # The IRT-building environment was cloned from nacl_env, but it should
3268 # ignore the --nacl_glibc, nacl_pic=1 and bitcode=1 switches.
3269 # We have to reinstantiate the naclsdk.py magic after clearing those flags,
3270 # so it regenerates the tool paths right.
3271 # TODO(mcgrathr,bradnelson): could get cleaner if naclsdk.py got folded back in.
3272 nacl_irt_env.ClearBits('nacl_glibc')
3273 nacl_irt_env.ClearBits('nacl_pic')
3274 # We build the IRT using the nnacl TC even when the pnacl TC is used otherwise.
3275 if nacl_irt_env.Bit('target_mips32') or nacl_irt_env.Bit('target_x86_64'):
3276 nacl_irt_env.SetBits('bitcode')
3278 nacl_irt_env.ClearBits('bitcode')
3279 nacl_irt_env.ClearBits('pnacl_generate_pexe')
3280 nacl_irt_env.ClearBits('use_sandboxed_translator')
3281 nacl_irt_env.Tool('naclsdk')
3282 # These are unfortunately clobbered by running Tool, which
3283 # we needed to do to get the destination directory reset.
3284 # We want all the same values from nacl_env.
3285 nacl_irt_env.Replace(EXTRA_CFLAGS=nacl_env['EXTRA_CFLAGS'],
3286 EXTRA_CXXFLAGS=nacl_env['EXTRA_CXXFLAGS'],
3287 CCFLAGS=nacl_env['CCFLAGS'],
3288 CFLAGS=nacl_env['CFLAGS'],
3289 CXXFLAGS=nacl_env['CXXFLAGS'])
3290 FixWindowsAssembler(nacl_irt_env)
3291 # Make it find the libraries it builds, rather than the SDK ones.
3292 nacl_irt_env.Replace(LIBPATH='${LIB_DIR}')
3294 if nacl_irt_env.Bit('bitcode'):
3295 if nacl_irt_env.Bit('target_x86_64'):
3296 nacl_irt_env.Append(CCFLAGS=['--target=x86_64-nacl'])
3297 nacl_irt_env.Append(LINKFLAGS=['--target=x86_64-nacl',
3298 '--pnacl-allow-translate',
3301 # All IRT code must avoid direct use of the TLS ABI register, which
3302 # is reserved for user TLS. Instead, ensure all TLS accesses use a
3303 # call to __nacl_read_tp, which the IRT code overrides to segregate
3304 # IRT-private TLS from user TLS.
3305 if nacl_irt_env.Bit('bitcode'):
3306 nacl_irt_env.Append(LINKFLAGS=['--pnacl-allow-native', '-Wt,-mtls-use-call'])
3307 elif nacl_irt_env.Bit('target_arm'):
3308 nacl_irt_env.Append(CCFLAGS=['-mtp=soft'])
3310 nacl_irt_env.Append(CCFLAGS=['-mtls-use-call'])
3311 # A debugger should be able to unwind IRT call frames. As the IRT is compiled
3312 # with high level of optimizations and without debug info, compiler is requested
3313 # to generate unwind tables explicitly. This is the default behavior on x86-64
3314 # and when compiling C++ with exceptions enabled, the change is for the benefit
3316 nacl_irt_env.Append(CCFLAGS=['-fasynchronous-unwind-tables'])
3318 # TODO(mcgrathr): Clean up uses of these methods.
3319 def AddLibraryDummy(env, nodes):
3321 nacl_irt_env.AddMethod(AddLibraryDummy, 'AddLibraryToSdk')
3323 def AddObjectInternal(env, nodes):
3324 return env.Replicate('${LIB_DIR}', nodes)
3325 nacl_env.AddMethod(AddObjectInternal, 'AddObjectToSdk')
3326 nacl_irt_env.AddMethod(AddObjectInternal, 'AddObjectToSdk')
3328 def IrtNaClSdkLibrary(env, lib_name, *args, **kwargs):
3329 env.ComponentLibrary(lib_name, *args, **kwargs)
3330 nacl_irt_env.AddMethod(IrtNaClSdkLibrary, 'NaClSdkLibrary')
3332 nacl_irt_env.AddMethod(SDKInstallBin)
3334 # Populate the internal include directory when AddHeaderToSdk
3335 # is used inside nacl_env.
3336 def AddHeaderInternal(env, nodes, subdir='nacl'):
3337 dir = '${INCLUDE_DIR}'
3338 if subdir is not None:
3340 n = env.Replicate(dir, nodes)
3343 nacl_irt_env.AddMethod(AddHeaderInternal, 'AddHeaderToSdk')
3345 def PublishHeader(env, nodes, subdir):
3346 if ('install' in COMMAND_LINE_TARGETS or
3347 'install_headers' in COMMAND_LINE_TARGETS):
3348 dir = env.GetAbsDirArg('includedir', 'install_headers')
3349 if subdir is not None:
3351 n = env.Install(dir, nodes)
3352 env.Alias('install', env.Alias('install_headers', n))
3355 def PublishLibrary(env, nodes):
3356 env.Alias('build_lib', nodes)
3358 if ('install' in COMMAND_LINE_TARGETS or
3359 'install_lib' in COMMAND_LINE_TARGETS):
3360 dir = env.GetAbsDirArg('libdir', 'install_lib')
3361 n = env.Install(dir, nodes)
3362 env.Alias('install', env.Alias('install_lib', n))
3365 def NaClAddHeader(env, nodes, subdir='nacl'):
3366 n = AddHeaderInternal(env, nodes, subdir)
3367 PublishHeader(env, n, subdir)
3369 nacl_env.AddMethod(NaClAddHeader, 'AddHeaderToSdk')
3371 def NaClAddLibrary(env, nodes):
3372 nodes = env.Replicate('${LIB_DIR}', nodes)
3373 PublishLibrary(env, nodes)
3375 nacl_env.AddMethod(NaClAddLibrary, 'AddLibraryToSdk')
3377 def NaClAddObject(env, nodes):
3378 lib_nodes = env.Replicate('${LIB_DIR}', nodes)
3379 PublishLibrary(env, lib_nodes)
3381 nacl_env.AddMethod(NaClAddObject, 'AddObjectToSdk')
3383 # We want to do this for nacl_env when not under --nacl_glibc,
3384 # but for nacl_irt_env whether or not under --nacl_glibc, so
3385 # we do it separately for each after making nacl_irt_env and
3386 # clearing its Bit('nacl_glibc').
3387 def AddImplicitLibs(env):
3390 # Require the pnacl_irt_shim for pnacl x86-64 and arm.
3391 # Use -B to have the compiler look for the fresh libpnacl_irt_shim.a.
3392 if ( env.Bit('bitcode') and
3393 (env.Bit('target_x86_64') or env.Bit('target_arm'))
3394 and env['NACL_BUILD_FAMILY'] != 'UNTRUSTED_IRT'):
3395 # Note: without this hack ibpnacl_irt_shim.a will be deleted
3396 # when "built_elsewhere=1"
3397 # Since we force the build in a previous step the dependency
3398 # is not really needed.
3399 # Note: the "precious" mechanism did not work in this case
3400 if not env.Bit('built_elsewhere'):
3401 if env.Bit('enable_chrome_side'):
3402 implicit_libs += ['libpnacl_irt_shim.a']
3404 if not env.Bit('nacl_glibc'):
3405 # These are automatically linked in by the compiler, either directly
3406 # or via the linker script that is -lc. In the non-glibc build, we
3407 # are the ones providing these files, so we need dependencies.
3408 # The ComponentProgram method (site_scons/site_tools/component_builders.py)
3409 # adds dependencies on env['IMPLICIT_LIBS'] if that's set.
3410 if env.Bit('bitcode'):
3411 implicit_libs += ['libnacl.a']
3413 implicit_libs += ['crt1.o',
3417 # TODO(mcgrathr): multilib nonsense defeats -B! figure out a better way.
3418 if env.GetPlatform() == 'x86-32':
3419 implicit_libs.append(os.path.join('32', 'crt1.o'))
3421 if implicit_libs != []:
3422 env['IMPLICIT_LIBS'] = [env.File(os.path.join('${LIB_DIR}', file))
3423 for file in implicit_libs]
3424 # The -B<dir>/ flag is necessary to tell gcc to look for crt[1in].o there.
3425 env.Prepend(LINKFLAGS=['-B${LIB_DIR}/'])
3427 AddImplicitLibs(nacl_env)
3428 AddImplicitLibs(nacl_irt_env)
3430 nacl_irt_env.Append(
3431 BUILD_SCONSCRIPTS = [
3432 'src/shared/gio/nacl.scons',
3433 'src/shared/platform/nacl.scons',
3434 'src/shared/srpc/nacl.scons',
3435 'src/untrusted/irt/nacl.scons',
3436 'src/untrusted/nacl/nacl.scons',
3437 'src/untrusted/stubs/nacl.scons',
3438 'tests/irt_private_pthread/nacl.scons',
3440 nacl_irt_env.AddChromeFilesFromGroup('untrusted_irt_scons_files')
3442 environment_list.append(nacl_irt_env)
3444 # Since browser_tests already use the IRT normally, those are fully covered
3445 # in nacl_env. But the non_browser_tests don't use the IRT in nacl_env.
3446 # We want additional variants of those tests with the IRT, so we make
3447 # another environment and repeat them with that adjustment.
3448 nacl_irt_test_env = nacl_env.Clone(
3449 BUILD_TYPE = 'nacl_irt_test',
3450 BUILD_TYPE_DESCRIPTION = 'NaCl tests build with IRT',
3451 NACL_BUILD_FAMILY = 'UNTRUSTED_IRT_TESTS',
3453 INCLUDE_DIR = nacl_env.Dir('${INCLUDE_DIR}'),
3454 LIB_DIR = nacl_env.Dir('${LIB_DIR}'),
3455 BUILD_SCONSCRIPTS = [],
3457 nacl_irt_test_env.SetBits('tests_use_irt')
3458 if nacl_irt_test_env.Bit('enable_chrome_side'):
3459 nacl_irt_test_env.Replace(TESTRUNNER_LIBS=['testrunner_browser'])
3461 nacl_irt_test_env.Append(BUILD_SCONSCRIPTS=irt_variant_tests)
3462 nacl_irt_test_env.AddChromeFilesFromGroup('irt_variant_test_scons_files')
3463 nacl_irt_test_env.Append(BUILD_SCONSCRIPTS=irt_only_tests)
3464 TestsUsePublicLibs(nacl_irt_test_env)
3465 TestsUsePublicListMappingsLib(nacl_irt_test_env)
3467 # If a tests/.../nacl.scons file builds a library, we will just use
3468 # the one already built in nacl_env instead.
3469 def IrtTestDummyLibrary(*args, **kwargs):
3471 nacl_irt_test_env.AddMethod(IrtTestDummyLibrary, 'ComponentLibrary')
3473 def IrtTestAddNodeToTestSuite(env, node, suite_name, node_name=None,
3474 is_broken=False, is_flaky=False,
3475 disable_irt_suffix=False):
3476 # The disable_irt_suffix argument is there for allowing tests
3477 # defined in nacl_irt_test_env to be part of chrome_browser_tests
3478 # (rather than part of chrome_browser_tests_irt).
3479 # TODO(mseaborn): But really, all of chrome_browser_tests should be
3480 # placed in nacl_irt_test_env rather than in nacl_env.
3481 if not disable_irt_suffix:
3482 if node_name is not None:
3484 suite_name = [name + '_irt' for name in suite_name]
3485 # NOTE: This needs to be called directly to as we're overriding the
3487 return AddNodeToTestSuite(env, node, suite_name, node_name,
3488 is_broken, is_flaky)
3489 nacl_irt_test_env.AddMethod(IrtTestAddNodeToTestSuite, 'AddNodeToTestSuite')
3491 environment_list.append(nacl_irt_test_env)
3494 windows_coverage_env = windows_debug_env.Clone(
3495 tools = ['code_coverage'],
3496 BUILD_TYPE = 'coverage-win',
3497 BUILD_TYPE_DESCRIPTION = 'Windows code coverage build',
3498 # TODO(bradnelson): switch nacl to common testing process so this won't be
3500 MANIFEST_FILE = None,
3501 COVERAGE_ANALYZER_DIR=r'..\third_party\coverage_analyzer\bin',
3502 COVERAGE_ANALYZER='$COVERAGE_ANALYZER_DIR\coverage_analyzer.exe',
3504 # TODO(bradnelson): Switch nacl to common testing process so this won't be
3505 # needed. Ignoring instrumentation failure as that's easier
3506 # than trying to gate out the ones with asm we can't handle.
3507 windows_coverage_env['LINKCOM'] = windows_coverage_env.Action([
3508 windows_coverage_env.get('LINKCOM', []),
3509 '-$COVERAGE_VSINSTR /COVERAGE ${TARGET}'])
3510 windows_coverage_env.Append(LINKFLAGS = ['/NODEFAULTLIB:msvcrt'])
3511 AddDualLibrary(windows_coverage_env)
3512 environment_list.append(windows_coverage_env)
3514 mac_coverage_env = mac_debug_env.Clone(
3515 tools = ['code_coverage'],
3516 BUILD_TYPE = 'coverage-mac',
3517 BUILD_TYPE_DESCRIPTION = 'MacOS code coverage build',
3518 # Strict doesnt't currently work for coverage because the path to gcov is
3519 # magically baked into the compiler.
3520 LIBS_STRICT = False,
3522 AddDualLibrary(mac_coverage_env)
3523 environment_list.append(mac_coverage_env)
3525 linux_coverage_env = linux_debug_env.Clone(
3526 tools = ['code_coverage'],
3527 BUILD_TYPE = 'coverage-linux',
3528 BUILD_TYPE_DESCRIPTION = 'Linux code coverage build',
3529 # Strict doesnt't currently work for coverage because the path to gcov is
3530 # magically baked into the compiler.
3531 LIBS_STRICT = False,
3534 linux_coverage_env.FilterOut(CCFLAGS=['-fPIE'])
3535 linux_coverage_env.Append(CCFLAGS=['-fPIC'])
3537 linux_coverage_env['OPTIONAL_COVERAGE_LIBS'] = '$COVERAGE_LIBS'
3538 AddDualLibrary(linux_coverage_env)
3539 environment_list.append(linux_coverage_env)
3542 # Environment Massaging
3543 RELEVANT_CONFIG = ['NACL_BUILD_FAMILY',
3547 'BUILD_TYPE_DESCRIPTION',
3550 MAYBE_RELEVANT_CONFIG = ['BUILD_OS',
3551 'BUILD_ARCHITECTURE',
3554 'TARGET_ARCHITECTURE',
3558 def DumpCompilerVersion(cc, env):
3560 env.Execute(env.Action('set'))
3561 env.Execute(env.Action('${CC} -v -c'))
3562 env.Execute(env.Action('${CC} -print-search-dirs'))
3563 env.Execute(env.Action('${CC} -print-libgcc-file-name'))
3564 elif cc.startswith('cl'):
3567 p = subprocess.Popen(env.subst('${CC} /V'),
3569 stdout=subprocess.PIPE,
3570 stderr=subprocess.PIPE)
3571 stdout, stderr = p.communicate()
3572 print stderr[0:stderr.find("\r")]
3573 except WindowsError:
3574 # If vcvars was not run before running SCons, we won't be able to find
3575 # the compiler at this point. SCons has built in functions for finding
3576 # the compiler, but they haven't run yet.
3577 print 'Can not find the compiler, assuming SCons will find it later.'
3579 print "UNKNOWN COMPILER"
3582 def SanityCheckEnvironments(all_envs):
3583 # simple completeness check
3584 for env in all_envs:
3585 for tag in RELEVANT_CONFIG:
3586 assert tag in env, repr(tag)
3587 assert env[tag], repr(env[tag])
3590 def LinkTrustedEnv(selected_envs):
3591 # Collect build families and ensure that we have only one env per family.
3593 for env in selected_envs:
3594 family = env['NACL_BUILD_FAMILY']
3595 if family not in family_map:
3596 family_map[family] = env
3598 msg = 'You are using incompatible environments simultaneously\n'
3599 msg += '%s vs %s\n' % (env['BUILD_TYPE'],
3600 family_map[family]['BUILD_TYPE'])
3601 msg += ('Please specfy the exact environments you require, e.g. '
3602 'MODE=dbg-host,nacl')
3603 raise Exception(msg)
3605 # Set TRUSTED_ENV so that tests of untrusted code can locate sel_ldr
3606 # etc. We set this on trusted envs too because some tests on
3607 # trusted envs run sel_ldr (e.g. using checked-in binaries).
3608 if 'TRUSTED' in family_map:
3609 for env in selected_envs:
3610 env['TRUSTED_ENV'] = family_map['TRUSTED']
3611 # Propagate some environment variables from the trusted environment,
3612 # in case some (e.g. Mac's DYLD_LIBRARY_PATH) are necessary for
3613 # running sel_ldr et al in untrusted environments' tests.
3614 for var in env['TRUSTED_ENV'].get('PROPAGATE_ENV', []):
3615 env['ENV'][var] = env['TRUSTED_ENV']['ENV'][var]
3616 if 'TRUSTED' not in family_map or 'UNTRUSTED' not in family_map:
3617 Banner('Warning: "--mode" did not specify both trusted and untrusted '
3618 'build environments. As a result, many tests will not be run.')
3621 def DumpEnvironmentInfo(selected_envs):
3622 if VerboseConfigInfo(pre_base_env):
3623 Banner("The following environments have been configured")
3624 for env in selected_envs:
3625 for tag in RELEVANT_CONFIG:
3626 assert tag in env, repr(tag)
3627 print "%s: %s" % (tag, env.subst(env.get(tag)))
3628 for tag in MAYBE_RELEVANT_CONFIG:
3629 print "%s: %s" % (tag, env.subst(env.get(tag)))
3630 cc = env.subst('${CC}')
3632 asppcom = env.subst('${ASPPCOM}')
3633 print 'ASPPCOM:', asppcom
3634 DumpCompilerVersion(cc, env)
3636 rev_file = 'toolchain/pnacl_linux_x86/REV'
3637 if os.path.exists(rev_file):
3638 for line in open(rev_file).read().split('\n'):
3639 if "Revision:" in line:
3640 print "PNACL : %s" % line
3642 def PnaclSetEmulatorForSandboxedTranslator(selected_envs):
3643 # Slip in emulator flags if necessary, for the sandboxed pnacl translator
3644 # on ARM, once emulator is actually known (vs in naclsdk.py, where it
3645 # is not yet known).
3646 for env in selected_envs:
3647 if (env.Bit('bitcode')
3648 and env.Bit('use_sandboxed_translator')
3649 and env.UsingEmulator()):
3650 # This must modify the LINK command itself, since LINKFLAGS may
3651 # be filtered (e.g., in barebones tests).
3652 env.Append(LINK=' --pnacl-use-emulator')
3653 env.Append(TRANSLATE=' --pnacl-use-emulator')
3656 # Blank out defaults.
3659 # Apply optional supplement if present in the directory tree.
3660 if os.path.exists(pre_base_env.subst('$MAIN_DIR/supplement/supplement.scons')):
3661 SConscript('supplement/supplement.scons', exports=['environment_list'])
3663 # print sytem info (optionally)
3664 if VerboseConfigInfo(pre_base_env):
3665 Banner('SCONS ARGS:' + str(sys.argv))
3666 os.system(pre_base_env.subst('${PYTHON} tools/sysinfo.py'))
3670 SanityCheckEnvironments(environment_list)
3671 selected_envs = FilterEnvironments(environment_list)
3673 # If we are building nacl, build nacl_irt too. This works around it being
3674 # a separate mode due to the vagaries of scons when we'd really rather it
3675 # not be, while not requiring that every bot command line using --mode be
3676 # changed to list '...,nacl,nacl_irt' explicitly.
3677 if nacl_env in selected_envs:
3678 selected_envs.append(nacl_irt_env)
3680 # The nacl_irt_test_env requires nacl_env to build things correctly.
3681 if nacl_irt_test_env in selected_envs and nacl_env not in selected_envs:
3682 selected_envs.append(nacl_env)
3685 DumpEnvironmentInfo(selected_envs)
3686 LinkTrustedEnv(selected_envs)
3687 # This must happen after LinkTrustedEnv, since that is where TRUSTED_ENV
3688 # is finally set, and env.UsingEmulator() checks TRUSTED_ENV for the emulator.
3689 # This must also happen before BuildEnvironments.
3690 PnaclSetEmulatorForSandboxedTranslator(selected_envs)
3691 BuildEnvironments(selected_envs)
3693 # Change default to build everything, but not run tests.
3694 Default(['all_programs', 'all_bundles', 'all_test_programs', 'all_libraries'])
3697 # Sanity check whether we are ready to build nacl modules
3698 # NOTE: this uses stuff from: site_scons/site_tools/naclsdk.py
3699 if nacl_env.Bit('naclsdk_validate') and (nacl_env in selected_envs or
3700 nacl_irt_env in selected_envs):
3701 nacl_env.ValidateSdk()
3703 if BROKEN_TEST_COUNT > 0:
3704 msg = "There are %d broken tests." % BROKEN_TEST_COUNT
3705 if GetOption('brief_comstr'):
3706 msg += " Add --verbose to the command line for more information."
3709 # separate warnings from actual build output
3710 Banner('B U I L D - O U T P U T:')