Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / native_client_sdk / src / tools / getos.py
blobc5fe5c2e788b3edfa03d59a81423ec8c8e930cef
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Determine OS and various other system properties.
8 Determine the name of the platform used and other system properties such as
9 the location of Chrome. This is used, for example, to determine the correct
10 Toolchain to invoke.
11 """
13 import argparse
14 import os
15 import re
16 import subprocess
17 import sys
19 import oshelpers
22 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
23 CHROME_DEFAULT_PATH = {
24 'win': r'c:\Program Files (x86)\Google\Chrome\Application\chrome.exe',
25 'mac': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
26 'linux': '/usr/bin/google-chrome',
30 if sys.version_info < (2, 7, 0):
31 sys.stderr.write("python 2.7 or later is required run this script\n")
32 sys.exit(1)
35 class Error(Exception):
36 pass
39 def GetSDKPath():
40 return os.getenv('NACL_SDK_ROOT', os.path.dirname(SCRIPT_DIR))
43 def GetPlatform():
44 if sys.platform.startswith('cygwin') or sys.platform.startswith('win'):
45 return 'win'
46 elif sys.platform.startswith('darwin'):
47 return 'mac'
48 elif sys.platform.startswith('linux'):
49 return 'linux'
50 else:
51 raise Error("Unknown platform: %s" % sys.platform)
54 def UseWin64():
55 arch32 = os.environ.get('PROCESSOR_ARCHITECTURE')
56 arch64 = os.environ.get('PROCESSOR_ARCHITEW6432')
58 if arch32 == 'AMD64' or arch64 == 'AMD64':
59 return True
60 return False
63 def GetSDKVersion():
64 root = GetSDKPath()
65 readme = os.path.join(root, "README")
66 if not os.path.exists(readme):
67 raise Error("README not found in SDK root: %s" % root)
69 version = None
70 revision = None
71 commit_position = None
72 for line in open(readme):
73 if ':' in line:
74 name, value = line.split(':', 1)
75 if name == "Version":
76 version = value.strip()
77 if name == "Chrome Revision":
78 revision = value.strip()
79 if name == "Chrome Commit Position":
80 commit_position = value.strip()
82 if revision is None or version is None or commit_position is None:
83 raise Error("error parsing SDK README: %s" % readme)
85 try:
86 version = int(version)
87 revision = int(revision)
88 except ValueError:
89 raise Error("error parsing SDK README: %s" % readme)
91 return (version, revision, commit_position)
94 def GetSystemArch(platform):
95 if platform == 'win':
96 if UseWin64():
97 return 'x86_64'
98 return 'x86_32'
100 if platform in ['mac', 'linux']:
101 try:
102 pobj = subprocess.Popen(['uname', '-m'], stdout= subprocess.PIPE)
103 arch = pobj.communicate()[0]
104 arch = arch.split()[0]
105 if arch.startswith('arm'):
106 arch = 'arm'
107 except Exception:
108 arch = None
109 return arch
112 def GetChromePath(platform):
113 # If CHROME_PATH is defined and exists, use that.
114 chrome_path = os.environ.get('CHROME_PATH')
115 if chrome_path:
116 if not os.path.exists(chrome_path):
117 raise Error('Invalid CHROME_PATH: %s' % chrome_path)
118 return os.path.realpath(chrome_path)
120 # Otherwise look in the PATH environment variable.
121 basename = os.path.basename(CHROME_DEFAULT_PATH[platform])
122 chrome_path = oshelpers.FindExeInPath(basename)
123 if chrome_path:
124 return os.path.realpath(chrome_path)
126 # Finally, try the default paths to Chrome.
127 chrome_path = CHROME_DEFAULT_PATH[platform]
128 if os.path.exists(chrome_path):
129 return os.path.realpath(chrome_path)
131 raise Error('CHROME_PATH is undefined, and %s not found in PATH, nor %s.' % (
132 basename, chrome_path))
135 def GetNaClArch(platform):
136 if platform == 'win':
137 # On windows the nacl arch always matches to system arch
138 return GetSystemArch(platform)
139 elif platform == 'mac':
140 # On Mac the nacl arch is currently always 32-bit.
141 return 'x86_32'
143 # On linux the nacl arch matches to chrome arch, so we inspect the chrome
144 # binary using objdump
145 chrome_path = GetChromePath(platform)
147 # If CHROME_PATH is set to point to google-chrome or google-chrome
148 # was found in the PATH and we are running on UNIX then google-chrome
149 # is a bash script that points to 'chrome' in the same folder.
151 # When running beta or dev branch, the name is google-chrome-{beta,dev}.
152 if os.path.basename(chrome_path).startswith('google-chrome'):
153 chrome_path = os.path.join(os.path.dirname(chrome_path), 'chrome')
155 if not os.path.exists(chrome_path):
156 raise Error("File %s does not exist." % chrome_path)
158 if not os.access(chrome_path, os.X_OK):
159 raise Error("File %s is not executable" % chrome_path)
161 try:
162 pobj = subprocess.Popen(['objdump', '-f', chrome_path],
163 stdout=subprocess.PIPE,
164 stderr=subprocess.PIPE)
165 output, stderr = pobj.communicate()
166 # error out here if objdump failed
167 if pobj.returncode:
168 raise Error(output + stderr.strip())
169 except OSError as e:
170 # This will happen if objdump is not installed
171 raise Error("Error running objdump: %s" % e)
173 pattern = r'(file format) ([a-zA-Z0-9_\-]+)'
174 match = re.search(pattern, output)
175 if not match:
176 raise Error("Error running objdump on: %s" % chrome_path)
178 arch = match.group(2)
179 if 'arm' in arch:
180 return 'arm'
181 if '64' in arch:
182 return 'x86_64'
183 return 'x86_32'
186 def ParseVersion(version):
187 """Parses a version number of the form '<major>.<position>'.
189 <position> is the Cr-Commit-Position number.
191 if '.' in version:
192 version = version.split('.')
193 else:
194 version = (version, '0')
196 try:
197 return tuple(int(x) for x in version)
198 except ValueError:
199 raise Error('error parsing SDK version: %s' % version)
202 def CheckVersion(required_version):
203 """Determines whether the current SDK version meets the required version.
205 Args:
206 required_version: (major, position) pair, where position is the
207 Cr-Commit-Position number.
209 Raises:
210 Error: The SDK version is older than required_version.
212 version = GetSDKVersion()[:2]
213 if version < required_version:
214 raise Error("SDK version too old (current: %d.%d, required: %d.%d)"
215 % (version[0], version[1], required_version[0], required_version[1]))
218 def main(args):
219 parser = argparse.ArgumentParser()
220 parser.add_argument('--arch', action='store_true',
221 help='Print architecture of current machine (x86_32, x86_64 or arm).')
222 parser.add_argument('--chrome', action='store_true',
223 help='Print the path chrome (by first looking in $CHROME_PATH and '
224 'then $PATH).')
225 parser.add_argument('--nacl-arch', action='store_true',
226 help='Print architecture used by NaCl on the current machine.')
227 parser.add_argument('--sdk-version', action='store_true',
228 help='Print major version of the NaCl SDK.')
229 parser.add_argument('--sdk-revision', action='store_true',
230 help='Print revision number of the NaCl SDK.')
231 parser.add_argument('--sdk-commit-position', action='store_true',
232 help='Print commit position of the NaCl SDK.')
233 parser.add_argument('--check-version',
234 metavar='MAJOR.POSITION',
235 help='Check that the SDK version is at least as great as the '
236 'version passed in. MAJOR is the major version number and POSITION '
237 'is the Cr-Commit-Position number.')
239 if len(args) > 1:
240 parser.error('Only one option can be specified at a time.')
242 options = parser.parse_args(args)
244 platform = GetPlatform()
246 if options.arch:
247 out = GetSystemArch(platform)
248 elif options.nacl_arch:
249 out = GetNaClArch(platform)
250 elif options.chrome:
251 out = GetChromePath(platform)
252 elif options.sdk_version:
253 out = GetSDKVersion()[0]
254 elif options.sdk_revision:
255 out = GetSDKVersion()[1]
256 elif options.sdk_commit_position:
257 out = GetSDKVersion()[2]
258 elif options.check_version:
259 required_version = ParseVersion(options.check_version)
260 CheckVersion(required_version)
261 out = None
262 else:
263 out = platform
265 if out:
266 print out
267 return 0
270 if __name__ == '__main__':
271 try:
272 sys.exit(main(sys.argv[1:]))
273 except Error as e:
274 sys.stderr.write(str(e) + '\n')
275 sys.exit(1)