Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / tools / getos.py
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.
5
6 """Determine OS and various other system properties.
7
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 """
12
13 import optparse
14 import os
15 import re
16 import subprocess
17 import sys
18
19 import oshelpers
20
21
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',
27 }
28
29
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)
33
34
35 class Error(Exception):
36   pass
37
38
39 def GetSDKPath():
40   return os.getenv('NACL_SDK_ROOT', os.path.dirname(SCRIPT_DIR))
41
42
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)
52
53
54 def UseWin64():
55   arch32 = os.environ.get('PROCESSOR_ARCHITECTURE')
56   arch64 = os.environ.get('PROCESSOR_ARCHITEW6432')
57
58   if arch32 == 'AMD64' or arch64 == 'AMD64':
59     return True
60   return False
61
62
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)
68
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()
78
79   if revision == None or version == None:
80     raise Error("error parsing SDK README: %s" % readme)
81
82   try:
83     revision = int(revision)
84     version = int(version)
85   except ValueError:
86     raise Error("error parsing SDK README: %s" % readme)
87
88   return (version, revision)
89
90
91 def GetSystemArch(platform):
92   if platform == 'win':
93     if UseWin64():
94       return 'x86_64'
95     return 'x86_32'
96
97   if platform in ['mac', 'linux']:
98     try:
99       pobj = subprocess.Popen(['uname', '-m'], stdout= subprocess.PIPE)
100       arch = pobj.communicate()[0]
101       arch = arch.split()[0]
102       if arch.startswith('arm'):
103         arch = 'arm'
104     except Exception:
105       arch = None
106   return arch
107
108
109 def GetChromePath(platform):
110   # If CHROME_PATH is defined and exists, use that.
111   chrome_path = os.environ.get('CHROME_PATH')
112   if chrome_path:
113     if not os.path.exists(chrome_path):
114       raise Error('Invalid CHROME_PATH: %s' % chrome_path)
115     return os.path.realpath(chrome_path)
116
117   # Otherwise look in the PATH environment variable.
118   basename = os.path.basename(CHROME_DEFAULT_PATH[platform])
119   chrome_path = oshelpers.FindExeInPath(basename)
120   if chrome_path:
121     return os.path.realpath(chrome_path)
122
123   # Finally, try the default paths to Chrome.
124   chrome_path = CHROME_DEFAULT_PATH[platform]
125   if os.path.exists(chrome_path):
126     return os.path.realpath(chrome_path)
127
128   raise Error('CHROME_PATH is undefined, and %s not found in PATH, nor %s.' % (
129               basename, chrome_path))
130
131
132 def GetNaClArch(platform):
133   if platform == 'win':
134     # On windows the nacl arch always matches to system arch
135     return GetSystemArch(platform)
136   elif platform == 'mac':
137     # On Mac the nacl arch is currently always 32-bit.
138     return 'x86_32'
139
140   # On linux the nacl arch matches to chrome arch, so we inspect the chrome
141   # binary using objdump
142   chrome_path = GetChromePath(platform)
143
144   # If CHROME_PATH is set to point to google-chrome or google-chrome
145   # was found in the PATH and we are running on UNIX then google-chrome
146   # is a bash script that points to 'chrome' in the same folder.
147   #
148   # When running beta or dev branch, the name is google-chrome-{beta,dev}.
149   if os.path.basename(chrome_path).startswith('google-chrome'):
150     chrome_path = os.path.join(os.path.dirname(chrome_path), 'chrome')
151
152   if not os.path.exists(chrome_path):
153     raise Error("File %s does not exist." % chrome_path)
154
155   if not os.access(chrome_path, os.X_OK):
156     raise Error("File %s is not executable" % chrome_path)
157
158   try:
159     pobj = subprocess.Popen(['objdump', '-f', chrome_path],
160                             stdout=subprocess.PIPE,
161                             stderr=subprocess.PIPE)
162     output, stderr = pobj.communicate()
163     # error out here if objdump failed
164     if pobj.returncode:
165       raise Error(output + stderr.strip())
166   except OSError as e:
167     # This will happen if objdump is not installed
168     raise Error("Error running objdump: %s" % e)
169
170   pattern = r'(file format) ([a-zA-Z0-9_\-]+)'
171   match = re.search(pattern, output)
172   if not match:
173     raise Error("Error running objdump on: %s" % chrome_path)
174
175   arch = match.group(2)
176   if 'arm' in arch:
177     return 'arm'
178   if '64' in arch:
179     return 'x86_64'
180   return 'x86_32'
181
182
183 def ParseVersion(version):
184   if '.' in version:
185     version = version.split('.')
186   else:
187     version = (version, '0')
188
189   try:
190     return tuple(int(x) for x in version)
191   except ValueError:
192     raise Error('error parsing SDK version: %s' % version)
193
194
195 def main(args):
196   parser = optparse.OptionParser()
197   parser.add_option('--arch', action='store_true',
198       help='Print architecture of current machine (x86_32, x86_64 or arm).')
199   parser.add_option('--chrome', action='store_true',
200       help='Print the path chrome (by first looking in $CHROME_PATH and '
201            'then $PATH).')
202   parser.add_option('--nacl-arch', action='store_true',
203       help='Print architecture used by NaCl on the current machine.')
204   parser.add_option('--sdk-version', action='store_true',
205       help='Print major version of the NaCl SDK.')
206   parser.add_option('--sdk-revision', action='store_true',
207       help='Print revision number of the NaCl SDK.')
208   parser.add_option('--check-version',
209       help='Check that the SDK version is at least as great as the '
210            'version passed in.')
211
212   options, _ = parser.parse_args(args)
213
214   platform = GetPlatform()
215
216   if len(args) > 1:
217     parser.error('Only one option can be specified at a time.')
218
219   if not args:
220     print platform
221     return 0
222
223   if options.arch:
224     out = GetSystemArch(platform)
225   elif options.nacl_arch:
226     out = GetNaClArch(platform)
227   elif options.chrome:
228     out = GetChromePath(platform)
229   elif options.sdk_version:
230     out = GetSDKVersion()[0]
231   elif options.sdk_revision:
232     out = GetSDKVersion()[1]
233   elif options.check_version:
234     required_version = ParseVersion(options.check_version)
235     version = GetSDKVersion()
236     if version < required_version:
237       raise Error("SDK version too old (current: %s.%s, required: %s.%s)"
238              % (version[0], version[1],
239                 required_version[0], required_version[1]))
240     out = None
241
242   if out:
243     print out
244   return 0
245
246
247 if __name__ == '__main__':
248   try:
249     sys.exit(main(sys.argv[1:]))
250   except Error as e:
251     sys.stderr.write(str(e) + '\n')
252     sys.exit(1)