Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / native_client_sdk / src / tools / getos.py
blob62c2b5b7632043f2f4f600404729792acf948036
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 optparse
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, 6, 0):
31 sys.stderr.write("python 2.6 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 for line in open(readme):
72 if ':' in line:
73 name, value = line.split(':', 1)
74 if name == "Version":
75 version = value.strip()
76 if name == "Chrome Revision":
77 revision = value.strip()
79 if revision == None or version == None:
80 raise Error("error parsing SDK README: %s" % readme)
82 try:
83 version = int(version)
84 except ValueError:
85 raise Error("error parsing SDK README: %s" % readme)
87 return (version, revision)
90 def GetSystemArch(platform):
91 if platform == 'win':
92 if UseWin64():
93 return 'x86_64'
94 return 'x86_32'
96 if platform in ['mac', 'linux']:
97 try:
98 pobj = subprocess.Popen(['uname', '-m'], stdout= subprocess.PIPE)
99 arch = pobj.communicate()[0]
100 arch = arch.split()[0]
101 if arch.startswith('arm'):
102 arch = 'arm'
103 except Exception:
104 arch = None
105 return arch
108 def GetChromePath(platform):
109 # If CHROME_PATH is defined and exists, use that.
110 chrome_path = os.environ.get('CHROME_PATH')
111 if chrome_path:
112 if not os.path.exists(chrome_path):
113 raise Error('Invalid CHROME_PATH: %s' % chrome_path)
114 return os.path.realpath(chrome_path)
116 # Otherwise look in the PATH environment variable.
117 basename = os.path.basename(CHROME_DEFAULT_PATH[platform])
118 chrome_path = oshelpers.FindExeInPath(basename)
119 if chrome_path:
120 return os.path.realpath(chrome_path)
122 # Finally, try the default paths to Chrome.
123 chrome_path = CHROME_DEFAULT_PATH[platform]
124 if os.path.exists(chrome_path):
125 return os.path.realpath(chrome_path)
127 raise Error('CHROME_PATH is undefined, and %s not found in PATH, nor %s.' % (
128 basename, chrome_path))
131 def GetNaClArch(platform):
132 if platform == 'win':
133 # On windows the nacl arch always matches to system arch
134 return GetSystemArch(platform)
135 elif platform == 'mac':
136 # On Mac the nacl arch is currently always 32-bit.
137 return 'x86_32'
139 # On linux the nacl arch matches to chrome arch, so we inspect the chrome
140 # binary using objdump
141 chrome_path = GetChromePath(platform)
143 # If CHROME_PATH is set to point to google-chrome or google-chrome
144 # was found in the PATH and we are running on UNIX then google-chrome
145 # is a bash script that points to 'chrome' in the same folder.
147 # When running beta or dev branch, the name is google-chrome-{beta,dev}.
148 if os.path.basename(chrome_path).startswith('google-chrome'):
149 chrome_path = os.path.join(os.path.dirname(chrome_path), 'chrome')
151 if not os.path.exists(chrome_path):
152 raise Error("File %s does not exist." % chrome_path)
154 if not os.access(chrome_path, os.X_OK):
155 raise Error("File %s is not executable" % chrome_path)
157 try:
158 pobj = subprocess.Popen(['objdump', '-f', chrome_path],
159 stdout=subprocess.PIPE,
160 stderr=subprocess.PIPE)
161 output, stderr = pobj.communicate()
162 # error out here if objdump failed
163 if pobj.returncode:
164 raise Error(output + stderr.strip())
165 except OSError as e:
166 # This will happen if objdump is not installed
167 raise Error("Error running objdump: %s" % e)
169 pattern = r'(file format) ([a-zA-Z0-9_\-]+)'
170 match = re.search(pattern, output)
171 if not match:
172 raise Error("Error running objdump on: %s" % chrome_path)
174 arch = match.group(2)
175 if 'arm' in arch:
176 return 'arm'
177 if '64' in arch:
178 return 'x86_64'
179 return 'x86_32'
182 def ParseVersion(version):
183 if '.' in version:
184 version = version.split('.')
185 else:
186 version = (version, '0')
188 try:
189 return tuple(int(x) for x in version)
190 except ValueError:
191 raise Error('error parsing SDK version: %s' % version)
194 def main(args):
195 parser = optparse.OptionParser()
196 parser.add_option('--arch', action='store_true',
197 help='Print architecture of current machine (x86_32, x86_64 or arm).')
198 parser.add_option('--chrome', action='store_true',
199 help='Print the path chrome (by first looking in $CHROME_PATH and '
200 'then $PATH).')
201 parser.add_option('--nacl-arch', action='store_true',
202 help='Print architecture used by NaCl on the current machine.')
203 parser.add_option('--sdk-version', action='store_true',
204 help='Print major version of the NaCl SDK.')
205 parser.add_option('--sdk-revision', action='store_true',
206 help='Print revision number of the NaCl SDK.')
207 parser.add_option('--check-version',
208 help='Check that the SDK version is at least as great as the '
209 'version passed in.')
211 options, _ = parser.parse_args(args)
213 platform = GetPlatform()
215 if len(args) > 1:
216 parser.error('Only one option can be specified at a time.')
218 if not args:
219 print platform
220 return 0
222 if options.arch:
223 out = GetSystemArch(platform)
224 elif options.nacl_arch:
225 out = GetNaClArch(platform)
226 elif options.chrome:
227 out = GetChromePath(platform)
228 elif options.sdk_version:
229 out = GetSDKVersion()[0]
230 elif options.sdk_revision:
231 out = GetSDKVersion()[1]
232 elif options.check_version:
233 required_version = ParseVersion(options.check_version)
234 version = GetSDKVersion()
235 # We currently ignore the revision and just check the major version number.
236 # Currently, version[1] is just a Git hash, which cannot be compared.
237 # TODO(mgiuca): Compare the minor revision numbers (which should be
238 # Cr-Commit-Position values), when http://crbug.com/406783 is fixed.
239 # Then Cr-Commit-Position should be available: see http://crbug.com/406993.
240 if version[0] < required_version[0]:
241 raise Error("SDK version too old (current: %s, required: %s)"
242 % (version[0], required_version[0]))
243 out = None
245 if out:
246 print out
247 return 0
250 if __name__ == '__main__':
251 try:
252 sys.exit(main(sys.argv[1:]))
253 except Error as e:
254 sys.stderr.write(str(e) + '\n')
255 sys.exit(1)