judas/dodo.py

148 lines
4.8 KiB
Python
Raw Normal View History

2022-10-11 23:53:12 +02:00
""" The doit file. Because makefiles are old and hard to read.
Can't promise this will be more readable, but at least it wont be old :)
"""
import os
from enum import Enum
from types import SimpleNamespace
from typing import Iterator
from pathlib import Path
from doit.tools import Interactive
class BoardTarget(Enum):
RPI3B = 1
RPI4 = 2
## Target
BOARD_TARGET = BoardTarget.RPI3B
## Common constants
consts = SimpleNamespace()
consts.WORK_DIR = os.getcwd()
# Rust equivalent to -Werror
consts.RUSTC_FLAGS = "-D warnings "
# Force documentation
consts.RUSTC_FLAGS += "-D missing_docs"
consts.CARGO_COMPILE_FLAGS = "--release"
if BOARD_TARGET == BoardTarget.RPI3B:
consts.TARGET = "aarch64-unknown-none-softfloat"
consts.KERNEL_NAME = "kernel8.img"
consts.QEMU_CMD = "qemu-system-aarch64"
consts.QEMU_MACHINE = "raspi3b"
consts.QEMU_ARGS = "-serial stdio -display none"
consts.OBJDUMP_CMD = "aarch64-none-elf-objdump"
consts.OBJDUMP_ARGS = "-D"
consts.NM_CMD = "aarch64-none-elf-nm"
consts.READELF_CMD = "aarch64-none-elf-readelf"
consts.LD_SCRIPT_PATH = f"{consts.WORK_DIR}/linker.ld"
consts.RUSTC_FLAGS = f"-C target-cpu=cortex-a53 -C link-arg=--script={consts.LD_SCRIPT_PATH} {consts.RUSTC_FLAGS}"
consts.CARGO_COMPILE_FLAGS = f"--features target_rpi3 {consts.CARGO_COMPILE_FLAGS}"
elif BOARD_TARGET == BoardTarget.RPI4:
consts.TARGET = "aarch64-unknown-none-softfloat"
consts.KERNEL_NAME = "kernel8.img"
consts.QEMU_CMD = "qemu-system-aarch64"
consts.QEMU_MACHINE = None
consts.QEMU_ARGS = "-serial stdio -display none"
consts.OBJDUMP_CMD = "aarch64-none-elf-objdump"
consts.OBJDUMP_ARGS = "-D"
consts.NM_CMD = "aarch64-none-elf-nm"
consts.READELF_CMD = "aarch64-none-elf-readelf"
consts.LD_SCRIPT_PATH = f"{consts.WORK_DIR}/linker.ld"
consts.RUSTC_FLAGS = f"-C target-cpu=cortex-a72 -C link-arg=--script={consts.LD_SCRIPT_PATH} {consts.RUSTC_FLAGS}"
consts.CARGO_COMPILE_FLAGS = f"--features target_rpi4 {consts.CARGO_COMPILE_FLAGS}"
DOIT_CONFIG = {
'default_tasks': ['build'],
}
def get_rust_files() -> Iterator[str]:
""" Get a list of the rust source files.
"""
return map(lambda p: str(p.resolve()), Path('./src').glob('**/*.rs'))
def get_asm_files() -> Iterator[str]:
""" Get a list of the assembly source files.
"""
return map(lambda p: str(p.resolve()), Path('./src').glob('**/*.s'))
def get_build_dep() -> list[str]:
""" Get a list of the files impacting the binary.
"""
# TODO: add dodo.py to the list?
return [
consts.LD_SCRIPT_PATH,
*get_rust_files(),
*get_asm_files(),
]
def task_install_dep():
""" Install some required tools.
"""
return {
'actions': [
'cargo install cargo-binutils',
f'rustup target add {consts.TARGET}',
'rustup component add llvm-tools-preview',
],
}
2022-11-07 19:58:09 +01:00
def task_check():
""" Run a compiler check on the code.
"""
task = {
'file_dep': get_build_dep(),
'actions': [f'RUSTFLAGS="{consts.RUSTC_FLAGS}" cargo check --target={consts.TARGET} {consts.CARGO_COMPILE_FLAGS}'],
}
print(task)
return task
2022-10-11 23:53:12 +02:00
def task_compile():
""" Compile the sources.
"""
2022-10-14 23:43:30 +02:00
task = {
2022-10-11 23:53:12 +02:00
'file_dep': get_build_dep(),
'targets': [f'{consts.WORK_DIR}/target/{consts.TARGET}/release/kernel'],
'actions': [f'RUSTFLAGS="{consts.RUSTC_FLAGS}" cargo rustc --target={consts.TARGET} {consts.CARGO_COMPILE_FLAGS}'],
'clean': [f'cargo clean']
}
2022-10-14 23:43:30 +02:00
print(task)
return task
2022-10-11 23:53:12 +02:00
def task_build():
""" Strip the binary from ELF format to raw binary.
"""
return {
'file_dep': [f'{consts.WORK_DIR}/target/{consts.TARGET}/release/kernel'],
'targets': [f'{consts.WORK_DIR}/consts.KERNEL_NAME'],
'actions': [
f'rust-objcopy --strip-all -O binary {consts.WORK_DIR}/target/{consts.TARGET}/release/kernel {consts.WORK_DIR}/{consts.KERNEL_NAME}',
],
'clean': True,
}
def task_qemu():
""" Run the kernel in qemu.
"""
if consts.QEMU_MACHINE is None:
raise Exception("qemu does not support emulation for this board yet")
r = {
'file_dep': [f'{consts.WORK_DIR}/{consts.KERNEL_NAME}'],
'uptodate': [False], # Always run the cmd
'actions': [Interactive(f'{consts.QEMU_CMD} -M {consts.QEMU_MACHINE} {consts.QEMU_ARGS} -kernel {consts.KERNEL_NAME}')],
}
print(r)
return r
def task_objdump():
""" Inspect the ELF binary file.
"""
r = {
'file_dep': [f'{consts.WORK_DIR}/target/{consts.TARGET}/release/kernel'],
'uptodate': [False], # Always run the cmd
'actions': [Interactive(f'{consts.OBJDUMP_CMD} {consts.OBJDUMP_ARGS} {consts.WORK_DIR}/target/{consts.TARGET}/release/kernel')]
}
print(r)
return r