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 revision = int(revision)
84 version = int(version)
86 raise Error("error parsing SDK README: %s" % readme)
88 return (version, revision)
91 def GetSystemArch(platform):
97 if platform in ['mac', 'linux']:
99 pobj = subprocess.Popen(['uname', '-m'], stdout= subprocess.PIPE)
100 arch = pobj.communicate()[0]
101 arch = arch.split()[0]
102 if arch.startswith('arm'):
109 def GetChromePath(platform):
110 # If CHROME_PATH is defined and exists, use that.
111 chrome_path = os.environ.get('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)
117 # Otherwise look in the PATH environment variable.
118 basename = os.path.basename(CHROME_DEFAULT_PATH[platform])
119 chrome_path = oshelpers.FindExeInPath(basename)
121 return os.path.realpath(chrome_path)
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)
128 raise Error('CHROME_PATH is undefined, and %s not found in PATH, nor %s.' % (
129 basename, chrome_path))
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.
140 # On linux the nacl arch matches to chrome arch, so we inspect the chrome
141 # binary using objdump
142 chrome_path = GetChromePath(platform)
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.
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')
152 if not os.path.exists(chrome_path):
153 raise Error("File %s does not exist." % chrome_path)
155 if not os.access(chrome_path, os.X_OK):
156 raise Error("File %s is not executable" % chrome_path)
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
165 raise Error(output + stderr.strip())
167 # This will happen if objdump is not installed
168 raise Error("Error running objdump: %s" % e)
170 pattern = r'(file format) ([a-zA-Z0-9_\-]+)'
171 match = re.search(pattern, output)
173 raise Error("Error running objdump on: %s" % chrome_path)
175 arch = match.group(2)
183 def ParseVersion(version):
185 version = version.split('.')
187 version = (version, '0')
190 return tuple(int(x) for x in version)
192 raise Error('error parsing SDK version: %s' % version)
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 '
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.')
212 options, _ = parser.parse_args(args)
214 platform = GetPlatform()
217 parser.error('Only one option can be specified at a time.')
224 out = GetSystemArch(platform)
225 elif options.nacl_arch:
226 out = GetNaClArch(platform)
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]))
247 if __name__ == '__main__':
249 sys.exit(main(sys.argv[1:]))
251 sys.stderr.write(str(e) + '\n')