jl777
9 years ago
22 changed files with 1673 additions and 168 deletions
@ -0,0 +1,107 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
# Copyright (c) 2013 The Chromium Authors. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""Fixup GCC-generated dependency files. |
||||
|
|
||||
|
Modify GCC generated dependency files so they are more suitable for including |
||||
|
in a GNU Makefile. Without the fixups, deleting or renaming headers can cause |
||||
|
the build to be broken. |
||||
|
|
||||
|
See http://mad-scientist.net/make/autodep.html for more details of the problem. |
||||
|
""" |
||||
|
|
||||
|
import argparse |
||||
|
import os |
||||
|
import sys |
||||
|
|
||||
|
TAG_LINE = '# Updated by fix_deps.py\n' |
||||
|
|
||||
|
|
||||
|
class Error(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
def ParseLine(line, new_target): |
||||
|
"""Parse one line of a GCC-generated deps file. |
||||
|
|
||||
|
Each line contains an optional target and then a list |
||||
|
of space seperated dependencies. Spaces within filenames |
||||
|
are escaped with a backslash. |
||||
|
""" |
||||
|
filenames = [] |
||||
|
|
||||
|
if new_target and ':' in line: |
||||
|
line = line.split(':', 1)[1] |
||||
|
|
||||
|
line = line.strip() |
||||
|
line = line.rstrip('\\') |
||||
|
|
||||
|
while True: |
||||
|
# Find the next non-escaped space |
||||
|
line = line.strip() |
||||
|
pos = line.find(' ') |
||||
|
while pos > 0 and line[pos-1] == '\\': |
||||
|
pos = line.find(' ', pos+1) |
||||
|
|
||||
|
if pos == -1: |
||||
|
filenames.append(line) |
||||
|
break |
||||
|
filenames.append(line[:pos]) |
||||
|
line = line[pos+1:] |
||||
|
|
||||
|
return filenames |
||||
|
|
||||
|
|
||||
|
def FixupDepFile(filename, output_filename=None): |
||||
|
if not os.path.exists(filename): |
||||
|
raise Error('File not found: %s' % filename) |
||||
|
|
||||
|
if output_filename is None: |
||||
|
output_filename = filename |
||||
|
|
||||
|
outlines = [TAG_LINE] |
||||
|
deps = [] |
||||
|
new_target = True |
||||
|
with open(filename) as infile: |
||||
|
for line in infile: |
||||
|
if line == TAG_LINE: |
||||
|
raise Error('Already processed: %s' % filename) |
||||
|
outlines.append(line) |
||||
|
deps += ParseLine(line, new_target) |
||||
|
new_target = line.endswith('\\') |
||||
|
|
||||
|
# For every depenency found output a dummy target with no rules |
||||
|
for dep in deps: |
||||
|
outlines.append('%s:\n' % dep) |
||||
|
|
||||
|
with open(output_filename, 'w') as outfile: |
||||
|
for line in outlines: |
||||
|
outfile.write(line) |
||||
|
|
||||
|
|
||||
|
def main(argv): |
||||
|
parser = argparse.ArgumentParser(description=__doc__) |
||||
|
parser.add_argument('-o', '--output', help='Output filename (defaults to ' |
||||
|
'input name with .deps extension') |
||||
|
parser.add_argument('-c', '--clean', action='store_true', |
||||
|
help='Remove input file after writing output') |
||||
|
parser.add_argument('dep_file') |
||||
|
options = parser.parse_args(argv) |
||||
|
output_filename = options.output |
||||
|
if not output_filename: |
||||
|
output_filename = os.path.splitext(options.dep_file)[0] + '.deps' |
||||
|
FixupDepFile(options.dep_file, output_filename) |
||||
|
if options.clean and options.dep_file != output_filename: |
||||
|
os.remove(options.dep_file) |
||||
|
|
||||
|
return 0 |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
try: |
||||
|
sys.exit(main(sys.argv[1:])) |
||||
|
except Error as e: |
||||
|
sys.stderr.write('%s: %s\n' % (os.path.basename(__file__), e)) |
||||
|
sys.exit(1) |
@ -0,0 +1,276 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
# Copyright 2013 The Chromium Authors. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""A helper script to print paths of NaCl binaries, includes, libs, etc. |
||||
|
|
||||
|
It is similar in behavior to pkg-config or sdl-config. |
||||
|
""" |
||||
|
|
||||
|
import argparse |
||||
|
import os |
||||
|
import posixpath |
||||
|
import sys |
||||
|
|
||||
|
import getos |
||||
|
|
||||
|
|
||||
|
if sys.version_info < (2, 7, 0): |
||||
|
sys.stderr.write("python 2.7 or later is required run this script\n") |
||||
|
sys.exit(1) |
||||
|
|
||||
|
|
||||
|
VALID_ARCHES = ('arm', 'x86_32', 'x86_64', 'i686') |
||||
|
VALID_PNACL_ARCHES = (None, 'pnacl') |
||||
|
ARCH_NAME = { |
||||
|
'arm': 'arm', |
||||
|
'x86_32': 'i686', |
||||
|
'i686': 'i686', |
||||
|
'x86_64': 'x86_64' |
||||
|
} |
||||
|
|
||||
|
ARCH_ALT_NAME = { |
||||
|
'arm': 'arm', |
||||
|
'x86_32': 'x86_32', |
||||
|
'i686': 'x86_32', |
||||
|
'x86_64': 'x86_64' |
||||
|
} |
||||
|
|
||||
|
ARCH_BASE_NAME = { |
||||
|
'arm': 'arm', |
||||
|
'x86_32': 'x86', |
||||
|
'i686': 'x86', |
||||
|
'x86_64': 'x86' |
||||
|
} |
||||
|
|
||||
|
NACL_TOOLCHAINS = ('newlib', 'glibc', 'pnacl', 'bionic', 'clang-newlib') |
||||
|
HOST_TOOLCHAINS = ('linux', 'mac', 'win') |
||||
|
VALID_TOOLCHAINS = list(HOST_TOOLCHAINS) + list(NACL_TOOLCHAINS) + ['host'] |
||||
|
|
||||
|
# This is not an exhaustive list of tools, just the ones that need to be |
||||
|
# special-cased. |
||||
|
|
||||
|
# e.g. For PNaCL cc => pnacl-clang |
||||
|
# For NaCl cc => pnacl-gcc |
||||
|
# |
||||
|
# Most tools will be passed through directly. |
||||
|
# e.g. For PNaCl foo => pnacl-foo |
||||
|
# For NaCl foo => x86_64-nacl-foo. |
||||
|
CLANG_TOOLS = { |
||||
|
'cc': 'clang', |
||||
|
'c++': 'clang++', |
||||
|
'gcc': 'clang', |
||||
|
'g++': 'clang++', |
||||
|
'ld': 'clang++' |
||||
|
} |
||||
|
|
||||
|
GCC_TOOLS = { |
||||
|
'cc': 'gcc', |
||||
|
'c++': 'g++', |
||||
|
'gcc': 'gcc', |
||||
|
'g++': 'g++', |
||||
|
'ld': 'g++' |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class Error(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
def Expect(condition, message): |
||||
|
if not condition: |
||||
|
raise Error(message) |
||||
|
|
||||
|
|
||||
|
def ExpectToolchain(toolchain, expected_toolchains): |
||||
|
Expect(toolchain in expected_toolchains, |
||||
|
'Expected toolchain to be one of [%s], not %s.' % ( |
||||
|
', '.join(expected_toolchains), toolchain)) |
||||
|
|
||||
|
|
||||
|
def ExpectArch(arch, expected_arches): |
||||
|
Expect(arch in expected_arches, |
||||
|
'Expected arch to be one of [%s], not %s.' % ( |
||||
|
', '.join(map(str, expected_arches)), arch)) |
||||
|
|
||||
|
|
||||
|
def CheckValidToolchainArch(toolchain, arch, arch_required=False): |
||||
|
if toolchain or arch or arch_required: |
||||
|
ExpectToolchain(toolchain, VALID_TOOLCHAINS) |
||||
|
|
||||
|
if toolchain in HOST_TOOLCHAINS: |
||||
|
Expect(arch is None, |
||||
|
'Expected no arch for host toolchain %r. Got %r.' % ( |
||||
|
toolchain, arch)) |
||||
|
elif toolchain == 'pnacl': |
||||
|
Expect(arch is None or arch == 'pnacl', |
||||
|
'Expected no arch for toolchain %r. Got %r.' % (toolchain, arch)) |
||||
|
elif arch_required: |
||||
|
Expect(arch is not None, |
||||
|
'Expected arch to be one of [%s] for toolchain %r.\n' |
||||
|
'Use the -a or --arch flags to specify one.\n' % ( |
||||
|
', '.join(VALID_ARCHES), toolchain)) |
||||
|
|
||||
|
if arch: |
||||
|
if toolchain == 'pnacl': |
||||
|
ExpectArch(arch, VALID_PNACL_ARCHES) |
||||
|
else: |
||||
|
ExpectArch(arch, VALID_ARCHES) |
||||
|
|
||||
|
if arch == 'arm': |
||||
|
Expect(toolchain in ['newlib', 'bionic', 'clang-newlib'], |
||||
|
'The arm arch only supports newlib.') |
||||
|
|
||||
|
|
||||
|
def GetArchName(arch): |
||||
|
return ARCH_NAME.get(arch) |
||||
|
|
||||
|
|
||||
|
def GetArchAltName(arch): |
||||
|
return ARCH_ALT_NAME.get(arch) |
||||
|
|
||||
|
|
||||
|
def GetArchBaseName(arch): |
||||
|
return ARCH_BASE_NAME.get(arch) |
||||
|
|
||||
|
|
||||
|
def CanonicalizeToolchain(toolchain): |
||||
|
if toolchain == 'host': |
||||
|
return getos.GetPlatform() |
||||
|
return toolchain |
||||
|
|
||||
|
|
||||
|
def GetPosixSDKPath(): |
||||
|
sdk_path = getos.GetSDKPath() |
||||
|
if getos.GetPlatform() == 'win': |
||||
|
return sdk_path.replace('\\', '/') |
||||
|
else: |
||||
|
return sdk_path |
||||
|
|
||||
|
|
||||
|
def GetToolchainDir(toolchain, arch=None): |
||||
|
ExpectToolchain(toolchain, NACL_TOOLCHAINS) |
||||
|
root = GetPosixSDKPath() |
||||
|
platform = getos.GetPlatform() |
||||
|
if toolchain in ('pnacl', 'clang-newlib'): |
||||
|
subdir = '%s_pnacl' % platform |
||||
|
else: |
||||
|
assert arch is not None |
||||
|
subdir = '%s_%s_%s' % (platform, GetArchBaseName(arch), toolchain) |
||||
|
|
||||
|
return posixpath.join(root, 'toolchain', subdir) |
||||
|
|
||||
|
|
||||
|
def GetToolchainArchDir(toolchain, arch): |
||||
|
ExpectToolchain(toolchain, NACL_TOOLCHAINS) |
||||
|
assert arch is not None |
||||
|
toolchain_dir = GetToolchainDir(toolchain, arch) |
||||
|
arch_dir = '%s-nacl' % GetArchName(arch) |
||||
|
return posixpath.join(toolchain_dir, arch_dir) |
||||
|
|
||||
|
|
||||
|
def GetToolchainBinDir(toolchain, arch=None): |
||||
|
ExpectToolchain(toolchain, NACL_TOOLCHAINS) |
||||
|
return posixpath.join(GetToolchainDir(toolchain, arch), 'bin') |
||||
|
|
||||
|
|
||||
|
def GetSDKIncludeDirs(toolchain): |
||||
|
root = GetPosixSDKPath() |
||||
|
base_include = posixpath.join(root, 'include') |
||||
|
if toolchain == 'clang-newlib': |
||||
|
toolchain = 'newlib' |
||||
|
return [base_include, posixpath.join(base_include, toolchain)] |
||||
|
|
||||
|
|
||||
|
def GetSDKLibDir(): |
||||
|
return posixpath.join(GetPosixSDKPath(), 'lib') |
||||
|
|
||||
|
|
||||
|
# Commands |
||||
|
|
||||
|
def GetToolPath(toolchain, arch, tool): |
||||
|
if tool == 'gdb': |
||||
|
# Always use the same gdb; it supports multiple toolchains/architectures. |
||||
|
# NOTE: this is always a i686 executable. i686-nacl-gdb is a symlink to |
||||
|
# x86_64-nacl-gdb. |
||||
|
return posixpath.join(GetToolchainBinDir('newlib', 'x86_64'), |
||||
|
'x86_64-nacl-gdb') |
||||
|
|
||||
|
if toolchain == 'pnacl': |
||||
|
CheckValidToolchainArch(toolchain, arch) |
||||
|
tool = CLANG_TOOLS.get(tool, tool) |
||||
|
full_tool_name = 'pnacl-%s' % tool |
||||
|
else: |
||||
|
CheckValidToolchainArch(toolchain, arch, arch_required=True) |
||||
|
ExpectArch(arch, VALID_ARCHES) |
||||
|
if toolchain == 'clang-newlib': |
||||
|
tool = CLANG_TOOLS.get(tool, tool) |
||||
|
else: |
||||
|
tool = GCC_TOOLS.get(tool, tool) |
||||
|
full_tool_name = '%s-nacl-%s' % (GetArchName(arch), tool) |
||||
|
return posixpath.join(GetToolchainBinDir(toolchain, arch), full_tool_name) |
||||
|
|
||||
|
|
||||
|
def GetCFlags(toolchain): |
||||
|
ExpectToolchain(toolchain, VALID_TOOLCHAINS) |
||||
|
return ' '.join('-I%s' % dirname for dirname in GetSDKIncludeDirs(toolchain)) |
||||
|
|
||||
|
|
||||
|
def GetIncludeDirs(toolchain): |
||||
|
ExpectToolchain(toolchain, VALID_TOOLCHAINS) |
||||
|
return ' '.join(GetSDKIncludeDirs(toolchain)) |
||||
|
|
||||
|
|
||||
|
def GetLDFlags(): |
||||
|
return '-L%s' % GetSDKLibDir() |
||||
|
|
||||
|
|
||||
|
def main(args): |
||||
|
parser = argparse.ArgumentParser(description=__doc__) |
||||
|
parser.add_argument('-t', '--toolchain', help='toolchain name. This can also ' |
||||
|
'be specified with the NACL_TOOLCHAIN environment ' |
||||
|
'variable.') |
||||
|
parser.add_argument('-a', '--arch', help='architecture name. This can also ' |
||||
|
'be specified with the NACL_ARCH environment variable.') |
||||
|
|
||||
|
group = parser.add_argument_group('Commands') |
||||
|
group.add_argument('--tool', help='get tool path') |
||||
|
group.add_argument('--cflags', |
||||
|
help='output all preprocessor and compiler flags', |
||||
|
action='store_true') |
||||
|
group.add_argument('--libs', '--ldflags', help='output all linker flags', |
||||
|
action='store_true') |
||||
|
group.add_argument('--include-dirs', |
||||
|
help='output include dirs, separated by spaces', |
||||
|
action='store_true') |
||||
|
|
||||
|
options = parser.parse_args(args) |
||||
|
|
||||
|
# Get toolchain/arch from environment, if not specified on commandline |
||||
|
options.toolchain = options.toolchain or os.getenv('NACL_TOOLCHAIN') |
||||
|
options.arch = options.arch or os.getenv('NACL_ARCH') |
||||
|
|
||||
|
options.toolchain = CanonicalizeToolchain(options.toolchain) |
||||
|
CheckValidToolchainArch(options.toolchain, options.arch) |
||||
|
|
||||
|
if options.cflags: |
||||
|
print GetCFlags(options.toolchain) |
||||
|
elif options.include_dirs: |
||||
|
print GetIncludeDirs(options.toolchain) |
||||
|
elif options.libs: |
||||
|
print GetLDFlags() |
||||
|
elif options.tool: |
||||
|
print GetToolPath(options.toolchain, options.arch, options.tool) |
||||
|
else: |
||||
|
parser.error('Expected a command. Run with --help for more information.') |
||||
|
|
||||
|
return 0 |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
try: |
||||
|
sys.exit(main(sys.argv[1:])) |
||||
|
except Error as e: |
||||
|
sys.stderr.write(str(e) + '\n') |
||||
|
sys.exit(1) |
@ -0,0 +1,107 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
# Copyright (c) 2013 The Chromium Authors. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""Fixup GCC-generated dependency files. |
||||
|
|
||||
|
Modify GCC generated dependency files so they are more suitable for including |
||||
|
in a GNU Makefile. Without the fixups, deleting or renaming headers can cause |
||||
|
the build to be broken. |
||||
|
|
||||
|
See http://mad-scientist.net/make/autodep.html for more details of the problem. |
||||
|
""" |
||||
|
|
||||
|
import argparse |
||||
|
import os |
||||
|
import sys |
||||
|
|
||||
|
TAG_LINE = '# Updated by fix_deps.py\n' |
||||
|
|
||||
|
|
||||
|
class Error(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
def ParseLine(line, new_target): |
||||
|
"""Parse one line of a GCC-generated deps file. |
||||
|
|
||||
|
Each line contains an optional target and then a list |
||||
|
of space seperated dependencies. Spaces within filenames |
||||
|
are escaped with a backslash. |
||||
|
""" |
||||
|
filenames = [] |
||||
|
|
||||
|
if new_target and ':' in line: |
||||
|
line = line.split(':', 1)[1] |
||||
|
|
||||
|
line = line.strip() |
||||
|
line = line.rstrip('\\') |
||||
|
|
||||
|
while True: |
||||
|
# Find the next non-escaped space |
||||
|
line = line.strip() |
||||
|
pos = line.find(' ') |
||||
|
while pos > 0 and line[pos-1] == '\\': |
||||
|
pos = line.find(' ', pos+1) |
||||
|
|
||||
|
if pos == -1: |
||||
|
filenames.append(line) |
||||
|
break |
||||
|
filenames.append(line[:pos]) |
||||
|
line = line[pos+1:] |
||||
|
|
||||
|
return filenames |
||||
|
|
||||
|
|
||||
|
def FixupDepFile(filename, output_filename=None): |
||||
|
if not os.path.exists(filename): |
||||
|
raise Error('File not found: %s' % filename) |
||||
|
|
||||
|
if output_filename is None: |
||||
|
output_filename = filename |
||||
|
|
||||
|
outlines = [TAG_LINE] |
||||
|
deps = [] |
||||
|
new_target = True |
||||
|
with open(filename) as infile: |
||||
|
for line in infile: |
||||
|
if line == TAG_LINE: |
||||
|
raise Error('Already processed: %s' % filename) |
||||
|
outlines.append(line) |
||||
|
deps += ParseLine(line, new_target) |
||||
|
new_target = line.endswith('\\') |
||||
|
|
||||
|
# For every depenency found output a dummy target with no rules |
||||
|
for dep in deps: |
||||
|
outlines.append('%s:\n' % dep) |
||||
|
|
||||
|
with open(output_filename, 'w') as outfile: |
||||
|
for line in outlines: |
||||
|
outfile.write(line) |
||||
|
|
||||
|
|
||||
|
def main(argv): |
||||
|
parser = argparse.ArgumentParser(description=__doc__) |
||||
|
parser.add_argument('-o', '--output', help='Output filename (defaults to ' |
||||
|
'input name with .deps extension') |
||||
|
parser.add_argument('-c', '--clean', action='store_true', |
||||
|
help='Remove input file after writing output') |
||||
|
parser.add_argument('dep_file') |
||||
|
options = parser.parse_args(argv) |
||||
|
output_filename = options.output |
||||
|
if not output_filename: |
||||
|
output_filename = os.path.splitext(options.dep_file)[0] + '.deps' |
||||
|
FixupDepFile(options.dep_file, output_filename) |
||||
|
if options.clean and options.dep_file != output_filename: |
||||
|
os.remove(options.dep_file) |
||||
|
|
||||
|
return 0 |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
try: |
||||
|
sys.exit(main(sys.argv[1:])) |
||||
|
except Error as e: |
||||
|
sys.stderr.write('%s: %s\n' % (os.path.basename(__file__), e)) |
||||
|
sys.exit(1) |
@ -0,0 +1,275 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
# Copyright (c) 2012 The Chromium Authors. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""Determine OS and various other system properties. |
||||
|
|
||||
|
Determine the name of the platform used and other system properties such as |
||||
|
the location of Chrome. This is used, for example, to determine the correct |
||||
|
Toolchain to invoke. |
||||
|
""" |
||||
|
|
||||
|
import argparse |
||||
|
import os |
||||
|
import re |
||||
|
import subprocess |
||||
|
import sys |
||||
|
|
||||
|
import oshelpers |
||||
|
|
||||
|
|
||||
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
||||
|
CHROME_DEFAULT_PATH = { |
||||
|
'win': r'c:\Program Files (x86)\Google\Chrome\Application\chrome.exe', |
||||
|
'mac': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', |
||||
|
'linux': '/usr/bin/google-chrome', |
||||
|
} |
||||
|
|
||||
|
|
||||
|
if sys.version_info < (2, 7, 0): |
||||
|
sys.stderr.write("python 2.7 or later is required run this script\n") |
||||
|
sys.exit(1) |
||||
|
|
||||
|
|
||||
|
class Error(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
def GetSDKPath(): |
||||
|
return os.getenv('NACL_SDK_ROOT', os.path.dirname(SCRIPT_DIR)) |
||||
|
|
||||
|
|
||||
|
def GetPlatform(): |
||||
|
if sys.platform.startswith('cygwin') or sys.platform.startswith('win'): |
||||
|
return 'win' |
||||
|
elif sys.platform.startswith('darwin'): |
||||
|
return 'mac' |
||||
|
elif sys.platform.startswith('linux'): |
||||
|
return 'linux' |
||||
|
else: |
||||
|
raise Error("Unknown platform: %s" % sys.platform) |
||||
|
|
||||
|
|
||||
|
def UseWin64(): |
||||
|
arch32 = os.environ.get('PROCESSOR_ARCHITECTURE') |
||||
|
arch64 = os.environ.get('PROCESSOR_ARCHITEW6432') |
||||
|
|
||||
|
if arch32 == 'AMD64' or arch64 == 'AMD64': |
||||
|
return True |
||||
|
return False |
||||
|
|
||||
|
|
||||
|
def GetSDKVersion(): |
||||
|
root = GetSDKPath() |
||||
|
readme = os.path.join(root, "README") |
||||
|
if not os.path.exists(readme): |
||||
|
raise Error("README not found in SDK root: %s" % root) |
||||
|
|
||||
|
version = None |
||||
|
revision = None |
||||
|
commit_position = None |
||||
|
for line in open(readme): |
||||
|
if ':' in line: |
||||
|
name, value = line.split(':', 1) |
||||
|
if name == "Version": |
||||
|
version = value.strip() |
||||
|
if name == "Chrome Revision": |
||||
|
revision = value.strip() |
||||
|
if name == "Chrome Commit Position": |
||||
|
commit_position = value.strip() |
||||
|
|
||||
|
if revision is None or version is None or commit_position is None: |
||||
|
raise Error("error parsing SDK README: %s" % readme) |
||||
|
|
||||
|
try: |
||||
|
version = int(version) |
||||
|
revision = int(revision) |
||||
|
except ValueError: |
||||
|
raise Error("error parsing SDK README: %s" % readme) |
||||
|
|
||||
|
return (version, revision, commit_position) |
||||
|
|
||||
|
|
||||
|
def GetSystemArch(platform): |
||||
|
if platform == 'win': |
||||
|
if UseWin64(): |
||||
|
return 'x86_64' |
||||
|
return 'x86_32' |
||||
|
|
||||
|
if platform in ['mac', 'linux']: |
||||
|
try: |
||||
|
pobj = subprocess.Popen(['uname', '-m'], stdout= subprocess.PIPE) |
||||
|
arch = pobj.communicate()[0] |
||||
|
arch = arch.split()[0] |
||||
|
if arch.startswith('arm'): |
||||
|
arch = 'arm' |
||||
|
except Exception: |
||||
|
arch = None |
||||
|
return arch |
||||
|
|
||||
|
|
||||
|
def GetChromePath(platform): |
||||
|
# If CHROME_PATH is defined and exists, use that. |
||||
|
chrome_path = os.environ.get('CHROME_PATH') |
||||
|
if chrome_path: |
||||
|
if not os.path.exists(chrome_path): |
||||
|
raise Error('Invalid CHROME_PATH: %s' % chrome_path) |
||||
|
return os.path.realpath(chrome_path) |
||||
|
|
||||
|
# Otherwise look in the PATH environment variable. |
||||
|
basename = os.path.basename(CHROME_DEFAULT_PATH[platform]) |
||||
|
chrome_path = oshelpers.FindExeInPath(basename) |
||||
|
if chrome_path: |
||||
|
return os.path.realpath(chrome_path) |
||||
|
|
||||
|
# Finally, try the default paths to Chrome. |
||||
|
chrome_path = CHROME_DEFAULT_PATH[platform] |
||||
|
if os.path.exists(chrome_path): |
||||
|
return os.path.realpath(chrome_path) |
||||
|
|
||||
|
raise Error('CHROME_PATH is undefined, and %s not found in PATH, nor %s.' % ( |
||||
|
basename, chrome_path)) |
||||
|
|
||||
|
|
||||
|
def GetNaClArch(platform): |
||||
|
if platform == 'win': |
||||
|
# On windows the nacl arch always matches to system arch |
||||
|
return GetSystemArch(platform) |
||||
|
elif platform == 'mac': |
||||
|
# On Mac the nacl arch is currently always 32-bit. |
||||
|
return 'x86_32' |
||||
|
|
||||
|
# On linux the nacl arch matches to chrome arch, so we inspect the chrome |
||||
|
# binary using objdump |
||||
|
chrome_path = GetChromePath(platform) |
||||
|
|
||||
|
# If CHROME_PATH is set to point to google-chrome or google-chrome |
||||
|
# was found in the PATH and we are running on UNIX then google-chrome |
||||
|
# is a bash script that points to 'chrome' in the same folder. |
||||
|
# |
||||
|
# When running beta or dev branch, the name is google-chrome-{beta,dev}. |
||||
|
if os.path.basename(chrome_path).startswith('google-chrome'): |
||||
|
chrome_path = os.path.join(os.path.dirname(chrome_path), 'chrome') |
||||
|
|
||||
|
if not os.path.exists(chrome_path): |
||||
|
raise Error("File %s does not exist." % chrome_path) |
||||
|
|
||||
|
if not os.access(chrome_path, os.X_OK): |
||||
|
raise Error("File %s is not executable" % chrome_path) |
||||
|
|
||||
|
try: |
||||
|
pobj = subprocess.Popen(['objdump', '-f', chrome_path], |
||||
|
stdout=subprocess.PIPE, |
||||
|
stderr=subprocess.PIPE) |
||||
|
output, stderr = pobj.communicate() |
||||
|
# error out here if objdump failed |
||||
|
if pobj.returncode: |
||||
|
raise Error(output + stderr.strip()) |
||||
|
except OSError as e: |
||||
|
# This will happen if objdump is not installed |
||||
|
raise Error("Error running objdump: %s" % e) |
||||
|
|
||||
|
pattern = r'(file format) ([a-zA-Z0-9_\-]+)' |
||||
|
match = re.search(pattern, output) |
||||
|
if not match: |
||||
|
raise Error("Error running objdump on: %s" % chrome_path) |
||||
|
|
||||
|
arch = match.group(2) |
||||
|
if 'arm' in arch: |
||||
|
return 'arm' |
||||
|
if '64' in arch: |
||||
|
return 'x86_64' |
||||
|
return 'x86_32' |
||||
|
|
||||
|
|
||||
|
def ParseVersion(version): |
||||
|
"""Parses a version number of the form '<major>.<position>'. |
||||
|
|
||||
|
<position> is the Cr-Commit-Position number. |
||||
|
""" |
||||
|
if '.' in version: |
||||
|
version = version.split('.') |
||||
|
else: |
||||
|
version = (version, '0') |
||||
|
|
||||
|
try: |
||||
|
return tuple(int(x) for x in version) |
||||
|
except ValueError: |
||||
|
raise Error('error parsing SDK version: %s' % version) |
||||
|
|
||||
|
|
||||
|
def CheckVersion(required_version): |
||||
|
"""Determines whether the current SDK version meets the required version. |
||||
|
|
||||
|
Args: |
||||
|
required_version: (major, position) pair, where position is the |
||||
|
Cr-Commit-Position number. |
||||
|
|
||||
|
Raises: |
||||
|
Error: The SDK version is older than required_version. |
||||
|
""" |
||||
|
version = GetSDKVersion()[:2] |
||||
|
if version < required_version: |
||||
|
raise Error("SDK version too old (current: %d.%d, required: %d.%d)" |
||||
|
% (version[0], version[1], required_version[0], required_version[1])) |
||||
|
|
||||
|
|
||||
|
def main(args): |
||||
|
parser = argparse.ArgumentParser() |
||||
|
parser.add_argument('--arch', action='store_true', |
||||
|
help='Print architecture of current machine (x86_32, x86_64 or arm).') |
||||
|
parser.add_argument('--chrome', action='store_true', |
||||
|
help='Print the path chrome (by first looking in $CHROME_PATH and ' |
||||
|
'then $PATH).') |
||||
|
parser.add_argument('--nacl-arch', action='store_true', |
||||
|
help='Print architecture used by NaCl on the current machine.') |
||||
|
parser.add_argument('--sdk-version', action='store_true', |
||||
|
help='Print major version of the NaCl SDK.') |
||||
|
parser.add_argument('--sdk-revision', action='store_true', |
||||
|
help='Print revision number of the NaCl SDK.') |
||||
|
parser.add_argument('--sdk-commit-position', action='store_true', |
||||
|
help='Print commit position of the NaCl SDK.') |
||||
|
parser.add_argument('--check-version', |
||||
|
metavar='MAJOR.POSITION', |
||||
|
help='Check that the SDK version is at least as great as the ' |
||||
|
'version passed in. MAJOR is the major version number and POSITION ' |
||||
|
'is the Cr-Commit-Position number.') |
||||
|
|
||||
|
if len(args) > 1: |
||||
|
parser.error('Only one option can be specified at a time.') |
||||
|
|
||||
|
options = parser.parse_args(args) |
||||
|
|
||||
|
platform = GetPlatform() |
||||
|
|
||||
|
if options.arch: |
||||
|
out = GetSystemArch(platform) |
||||
|
elif options.nacl_arch: |
||||
|
out = GetNaClArch(platform) |
||||
|
elif options.chrome: |
||||
|
out = GetChromePath(platform) |
||||
|
elif options.sdk_version: |
||||
|
out = GetSDKVersion()[0] |
||||
|
elif options.sdk_revision: |
||||
|
out = GetSDKVersion()[1] |
||||
|
elif options.sdk_commit_position: |
||||
|
out = GetSDKVersion()[2] |
||||
|
elif options.check_version: |
||||
|
required_version = ParseVersion(options.check_version) |
||||
|
CheckVersion(required_version) |
||||
|
out = None |
||||
|
else: |
||||
|
out = platform |
||||
|
|
||||
|
if out: |
||||
|
print out |
||||
|
return 0 |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
try: |
||||
|
sys.exit(main(sys.argv[1:])) |
||||
|
except Error as e: |
||||
|
sys.stderr.write(str(e) + '\n') |
||||
|
sys.exit(1) |
@ -0,0 +1,276 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
# Copyright 2013 The Chromium Authors. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""A helper script to print paths of NaCl binaries, includes, libs, etc. |
||||
|
|
||||
|
It is similar in behavior to pkg-config or sdl-config. |
||||
|
""" |
||||
|
|
||||
|
import argparse |
||||
|
import os |
||||
|
import posixpath |
||||
|
import sys |
||||
|
|
||||
|
import getos |
||||
|
|
||||
|
|
||||
|
if sys.version_info < (2, 7, 0): |
||||
|
sys.stderr.write("python 2.7 or later is required run this script\n") |
||||
|
sys.exit(1) |
||||
|
|
||||
|
|
||||
|
VALID_ARCHES = ('arm', 'x86_32', 'x86_64', 'i686') |
||||
|
VALID_PNACL_ARCHES = (None, 'pnacl') |
||||
|
ARCH_NAME = { |
||||
|
'arm': 'arm', |
||||
|
'x86_32': 'i686', |
||||
|
'i686': 'i686', |
||||
|
'x86_64': 'x86_64' |
||||
|
} |
||||
|
|
||||
|
ARCH_ALT_NAME = { |
||||
|
'arm': 'arm', |
||||
|
'x86_32': 'x86_32', |
||||
|
'i686': 'x86_32', |
||||
|
'x86_64': 'x86_64' |
||||
|
} |
||||
|
|
||||
|
ARCH_BASE_NAME = { |
||||
|
'arm': 'arm', |
||||
|
'x86_32': 'x86', |
||||
|
'i686': 'x86', |
||||
|
'x86_64': 'x86' |
||||
|
} |
||||
|
|
||||
|
NACL_TOOLCHAINS = ('newlib', 'glibc', 'pnacl', 'bionic', 'clang-newlib') |
||||
|
HOST_TOOLCHAINS = ('linux', 'mac', 'win') |
||||
|
VALID_TOOLCHAINS = list(HOST_TOOLCHAINS) + list(NACL_TOOLCHAINS) + ['host'] |
||||
|
|
||||
|
# This is not an exhaustive list of tools, just the ones that need to be |
||||
|
# special-cased. |
||||
|
|
||||
|
# e.g. For PNaCL cc => pnacl-clang |
||||
|
# For NaCl cc => pnacl-gcc |
||||
|
# |
||||
|
# Most tools will be passed through directly. |
||||
|
# e.g. For PNaCl foo => pnacl-foo |
||||
|
# For NaCl foo => x86_64-nacl-foo. |
||||
|
CLANG_TOOLS = { |
||||
|
'cc': 'clang', |
||||
|
'c++': 'clang++', |
||||
|
'gcc': 'clang', |
||||
|
'g++': 'clang++', |
||||
|
'ld': 'clang++' |
||||
|
} |
||||
|
|
||||
|
GCC_TOOLS = { |
||||
|
'cc': 'gcc', |
||||
|
'c++': 'g++', |
||||
|
'gcc': 'gcc', |
||||
|
'g++': 'g++', |
||||
|
'ld': 'g++' |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class Error(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
def Expect(condition, message): |
||||
|
if not condition: |
||||
|
raise Error(message) |
||||
|
|
||||
|
|
||||
|
def ExpectToolchain(toolchain, expected_toolchains): |
||||
|
Expect(toolchain in expected_toolchains, |
||||
|
'Expected toolchain to be one of [%s], not %s.' % ( |
||||
|
', '.join(expected_toolchains), toolchain)) |
||||
|
|
||||
|
|
||||
|
def ExpectArch(arch, expected_arches): |
||||
|
Expect(arch in expected_arches, |
||||
|
'Expected arch to be one of [%s], not %s.' % ( |
||||
|
', '.join(map(str, expected_arches)), arch)) |
||||
|
|
||||
|
|
||||
|
def CheckValidToolchainArch(toolchain, arch, arch_required=False): |
||||
|
if toolchain or arch or arch_required: |
||||
|
ExpectToolchain(toolchain, VALID_TOOLCHAINS) |
||||
|
|
||||
|
if toolchain in HOST_TOOLCHAINS: |
||||
|
Expect(arch is None, |
||||
|
'Expected no arch for host toolchain %r. Got %r.' % ( |
||||
|
toolchain, arch)) |
||||
|
elif toolchain == 'pnacl': |
||||
|
Expect(arch is None or arch == 'pnacl', |
||||
|
'Expected no arch for toolchain %r. Got %r.' % (toolchain, arch)) |
||||
|
elif arch_required: |
||||
|
Expect(arch is not None, |
||||
|
'Expected arch to be one of [%s] for toolchain %r.\n' |
||||
|
'Use the -a or --arch flags to specify one.\n' % ( |
||||
|
', '.join(VALID_ARCHES), toolchain)) |
||||
|
|
||||
|
if arch: |
||||
|
if toolchain == 'pnacl': |
||||
|
ExpectArch(arch, VALID_PNACL_ARCHES) |
||||
|
else: |
||||
|
ExpectArch(arch, VALID_ARCHES) |
||||
|
|
||||
|
if arch == 'arm': |
||||
|
Expect(toolchain in ['newlib', 'bionic', 'clang-newlib'], |
||||
|
'The arm arch only supports newlib.') |
||||
|
|
||||
|
|
||||
|
def GetArchName(arch): |
||||
|
return ARCH_NAME.get(arch) |
||||
|
|
||||
|
|
||||
|
def GetArchAltName(arch): |
||||
|
return ARCH_ALT_NAME.get(arch) |
||||
|
|
||||
|
|
||||
|
def GetArchBaseName(arch): |
||||
|
return ARCH_BASE_NAME.get(arch) |
||||
|
|
||||
|
|
||||
|
def CanonicalizeToolchain(toolchain): |
||||
|
if toolchain == 'host': |
||||
|
return getos.GetPlatform() |
||||
|
return toolchain |
||||
|
|
||||
|
|
||||
|
def GetPosixSDKPath(): |
||||
|
sdk_path = getos.GetSDKPath() |
||||
|
if getos.GetPlatform() == 'win': |
||||
|
return sdk_path.replace('\\', '/') |
||||
|
else: |
||||
|
return sdk_path |
||||
|
|
||||
|
|
||||
|
def GetToolchainDir(toolchain, arch=None): |
||||
|
ExpectToolchain(toolchain, NACL_TOOLCHAINS) |
||||
|
root = GetPosixSDKPath() |
||||
|
platform = getos.GetPlatform() |
||||
|
if toolchain in ('pnacl', 'clang-newlib'): |
||||
|
subdir = '%s_pnacl' % platform |
||||
|
else: |
||||
|
assert arch is not None |
||||
|
subdir = '%s_%s_%s' % (platform, GetArchBaseName(arch), toolchain) |
||||
|
|
||||
|
return posixpath.join(root, 'toolchain', subdir) |
||||
|
|
||||
|
|
||||
|
def GetToolchainArchDir(toolchain, arch): |
||||
|
ExpectToolchain(toolchain, NACL_TOOLCHAINS) |
||||
|
assert arch is not None |
||||
|
toolchain_dir = GetToolchainDir(toolchain, arch) |
||||
|
arch_dir = '%s-nacl' % GetArchName(arch) |
||||
|
return posixpath.join(toolchain_dir, arch_dir) |
||||
|
|
||||
|
|
||||
|
def GetToolchainBinDir(toolchain, arch=None): |
||||
|
ExpectToolchain(toolchain, NACL_TOOLCHAINS) |
||||
|
return posixpath.join(GetToolchainDir(toolchain, arch), 'bin') |
||||
|
|
||||
|
|
||||
|
def GetSDKIncludeDirs(toolchain): |
||||
|
root = GetPosixSDKPath() |
||||
|
base_include = posixpath.join(root, 'include') |
||||
|
if toolchain == 'clang-newlib': |
||||
|
toolchain = 'newlib' |
||||
|
return [base_include, posixpath.join(base_include, toolchain)] |
||||
|
|
||||
|
|
||||
|
def GetSDKLibDir(): |
||||
|
return posixpath.join(GetPosixSDKPath(), 'lib') |
||||
|
|
||||
|
|
||||
|
# Commands |
||||
|
|
||||
|
def GetToolPath(toolchain, arch, tool): |
||||
|
if tool == 'gdb': |
||||
|
# Always use the same gdb; it supports multiple toolchains/architectures. |
||||
|
# NOTE: this is always a i686 executable. i686-nacl-gdb is a symlink to |
||||
|
# x86_64-nacl-gdb. |
||||
|
return posixpath.join(GetToolchainBinDir('newlib', 'x86_64'), |
||||
|
'x86_64-nacl-gdb') |
||||
|
|
||||
|
if toolchain == 'pnacl': |
||||
|
CheckValidToolchainArch(toolchain, arch) |
||||
|
tool = CLANG_TOOLS.get(tool, tool) |
||||
|
full_tool_name = 'pnacl-%s' % tool |
||||
|
else: |
||||
|
CheckValidToolchainArch(toolchain, arch, arch_required=True) |
||||
|
ExpectArch(arch, VALID_ARCHES) |
||||
|
if toolchain == 'clang-newlib': |
||||
|
tool = CLANG_TOOLS.get(tool, tool) |
||||
|
else: |
||||
|
tool = GCC_TOOLS.get(tool, tool) |
||||
|
full_tool_name = '%s-nacl-%s' % (GetArchName(arch), tool) |
||||
|
return posixpath.join(GetToolchainBinDir(toolchain, arch), full_tool_name) |
||||
|
|
||||
|
|
||||
|
def GetCFlags(toolchain): |
||||
|
ExpectToolchain(toolchain, VALID_TOOLCHAINS) |
||||
|
return ' '.join('-I%s' % dirname for dirname in GetSDKIncludeDirs(toolchain)) |
||||
|
|
||||
|
|
||||
|
def GetIncludeDirs(toolchain): |
||||
|
ExpectToolchain(toolchain, VALID_TOOLCHAINS) |
||||
|
return ' '.join(GetSDKIncludeDirs(toolchain)) |
||||
|
|
||||
|
|
||||
|
def GetLDFlags(): |
||||
|
return '-L%s' % GetSDKLibDir() |
||||
|
|
||||
|
|
||||
|
def main(args): |
||||
|
parser = argparse.ArgumentParser(description=__doc__) |
||||
|
parser.add_argument('-t', '--toolchain', help='toolchain name. This can also ' |
||||
|
'be specified with the NACL_TOOLCHAIN environment ' |
||||
|
'variable.') |
||||
|
parser.add_argument('-a', '--arch', help='architecture name. This can also ' |
||||
|
'be specified with the NACL_ARCH environment variable.') |
||||
|
|
||||
|
group = parser.add_argument_group('Commands') |
||||
|
group.add_argument('--tool', help='get tool path') |
||||
|
group.add_argument('--cflags', |
||||
|
help='output all preprocessor and compiler flags', |
||||
|
action='store_true') |
||||
|
group.add_argument('--libs', '--ldflags', help='output all linker flags', |
||||
|
action='store_true') |
||||
|
group.add_argument('--include-dirs', |
||||
|
help='output include dirs, separated by spaces', |
||||
|
action='store_true') |
||||
|
|
||||
|
options = parser.parse_args(args) |
||||
|
|
||||
|
# Get toolchain/arch from environment, if not specified on commandline |
||||
|
options.toolchain = options.toolchain or os.getenv('NACL_TOOLCHAIN') |
||||
|
options.arch = options.arch or os.getenv('NACL_ARCH') |
||||
|
|
||||
|
options.toolchain = CanonicalizeToolchain(options.toolchain) |
||||
|
CheckValidToolchainArch(options.toolchain, options.arch) |
||||
|
|
||||
|
if options.cflags: |
||||
|
print GetCFlags(options.toolchain) |
||||
|
elif options.include_dirs: |
||||
|
print GetIncludeDirs(options.toolchain) |
||||
|
elif options.libs: |
||||
|
print GetLDFlags() |
||||
|
elif options.tool: |
||||
|
print GetToolPath(options.toolchain, options.arch, options.tool) |
||||
|
else: |
||||
|
parser.error('Expected a command. Run with --help for more information.') |
||||
|
|
||||
|
return 0 |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
try: |
||||
|
sys.exit(main(sys.argv[1:])) |
||||
|
except Error as e: |
||||
|
sys.stderr.write(str(e) + '\n') |
||||
|
sys.exit(1) |
@ -0,0 +1,107 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
# Copyright (c) 2013 The Chromium Authors. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""Fixup GCC-generated dependency files. |
||||
|
|
||||
|
Modify GCC generated dependency files so they are more suitable for including |
||||
|
in a GNU Makefile. Without the fixups, deleting or renaming headers can cause |
||||
|
the build to be broken. |
||||
|
|
||||
|
See http://mad-scientist.net/make/autodep.html for more details of the problem. |
||||
|
""" |
||||
|
|
||||
|
import argparse |
||||
|
import os |
||||
|
import sys |
||||
|
|
||||
|
TAG_LINE = '# Updated by fix_deps.py\n' |
||||
|
|
||||
|
|
||||
|
class Error(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
def ParseLine(line, new_target): |
||||
|
"""Parse one line of a GCC-generated deps file. |
||||
|
|
||||
|
Each line contains an optional target and then a list |
||||
|
of space seperated dependencies. Spaces within filenames |
||||
|
are escaped with a backslash. |
||||
|
""" |
||||
|
filenames = [] |
||||
|
|
||||
|
if new_target and ':' in line: |
||||
|
line = line.split(':', 1)[1] |
||||
|
|
||||
|
line = line.strip() |
||||
|
line = line.rstrip('\\') |
||||
|
|
||||
|
while True: |
||||
|
# Find the next non-escaped space |
||||
|
line = line.strip() |
||||
|
pos = line.find(' ') |
||||
|
while pos > 0 and line[pos-1] == '\\': |
||||
|
pos = line.find(' ', pos+1) |
||||
|
|
||||
|
if pos == -1: |
||||
|
filenames.append(line) |
||||
|
break |
||||
|
filenames.append(line[:pos]) |
||||
|
line = line[pos+1:] |
||||
|
|
||||
|
return filenames |
||||
|
|
||||
|
|
||||
|
def FixupDepFile(filename, output_filename=None): |
||||
|
if not os.path.exists(filename): |
||||
|
raise Error('File not found: %s' % filename) |
||||
|
|
||||
|
if output_filename is None: |
||||
|
output_filename = filename |
||||
|
|
||||
|
outlines = [TAG_LINE] |
||||
|
deps = [] |
||||
|
new_target = True |
||||
|
with open(filename) as infile: |
||||
|
for line in infile: |
||||
|
if line == TAG_LINE: |
||||
|
raise Error('Already processed: %s' % filename) |
||||
|
outlines.append(line) |
||||
|
deps += ParseLine(line, new_target) |
||||
|
new_target = line.endswith('\\') |
||||
|
|
||||
|
# For every depenency found output a dummy target with no rules |
||||
|
for dep in deps: |
||||
|
outlines.append('%s:\n' % dep) |
||||
|
|
||||
|
with open(output_filename, 'w') as outfile: |
||||
|
for line in outlines: |
||||
|
outfile.write(line) |
||||
|
|
||||
|
|
||||
|
def main(argv): |
||||
|
parser = argparse.ArgumentParser(description=__doc__) |
||||
|
parser.add_argument('-o', '--output', help='Output filename (defaults to ' |
||||
|
'input name with .deps extension') |
||||
|
parser.add_argument('-c', '--clean', action='store_true', |
||||
|
help='Remove input file after writing output') |
||||
|
parser.add_argument('dep_file') |
||||
|
options = parser.parse_args(argv) |
||||
|
output_filename = options.output |
||||
|
if not output_filename: |
||||
|
output_filename = os.path.splitext(options.dep_file)[0] + '.deps' |
||||
|
FixupDepFile(options.dep_file, output_filename) |
||||
|
if options.clean and options.dep_file != output_filename: |
||||
|
os.remove(options.dep_file) |
||||
|
|
||||
|
return 0 |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
try: |
||||
|
sys.exit(main(sys.argv[1:])) |
||||
|
except Error as e: |
||||
|
sys.stderr.write('%s: %s\n' % (os.path.basename(__file__), e)) |
||||
|
sys.exit(1) |
@ -0,0 +1,276 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
# Copyright 2013 The Chromium Authors. All rights reserved. |
||||
|
# Use of this source code is governed by a BSD-style license that can be |
||||
|
# found in the LICENSE file. |
||||
|
|
||||
|
"""A helper script to print paths of NaCl binaries, includes, libs, etc. |
||||
|
|
||||
|
It is similar in behavior to pkg-config or sdl-config. |
||||
|
""" |
||||
|
|
||||
|
import argparse |
||||
|
import os |
||||
|
import posixpath |
||||
|
import sys |
||||
|
|
||||
|
import getos |
||||
|
|
||||
|
|
||||
|
if sys.version_info < (2, 7, 0): |
||||
|
sys.stderr.write("python 2.7 or later is required run this script\n") |
||||
|
sys.exit(1) |
||||
|
|
||||
|
|
||||
|
VALID_ARCHES = ('arm', 'x86_32', 'x86_64', 'i686') |
||||
|
VALID_PNACL_ARCHES = (None, 'pnacl') |
||||
|
ARCH_NAME = { |
||||
|
'arm': 'arm', |
||||
|
'x86_32': 'i686', |
||||
|
'i686': 'i686', |
||||
|
'x86_64': 'x86_64' |
||||
|
} |
||||
|
|
||||
|
ARCH_ALT_NAME = { |
||||
|
'arm': 'arm', |
||||
|
'x86_32': 'x86_32', |
||||
|
'i686': 'x86_32', |
||||
|
'x86_64': 'x86_64' |
||||
|
} |
||||
|
|
||||
|
ARCH_BASE_NAME = { |
||||
|
'arm': 'arm', |
||||
|
'x86_32': 'x86', |
||||
|
'i686': 'x86', |
||||
|
'x86_64': 'x86' |
||||
|
} |
||||
|
|
||||
|
NACL_TOOLCHAINS = ('newlib', 'glibc', 'pnacl', 'bionic', 'clang-newlib') |
||||
|
HOST_TOOLCHAINS = ('linux', 'mac', 'win') |
||||
|
VALID_TOOLCHAINS = list(HOST_TOOLCHAINS) + list(NACL_TOOLCHAINS) + ['host'] |
||||
|
|
||||
|
# This is not an exhaustive list of tools, just the ones that need to be |
||||
|
# special-cased. |
||||
|
|
||||
|
# e.g. For PNaCL cc => pnacl-clang |
||||
|
# For NaCl cc => pnacl-gcc |
||||
|
# |
||||
|
# Most tools will be passed through directly. |
||||
|
# e.g. For PNaCl foo => pnacl-foo |
||||
|
# For NaCl foo => x86_64-nacl-foo. |
||||
|
CLANG_TOOLS = { |
||||
|
'cc': 'clang', |
||||
|
'c++': 'clang++', |
||||
|
'gcc': 'clang', |
||||
|
'g++': 'clang++', |
||||
|
'ld': 'clang++' |
||||
|
} |
||||
|
|
||||
|
GCC_TOOLS = { |
||||
|
'cc': 'gcc', |
||||
|
'c++': 'g++', |
||||
|
'gcc': 'gcc', |
||||
|
'g++': 'g++', |
||||
|
'ld': 'g++' |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class Error(Exception): |
||||
|
pass |
||||
|
|
||||
|
|
||||
|
def Expect(condition, message): |
||||
|
if not condition: |
||||
|
raise Error(message) |
||||
|
|
||||
|
|
||||
|
def ExpectToolchain(toolchain, expected_toolchains): |
||||
|
Expect(toolchain in expected_toolchains, |
||||
|
'Expected toolchain to be one of [%s], not %s.' % ( |
||||
|
', '.join(expected_toolchains), toolchain)) |
||||
|
|
||||
|
|
||||
|
def ExpectArch(arch, expected_arches): |
||||
|
Expect(arch in expected_arches, |
||||
|
'Expected arch to be one of [%s], not %s.' % ( |
||||
|
', '.join(map(str, expected_arches)), arch)) |
||||
|
|
||||
|
|
||||
|
def CheckValidToolchainArch(toolchain, arch, arch_required=False): |
||||
|
if toolchain or arch or arch_required: |
||||
|
ExpectToolchain(toolchain, VALID_TOOLCHAINS) |
||||
|
|
||||
|
if toolchain in HOST_TOOLCHAINS: |
||||
|
Expect(arch is None, |
||||
|
'Expected no arch for host toolchain %r. Got %r.' % ( |
||||
|
toolchain, arch)) |
||||
|
elif toolchain == 'pnacl': |
||||
|
Expect(arch is None or arch == 'pnacl', |
||||
|
'Expected no arch for toolchain %r. Got %r.' % (toolchain, arch)) |
||||
|
elif arch_required: |
||||
|
Expect(arch is not None, |
||||
|
'Expected arch to be one of [%s] for toolchain %r.\n' |
||||
|
'Use the -a or --arch flags to specify one.\n' % ( |
||||
|
', '.join(VALID_ARCHES), toolchain)) |
||||
|
|
||||
|
if arch: |
||||
|
if toolchain == 'pnacl': |
||||
|
ExpectArch(arch, VALID_PNACL_ARCHES) |
||||
|
else: |
||||
|
ExpectArch(arch, VALID_ARCHES) |
||||
|
|
||||
|
if arch == 'arm': |
||||
|
Expect(toolchain in ['newlib', 'bionic', 'clang-newlib'], |
||||
|
'The arm arch only supports newlib.') |
||||
|
|
||||
|
|
||||
|
def GetArchName(arch): |
||||
|
return ARCH_NAME.get(arch) |
||||
|
|
||||
|
|
||||
|
def GetArchAltName(arch): |
||||
|
return ARCH_ALT_NAME.get(arch) |
||||
|
|
||||
|
|
||||
|
def GetArchBaseName(arch): |
||||
|
return ARCH_BASE_NAME.get(arch) |
||||
|
|
||||
|
|
||||
|
def CanonicalizeToolchain(toolchain): |
||||
|
if toolchain == 'host': |
||||
|
return getos.GetPlatform() |
||||
|
return toolchain |
||||
|
|
||||
|
|
||||
|
def GetPosixSDKPath(): |
||||
|
sdk_path = getos.GetSDKPath() |
||||
|
if getos.GetPlatform() == 'win': |
||||
|
return sdk_path.replace('\\', '/') |
||||
|
else: |
||||
|
return sdk_path |
||||
|
|
||||
|
|
||||
|
def GetToolchainDir(toolchain, arch=None): |
||||
|
ExpectToolchain(toolchain, NACL_TOOLCHAINS) |
||||
|
root = GetPosixSDKPath() |
||||
|
platform = getos.GetPlatform() |
||||
|
if toolchain in ('pnacl', 'clang-newlib'): |
||||
|
subdir = '%s_pnacl' % platform |
||||
|
else: |
||||
|
assert arch is not None |
||||
|
subdir = '%s_%s_%s' % (platform, GetArchBaseName(arch), toolchain) |
||||
|
|
||||
|
return posixpath.join(root, 'toolchain', subdir) |
||||
|
|
||||
|
|
||||
|
def GetToolchainArchDir(toolchain, arch): |
||||
|
ExpectToolchain(toolchain, NACL_TOOLCHAINS) |
||||
|
assert arch is not None |
||||
|
toolchain_dir = GetToolchainDir(toolchain, arch) |
||||
|
arch_dir = '%s-nacl' % GetArchName(arch) |
||||
|
return posixpath.join(toolchain_dir, arch_dir) |
||||
|
|
||||
|
|
||||
|
def GetToolchainBinDir(toolchain, arch=None): |
||||
|
ExpectToolchain(toolchain, NACL_TOOLCHAINS) |
||||
|
return posixpath.join(GetToolchainDir(toolchain, arch), 'bin') |
||||
|
|
||||
|
|
||||
|
def GetSDKIncludeDirs(toolchain): |
||||
|
root = GetPosixSDKPath() |
||||
|
base_include = posixpath.join(root, 'include') |
||||
|
if toolchain == 'clang-newlib': |
||||
|
toolchain = 'newlib' |
||||
|
return [base_include, posixpath.join(base_include, toolchain)] |
||||
|
|
||||
|
|
||||
|
def GetSDKLibDir(): |
||||
|
return posixpath.join(GetPosixSDKPath(), 'lib') |
||||
|
|
||||
|
|
||||
|
# Commands |
||||
|
|
||||
|
def GetToolPath(toolchain, arch, tool): |
||||
|
if tool == 'gdb': |
||||
|
# Always use the same gdb; it supports multiple toolchains/architectures. |
||||
|
# NOTE: this is always a i686 executable. i686-nacl-gdb is a symlink to |
||||
|
# x86_64-nacl-gdb. |
||||
|
return posixpath.join(GetToolchainBinDir('newlib', 'x86_64'), |
||||
|
'x86_64-nacl-gdb') |
||||
|
|
||||
|
if toolchain == 'pnacl': |
||||
|
CheckValidToolchainArch(toolchain, arch) |
||||
|
tool = CLANG_TOOLS.get(tool, tool) |
||||
|
full_tool_name = 'pnacl-%s' % tool |
||||
|
else: |
||||
|
CheckValidToolchainArch(toolchain, arch, arch_required=True) |
||||
|
ExpectArch(arch, VALID_ARCHES) |
||||
|
if toolchain == 'clang-newlib': |
||||
|
tool = CLANG_TOOLS.get(tool, tool) |
||||
|
else: |
||||
|
tool = GCC_TOOLS.get(tool, tool) |
||||
|
full_tool_name = '%s-nacl-%s' % (GetArchName(arch), tool) |
||||
|
return posixpath.join(GetToolchainBinDir(toolchain, arch), full_tool_name) |
||||
|
|
||||
|
|
||||
|
def GetCFlags(toolchain): |
||||
|
ExpectToolchain(toolchain, VALID_TOOLCHAINS) |
||||
|
return ' '.join('-I%s' % dirname for dirname in GetSDKIncludeDirs(toolchain)) |
||||
|
|
||||
|
|
||||
|
def GetIncludeDirs(toolchain): |
||||
|
ExpectToolchain(toolchain, VALID_TOOLCHAINS) |
||||
|
return ' '.join(GetSDKIncludeDirs(toolchain)) |
||||
|
|
||||
|
|
||||
|
def GetLDFlags(): |
||||
|
return '-L%s' % GetSDKLibDir() |
||||
|
|
||||
|
|
||||
|
def main(args): |
||||
|
parser = argparse.ArgumentParser(description=__doc__) |
||||
|
parser.add_argument('-t', '--toolchain', help='toolchain name. This can also ' |
||||
|
'be specified with the NACL_TOOLCHAIN environment ' |
||||
|
'variable.') |
||||
|
parser.add_argument('-a', '--arch', help='architecture name. This can also ' |
||||
|
'be specified with the NACL_ARCH environment variable.') |
||||
|
|
||||
|
group = parser.add_argument_group('Commands') |
||||
|
group.add_argument('--tool', help='get tool path') |
||||
|
group.add_argument('--cflags', |
||||
|
help='output all preprocessor and compiler flags', |
||||
|
action='store_true') |
||||
|
group.add_argument('--libs', '--ldflags', help='output all linker flags', |
||||
|
action='store_true') |
||||
|
group.add_argument('--include-dirs', |
||||
|
help='output include dirs, separated by spaces', |
||||
|
action='store_true') |
||||
|
|
||||
|
options = parser.parse_args(args) |
||||
|
|
||||
|
# Get toolchain/arch from environment, if not specified on commandline |
||||
|
options.toolchain = options.toolchain or os.getenv('NACL_TOOLCHAIN') |
||||
|
options.arch = options.arch or os.getenv('NACL_ARCH') |
||||
|
|
||||
|
options.toolchain = CanonicalizeToolchain(options.toolchain) |
||||
|
CheckValidToolchainArch(options.toolchain, options.arch) |
||||
|
|
||||
|
if options.cflags: |
||||
|
print GetCFlags(options.toolchain) |
||||
|
elif options.include_dirs: |
||||
|
print GetIncludeDirs(options.toolchain) |
||||
|
elif options.libs: |
||||
|
print GetLDFlags() |
||||
|
elif options.tool: |
||||
|
print GetToolPath(options.toolchain, options.arch, options.tool) |
||||
|
else: |
||||
|
parser.error('Expected a command. Run with --help for more information.') |
||||
|
|
||||
|
return 0 |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
try: |
||||
|
sys.exit(main(sys.argv[1:])) |
||||
|
except Error as e: |
||||
|
sys.stderr.write(str(e) + '\n') |
||||
|
sys.exit(1) |
Loading…
Reference in new issue