Support building with LLVM

This commit adds support for building the seL4 kernel, loader, monitor,
and libmicrokit with LLVM (Clang, LLVM and ld.lld). Passing --llvm
should instruct the tool to build everything with with LLVM.

Clang/RISC-V don't implement or need -mstrict-align
Also fix a trivial error adding single quotes within a string.

Signed-off-by: Hesham Almatary <heshamalmatary@capabilitieslimited.co.uk>
This commit is contained in:
Hesham Almatary 2025-06-05 18:39:03 +00:00 committed by Ivan Velickovic
parent a022c14004
commit f340269411
10 changed files with 170 additions and 79 deletions

View File

@ -31,8 +31,8 @@ ENV_BIN_DIR = Path(executable).parent
MICROKIT_EPOCH = 1616367257
TOOLCHAIN_AARCH64 = "aarch64-none-elf"
TOOLCHAIN_RISCV = "riscv64-unknown-elf"
TRIPLE_AARCH64 = "aarch64-none-elf"
TRIPLE_RISCV = "riscv64-unknown-elf"
KERNEL_CONFIG_TYPE = Union[bool, str]
KERNEL_OPTIONS = Dict[str, Union[bool, str]]
@ -42,13 +42,13 @@ class KernelArch(IntEnum):
AARCH64 = 1
RISCV64 = 2
def c_toolchain(self) -> str:
def target_triple(self) -> str:
if self == KernelArch.AARCH64:
return TOOLCHAIN_AARCH64
return TRIPLE_AARCH64
elif self == KernelArch.RISCV64:
return TOOLCHAIN_RISCV
return TRIPLE_RISCV
else:
raise Exception(f"Unsupported toolchain architecture '{self}'")
raise Exception(f"Unsupported toolchain target triple '{self}'")
def is_riscv(self) -> bool:
return self == KernelArch.RISCV64
@ -431,6 +431,7 @@ def build_sel4(
build_dir: Path,
board: BoardInfo,
config: ConfigInfo,
llvm: bool
) -> Dict[str, Any]:
"""Build seL4"""
build_dir = build_dir / board.name / config.name / "sel4"
@ -459,14 +460,19 @@ def build_sel4(
config_strs.append(s)
config_str = " ".join(config_strs)
toolchain = f"{board.arch.c_toolchain()}-"
target_triple = f"{board.arch.target_triple()}"
cmd = (
f"cmake -GNinja -DCMAKE_INSTALL_PREFIX={sel4_install_dir.absolute()} "
f" -DPYTHON3={executable} "
f" -DCROSS_COMPILER_PREFIX={toolchain}"
f" {config_str} "
f"-S {sel4_dir.absolute()} -B {sel4_build_dir.absolute()}")
if llvm:
cmd += f" -DTRIPLE={target_triple}"
else:
cmd += f" -DCROSS_COMPILER_PREFIX={target_triple}-"
r = system(cmd)
if r != 0:
raise Exception(f"Error configuring sel4: cmd={cmd}")
@ -527,7 +533,8 @@ def build_elf_component(
build_dir: Path,
board: BoardInfo,
config: ConfigInfo,
defines: List[Tuple[str, str]]
llvm: bool,
defines: List[Tuple[str, str]],
) -> None:
"""Build a specific ELF component.
@ -536,9 +543,9 @@ def build_elf_component(
sel4_dir = root_dir / "board" / board.name / config.name
build_dir = build_dir / board.name / config.name / component_name
build_dir.mkdir(exist_ok=True, parents=True)
toolchain = f"{board.arch.c_toolchain()}-"
target_triple = f"{board.arch.target_triple()}"
defines_str = " ".join(f"{k}={v}" for k, v in defines)
defines_str += f" ARCH={board.arch.to_str()} BOARD={board.name} BUILD_DIR={build_dir.absolute()} SEL4_SDK={sel4_dir.absolute()} TOOLCHAIN={toolchain}"
defines_str += f" ARCH={board.arch.to_str()} BOARD={board.name} BUILD_DIR={build_dir.absolute()} SEL4_SDK={sel4_dir.absolute()} TARGET_TRIPLE={target_triple} LLVM={llvm}"
if board.gcc_cpu is not None:
defines_str += f" GCC_CPU={board.gcc_cpu}"
@ -574,6 +581,7 @@ def build_lib_component(
build_dir: Path,
board: BoardInfo,
config: ConfigInfo,
llvm: bool
) -> None:
"""Build a specific library component.
@ -583,8 +591,8 @@ def build_lib_component(
build_dir = build_dir / board.name / config.name / component_name
build_dir.mkdir(exist_ok=True, parents=True)
toolchain = f"{board.arch.c_toolchain()}-"
defines_str = f" ARCH={board.arch.to_str()} BUILD_DIR={build_dir.absolute()} SEL4_SDK={sel4_dir.absolute()} TOOLCHAIN={toolchain}"
target_triple = f"{board.arch.target_triple()}"
defines_str = f" ARCH={board.arch.to_str()} BUILD_DIR={build_dir.absolute()} SEL4_SDK={sel4_dir.absolute()} TARGET_TRIPLE={target_triple} LLVM={llvm}"
if board.gcc_cpu is not None:
defines_str += f" GCC_CPU={board.gcc_cpu}"
@ -628,6 +636,7 @@ def main() -> None:
parser = ArgumentParser()
parser.add_argument("--sel4", type=Path, required=True)
parser.add_argument("--tool-target-triple", default=get_tool_target_triple(), help="Compile the Microkit tool for this target triple")
parser.add_argument("--llvm", action="store_true", help="Cross-compile seL4 and Microkit's run-time targets with LLVM")
parser.add_argument("--boards", metavar="BOARDS", help="Comma-separated list of boards to support. When absent, all boards are supported.")
parser.add_argument("--configs", metavar="CONFIGS", help="Comma-separated list of configurations to support. When absent, all configurations are supported.")
parser.add_argument("--skip-tool", action="store_true", help="Tool will not be built")
@ -641,14 +650,14 @@ def main() -> None:
parser.add_argument("--version", default=default_version, help="SDK version")
for arch in KernelArch:
arch_str = arch.name.lower()
parser.add_argument(f"--toolchain-prefix-{arch_str}", default=arch.c_toolchain(), help=f"C toolchain prefix when compiling for {arch_str}, e.g {arch_str}-none-elf")
parser.add_argument(f"--gcc-toolchain-prefix-{arch_str}", default=arch.target_triple(), help=f"GCC toolchain prefix when compiling for {arch_str}, e.g {arch_str}-none-elf")
args = parser.parse_args()
global TOOLCHAIN_AARCH64
global TOOLCHAIN_RISCV
TOOLCHAIN_AARCH64 = args.toolchain_prefix_aarch64
TOOLCHAIN_RISCV = args.toolchain_prefix_riscv64
global TRIPLE_AARCH64
global TRIPLE_RISCV
TRIPLE_AARCH64 = args.gcc_toolchain_prefix_aarch64
TRIPLE_RISCV = args.gcc_toolchain_prefix_riscv64
version = args.version
@ -728,7 +737,7 @@ def main() -> None:
for board in selected_boards:
for config in selected_configs:
if not args.skip_sel4:
sel4_gen_config = build_sel4(sel4_dir, root_dir, build_dir, board, config)
sel4_gen_config = build_sel4(sel4_dir, root_dir, build_dir, board, config, args.llvm)
loader_printing = 1 if config.name == "debug" else 0
loader_defines = [
("LINK_ADDRESS", hex(board.loader_link_address)),
@ -747,9 +756,9 @@ def main() -> None:
raise Exception("Unexpected ARM physical address bits defines")
loader_defines.append(("PHYSICAL_ADDRESS_BITS", arm_pa_size_bits))
build_elf_component("loader", root_dir, build_dir, board, config, loader_defines)
build_elf_component("monitor", root_dir, build_dir, board, config, [])
build_lib_component("libmicrokit", root_dir, build_dir, board, config)
build_elf_component("loader", root_dir, build_dir, board, config, args.llvm, loader_defines)
build_elf_component("monitor", root_dir, build_dir, board, config, args.llvm, [])
build_lib_component("libmicrokit", root_dir, build_dir, board, config, args.llvm)
# Setup the examples
for example, example_path in EXAMPLES.items():

View File

@ -64,6 +64,11 @@ def main():
default="debug",
help="Config option to be passed to the tool"
)
parser.add_argument(
"--llvm",
action="store_true",
help="Build with LLVM/Clang toolchain"
)
args = parser.parse_args()
# TODO: Support choosing a release by specifying on command line
@ -76,7 +81,7 @@ def main():
if not BUILD_DIR.exists():
BUILD_DIR.mkdir()
tool_rebuild = f"cd {CWD / "tool/microkit"} && cargo build --release"
tool_rebuild = f"cd {CWD / 'tool/microkit'} && cargo build --release"
r = system(tool_rebuild)
assert r == 0
@ -86,6 +91,7 @@ def main():
make_env["MICROKIT_CONFIG"] = args.config
make_env["MICROKIT_SDK"] = str(release)
make_env["MICROKIT_TOOL"] = (CWD / "tool/microkit/target/release/microkit").absolute()
make_env["LLVM"] = str(args.llvm)
# Choose the makefile based on the `--example-from-sdk` command line flag
makefile_directory = (

View File

@ -23,13 +23,20 @@ ifneq ($(MICROKIT_BOARD),tqma8xqp1gb)
$(error Unsupported MICROKIT_BOARD given, only tqma8xqp1gb supported)
endif
TOOLCHAIN := aarch64-none-elf
TARGET_TRIPLE := aarch64-none-elf
CPU := cortex-a35
CC := $(TOOLCHAIN)-gcc
LD := $(TOOLCHAIN)-ld
AS := $(TOOLCHAIN)-as
ifeq ($(strip $(LLVM)),True)
CC := clang -target $(TARGET_TRIPLE)
AS := clang -target $(TARGET_TRIPLE)
LD := ld.lld
else
CC := $(TARGET_TRIPLE)-gcc
LD := $(TARGET_TRIPLE)-ld
AS := $(TARGET_TRIPLE)-as
endif
MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
ETH_OBJS := eth.o

View File

@ -24,25 +24,31 @@ BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
ifeq ($(ARCH),aarch64)
TOOLCHAIN := aarch64-none-elf
# No specific AArch64 flags
CFLAGS_ARCH :=
TARGET_TRIPLE := aarch64-none-elf
CFLAGS_ARCH := -mstrict-align
else ifeq ($(ARCH),riscv64)
TOOLCHAIN := riscv64-unknown-elf
CFLAGS_ARCH := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
TARGET_TRIPLE := riscv64-unknown-elf
CFLAGS_ARCH := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
else
$(error Unsupported ARCH)
endif
CC := $(TOOLCHAIN)-gcc
LD := $(TOOLCHAIN)-ld
AS := $(TOOLCHAIN)-as
ifeq ($(strip $(LLVM)),True)
CC := clang -target $(TARGET_TRIPLE)
AS := clang -target $(TARGET_TRIPLE)
LD := ld.lld
else
CC := $(TARGET_TRIPLE)-gcc
LD := $(TARGET_TRIPLE)-ld
AS := $(TARGET_TRIPLE)-as
endif
MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
HELLO_OBJS := hello.o
IMAGES := hello.elf
CFLAGS := -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
CFLAGS := -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
LDFLAGS := -L$(BOARD_DIR)/lib
LIBS := -lmicrokit -Tmicrokit.ld

View File

@ -24,19 +24,25 @@ BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
ifeq ($(ARCH),aarch64)
TOOLCHAIN := aarch64-none-elf
# No specific AArch64 flags
CFLAGS_ARCH :=
TARGET_TRIPLE := aarch64-none-elf
CFLAGS_ARCH := -mstrict-align
else ifeq ($(ARCH),riscv64)
TOOLCHAIN := riscv64-unknown-elf
CFLAGS_ARCH := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
TARGET_TRIPLE := riscv64-unknown-elf
CFLAGS_ARCH := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
else
$(error Unsupported ARCH)
endif
CC := $(TOOLCHAIN)-gcc
LD := $(TOOLCHAIN)-ld
AS := $(TOOLCHAIN)-as
ifeq ($(strip $(LLVM)),True)
CC := clang -target $(TARGET_TRIPLE)
AS := clang -target $(TARGET_TRIPLE)
LD := ld.lld
else
CC := $(TARGET_TRIPLE)-gcc
LD := $(TARGET_TRIPLE)-ld
AS := $(TARGET_TRIPLE)-as
endif
MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
RESTARTER_OBJS := restarter.o
@ -44,7 +50,7 @@ CRASHER_OBJS := crasher.o
HELLO_OBJS := hello.o
IMAGES := restarter.elf crasher.elf hello.elf
CFLAGS := -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
CFLAGS := -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
LDFLAGS := -L$(BOARD_DIR)/lib
LIBS := -lmicrokit -Tmicrokit.ld

View File

@ -24,26 +24,32 @@ BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)
ARCH := ${shell grep 'CONFIG_SEL4_ARCH ' $(BOARD_DIR)/include/kernel/gen_config.h | cut -d' ' -f4}
ifeq ($(ARCH),aarch64)
TOOLCHAIN := aarch64-none-elf
# No specific AArch64 flags
CFLAGS_ARCH :=
TARGET_TRIPLE := aarch64-none-elf
CFLAGS_ARCH := -mstrict-align
else ifeq ($(ARCH),riscv64)
TOOLCHAIN := riscv64-unknown-elf
CFLAGS_ARCH := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
TARGET_TRIPLE := riscv64-unknown-elf
CFLAGS_ARCH := -march=rv64imafdc_zicsr_zifencei -mabi=lp64d
else
$(error Unsupported ARCH)
endif
CC := $(TOOLCHAIN)-gcc
LD := $(TOOLCHAIN)-ld
AS := $(TOOLCHAIN)-as
ifeq ($(strip $(LLVM)),True)
CC := clang -target $(TARGET_TRIPLE)
AS := clang -target $(TARGET_TRIPLE)
LD := ld.lld
else
CC := $(TARGET_TRIPLE)-gcc
LD := $(TARGET_TRIPLE)-ld
AS := $(TARGET_TRIPLE)-as
endif
MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
SERVER_OBJS := server.o
CLIENT_OBJS := client.o
IMAGES := server.elf client.elf
CFLAGS := -mstrict-align -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
CFLAGS := -nostdlib -ffreestanding -g -O3 -Wall -Wno-unused-function -Werror -I$(BOARD_DIR)/include $(CFLAGS_ARCH)
LDFLAGS := -L$(BOARD_DIR)/lib
LIBS := -lmicrokit -Tmicrokit.ld

View File

@ -23,13 +23,20 @@ ifneq ($(MICROKIT_BOARD),odroidc4)
$(error Unsupported MICROKIT_BOARD given, only odroidc4 supported)
endif
TOOLCHAIN := aarch64-none-elf
TARGET_TRIPLE := aarch64-none-elf
CPU := cortex-a55
CC := $(TOOLCHAIN)-gcc
LD := $(TOOLCHAIN)-ld
AS := $(TOOLCHAIN)-as
ifeq ($(strip $(LLVM)),True)
CC := clang -target $(TARGET_TRIPLE)
AS := clang -target $(TARGET_TRIPLE)
LD := ld.lld
else
CC := $(TARGET_TRIPLE)-gcc
LD := $(TARGET_TRIPLE)-ld
AS := $(TARGET_TRIPLE)-as
endif
MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit
TIMER_OBJS := timer.o

View File

@ -11,8 +11,24 @@ ifeq ($(strip $(ARCH)),)
$(error ARCH must be specified)
endif
ifeq ($(strip $(TOOLCHAIN)),)
$(error TOOLCHAIN must be specified)
ifeq ($(strip $(TARGET_TRIPLE)),)
$(error TARGET_TRIPLE must be specified)
endif
ifeq ($(strip $(LLVM)),True)
CC := clang -target $(TARGET_TRIPLE)
CPP := clang-cpp -target $(TARGET_TRIPLE)
AS := clang -target $(TARGET_TRIPLE)
LD := ld.lld
AR := llvm-ar
CFLAGS_TOOLCHAIN :=
else
CC = $(TARGET_TRIPLE)-gcc
CPP = $(TARGET_TRIPLE)-cpp
AS = $(TARGET_TRIPLE)-as
LD = $(TARGET_TRIPLE)-ld
AR = $(TARGET_TRIPLE)-ar
CFLAGS_TOOLCHAIN := -Wno-maybe-uninitialized
endif
ifeq ($(ARCH),aarch64)
@ -30,7 +46,7 @@ endif
CFLAGS := -std=gnu11 \
-g -O3 -nostdlib \
-ffreestanding \
-Wall -Wno-maybe-uninitialized \
-Wall $(CFLAGS_TOOLCHAIN) \
-Wno-unused-function -Werror \
-Iinclude -I$(SEL4_SDK)/include \
$(CFLAGS_ARCH)
@ -39,17 +55,17 @@ LIBS := libmicrokit.a
OBJS := main.o crt0.o dbg.o
$(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.S
$(TOOLCHAIN)gcc -x assembler-with-cpp -c $(CFLAGS) $< -o $@
$(CC) -x assembler-with-cpp -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.s
$(TOOLCHAIN)as -g $(ASM_FLAGS) $< -o $@
$(AS) -c -g $(ASM_FLAGS) $< -o $@
$(BUILD_DIR)/%.o : src/%.c
$(TOOLCHAIN)gcc -c $(CFLAGS) $< -o $@
$(CC) -c $(CFLAGS) $< -o $@
LIB = $(addprefix $(BUILD_DIR)/, $(LIBS))
all: $(LIB)
$(LIB): $(addprefix $(BUILD_DIR)/, $(OBJS))
$(TOOLCHAIN)ar -rv $@ $^
$(AR) -rv $@ $^

View File

@ -19,8 +19,20 @@ ifeq ($(strip $(LINK_ADDRESS)),)
$(error LINK_ADDRESS must be specified)
endif
ifeq ($(strip $(TOOLCHAIN)),)
$(error TOOLCHAIN must be specified)
ifeq ($(strip $(TARGET_TRIPLE)),)
$(error TARGET_TRIPLE must be specified)
endif
ifeq ($(strip $(LLVM)),True)
CC = clang -target $(TARGET_TRIPLE)
CPP = clang-cpp -target $(TARGET_TRIPLE)
AS = clang -target $(TARGET_TRIPLE)
LD = ld.lld
else
CC = $(TARGET_TRIPLE)-gcc
CPP = $(TARGET_TRIPLE)-cpp
AS = $(TARGET_TRIPLE)-as
LD = $(TARGET_TRIPLE)-ld
endif
ifeq ($(strip $(PRINTING)),)
@ -54,20 +66,20 @@ LINKSCRIPT_INPUT := $(ARCH).ld
LINKSCRIPT := $(BUILD_DIR)/link.ld
$(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.S
$(TOOLCHAIN)gcc -DLINK_ADDRESS=$(LINK_ADDRESS) -x assembler-with-cpp -c $(ASM_FLAGS) $< -o $@
$(CC) -DLINK_ADDRESS=$(LINK_ADDRESS) -x assembler-with-cpp -c $(ASM_FLAGS) $< -o $@
$(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.s
$(TOOLCHAIN)as $< -o $@
$(AS) -c $< -o $@
$(BUILD_DIR)/%.o : src/%.c
$(TOOLCHAIN)gcc -c $(CFLAGS) $< -o $@
$(CC) -c $(CFLAGS) $< -o $@
OBJPROG = $(addprefix $(BUILD_DIR)/, $(PROGS))
all: $(OBJPROG)
$(LINKSCRIPT): $(LINKSCRIPT_INPUT)
$(TOOLCHAIN)cpp -DLINK_ADDRESS=$(LINK_ADDRESS) $< | grep -v "^#" > $@
$(CPP) -DLINK_ADDRESS=$(LINK_ADDRESS) $< | grep -v "^#" > $@
$(OBJPROG): $(addprefix $(BUILD_DIR)/, $(OBJECTS)) $(LINKSCRIPT)
$(TOOLCHAIN)ld -T$(LINKSCRIPT) $(addprefix $(BUILD_DIR)/, $(OBJECTS)) -o $@
$(LD) -T$(LINKSCRIPT) $(addprefix $(BUILD_DIR)/, $(OBJECTS)) -o $@

View File

@ -11,8 +11,24 @@ ifeq ($(strip $(ARCH)),)
$(error ARCH must be specified)
endif
ifeq ($(strip $(TOOLCHAIN)),)
$(error TOOLCHAIN must be specified)
ifeq ($(strip $(TARGET_TRIPLE)),)
$(error TARGET_TRIPLE must be specified)
endif
ifeq ($(strip $(LLVM)),True)
CC = clang -target $(TARGET_TRIPLE)
CPP = clang-cpp -target $(TARGET_TRIPLE)
AS = clang -target $(TARGET_TRIPLE)
LD = ld.lld
AR = llvm-ar
CFLAGS_TOOLCHAIN :=
else
CC = $(TARGET_TRIPLE)-gcc
CPP = $(TARGET_TRIPLE)-cpp
AS = $(TARGET_TRIPLE)-as
LD = $(TARGET_TRIPLE)-ld
AR = $(TARGET_TRIPLE)-ar
CFLAGS_TOOLCHAIN := -Wno-maybe-uninitialized
endif
ifeq ($(ARCH),aarch64)
@ -31,24 +47,24 @@ else
$(error ARCH is unsupported)
endif
CFLAGS := -std=gnu11 -g -O3 -nostdlib -ffreestanding -Wall -Wno-maybe-uninitialized -Werror -I$(SEL4_SDK)/include $(CFLAGS_ARCH) -DARCH_$(ARCH)
CFLAGS := -std=gnu11 -g -O3 -nostdlib -ffreestanding -Wall $(CFLAGS_TOOLCHAIN) -Werror -I$(SEL4_SDK)/include $(CFLAGS_ARCH) -DARCH_$(ARCH)
PROGS := monitor.elf
OBJECTS := main.o crt0.o debug.o util.o
LINKSCRIPT := monitor.ld
$(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.S
$(TOOLCHAIN)gcc $(ASM_CPP_FLAGS) $< -o $@
$(CC) $(ASM_CPP_FLAGS) $< -o $@
$(BUILD_DIR)/%.o : src/$(ARCH_DIR)/%.s
$(TOOLCHAIN)as -g $(ASM_FLAGS) $< -o $@
$(AS) -c -g $(ASM_FLAGS) $< -o $@
$(BUILD_DIR)/%.o : src/%.c
$(TOOLCHAIN)gcc -c $(CFLAGS) $< -o $@
$(CC) -c $(CFLAGS) $< -o $@
OBJPROG = $(addprefix $(BUILD_DIR)/, $(PROGS))
all: $(OBJPROG)
$(OBJPROG): $(addprefix $(BUILD_DIR)/, $(OBJECTS)) $(LINKSCRIPT)
$(TOOLCHAIN)ld -T$(LINKSCRIPT) $(addprefix $(BUILD_DIR)/, $(OBJECTS)) -o $@
$(LD) -T$(LINKSCRIPT) $(addprefix $(BUILD_DIR)/, $(OBJECTS)) -o $@