#!/usr/bin/env python

# This script is used to generate Makefile.qemu2-sources.mk from
# the build output of build-qemu-android.sh. To use it:
#
#  rm -rf /tmp/qemu2-build
#  external/qemu/android/scripts/build-qemu-android.sh \
#      --darwin-ssh=<hostname> \
#      --install-dir=/tmp/qemu2-build
#
#  external/qemu-android/android-qemu2-glue/scripts/gen-qemu2-sources-mk.py \
#      /tmp/qemu2-build \
#      > external/qemu-android/android-qemu2-glue/build/Makefile.qemu2-sources.mk
#
import os
import sys

TARGET_SUFFIX="-softmmu"

EXPECTED_HOSTS = set([
    'linux-x86_64',
    'windows-x86',
    'windows-x86_64',
    'darwin-x86_64'])

LINK_QEMU_PREFIX = 'LINK-qemu-system-'
IGNORED_OBJECTS = [
    '../audio/sdlaudio.o',
    '../disas/arm-a64.o',
    '../disas/libvixl/a64/decoder-a64.o',
    '../disas/libvixl/a64/disasm-a64.o',
    '../disas/libvixl/a64/instructions-a64.o',
    '../disas/libvixl/utils.o',
    'gdbstub-xml.o',
    '../hw/display/framebuffer.o',
    'hw/misc/android_boot_properties.o',
    'hw/misc/android_pipe_opengles.o',
    '../qmp-marshal.o',
    'trace/generated-helpers.o',
    '../ui/sdl_zoom.o',
    '../ui/sdl.o',
    '../ui/sdl2.o',
    '/version.o',   # something from the Windows build
    ]

CC_OBJECTS = [
    'disas/arm-a64.o',
    'disas/libvixl/a64/decoder-a64.o',
    'disas/libvixl/a64/disasm-a64.o',
    'disas/libvixl/a64/instructions-a64.o',
    'disas/libvixl/utils.o',
    ]

# objects which have to be moved to *TARGET files,
# even if they could've been common (e.g. to fix some linking issues)
FORCE_TARGET_OBJECTS = [
    '../vl.o'
    ]

def find_target_lists(build_path, hosts):
    """Return a set of QEMU cpu architectures targetted by the binaries
       found under |build_path|. |hosts| is a set of hosts to probe for"""
    result = set()
    for host in hosts:
        for subdir, dirs, files in os.walk(os.path.join(build_path,host)):
            for efile in files:
                if efile.startswith(LINK_QEMU_PREFIX):
                    arch = efile[len(LINK_QEMU_PREFIX):]
                    if arch[-5:] == 'w.exe':
                        arch = arch[:-5]
                    result.add(arch)
            dirs = []
    return sorted(result)

def find_link_map(build_path, host):
    """Return a map of target architecture -> set of object file names
       as they appear in LINK-qemu-system-* files. |build_path| is the
       top-level build path, and |host| is the host to probe."""
    result = {}
    build_path = os.path.join(build_path, host)
    link_prefix = 'LINK-qemu-system-'
    for subdir, dirs, files in os.walk(build_path):
        for efile in files:
            if efile.startswith(link_prefix):
                target = efile[len(link_prefix):]
                # Remove w.exe suffix for Windows binaries.
                if target[-5:] == 'w.exe':
                    target = target[:-5]
                result[target] = set()
                with open(os.path.join(subdir,efile)) as lfile:
                    for line in lfile:
                        line = line.strip()
                        if line[-2:] in [ '.o', '.a' ]:
                            result[target].add(line)
        dirs = []
    return result

def list_files(name, files):
    print "%s := \\" % name

    for f in sorted(source_list_from_objects(files)):
        print "    %s \\" % f
    print ""


def source_list_from_objects(objects):
    result = set()
    for obj in objects:
        if obj in IGNORED_OBJECTS:
            continue
        if obj.startswith('@BUILD_DIR@/'):
            continue
        if obj.endswith('.a'):
            continue
        if obj.startswith('../'):
            obj = obj[3:]
        if obj in CC_OBJECTS:
            obj = obj[:-2] + '.cc'
        else:
            obj = obj[:-2] + '.c'
        result.add(obj)
    return sorted(result)

def main(args):
    """\
A small script used to generate the sub-Makefiles
describing the common and target-specific sources
for the QEMU2 build performed with the emulator's
build system. This is done by looking at the output
of a regular QEMU2 build, and finding which files
were built and where.

Usage: <program-name> <path-to-build-dir>

"""
    if len(args) != 2:
        print "ERROR: This script takes a single argument."
        sys.exit(1)
    build_dir = args[1]

    print "# Auto-generated by %s - DO NOT EDIT !!" % os.path.basename(args[0])
    print ""

    target_list = find_target_lists(build_dir, EXPECTED_HOSTS)
    #print "# Found targets: %s" % repr(target_list)

    host_link_map = {}
    for host in EXPECTED_HOSTS:
        host_link_map[host] = find_link_map(build_dir, host)

    host_list = sorted(host_link_map.keys())
    # The set of all objects
    all_objects = set()
    for host in host_list:
        for target in host_link_map[host]:
            all_objects |= host_link_map[host][target]

    # The set of all objects whose path begins with ../
    # this corresponds to objects that will end up in the qemu2_common
    # static library.
    common_all_objects = set([x for x in all_objects if x.startswith('../')])

    # move the forced target object out of common
    common_all_objects -= set(FORCE_TARGET_OBJECTS)

    # The set of common objects that are shared by all hosts.
    common_objects = common_all_objects.copy()
    for host in host_list:
        for target in host_link_map[host]:
            common_objects &= host_link_map[host][target]

    list_files('QEMU2_COMMON_SOURCES', common_objects)

    # For each host, the specific common objects that are not shared with
    # all other hosts, but still shared by all targets.
    host_common_map = {}
    for host in host_list:
        host_common_map[host] = common_all_objects - common_objects
        for target in host_link_map[host]:
            host_common_map[host] &= host_link_map[host][target]
        list_files('QEMU2_COMMON_SOURCES_%s' % host, host_common_map[host])

    # The set of all target-specifc objects.
    all_target_objects = all_objects - common_objects
    for host in host_list:
        all_target_objects -= host_common_map[host]

    # Find the list of target files that are shared by all targets and all
    # hosts at the same time.
    target_common_map = {}
    for target in target_list:
        target_common_map[target] = all_target_objects.copy()
        for host in host_list:
            target_common_map[target] &= host_link_map[host][target]

    target_common_objects = all_target_objects.copy()
    for target in target_common_map:
        target_common_objects &= target_common_map[target]

    list_files('QEMU2_TARGET_SOURCES', target_common_objects)

    # For each target, find the files shared by all hosts, that only
    # belong to this target.
    for target in target_list:
        target_objects = target_common_map[target] - target_common_objects
        list_files('QEMU2_TARGET_%s_SOURCES' % target, target_objects)

    # Finally, the target- and host- specific objects.
    for target in target_list:
        for host in host_list:
            objects = host_link_map[host][target] - target_common_map[target] - \
                      target_common_objects - common_all_objects
            list_files('QEMU2_TARGET_%s_SOURCES_%s' % (target, host), objects)

if __name__ == "__main__":
    main(sys.argv)
