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
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")
35 class Error(Exception):
40 return os
.getenv('NACL_SDK_ROOT', os
.path
.dirname(SCRIPT_DIR
))
44 if sys
.platform
.startswith('cygwin') or sys
.platform
.startswith('win'):
46 elif sys
.platform
.startswith('darwin'):
48 elif sys
.platform
.startswith('linux'):
51 raise Error("Unknown platform: %s" % sys
.platform
)
55 arch32
= os
.environ
.get('PROCESSOR_ARCHITECTURE')
56 arch64
= os
.environ
.get('PROCESSOR_ARCHITEW6432')
58 if arch32
== 'AMD64' or arch64
== 'AMD64':
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
)
71 for line
in open(readme
):
73 name
, value
= line
.split(':', 1)
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
)
83 version
= int(version
)
85 raise Error("error parsing SDK README: %s" % readme
)
87 return (version
, revision
)
90 def GetSystemArch(platform
):
96 if platform
in ['mac', 'linux']:
98 pobj
= subprocess
.Popen(['uname', '-m'], stdout
= subprocess
.PIPE
)
99 arch
= pobj
.communicate()[0]
100 arch
= arch
.split()[0]
101 if arch
.startswith('arm'):
108 def GetChromePath(platform
):
109 # If CHROME_PATH is defined and exists, use that.
110 chrome_path
= os
.environ
.get('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
)
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.
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
)
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
164 raise Error(output
+ stderr
.strip())
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
)
172 raise Error("Error running objdump on: %s" % chrome_path
)
174 arch
= match
.group(2)
182 def ParseVersion(version
):
184 version
= version
.split('.')
186 version
= (version
, '0')
189 return tuple(int(x
) for x
in version
)
191 raise Error('error parsing SDK version: %s' % version
)
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 '
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()
216 parser
.error('Only one option can be specified at a time.')
223 out
= GetSystemArch(platform
)
224 elif options
.nacl_arch
:
225 out
= GetNaClArch(platform
)
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]))
250 if __name__
== '__main__':
252 sys
.exit(main(sys
.argv
[1:]))
254 sys
.stderr
.write(str(e
) + '\n')