#!/usr/bin/env python3

#  Copyright 2021 Google, Inc.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at:
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
""" Build BT targets on the host system.

For building, you will first have to stage a platform directory that has the
following structure:
|-common-mk
|-bt
|-external
|-|-rust
|-|-|-vendor

The simplest way to do this is to check out platform2 to another directory (that
is not a subdir of this bt directory), symlink bt there and symlink the rust
vendor repository as well.
"""
import argparse
import multiprocessing
import os
import shutil
import six
import subprocess
import sys
import tarfile
import time

# Use flags required by common-mk (find -type f | grep -nE 'use[.]' {})
COMMON_MK_USES = [
    'asan',
    'coverage',
    'cros_host',
    'fuzzer',
    'fuzzer',
    'msan',
    'profiling',
    'tcmalloc',
    'test',
    'ubsan',
]

# Default use flags.
USE_DEFAULTS = {
    'android': False,
    'bt_nonstandard_codecs': False,
    'test': False,
}

VALID_TARGETS = [
    'all',  # All targets except test and clean
    'clean',  # Clean up output directory
    'docs',  # Build Rust docs
    'main',  # Build the main C++ codebase
    'prepare',  # Prepare the output directory (gn gen + rust setup)
    'rootcanal',  # Build Rust targets for RootCanal
    'rust',  # Build only the rust components + copy artifacts to output dir
    'test',  # Run the unit tests
    'tools',  # Build the host tools (i.e. packetgen)
]

# TODO(b/190750167) - Host tests are disabled until we are full bazel build
HOST_TESTS = [
    # 'bluetooth_test_common',
    # 'bluetoothtbd_test',
    # 'net_test_avrcp',
    # 'net_test_btcore',
    # 'net_test_types',
    # 'net_test_btm_iso',
    # 'net_test_btpackets',
]

BOOTSTRAP_GIT_REPOS = {
    'platform2': 'https://chromium.googlesource.com/chromiumos/platform2',
    'rust_crates': 'https://chromium.googlesource.com/chromiumos/third_party/rust_crates',
    'proto_logging': 'https://android.googlesource.com/platform/frameworks/proto_logging'
}

# List of packages required for linux build
REQUIRED_APT_PACKAGES = [
    'bison',
    'build-essential',
    'curl',
    'debmake',
    'flatbuffers-compiler',
    'flex',
    'g++-multilib',
    'gcc-multilib',
    'generate-ninja',
    'gnupg',
    'gperf',
    'libc++abi-dev',
    'libc++-dev',
    'libdbus-1-dev',
    'libdouble-conversion-dev',
    'libevent-dev',
    'libevent-dev',
    'libflatbuffers-dev',
    'libflatbuffers1',
    'libgl1-mesa-dev',
    'libglib2.0-dev',
    'libgtest-dev',
    'libgmock-dev',
    'liblz4-tool',
    'libncurses5',
    'libnss3-dev',
    'libprotobuf-dev',
    'libre2-9',
    'libre2-dev',
    'libssl-dev',
    'libtinyxml2-dev',
    'libx11-dev',
    'libxml2-utils',
    'ninja-build',
    'openssl',
    'protobuf-compiler',
    'unzip',
    'x11proto-core-dev',
    'xsltproc',
    'zip',
    'zlib1g-dev',
]

# List of cargo packages required for linux build
REQUIRED_CARGO_PACKAGES = ['cxxbridge-cmd']

APT_PKG_LIST = ['apt', '-qq', 'list']
CARGO_PKG_LIST = ['cargo', 'install', '--list']


class UseFlags():

    def __init__(self, use_flags):
        """ Construct the use flags.

        Args:
            use_flags: List of use flags parsed from the command.
        """
        self.flags = {}

        # Import use flags required by common-mk
        for use in COMMON_MK_USES:
            self.set_flag(use, False)

        # Set our defaults
        for use, value in USE_DEFAULTS.items():
            self.set_flag(use, value)

        # Set use flags - value is set to True unless the use starts with -
        # All given use flags always override the defaults
        for use in use_flags:
            value = not use.startswith('-')
            self.set_flag(use, value)

    def set_flag(self, key, value=True):
        setattr(self, key, value)
        self.flags[key] = value


