Debugging: Add code to print backtrace for guest on SIGSEGV
[nativeclient.git] / site_scons / site_tools / naclsdk.py
blob127a95850ebca7093f70ac99446b028b22915310
1 #!/usr/bin/python2.4
2 # Copyright 2009, Google Inc.
3 # All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
14 # distribution.
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 """Nacl SDK tool SCons."""
33 import __builtin__
34 import os
35 import sys
36 import SCons.Script
37 import subprocess
38 import sync_tgz
41 NACL_PLATFORM_DIR_MAP = {
42 'win32': 'windows',
43 'cygwin': 'windows',
44 'posix': 'linux',
45 'linux': 'linux',
46 'linux2': 'linux',
47 'darwin': 'mac',
51 def _GetNaclSdkRoot(env, sdk_mode):
52 """Return the path to the sdk.
54 Args:
55 env: The SCons environment in question.
56 sdk_mode: A string indicating which location to select the tools from.
57 Returns:
58 The path to the sdk.
59 """
60 if sdk_mode == 'local':
61 if env['PLATFORM'] in ['win32', 'cygwin']:
62 # Try to use cygpath under the assumption we are running thru cygwin.
63 # If this is not the case, then 'local' doesn't really make any sense,
64 # so then we should complain.
65 try:
66 path = subprocess.Popen(
67 ['cygpath', '-m', '/usr/local/nacl-sdk'],
68 env={'PATH': os.environ['PRESCONS_PATH']}, shell=True,
69 stdout=subprocess.PIPE).communicate()[0].replace('\n', '')
70 except WindowsError:
71 raise NotImplementedError(
72 'Not able to decide where /usr/local/nacl-sdk is on this platform,'
73 'use naclsdk_mode=custom:...')
74 return path
75 else:
76 return '/usr/local/nacl-sdk'
78 elif sdk_mode == 'download':
79 return ('$THIRD_PARTY/nacl_sdk/' +
80 NACL_PLATFORM_DIR_MAP[env['PLATFORM']] + '/sdk/nacl-sdk')
82 elif sdk_mode.startswith('custom:'):
83 return os.path.abspath(sdk_mode[len('custom:'):])
85 else:
86 assert 0
89 def _DownloadSdk(env):
90 """Download and untar the latest sdk.
92 Args:
93 env: SCons environment in question.
94 """
96 # Only try to download once.
97 try:
98 if __builtin__.nacl_sdk_downloaded: return
99 except AttributeError:
100 __builtin__.nacl_sdk_downloaded = True
102 # Get path to extract to.
103 target = env.subst('$THIRD_PARTY/nacl_sdk/' +
104 NACL_PLATFORM_DIR_MAP[env['PLATFORM']])
106 # Set NATIVE_CLIENT_SDK_PLATFORM before substitution.
107 env['NATIVE_CLIENT_SDK_PLATFORM'] = NACL_PLATFORM_DIR_MAP[env['PLATFORM']]
109 # Allow sdk selection function to be used instead.
110 if env.get('NATIVE_CLIENT_SDK_SOURCE'):
111 url = env['NATIVE_CLIENT_SDK_SOURCE'](env)
112 else:
113 # Pick download url.
114 url = [
115 env.subst(
116 '$NATIVE_CLIENT_SDK_URL',
117 'http://nativeclient.googlecode.com/files/'
118 'nacl_${NATIVE_CLIENT_SDK_PLATFORM}_latest.tgz'),
119 env.get('NATIVE_CLIENT_SDK_USERNAME'),
120 env.get('NATIVE_CLIENT_SDK_PASSWORD'),
123 sync_tgz.SyncTgz(url[0], target, url[1], url[2])
126 def _ValidateSdk(env, sdk_mode):
127 """Check that the sdk is present.
129 Args:
130 env: SCons environment in question.
131 sdk_mode: mode string indicating where to get the sdk from.
134 # Try to download SDK if in download mode and using download version.
135 if env.GetOption('download') and sdk_mode == 'download':
136 _DownloadSdk(env)
138 # Check if stdio.h is present as a cheap check for the sdk.
139 if not os.path.exists(env.subst('$NACL_SDK_ROOT/nacl/include/stdio.h')):
140 sys.stderr.write('NativeClient SDK not present in %s\n'
141 'Run again with the --download flag.\n' %
142 env.subst('$NACL_SDK_ROOT'))
143 sys.exit(1)
146 def generate(env):
147 """SCons entry point for this tool.
149 Args:
150 env: The SCons environment in question.
152 NOTE: SCons requires the use of this name, which fails lint.
155 # Add the download option.
156 try:
157 env.GetOption('download')
158 except AttributeError:
159 SCons.Script.AddOption('--download',
160 dest='download',
161 metavar='DOWNLOAD',
162 default=False,
163 action='store_true',
164 help='allow tools to download')
166 # Pick default sdk source.
167 default_mode = env.get('NATIVE_CLIENT_SDK_DEFAULT_MODE',
168 'custom:tools_bin/' +
169 NACL_PLATFORM_DIR_MAP[env['PLATFORM']] +
170 '/sdk/nacl-sdk')
172 # Get sdk mode (support sdk_mode for backward compatibility).
173 sdk_mode = SCons.Script.ARGUMENTS.get('sdk_mode', default_mode)
174 sdk_mode = SCons.Script.ARGUMENTS.get('naclsdk_mode', sdk_mode)
176 # Decide where to get the SDK.
177 env.Replace(NACL_SDK_ROOT=_GetNaclSdkRoot(env, sdk_mode))
179 # Validate the sdk unless disabled from the command line.
180 env.SetDefault(NACL_SDK_VALIDATE='1')
181 if int(SCons.Script.ARGUMENTS.get('naclsdk_validate',
182 env.subst('$NACL_SDK_VALIDATE'))):
183 _ValidateSdk(env, sdk_mode)
185 if env.subst('$NACL_SDK_ROOT_ONLY'): return
187 # Invoke the various unix tools that the NativeClient SDK resembles.
188 env.Tool('g++')
189 env.Tool('gcc')
190 env.Tool('gnulink')
191 env.Tool('ar')
192 env.Tool('as')
194 env.Replace(
195 HOST_PLATFORMS=['*'], # NaCl builds on all platforms.
197 COMPONENT_LINKFLAGS=['-Wl,-rpath-link,$COMPONENT_LIBRARY_DIR'],
198 COMPONENT_LIBRARY_LINK_SUFFIXES=['.so', '.a'],
199 COMPONENT_LIBRARY_DEBUG_SUFFIXES=[],
201 # TODO: This is needed for now to work around unc paths. Take this out
202 # when unc paths are fixed.
203 IMPLICIT_COMMAND_DEPENDENCIES=False,
205 # Setup path to NativeClient tools.
206 NACL_SDK_BIN='$NACL_SDK_ROOT/bin',
207 NACL_SDK_INCLUDE='$NACL_SDK_ROOT/nacl/include',
208 NACL_SDK_LIB='$NACL_SDK_ROOT/nacl/lib',
210 # Replace the normal unix tools with the NaCl ones.
211 CC='nacl-gcc',
212 CXX='nacl-g++',
213 AR='nacl-ar',
214 AS='nacl-as',
215 LINK='nacl-g++', # use g++ for linking so we can handle c AND c++
216 RANLIB='nacl-ranlib',
218 # TODO: this could be .nexe and then all the .nexe stuff goes away?
219 PROGSUFFIX='' # Force PROGSUFFIX to '' on all platforms.
222 env.PrependENVPath('PATH', [env.subst('$NACL_SDK_BIN')])
223 env.PrependENVPath('INCLUDE', [env.subst('$NACL_SDK_INCLUDE')])
224 env.Prepend(LINKFLAGS='-L' + env.subst('$NACL_SDK_LIB'))
226 env.Append(
227 CCFLAGS=[
228 '-fno-stack-protector',
229 '-fno-builtin',