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, 7, 0):
31 sys
.stderr
.write("python 2.7 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 commit_position
= None
72 for line
in open(readme
):
74 name
, value
= line
.split(':', 1)
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
)
86 version
= int(version
)
87 revision
= int(revision
)
89 raise Error("error parsing SDK README: %s" % readme
)
91 return (version
, revision
, commit_position
)
94 def GetSystemArch(platform
):
100 if platform
in ['mac', 'linux']:
102 pobj
= subprocess
.Popen(['uname', '-m'], stdout
= subprocess
.PIPE
)
103 arch
= pobj
.communicate()[0]
104 arch
= arch
.split()[0]
105 if arch
.startswith('arm'):
112 def GetChromePath(platform
):
113 # If CHROME_PATH is defined and exists, use that.
114 chrome_path
= os
.environ
.get('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
)
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.
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
)
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
168 raise Error(output
+ stderr
.strip())
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
)
176 raise Error("Error running objdump on: %s" % chrome_path
)
178 arch
= match
.group(2)
186 def ParseVersion(version
):
187 """Parses a version number of the form '<major>.<position>'.
189 <position> is the Cr-Commit-Position number.
192 version
= version
.split('.')
194 version
= (version
, '0')
197 return tuple(int(x
) for x
in version
)
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.
206 required_version: (major, position) pair, where position is the
207 Cr-Commit-Position number.
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]))
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 '
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.')
240 parser
.error('Only one option can be specified at a time.')
242 options
= parser
.parse_args(args
)
244 platform
= GetPlatform()
247 out
= GetSystemArch(platform
)
248 elif options
.nacl_arch
:
249 out
= GetNaClArch(platform
)
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
)
270 if __name__
== '__main__':
272 sys
.exit(main(sys
.argv
[1:]))
274 sys
.stderr
.write(str(e
) + '\n')