class HostBuild():

    def __init__(self, args):
        """ Construct the builder.

        Args:
            args: Parsed arguments from ArgumentParser
        """
        self.args = args

        # Set jobs to number of cpus unless explicitly set
        self.jobs = self.args.jobs
        if not self.jobs:
            self.jobs = multiprocessing.cpu_count()
            print("Number of jobs = {}".format(self.jobs))

        # Normalize bootstrap dir and make sure it exists
        self.bootstrap_dir = os.path.abspath(self.args.bootstrap_dir)
        os.makedirs(self.bootstrap_dir, exist_ok=True)

        # Output and platform directories are based on bootstrap
        self.output_dir = os.path.join(self.bootstrap_dir, 'output')
        self.platform_dir = os.path.join(self.bootstrap_dir, 'staging')
        self.sysroot = self.args.sysroot
        self.libdir = self.args.libdir
        self.install_dir = os.path.join(self.output_dir, 'install')

        # If default target isn't set, build everything
        self.target = 'all'
        if hasattr(self.args, 'target') and self.args.target:
            self.target = self.args.target

        target_use = self.args.use if self.args.use else []

        # Unless set, always build test code
        if not self.args.notest:
            target_use.append('test')

        self.use = UseFlags(target_use)

        # Validate platform directory
        assert os.path.isdir(self.platform_dir), 'Platform dir does not exist'
        assert os.path.isfile(os.path.join(self.platform_dir, '.gn')), 'Platform dir does not have .gn at root'

        # Make sure output directory exists (or create it)
        os.makedirs(self.output_dir, exist_ok=True)

        # Set some default attributes
        self.libbase_ver = None

        self.configure_environ()

    def _generate_rustflags(self):
        """ Rustflags to include for the build.
      """
        rust_flags = [
            '-L',
            '{}/out/Default'.format(self.output_dir),
            '-C',
            'link-arg=-Wl,--allow-multiple-definition',
        ]

        return ' '.join(rust_flags)

    def configure_environ(self):
        """ Configure environment variables for GN and Cargo.
        """
        self.env = os.environ.copy()

        # Make sure cargo home dir exists and has a bin directory
        cargo_home = os.path.join(self.output_dir, 'cargo_home')
        os.makedirs(cargo_home, exist_ok=True)
        os.makedirs(os.path.join(cargo_home, 'bin'), exist_ok=True)

        # Configure Rust env variables
        self.env['CARGO_TARGET_DIR'] = self.output_dir
        self.env['CARGO_HOME'] = os.path.join(self.output_dir, 'cargo_home')
        self.env['RUSTFLAGS'] = self._generate_rustflags()
        self.env['CXX_ROOT_PATH'] = os.path.join(self.platform_dir, 'bt')

    def run_command(self, target, args, cwd=None, env=None):
        """ Run command and stream the output.
        """
        # Set some defaults
        if not cwd:
            cwd = self.platform_dir
        if not env:
            env = self.env

        log_file = os.path.join(self.output_dir, '{}.log'.format(target))
        with open(log_file, 'wb') as lf:
            rc = 0
            process = subprocess.Popen(args, cwd=cwd, env=env, stdout=subprocess.PIPE)
            while True:
                line = process.stdout.readline()
                print(line.decode('utf-8'), end="")
                lf.write(line)
                if not line:
                    rc = process.poll()
                    if rc is not None:
                        break

                    time.sleep(0.1)

            if rc != 0:
                raise Exception("Return code is {}".format(rc))

    def _get_basever(self):
        if self.libbase_ver:
            return self.libbase_ver

        self.libbase_ver = os.environ.get('BASE_VER', '')
        if not self.libbase_ver:
            base_file = os.path.join(self.sysroot, 'usr/share/libchrome/BASE_VER')
            try:
                with open(base_file, 'r') as f:
                    self.libbase_ver = f.read().strip('\n')
            except:
                self.libbase_ver = 'NOT-INSTALLED'

        return self.libbase_ver

    def _gn_default_output(self):
        return os.path.join(self.output_dir, 'out/Default')

    def _gn_configure(self):
        """ Configure all required parameters for platform2.

        Mostly copied from //common-mk/platform2.py
        """
        clang = not self.args.no_clang

        def to_gn_string(s):
            return '"%s"' % s.replace('"', '\\"')

        def to_gn_list(strs):
            return '[%s]' % ','.join([to_gn_string(s) for s in strs])

        def to_gn_args_args(gn_args):
            for k, v in gn_args.items():
                if isinstance(v, bool):
                    v = str(v).lower()
                elif isinstance(v, list):
                    v = to_gn_list(v)
                elif isinstance(v, six.string_types):
                    v = to_gn_string(v)
                else:
                    raise AssertionError('Unexpected %s, %r=%r' % (type(v), k, v))
                yield '%s=%s' % (k.replace('-', '_'), v)

        gn_args = {
            'platform_subdir': 'bt',
            'cc': 'clang' if clang else 'gcc',
            'cxx': 'clang++' if clang else 'g++',
            'ar': 'llvm-ar' if clang else 'ar',
            'pkg-config': 'pkg-config',
            'clang_cc': clang,
            'clang_cxx': clang,
            'OS': 'linux',
            'sysroot': self.sysroot,
            'libdir': os.path.join(self.sysroot, self.libdir),
            'build_root': self.output_dir,
            'platform2_root': self.platform_dir,
            'libbase_ver': self._get_basever(),
            'enable_exceptions': os.environ.get('CXXEXCEPTIONS', 0) == '1',
            'external_cflags': [],
            'external_cxxflags': ["-DNDEBUG"],
            'enable_werror': False,
        }

        if clang:
            # Make sure to mark the clang use flag as true
            self.use.set_flag('clang', True)
            gn_args['external_cxxflags'] += ['-I/usr/include/']

        gn_args_args = list(to_gn_args_args(gn_args))
        use_args = ['%s=%s' % (k, str(v).lower()) for k, v in self.use.flags.items()]
        gn_args_args += ['use={%s}' % (' '.join(use_args))]

        gn_args = [
            'gn',
            'gen',
        ]

        if self.args.verbose:
            gn_args.append('-v')

        gn_args += [
            '--root=%s' % self.platform_dir,
            '--args=%s' % ' '.join(gn_args_args),
            self._gn_default_output(),
        ]

        if 'PKG_CONFIG_PATH' in self.env:
            print('DEBUG: PKG_CONFIG_PATH is', self.env['PKG_CONFIG_PATH'])

        self.run_command('configure', gn_args)

    def _gn_build(self, target):
        """ Generate the ninja command for the target and run it.
        """
        args = ['%s:%s' % ('bt', target)]
        ninja_args = ['ninja', '-C', self._gn_default_output()]
        if self.jobs:
            ninja_args += ['-j', str(self.jobs)]
        ninja_args += args

        if self.args.verbose:
            ninja_args.append('-v')

        self.run_command('build', ninja_args)

    def _rust_configure(self):
        """ Generate config file at cargo_home so we use vendored crates.
        """
        template = """
        [source.systembt]
        directory = "{}/external/rust/vendor"

        [source.crates-io]
        replace-with = "systembt"
        local-registry = "/nonexistent"
        """

        if not self.args.no_vendored_rust:
            contents = template.format(self.platform_dir)
            with open(os.path.join(self.env['CARGO_HOME'], 'config'), 'w') as f:
                f.write(contents)

    def _rust_build(self):
        """ Run `cargo build` from platform2/bt directory.
        """
        self.run_command('rust', ['cargo', 'build'], cwd=os.path.join(self.platform_dir, 'bt'), env=self.env)

    def _target_prepare(self):
        """ Target to prepare the output directory for building.

        This runs gn gen to generate all rquired files and set up the Rust
        config properly. This will be run
        """
        self._gn_configure()
        self._rust_configure()

    def _target_tools(self):
        """ Build the tools target in an already prepared environment.
        """
        self._gn_build('tools')

        # Also copy bluetooth_packetgen to CARGO_HOME so it's available
        shutil.copy(
            os.path.join(self._gn_default_output(), 'bluetooth_packetgen'), os.path.join(self.env['CARGO_HOME'], 'bin'))

    def _target_docs(self):
        """Build the Rust docs."""
        self.run_command('docs', ['cargo', 'doc'], cwd=os.path.join(self.platform_dir, 'bt'), env=self.env)

    def _target_rust(self):
        """ Build rust artifacts in an already prepared environment.
        """
        self._rust_build()

    def _target_rootcanal(self):
        """ Build rust artifacts for RootCanal in an already prepared environment.
        """
        self.run_command('rust', ['cargo', 'build'], cwd=os.path.join(self.platform_dir, 'bt/tools/rootcanal'), env=self.env)

    def _target_main(self):
        """ Build the main GN artifacts in an already prepared environment.
        """
        self._gn_build('all')

    def _target_test(self):
        """ Runs the host tests.
        """
        # Rust tests first
        rust_test_cmd = ['cargo', 'test']
        if self.args.test_name:
            rust_test_cmd = rust_test_cmd + [self.args.test_name]

        self.run_command('test', rust_test_cmd, cwd=os.path.join(self.platform_dir, 'bt'), env=self.env)
        self.run_command('test', rust_test_cmd, cwd=os.path.join(self.platform_dir, 'bt/tools/rootcanal'), env=self.env)

        # Host tests second based on host test list
        for t in HOST_TESTS:
            self.run_command(
                'test', [os.path.join(self.output_dir, 'out/Default', t)],
                cwd=os.path.join(self.output_dir),
                env=self.env)

    def _target_install(self):
        """ Installs files required to run Floss to install directory.
        """
        # First make the install directory
        prefix = self.install_dir
        os.makedirs(prefix, exist_ok=True)

        # Next save the cwd and change to install directory
        last_cwd = os.getcwd()
        os.chdir(prefix)

        bindir = os.path.join(self.output_dir, 'debug')
        srcdir = os.path.dirname(__file__)

        install_map = [
            {
                'src': os.path.join(bindir, 'btadapterd'),
                'dst': 'usr/libexec/bluetooth/btadapterd',
                'strip': True
            },
            {
                'src': os.path.join(bindir, 'btmanagerd'),
                'dst': 'usr/libexec/bluetooth/btmanagerd',
                'strip': True
            },
            {
                'src': os.path.join(bindir, 'btclient'),
                'dst': 'usr/local/bin/btclient',
                'strip': True
            },
        ]

        for v in install_map:
            src, partial_dst, strip = (v['src'], v['dst'], v['strip'])
            dst = os.path.join(prefix, partial_dst)

            # Create dst directory first and copy file there
            os.makedirs(os.path.dirname(dst), exist_ok=True)
            print('Installing {}'.format(dst))
            shutil.copy(src, dst)

            # Binary should be marked for strip and no-strip option shouldn't be
            # set. No-strip is useful while debugging.
            if strip and not self.args.no_strip:
                self.run_command('install', ['llvm-strip', dst])

        # Put all files into a tar.gz for easier installation
        tar_location = os.path.join(prefix, 'floss.tar.gz')
        with tarfile.open(tar_location, 'w:gz') as tar:
            for v in install_map:
                tar.add(v['dst'])

        print('Tarball created at {}'.format(tar_location))

    def _target_clean(self):
        """ Delete the output directory entirely.
        """
        shutil.rmtree(self.output_dir)

        # Remove Cargo.lock that may have become generated
        try:
            os.remove(os.path.join(self.platform_dir, 'bt', 'Cargo.lock'))
        except FileNotFoundError:
            pass

    def _target_all(self):
        """ Build all common targets (skipping doc, test, and clean).
        """
        self._target_prepare()
        self._target_tools()
        self._target_main()
        self._target_rust()

    def build(self):
        """ Builds according to self.target
        """
        print('Building target ', self.target)

        # Validate that the target is valid
        if self.target not in VALID_TARGETS:
            print('Target {} is not valid. Must be in {}', self.target, VALID_TARGETS)
            return

        if self.target == 'prepare':
            self._target_prepare()
        elif self.target == 'tools':
            self._target_tools()
        elif self.target == 'rootcanal':
            self._target_rootcanal()
        elif self.target == 'rust':
            self._target_rust()
        elif self.target == 'docs':
            self._target_docs()
        elif self.target == 'main':
            self._target_main()
        elif self.target == 'test':
            self._target_test()
        elif self.target == 'clean':
            self._target_clean()
        elif self.target == 'install':
            self._target_install()
        elif self.target == 'all':
            self._target_all()


