diff options
author | Dan Albert <danalbert@google.com> | 2015-10-07 14:14:58 -0700 |
---|---|---|
committer | Dan Albert <danalbert@google.com> | 2015-10-14 15:56:12 -0700 |
commit | a8f9569e21a17d1e8a37c3f6af544183ca44917f (patch) | |
tree | f2eda1b466515abc5959b97318ac75e65197496f /checkbuild.py | |
parent | 15a30020a8e5ca380db1dc8769bbcbfbc13b3bf1 (diff) | |
download | ndk-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.py | 129 |
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), |