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.
19 if sys
.version_info
< (2, 7, 0):
20 sys
.stderr
.write("python 2.7 or later is required run this script\n")
24 VALID_ARCHES
= ('arm', 'x86_32', 'x86_64', 'i686')
25 VALID_PNACL_ARCHES
= (None, 'pnacl')
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
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.
77 class Error(Exception):
81 def Expect(condition
, 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
:
104 'Expected no arch for host toolchain %r. Got %r.' % (
106 elif toolchain
== 'pnacl':
107 Expect(arch
is None or arch
== 'pnacl',
108 'Expected no arch for toolchain %r. Got %r.' % (toolchain
, arch
))
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
))
116 if toolchain
== 'pnacl':
117 ExpectArch(arch
, VALID_PNACL_ARCHES
)
119 ExpectArch(arch
, VALID_ARCHES
)
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()
144 def GetPosixSDKPath():
145 sdk_path
= getos
.GetSDKPath()
146 if getos
.GetPlatform() == 'win':
147 return sdk_path
.replace('\\', '/')
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
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':
183 return [base_include
, posixpath
.join(base_include
, toolchain
)]
187 return posixpath
.join(GetPosixSDKPath(), 'lib')
192 def GetToolPath(toolchain
, arch
, tool
):
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
197 return posixpath
.join(GetToolchainBinDir('newlib', 'x86_64'),
200 if toolchain
== 'pnacl':
201 CheckValidToolchainArch(toolchain
, arch
)
202 tool
= CLANG_TOOLS
.get(tool
, tool
)
203 full_tool_name
= 'pnacl-%s' % tool
205 CheckValidToolchainArch(toolchain
, arch
, arch_required
=True)
206 ExpectArch(arch
, VALID_ARCHES
)
207 if toolchain
== 'clang-newlib':
208 tool
= CLANG_TOOLS
.get(tool
, tool
)
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
))
226 return '-L%s' % GetSDKLibDir()
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 '
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',
242 group
.add_argument('--libs', '--ldflags', help='output all linker flags',
244 group
.add_argument('--include-dirs',
245 help='output include dirs, separated by spaces',
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
)
258 print GetCFlags(options
.toolchain
)
259 elif options
.include_dirs
:
260 print GetIncludeDirs(options
.toolchain
)
264 print GetToolPath(options
.toolchain
, options
.arch
, options
.tool
)
266 parser
.error('Expected a command. Run with --help for more information.')
271 if __name__
== '__main__':
273 sys
.exit(main(sys
.argv
[1:]))
275 sys
.stderr
.write(str(e
) + '\n')