class Bootstrap():

    def __init__(self, base_dir, bt_dir):
        """ Construct bootstrapper.

        Args:
            base_dir: Where to stage everything.
            bt_dir: Where bluetooth source is kept (will be symlinked)
        """
        self.base_dir = os.path.abspath(base_dir)
        self.bt_dir = os.path.abspath(bt_dir)

        # Create base directory if it doesn't already exist
        os.makedirs(self.base_dir, exist_ok=True)

        if not os.path.isdir(self.bt_dir):
            raise Exception('{} is not a valid directory'.format(self.bt_dir))

        self.git_dir = os.path.join(self.base_dir, 'repos')
        self.staging_dir = os.path.join(self.base_dir, 'staging')
        self.output_dir = os.path.join(self.base_dir, 'output')
        self.external_dir = os.path.join(self.base_dir, 'staging', 'external')

        self.dir_setup_complete = os.path.join(self.base_dir, '.setup-complete')

    def _update_platform2(self):
        """Updates repositories used for build."""
        for repo in BOOTSTRAP_GIT_REPOS.keys():
            cwd = os.path.join(self.git_dir, repo)
            subprocess.check_call(['git', 'pull'], cwd=cwd)

    def _setup_platform2(self):
        """ Set up platform2.

        This will check out all the git repos and symlink everything correctly.
        """

        # Create all directories we will need to use
        for dirpath in [self.git_dir, self.staging_dir, self.output_dir, self.external_dir]:
            os.makedirs(dirpath, exist_ok=True)

        # If already set up, only update platform2
        if os.path.isfile(self.dir_setup_complete):
            print('{} already set-up. Updating instead.'.format(self.base_dir))
            self._update_platform2()
        else:
            # Check out all repos in git directory
            for repo in BOOTSTRAP_GIT_REPOS.values():
                subprocess.check_call(['git', 'clone', repo], cwd=self.git_dir)

        # Symlink things
        symlinks = [
            (os.path.join(self.git_dir, 'platform2', 'common-mk'), os.path.join(self.staging_dir, 'common-mk')),
            (os.path.join(self.git_dir, 'platform2', '.gn'), os.path.join(self.staging_dir, '.gn')),
            (os.path.join(self.bt_dir), os.path.join(self.staging_dir, 'bt')),
            (os.path.join(self.git_dir, 'rust_crates'), os.path.join(self.external_dir, 'rust')),
            (os.path.join(self.git_dir, 'proto_logging'), os.path.join(self.external_dir, 'proto_logging')),
        ]

        # Create symlinks
        for pairs in symlinks:
            (src, dst) = pairs
            try:
                os.unlink(dst)
            except Exception as e:
                print(e)
            os.symlink(src, dst)

        # Write to setup complete file so we don't repeat this step
        with open(self.dir_setup_complete, 'w') as f:
            f.write('Setup complete.')

    def _pretty_print_install(self, install_cmd, packages, line_limit=80):
        """ Pretty print an install command.

        Args:
            install_cmd: Prefixed install command.
            packages: Enumerate packages and append them to install command.
            line_limit: Number of characters per line.

        Return:
            Array of lines to join and print.
        """
        install = [install_cmd]
        line = '  '
        # Remainder needed = space + len(pkg) + space + \
        # Assuming 80 character lines, that's 80 - 3 = 77
        line_limit = line_limit - 3
        for pkg in packages:
            if len(line) + len(pkg) < line_limit:
                line = '{}{} '.format(line, pkg)
            else:
                install.append(line)
                line = '  {} '.format(pkg)

        if len(line) > 0:
            install.append(line)

        return install

    def _check_package_installed(self, package, cmd, predicate):
        """Check that the given package is installed.

        Args:
            package: Check that this package is installed.
            cmd: Command prefix to check if installed (package appended to end)
            predicate: Function/lambda to check if package is installed based
                       on output. Takes string output and returns boolean.

        Return:
            True if package is installed.
        """
        try:
            output = subprocess.check_output(cmd + [package], stderr=subprocess.STDOUT)
            is_installed = predicate(output.decode('utf-8'))
            print('  {} is {}'.format(package, 'installed' if is_installed else 'missing'))

            return is_installed
        except Exception as e:
            print(e)
            return False

    def _get_command_output(self, cmd):
        """Runs the command and gets the output.

        Args:
            cmd: Command to run.

        Return:
            Tuple (Success, Output). Success represents if the command ran ok.
        """
        try:
            output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
            return (True, output.decode('utf-8').split('\n'))
        except Exception as e:
            print(e)
            return (False, "")

    def _print_missing_packages(self):
        """Print any missing packages found via apt.

        This will find any missing packages necessary for build using apt and
        print it out as an apt-get install printf.
        """
        print('Checking for any missing packages...')

        (success, output) = self._get_command_output(APT_PKG_LIST)
        if not success:
            raise Exception("Could not query apt for packages.")

        packages_installed = {}
        for line in output:
            if 'installed' in line:
                split = line.split('/', 2)
                packages_installed[split[0]] = True

        need_packages = []
        for pkg in REQUIRED_APT_PACKAGES:
            if pkg not in packages_installed:
                need_packages.append(pkg)

        # No packages need to be installed
        if len(need_packages) == 0:
            print('+ All required packages are installed')
            return

        install = self._pretty_print_install('sudo apt-get install', need_packages)

        # Print all lines so they can be run in cmdline
        print('Missing system packages. Run the following command: ')
        print(' \\\n'.join(install))

    def _print_missing_rust_packages(self):
        """Print any missing packages found via cargo.

        This will find any missing packages necessary for build using cargo and
        print it out as a cargo-install printf.
        """
        print('Checking for any missing cargo packages...')

        (success, output) = self._get_command_output(CARGO_PKG_LIST)
        if not success:
            raise Exception("Could not query cargo for packages.")

        packages_installed = {}
        for line in output:
            # Cargo installed packages have this format
            # <crate name> <version>:
            #   <binary name>
            # We only care about the crates themselves
            if ':' not in line:
                continue

            split = line.split(' ', 2)
            packages_installed[split[0]] = True

        need_packages = []
        for pkg in REQUIRED_CARGO_PACKAGES:
            if pkg not in packages_installed:
                need_packages.append(pkg)

        # No packages to be installed
        if len(need_packages) == 0:
            print('+ All required cargo packages are installed')
            return

        install = self._pretty_print_install('cargo install', need_packages)
        print('Missing cargo packages. Run the following command: ')
        print(' \\\n'.join(install))

    def bootstrap(self):
        """ Bootstrap the Linux build."""
        self._setup_platform2()
        self._print_missing_packages()
        self._print_missing_rust_packages()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Simple build for host.')
    parser.add_argument(
        '--bootstrap-dir', help='Directory to run bootstrap on (or was previously run on).', default="~/.floss")
    parser.add_argument(
        '--run-bootstrap',
        help='Run bootstrap code to verify build env is ok to build.',
        default=False,
        action='store_true')
    parser.add_argument('--no-clang', help='Use clang compiler.', default=False, action='store_true')
    parser.add_argument(
        '--no-strip', help='Skip stripping binaries during install.', default=False, action='store_true')
    parser.add_argument('--use', help='Set a specific use flag.')
    parser.add_argument('--notest', help='Don\'t compile test code.', default=False, action='store_true')
    parser.add_argument('--test-name', help='Run test with this string in the name.', default=None)
    parser.add_argument('--target', help='Run specific build target')
    parser.add_argument('--sysroot', help='Set a specific sysroot path', default='/')
    parser.add_argument('--libdir', help='Libdir - default = usr/lib', default='usr/lib')
    parser.add_argument('--jobs', help='Number of jobs to run', default=0, type=int)
    parser.add_argument(
        '--no-vendored-rust', help='Do not use vendored rust crates', default=False, action='store_true')
    parser.add_argument('--verbose', help='Verbose logs for build.')
    args = parser.parse_args()

    # Make sure we get absolute path + expanded path for bootstrap directory
    args.bootstrap_dir = os.path.abspath(os.path.expanduser(args.bootstrap_dir))

    if args.run_bootstrap:
        bootstrap = Bootstrap(args.bootstrap_dir, os.path.dirname(__file__))
        bootstrap.bootstrap()
    else:
        build = HostBuild(args)
        build.build()
