aboutsummaryrefslogtreecommitdiff
path: root/checkbuild.py
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2015-10-07 14:14:58 -0700
committerDan Albert <danalbert@google.com>2015-10-14 15:56:12 -0700
commita8f9569e21a17d1e8a37c3f6af544183ca44917f (patch)
treef2eda1b466515abc5959b97318ac75e65197496f /checkbuild.py
parent15a30020a8e5ca380db1dc8769bbcbfbc13b3bf1 (diff)
downloadndk-a8f9569e21a17d1e8a37c3f6af544183ca44917f.tar.gz
Add a binutils "build".
Rather than conquer the toolchain/build hellscape, just copy the binutils files out of the prebuilt gcc into their own package. This removes one of dependencies clang has on gcc being present. The other is the target libraries provided by GCC. Bug: http://b/22387400 Change-Id: I08a3985f2e46bee56cdbc7be58183d699310a75f
Diffstat (limited to 'checkbuild.py')
-rw-r--r--checkbuild.py129
1 files changed, 129 insertions, 0 deletions
diff --git a/checkbuild.py b/checkbuild.py
index 7ffd2fba1..8eb09e5d4 100644
--- a/checkbuild.py
+++ b/checkbuild.py
@@ -30,6 +30,7 @@ import shutil
import site
import subprocess
import sys
+import tempfile
site.addsitedir(os.path.join(os.path.dirname(__file__), 'build/lib'))
@@ -37,6 +38,7 @@ import build_support # pylint: disable=import-error
ALL_MODULES = {
+ 'binutils',
'clang',
'gcc',
'gdbserver',
@@ -136,6 +138,132 @@ def common_build_args(out_dir, args):
return build_args
+def fixup_toolchain_triple(toolchain):
+ """Maps toolchain names to their proper triple.
+
+ The x86 toolchains are named stupidly and aren't a proper triple.
+ """
+ return {
+ 'x86': 'i686-linux-android',
+ 'x86_64': 'x86_64-linux-android',
+ }.get(toolchain, toolchain)
+
+
+def get_binutils_files(triple, has_gold):
+ files = [
+ 'ld.bfd',
+ 'nm',
+ 'as',
+ 'objcopy',
+ 'strip',
+ 'objdump',
+ 'ld',
+ 'ar',
+ 'ranlib',
+ ]
+
+ if has_gold:
+ files.append('ld.gold')
+
+ # binutils programs get installed to two locations:
+ # 1: $INSTALL_DIR/bin/$TRIPLE-$PROGRAM
+ # 2: $INSTALL_DIR/$TRIPLE/bin/$PROGRAM
+ #
+ # We need to copy both.
+
+ prefixed_files = []
+ for file_name in files:
+ prefixed_name = '-'.join([triple, file_name])
+ prefixed_files.append(os.path.join('bin', prefixed_name))
+
+ dir_prefixed_files = []
+ for file_name in files:
+ dir_prefixed_files.append(os.path.join(triple, 'bin', file_name))
+
+ ldscripts_dir = os.path.join(triple, 'lib/ldscripts')
+ return prefixed_files + dir_prefixed_files + [ldscripts_dir]
+
+
+def install_file(file_name, src_dir, dst_dir):
+ src_file = os.path.join(src_dir, file_name)
+ dst_file = os.path.join(dst_dir, file_name)
+
+ print('Copying {} to {}...'.format(src_file, dst_file))
+ if os.path.isdir(src_file):
+ _install_dir(src_file, dst_file)
+ elif os.path.islink(src_file):
+ _install_symlink(src_file, dst_file)
+ else:
+ _install_file(src_file, dst_file)
+
+
+def _install_dir(src_dir, dst_dir):
+ parent_dir = os.path.normpath(os.path.join(dst_dir, '..'))
+ if not os.path.exists(parent_dir):
+ os.makedirs(parent_dir)
+ shutil.copytree(src_dir, dst_dir, symlinks=True)
+
+
+def _install_symlink(src_file, dst_file):
+ dirname = os.path.dirname(dst_file)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ link_target = os.readlink(src_file)
+ os.symlink(link_target, dst_file)
+
+
+def _install_file(src_file, dst_file):
+ dirname = os.path.dirname(dst_file)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ # copy2 is just copy followed by copystat (preserves file metadata).
+ shutil.copy2(src_file, dst_file)
+
+
+def pack_binutils(toolchain, host_tag, out_dir, root_dir, binutils_path):
+ archive_name = '-'.join(['binutils', toolchain, host_tag])
+ archive_path = os.path.join(out_dir, archive_name)
+ base_dir = os.path.relpath(binutils_path, root_dir)
+ shutil.make_archive(archive_path, 'bztar', root_dir=root_dir,
+ base_dir=base_dir)
+
+
+def get_prebuilt_gcc(host, arch):
+ tag = build_support.host_to_tag(host)
+ system_subdir = 'prebuilts/ndk/current/toolchains/{}'.format(tag)
+ system_path = build_support.android_path(system_subdir)
+ toolchain = build_support.arch_to_toolchain(arch)
+ toolchain_dir = toolchain + '-4.9'
+ return os.path.join(system_path, toolchain_dir, 'prebuilt')
+
+
+def build_binutils(out_dir, args):
+ print('Extracting binutils package from GCC...')
+
+ arches = build_support.ALL_ARCHITECTURES
+ if args.arch is not None:
+ arches = [args.arch]
+
+ host_tag = build_support.host_to_tag(args.system)
+
+ for arch in arches:
+ toolchain = build_support.arch_to_toolchain(arch)
+ toolchain_path = get_prebuilt_gcc(args.system, arch)
+
+ triple = fixup_toolchain_triple(toolchain)
+ tmpdir = tempfile.mkdtemp()
+ try:
+ install_dir = os.path.join(tmpdir, 'binutils', host_tag,
+ toolchain)
+ os.makedirs(install_dir)
+ has_gold = not triple.startswith('mips')
+ for file_name in get_binutils_files(triple, has_gold):
+ install_file(file_name, toolchain_path, install_dir)
+ pack_binutils(toolchain, host_tag, out_dir, tmpdir, install_dir)
+ finally:
+ shutil.rmtree(tmpdir)
+
+
def build_clang(out_dir, args):
print('Building Clang...')
invoke_build('build-llvm.py', common_build_args(out_dir, args))
@@ -280,6 +408,7 @@ def main():
invoke_build('dev-cleanup.sh')
module_builds = collections.OrderedDict([
+ ('binutils', build_binutils),
('clang', build_clang),
('gcc', build_gcc),
('gdbserver', build_gdbserver),