Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / native_client_sdk / src / tools / nacl_config.py
blob146563be46098ad4b2d08c3c47fa627776d25050
1 #!/usr/bin/env python
2 # Copyright 2013 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 """A helper script to print paths of NaCl binaries, includes, libs, etc.
8 It is similar in behavior to pkg-config or sdl-config.
9 """
11 import argparse
12 import os
13 import posixpath
14 import sys
16 import getos
19 if sys.version_info < (2, 7, 0):
20 sys.stderr.write("python 2.7 or later is required run this script\n")
21 sys.exit(1)
24 VALID_ARCHES = ('arm', 'x86_32', 'x86_64', 'i686')
25 VALID_PNACL_ARCHES = (None, 'pnacl')
26 ARCH_NAME = {
27 'arm': 'arm',
28 'x86_32': 'i686',
29 'i686': 'i686',
30 'x86_64': 'x86_64'
33 ARCH_ALT_NAME = {
34 'arm': 'arm',
35 'x86_32': 'x86_32',
36 'i686': 'x86_32',
37 'x86_64': 'x86_64'
40 ARCH_BASE_NAME = {
41 'arm': 'arm',
42 'x86_32': 'x86',
43 'i686': 'x86',
44 'x86_64': 'x86'
47 NACL_TOOLCHAINS = ('newlib', 'glibc', 'pnacl', 'bionic', 'clang-newlib')
48 HOST_TOOLCHAINS = ('linux', 'mac', 'win')
49 VALID_TOOLCHAINS = list(HOST_TOOLCHAINS) + list(NACL_TOOLCHAINS) + ['host']
51 # This is not an exhaustive list of tools, just the ones that need to be
52 # special-cased.
54 # e.g. For PNaCL cc => pnacl-clang
55 # For NaCl cc => pnacl-gcc
57 # Most tools will be passed through directly.
58 # e.g. For PNaCl foo => pnacl-foo
59 # For NaCl foo => x86_64-nacl-foo.
60 CLANG_TOOLS = {
61 'cc': 'clang',
62 'c++': 'clang++',
63 'gcc': 'clang',
64 'g++': 'clang++',
65 'ld': 'clang++'
68 GCC_TOOLS = {
69 'cc': 'gcc',
70 'c++': 'g++',
71 'gcc': 'gcc',
72 'g++': 'g++',
73 'ld': 'g++'
77 class Error(Exception):
78 pass
81 def Expect(condition, message):
82 if not condition:
83 raise Error(message)
86 def ExpectToolchain(toolchain, expected_toolchains):
87 Expect(toolchain in expected_toolchains,
88 'Expected toolchain to be one of [%s], not %s.' % (
89 ', '.join(expected_toolchains), toolchain))
92 def ExpectArch(arch, expected_arches):
93 Expect(arch in expected_arches,
94 'Expected arch to be one of [%s], not %s.' % (
95 ', '.join(map(str, expected_arches)), arch))
98 def CheckValidToolchainArch(toolchain, arch, arch_required=False):
99 if toolchain or arch or arch_required:
100 ExpectToolchain(toolchain, VALID_TOOLCHAINS)
102 if toolchain in HOST_TOOLCHAINS:
103 Expect(arch is None,
104 'Expected no arch for host toolchain %r. Got %r.' % (
105 toolchain, arch))
106 elif toolchain == 'pnacl':
107 Expect(arch is None or arch == 'pnacl',
108 'Expected no arch for toolchain %r. Got %r.' % (toolchain, arch))
109 elif arch_required:
110 Expect(arch is not None,
111 'Expected arch to be one of [%s] for toolchain %r.\n'
112 'Use the -a or --arch flags to specify one.\n' % (
113 ', '.join(VALID_ARCHES), toolchain))
115 if arch:
116 if toolchain == 'pnacl':
117 ExpectArch(arch, VALID_PNACL_ARCHES)
118 else:
119 ExpectArch(arch, VALID_ARCHES)
121 if arch == 'arm':
122 Expect(toolchain in ['newlib', 'bionic', 'clang-newlib'],
123 'The arm arch only supports newlib.')
126 def GetArchName(arch):
127 return ARCH_NAME.get(arch)
130 def GetArchAltName(arch):
131 return ARCH_ALT_NAME.get(arch)
134 def GetArchBaseName(arch):
135 return ARCH_BASE_NAME.get(arch)
138 def CanonicalizeToolchain(toolchain):
139 if toolchain == 'host':
140 return getos.GetPlatform()
141 return toolchain
144 def GetPosixSDKPath():
145 sdk_path = getos.GetSDKPath()
146 if getos.GetPlatform() == 'win':
147 return sdk_path.replace('\\', '/')
148 else:
149 return sdk_path
152 def GetToolchainDir(toolchain, arch=None):
153 ExpectToolchain(toolchain, NACL_TOOLCHAINS)
154 root = GetPosixSDKPath()
155 platform = getos.GetPlatform()
156 if toolchain in ('pnacl', 'clang-newlib'):
157 subdir = '%s_pnacl' % platform
158 else:
159 assert arch is not None
160 subdir = '%s_%s_%s' % (platform, GetArchBaseName(arch), toolchain)
162 return posixpath.join(root, 'toolchain', subdir)
165 def GetToolchainArchDir(toolchain, arch):
166 ExpectToolchain(toolchain, NACL_TOOLCHAINS)
167 assert arch is not None
168 toolchain_dir = GetToolchainDir(toolchain, arch)
169 arch_dir = '%s-nacl' % GetArchName(arch)
170 return posixpath.join(toolchain_dir, arch_dir)
173 def GetToolchainBinDir(toolchain, arch=None):
174 ExpectToolchain(toolchain, NACL_TOOLCHAINS)
175 return posixpath.join(GetToolchainDir(toolchain, arch), 'bin')
178 def GetSDKIncludeDirs(toolchain):
179 root = GetPosixSDKPath()
180 base_include = posixpath.join(root, 'include')
181 if toolchain == 'clang-newlib':
182 toolchain = 'newlib'
183 return [base_include, posixpath.join(base_include, toolchain)]
186 def GetSDKLibDir():
187 return posixpath.join(GetPosixSDKPath(), 'lib')
190 # Commands
192 def GetToolPath(toolchain, arch, tool):
193 if tool == 'gdb':
194 # Always use the same gdb; it supports multiple toolchains/architectures.
195 # NOTE: this is always a i686 executable. i686-nacl-gdb is a symlink to
196 # x86_64-nacl-gdb.
197 return posixpath.join(GetToolchainBinDir('newlib', 'x86_64'),
198 'x86_64-nacl-gdb')
200 if toolchain == 'pnacl':
201 CheckValidToolchainArch(toolchain, arch)
202 tool = CLANG_TOOLS.get(tool, tool)
203 full_tool_name = 'pnacl-%s' % tool
204 else:
205 CheckValidToolchainArch(toolchain, arch, arch_required=True)
206 ExpectArch(arch, VALID_ARCHES)
207 if toolchain == 'clang-newlib':
208 tool = CLANG_TOOLS.get(tool, tool)
209 else:
210 tool = GCC_TOOLS.get(tool, tool)
211 full_tool_name = '%s-nacl-%s' % (GetArchName(arch), tool)
212 return posixpath.join(GetToolchainBinDir(toolchain, arch), full_tool_name)
215 def GetCFlags(toolchain):
216 ExpectToolchain(toolchain, VALID_TOOLCHAINS)
217 return ' '.join('-I%s' % dirname for dirname in GetSDKIncludeDirs(toolchain))
220 def GetIncludeDirs(toolchain):
221 ExpectToolchain(toolchain, VALID_TOOLCHAINS)
222 return ' '.join(GetSDKIncludeDirs(toolchain))
225 def GetLDFlags():
226 return '-L%s' % GetSDKLibDir()
229 def main(args):
230 parser = argparse.ArgumentParser(description=__doc__)
231 parser.add_argument('-t', '--toolchain', help='toolchain name. This can also '
232 'be specified with the NACL_TOOLCHAIN environment '
233 'variable.')
234 parser.add_argument('-a', '--arch', help='architecture name. This can also '
235 'be specified with the NACL_ARCH environment variable.')
237 group = parser.add_argument_group('Commands')
238 group.add_argument('--tool', help='get tool path')
239 group.add_argument('--cflags',
240 help='output all preprocessor and compiler flags',
241 action='store_true')
242 group.add_argument('--libs', '--ldflags', help='output all linker flags',
243 action='store_true')
244 group.add_argument('--include-dirs',
245 help='output include dirs, separated by spaces',
246 action='store_true')
248 options = parser.parse_args(args)
250 # Get toolchain/arch from environment, if not specified on commandline
251 options.toolchain = options.toolchain or os.getenv('NACL_TOOLCHAIN')
252 options.arch = options.arch or os.getenv('NACL_ARCH')
254 options.toolchain = CanonicalizeToolchain(options.toolchain)
255 CheckValidToolchainArch(options.toolchain, options.arch)
257 if options.cflags:
258 print GetCFlags(options.toolchain)
259 elif options.include_dirs:
260 print GetIncludeDirs(options.toolchain)
261 elif options.libs:
262 print GetLDFlags()
263 elif options.tool:
264 print GetToolPath(options.toolchain, options.arch, options.tool)
265 else:
266 parser.error('Expected a command. Run with --help for more information.')
268 return 0
271 if __name__ == '__main__':
272 try:
273 sys.exit(main(sys.argv[1:]))
274 except Error as e:
275 sys.stderr.write(str(e) + '\n')
276 sys.exit(1)