blob: a951a0adfedc69e3325695536a1a9d4852a97bc6 [file] [log] [blame]
#!/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',
'gdbstub-xml.o',
'hw/i386/acpi-build.o',
'hw/i386/pc_piix.o',
'../qmp-introspect.o',
'../qmp-marshal.o',
'trace/generated-helpers.o',
'../ui/sdl_zoom.o',
'../ui/sdl.o',
'../ui/sdl2.o',
'../ui/sdl2-2d.o',
'../ui/sdl2-input.o',
'../vl.o',
'/version.o', # something from the Windows build
]
CC_OBJECTS = [
'disas/arm-a64.o',
'disas/libvixl/vixl/a64/decoder-a64.o',
'disas/libvixl/vixl/a64/disasm-a64.o',
'disas/libvixl/vixl/a64/instructions-a64.o',
'disas/libvixl/vixl/compiler-intrinsics.o',
'disas/libvixl/vixl/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)