2023-12-20 16:20:42 +00:00
|
|
|
# Makefile for AbstractMachine Kernels and Libraries
|
|
|
|
|
|
|
|
### *Get a more readable version of this Makefile* by `make html` (requires python-markdown)
|
|
|
|
html:
|
|
|
|
cat Makefile | sed 's/^\([^#]\)/ \1/g' | markdown_py > Makefile.html
|
|
|
|
.PHONY: html
|
|
|
|
|
|
|
|
## 1. Basic Setup and Checks
|
|
|
|
|
|
|
|
### Default to create a bare-metal kernel image
|
|
|
|
ifeq ($(MAKECMDGOALS),)
|
|
|
|
MAKECMDGOALS = image
|
|
|
|
.DEFAULT_GOAL = image
|
|
|
|
endif
|
|
|
|
|
|
|
|
### Override checks when `make clean/clean-all/html`
|
|
|
|
ifeq ($(findstring $(MAKECMDGOALS),clean|clean-all|html),)
|
|
|
|
|
|
|
|
### Print build info message
|
|
|
|
$(info # Building $(NAME)-$(MAKECMDGOALS) [$(ARCH)])
|
|
|
|
|
|
|
|
### Check: environment variable `$AM_HOME` looks sane
|
|
|
|
ifeq ($(wildcard $(AM_HOME)/am/include/am.h),)
|
|
|
|
$(error $$AM_HOME must be an AbstractMachine repo)
|
|
|
|
endif
|
|
|
|
|
|
|
|
### Check: environment variable `$ARCH` must be in the supported list
|
|
|
|
ARCHS = $(basename $(notdir $(shell ls $(AM_HOME)/scripts/*.mk)))
|
|
|
|
ifeq ($(filter $(ARCHS), $(ARCH)), )
|
|
|
|
$(error Expected $$ARCH in {$(ARCHS)}, Got "$(ARCH)")
|
|
|
|
endif
|
|
|
|
|
|
|
|
### Extract instruction set architecture (`ISA`) and platform from `$ARCH`. Example: `ARCH=x86_64-qemu -> ISA=x86_64; PLATFORM=qemu`
|
|
|
|
ARCH_SPLIT = $(subst -, ,$(ARCH))
|
|
|
|
ISA = $(word 1,$(ARCH_SPLIT))
|
|
|
|
PLATFORM = $(word 2,$(ARCH_SPLIT))
|
|
|
|
|
|
|
|
### Check if there is something to build
|
|
|
|
ifeq ($(flavor SRCS), undefined)
|
|
|
|
$(error Nothing to build)
|
|
|
|
endif
|
|
|
|
|
|
|
|
### Checks end here
|
|
|
|
endif
|
|
|
|
|
|
|
|
## 2. General Compilation Targets
|
|
|
|
|
|
|
|
### Create the destination directory (`build/$ARCH`)
|
|
|
|
WORK_DIR = $(shell pwd)
|
2024-03-04 03:59:50 +00:00
|
|
|
BUILD_DIR ?= $(WORK_DIR)/build
|
|
|
|
DST_DIR = $(BUILD_DIR)/$(ARCH)
|
2023-12-20 16:20:42 +00:00
|
|
|
$(shell mkdir -p $(DST_DIR))
|
|
|
|
|
|
|
|
### Compilation targets (a binary image or archive)
|
2024-03-04 03:59:50 +00:00
|
|
|
IMAGE_REL = $(DST_DIR)/$(NAME)-$(ARCH)
|
2023-12-20 16:20:42 +00:00
|
|
|
IMAGE = $(abspath $(IMAGE_REL))
|
2024-03-04 03:59:50 +00:00
|
|
|
ARCHIVE = $(BUILD_DIR)/$(NAME)-$(ARCH).a
|
2023-12-20 16:20:42 +00:00
|
|
|
|
|
|
|
### Collect the files to be linked: object files (`.o`) and libraries (`.a`)
|
|
|
|
OBJS = $(addprefix $(DST_DIR)/, $(addsuffix .o, $(basename $(SRCS))))
|
|
|
|
LIBS := $(sort $(LIBS) am klib) # lazy evaluation ("=") causes infinite recursions
|
|
|
|
LINKAGE = $(OBJS) \
|
2024-03-04 03:59:50 +00:00
|
|
|
$(addsuffix -$(ARCH).a, $(addprefix $(BUILD_DIR)/, $(LIBS)))
|
2023-12-20 16:20:42 +00:00
|
|
|
|
|
|
|
## 3. General Compilation Flags
|
|
|
|
|
|
|
|
### (Cross) compilers, e.g., mips-linux-gnu-g++
|
2024-03-04 03:59:50 +00:00
|
|
|
AS ?= $(CROSS_COMPILE)gcc
|
|
|
|
CC ?= $(CROSS_COMPILE)gcc
|
|
|
|
CXX ?= $(CROSS_COMPILE)g++
|
|
|
|
LD ?= $(CROSS_COMPILE)ld
|
|
|
|
AR ?= $(CROSS_COMPILE)ar
|
|
|
|
OBJDUMP ?= $(CROSS_COMPILE)objdump
|
|
|
|
OBJCOPY ?= $(CROSS_COMPILE)objcopy
|
|
|
|
READELF ?= $(CROSS_COMPILE)readelf
|
2023-12-20 16:20:42 +00:00
|
|
|
|
|
|
|
### Compilation flags
|
|
|
|
INC_PATH += $(WORK_DIR)/include $(addsuffix /include/, $(addprefix $(AM_HOME)/, $(LIBS)))
|
|
|
|
INCFLAGS += $(addprefix -I, $(INC_PATH))
|
|
|
|
|
|
|
|
ARCH_H := arch/$(ARCH).h
|
|
|
|
CFLAGS += -O2 -MMD -Wall -Werror $(INCFLAGS) \
|
|
|
|
-D__ISA__=\"$(ISA)\" -D__ISA_$(shell echo $(ISA) | tr a-z A-Z)__ \
|
|
|
|
-D__ARCH__=$(ARCH) -D__ARCH_$(shell echo $(ARCH) | tr a-z A-Z | tr - _) \
|
|
|
|
-D__PLATFORM__=$(PLATFORM) -D__PLATFORM_$(shell echo $(PLATFORM) | tr a-z A-Z | tr - _) \
|
|
|
|
-DARCH_H=\"$(ARCH_H)\" \
|
|
|
|
-fno-asynchronous-unwind-tables -fno-builtin -fno-stack-protector \
|
|
|
|
-Wno-main -U_FORTIFY_SOURCE
|
|
|
|
CXXFLAGS += $(CFLAGS) -ffreestanding -fno-rtti -fno-exceptions
|
|
|
|
ASFLAGS += -MMD $(INCFLAGS)
|
|
|
|
LDFLAGS += -z noexecstack
|
|
|
|
|
|
|
|
## 4. Arch-Specific Configurations
|
|
|
|
|
|
|
|
### Paste in arch-specific configurations (e.g., from `scripts/x86_64-qemu.mk`)
|
|
|
|
-include $(AM_HOME)/scripts/$(ARCH).mk
|
|
|
|
|
|
|
|
### Fall back to native gcc/binutils if there is no cross compiler
|
|
|
|
ifeq ($(wildcard $(shell which $(CC))),)
|
|
|
|
$(info # $(CC) not found; fall back to default gcc and binutils)
|
|
|
|
CROSS_COMPILE :=
|
|
|
|
endif
|
|
|
|
|
|
|
|
## 5. Compilation Rules
|
|
|
|
|
|
|
|
### Rule (compile): a single `.c` -> `.o` (gcc)
|
|
|
|
$(DST_DIR)/%.o: %.c
|
|
|
|
@mkdir -p $(dir $@) && echo + CC $<
|
|
|
|
@$(CC) -std=gnu11 $(CFLAGS) -c -o $@ $(realpath $<)
|
|
|
|
|
|
|
|
### Rule (compile): a single `.cc` -> `.o` (g++)
|
|
|
|
$(DST_DIR)/%.o: %.cc
|
|
|
|
@mkdir -p $(dir $@) && echo + CXX $<
|
|
|
|
@$(CXX) -std=c++17 $(CXXFLAGS) -c -o $@ $(realpath $<)
|
|
|
|
|
|
|
|
### Rule (compile): a single `.cpp` -> `.o` (g++)
|
|
|
|
$(DST_DIR)/%.o: %.cpp
|
|
|
|
@mkdir -p $(dir $@) && echo + CXX $<
|
|
|
|
@$(CXX) -std=c++17 $(CXXFLAGS) -c -o $@ $(realpath $<)
|
|
|
|
|
|
|
|
### Rule (compile): a single `.S` -> `.o` (gcc, which preprocesses and calls as)
|
|
|
|
$(DST_DIR)/%.o: %.S
|
|
|
|
@mkdir -p $(dir $@) && echo + AS $<
|
|
|
|
@$(AS) $(ASFLAGS) -c -o $@ $(realpath $<)
|
|
|
|
|
|
|
|
### Rule (recursive make): build a dependent library (am, klib, ...)
|
|
|
|
$(LIBS): %:
|
|
|
|
@$(MAKE) -s -C $(AM_HOME)/$* archive
|
|
|
|
|
|
|
|
### Rule (link): objects (`*.o`) and libraries (`*.a`) -> `IMAGE.elf`, the final ELF binary to be packed into image (ld)
|
|
|
|
$(IMAGE).elf: $(OBJS) am $(LIBS)
|
|
|
|
@echo + LD "->" $(IMAGE_REL).elf
|
|
|
|
@$(LD) $(LDFLAGS) -o $(IMAGE).elf --start-group $(LINKAGE) --end-group
|
|
|
|
|
|
|
|
### Rule (archive): objects (`*.o`) -> `ARCHIVE.a` (ar)
|
|
|
|
$(ARCHIVE): $(OBJS)
|
|
|
|
@echo + AR "->" $(shell realpath $@ --relative-to .)
|
|
|
|
@$(AR) rcs $(ARCHIVE) $(OBJS)
|
|
|
|
|
|
|
|
### Rule (`#include` dependencies): paste in `.d` files generated by gcc on `-MMD`
|
|
|
|
-include $(addprefix $(DST_DIR)/, $(addsuffix .d, $(basename $(SRCS))))
|
|
|
|
|
|
|
|
## 6. Miscellaneous
|
|
|
|
|
|
|
|
### Build order control
|
|
|
|
image: image-dep
|
|
|
|
archive: $(ARCHIVE)
|
|
|
|
image-dep: $(OBJS) am $(LIBS)
|
|
|
|
@echo \# Creating image [$(ARCH)]
|
|
|
|
.PHONY: image image-dep archive run $(LIBS)
|
|
|
|
|
|
|
|
### Clean a single project (remove `build/`)
|
|
|
|
clean:
|
|
|
|
rm -rf Makefile.html $(WORK_DIR)/build/
|
|
|
|
.PHONY: clean
|
|
|
|
|
|
|
|
### Clean all sub-projects within depth 2 (and ignore errors)
|
|
|
|
CLEAN_ALL = $(dir $(shell find . -mindepth 2 -name Makefile))
|
|
|
|
clean-all: $(CLEAN_ALL) clean
|
|
|
|
$(CLEAN_ALL):
|
|
|
|
-@$(MAKE) -s -C $@ clean
|
|
|
|
.PHONY: clean-all $(CLEAN_ALL)
|