Files
swift-mirror/utils/embedded-test-support/embedded-test-support.py

144 lines
4.8 KiB
Python
Executable File

#!/usr/bin/env python3
# flake8: noqa
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2024 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
import argparse
import os
import subprocess
import tempfile
import pathlib
MY_DIR = os.path.dirname(os.path.abspath(__file__))
def shell(cmd):
return subprocess.check_output(["bash", "-c", cmd])
def shell_print(cmd):
print(cmd)
subprocess.check_call(["bash", "-c", cmd])
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--device', choices=sorted([d for d in os.listdir(MY_DIR) if os.path.isdir(MY_DIR + "/" + d)]), required=True)
parser.add_argument('command', choices=['run', 'demo-run', 'print-c-flags', 'print-swift-flags', 'print-swift-frontend-flags'])
parser.add_argument('--elf-file')
args = parser.parse_args()
if args.device == "arm-qemu-stm32f1":
target = "armv7em-none-none-eabi"
qemu_binary = "qemu-system-arm"
qemu_machine = "stm32vldiscovery"
mmcu = ""
entry_point = "vector_table"
semihosting = True
qemu_mode = "-kernel"
always_optimize_for_size = False
elif args.device == "arm-qemu-stm32f4":
target = "armv7em-none-none-eabi"
qemu_binary = "qemu-system-arm"
qemu_machine = "netduinoplus2"
mmcu = ""
entry_point = "vector_table"
semihosting = True
qemu_mode = "-kernel"
always_optimize_for_size = False
elif args.device == "avr-qemu-atmega2560":
target = "avr-none-none-elf"
qemu_binary = "qemu-system-avr"
qemu_machine = "mega2560"
mmcu = "-mmcu=atmega2560"
entry_point = "start"
semihosting = False
qemu_mode = "-bios"
always_optimize_for_size = True
elif args.device == "riscv32-qemu-virt":
target = "riscv32-none-none-eabi"
qemu_binary = "qemu-system-riscv32"
qemu_machine = "virt"
mmcu = ""
entry_point = "start"
semihosting = False
qemu_mode = "-bios none -kernel"
always_optimize_for_size = True
else:
assert False
tmpdir = tempfile.gettempdir()
cflags = ""
cflags += " -nostdlib"
cflags += " -ffunction-sections -fdata-sections"
cflags += " -ffreestanding"
cflags += " -O2"
cflags += " -g"
cflags += f" {mmcu}"
supportfile = tmpdir + "/" + target + "-support.o"
shell(f"clang -target {target} {cflags} -c {MY_DIR}/{args.device}/support.c -o {supportfile}")
libcfile = tmpdir + "/" + target + "-libc.o"
shell(f"clang -target {target} {cflags} -c {MY_DIR}/libc.c -o {libcfile}")
demo_o_file = tmpdir + "/" + target + "-demo.o"
shell(f"clang -target {target} {cflags} -c {MY_DIR}/demo.c -o {demo_o_file}")
cflags += f" {supportfile} {libcfile}"
swift_frontend_flags = ""
swift_frontend_flags += " -disable-stack-protector -function-sections"
if mmcu != "": swift_frontend_flags += f" -Xcc {mmcu}"
swift_flags = ""
swift_flags += " -Xfrontend -disable-stack-protector -Xfrontend -function-sections -use-ld=lld"
swift_flags += " -Xclang-linker -nostdlib -Xlinker --gc-sections"
swift_flags += f" {supportfile} {libcfile}"
swift_flags += f" -Xlinker -T -Xlinker {MY_DIR}/{args.device}/linkerscript.ld -Xlinker -e -Xlinker {entry_point}"
if mmcu != "": swift_flags += f" -Xcc {mmcu}"
if always_optimize_for_size: swift_flags += " -Osize"
cflags += " -fuse-ld=lld"
cflags += " -nostdlib"
cflags += " -Xlinker --gc-sections"
cflags += f" -Xlinker -T -Xlinker {MY_DIR}/{args.device}/linkerscript.ld"
cflags += f" -Wl,-e,{entry_point}"
if args.command == "print-swift-flags":
print(swift_flags)
elif args.command == "print-swift-frontend-flags":
print(swift_frontend_flags)
elif args.command == "print-c-flags":
print(cflags)
elif args.command == "run":
if args.elf_file is None:
print("Must specify --elf-file <...>")
exit(1)
qemu_command = f"{qemu_binary} -M {qemu_machine} -nographic {qemu_mode} {args.elf_file} {'-semihosting' if semihosting else ''}"
shell_print(f"expect -c 'spawn {qemu_command}; expect -timeout 5 -re \"HALT\"'")
elif args.command == "demo-run":
elffile = tmpdir + "/" + target + ".elf"
shell(f"clang -target {target} {cflags} {demo_o_file} -o {elffile}")
qemu_command = f"{qemu_binary} -M {qemu_machine} -nographic {qemu_mode} {elffile} {'-semihosting' if semihosting else ''}"
shell_print(f"expect -c 'spawn {qemu_command}; expect -timeout 5 -re \"HALT\"'")
if __name__ == "__main__":
main()