Upstream version 10.39.225.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   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()
81
82   if revision is None or version is None or commit_position is None:
83     raise Error("error parsing SDK README: %s" % readme)
84
85   try:
86     version = int(version)
87     revision = int(revision)
88   except ValueError:
89     raise Error("error parsing SDK README: %s" % readme)
90
91   return (version, revision, commit_position)
92
93
94 def GetSystemArch(platform):
95   if platform == 'win':
96     if UseWin64():
97       return 'x86_64'
98     return 'x86_32'
99
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
110
111
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)
119
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)
125
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)
130
131   raise Error('CHROME_PATH is undefined, and %s not found in PATH, nor %s.' % (
132               basename, chrome_path))
133
134
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'
142
143   # On linux the nacl arch matches to chrome arch, so we inspect the chrome
144   # binary using objdump
145   chrome_path = GetChromePath(platform)
146
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.
150   #
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')
154
155   if not os.path.exists(chrome_path):
156     raise Error("File %s does not exist." % chrome_path)
157
158   if not os.access(chrome_path, os.X_OK):
159     raise Error("File %s is not executable" % chrome_path)
160
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)
172
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)
177
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'
184
185
186 def ParseVersion(version):
187   """Parses a version number of the form '<major>.<position>'.
188
189   <position> is the Cr-Commit-Position number.
190   """
191   if '.' in version:
192     version = version.split('.')
193   else:
194     version = (version, '0')
195
196   try:
197     return tuple(int(x) for x in version)
198   except ValueError:
199     raise Error('error parsing SDK version: %s' % version)
200
201
202 def CheckVersion(required_version):
203   """Determines whether the current SDK version meets the required version.
204
205   Args:
206     required_version: (major, position) pair, where position is the
207     Cr-Commit-Position number.
208
209   Raises:
210     Error: The SDK version is older than required_version.
211   """
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]))
216
217
218 def main(args):
219   parser = optparse.OptionParser()
220   parser.add_option('--arch', action='store_true',
221       help='Print architecture of current machine (x86_32, x86_64 or arm).')
222   parser.add_option('--chrome', action='store_true',
223       help='Print the path chrome (by first looking in $CHROME_PATH and '
224            'then $PATH).')
225   parser.add_option('--nacl-arch', action='store_true',
226       help='Print architecture used by NaCl on the current machine.')
227   parser.add_option('--sdk-version', action='store_true',
228       help='Print major version of the NaCl SDK.')
229   parser.add_option('--sdk-revision', action='store_true',
230       help='Print revision number of the NaCl SDK.')
231   parser.add_option('--sdk-commit-position', action='store_true',
232       help='Print commit position of the NaCl SDK.')
233   parser.add_option('--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.')
238
239   options, _ = parser.parse_args(args)
240
241   platform = GetPlatform()
242
243   if len(args) > 1:
244     parser.error('Only one option can be specified at a time.')
245
246   if not args:
247     print platform
248     return 0
249
250   if options.arch:
251     out = GetSystemArch(platform)
252   elif options.nacl_arch:
253     out = GetNaClArch(platform)
254   elif options.chrome:
255     out = GetChromePath(platform)
256   elif options.sdk_version:
257     out = GetSDKVersion()[0]
258   elif options.sdk_revision:
259     out = GetSDKVersion()[1]
260   elif options.sdk_commit_position:
261     out = GetSDKVersion()[2]
262   elif options.check_version:
263     required_version = ParseVersion(options.check_version)
264     CheckVersion(required_version)
265     out = None
266
267   if out:
268     print out
269   return 0
270
271
272 if __name__ == '__main__':
273   try:
274     sys.exit(main(sys.argv[1:]))
275   except Error as e:
276     sys.stderr.write(str(e) + '\n')
277     sys.exit(1)