170 lines
6.4 KiB
Makefile
170 lines
6.4 KiB
Makefile
# Makefile for AbstractMachine Kernels and Libraries
|
|
include scripts/helpers/rules.mk
|
|
|
|
### *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
|
|
cat Makefile | markdown_py > Makefile.html
|
|
.PHONY: html
|
|
|
|
## 1. Basic Setup and Checks
|
|
|
|
### Default to create all static libraries
|
|
ifeq ($(MAKECMDGOALS),)
|
|
MAKECMDGOALS = libs
|
|
.DEFAULT_GOAL = libs
|
|
endif
|
|
|
|
### Override checks when `make clean/clean-all/html`
|
|
ifeq ($(findstring $(MAKECMDGOALS),clean|clean-all|html),)
|
|
|
|
### 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))
|
|
|
|
### Checks end here
|
|
endif
|
|
|
|
## 2. Setup variables pointing to build and install directory
|
|
|
|
### Create the destination directory (`build/$ARCH`)
|
|
WORK_DIR ?= $(shell pwd)
|
|
DST_DIR ?= $(WORK_DIR)/build/$(ARCH)
|
|
LIB_BUILDDIR ?= $(DST_DIR)/lib
|
|
INSTALLDIR ?= $(WORK_DIR)/build/install/$(ARCH)
|
|
LIB_INSTALLDIR ?= $(INSTALLDIR)/lib
|
|
INC_INSTALLDIR ?= $(INSTALLDIR)/include
|
|
|
|
## 3. Toolchain setup
|
|
|
|
### (Cross) compilers, e.g., mips-linux-gnu-g++
|
|
CC ?= $(CROSS_COMPILE)gcc
|
|
AS := $(CC)
|
|
CXX ?= $(CROSS_COMPILE)g++
|
|
LD ?= $(CROSS_COMPILE)ld
|
|
AR ?= $(CROSS_COMPILE)ar
|
|
OBJDUMP ?= $(CROSS_COMPILE)objdump
|
|
OBJCOPY ?= $(CROSS_COMPILE)objcopy
|
|
READELF ?= $(CROSS_COMPILE)readelf
|
|
|
|
## 4. Arch-Specific Configurations
|
|
|
|
# TODO: Removed CROSS_COMPILE toolchain setup as it's too complicated
|
|
# for Makefile to do right. Force the user to provide a CROSS_COMPILE
|
|
# prefix for now. They can also specify CFLAGS and LDFLAGS through
|
|
# environment variable.
|
|
include $(AM_HOME)/scripts/$(ARCH).mk
|
|
|
|
## 5. Compilation Rules
|
|
|
|
BUILDDIR := $(DST_DIR)
|
|
COMMON_CFLAGS := $(CFLAGS) -g -O3 -MMD -Wall \
|
|
-fno-asynchronous-unwind-tables -fno-builtin -fno-stack-protector \
|
|
-U_FORTIFY_SOURCE -fvisibility=hidden -fno-exceptions -std=gnu11
|
|
INTERFACE_LDFLAGS += -z noexecstack
|
|
INTERFACE_CFLAGS += -fno-asynchronous-unwind-tables \
|
|
-fno-builtin -fno-stack-protector \
|
|
-U_FORTIFY_SOURCE -fvisibility=hidden -fno-exceptions
|
|
### Build libam
|
|
#### Include archetecture specific build flags
|
|
COMMON_CFLAGS += -D__ARCH_$(shell echo $(ARCH) | tr a-z A-Z | tr - _) \
|
|
-D__ISA_$(shell echo $(ISA) | tr a-z A-Z)__ \
|
|
-DARCH_H=\"$(ARCH_H)\"
|
|
INTERFACE_CFLAGS += -DARCH_H=\"$(ARCH_H)\"
|
|
|
|
#### Generating build rules with ADD_LIBRARY call. Target specific build flags can be tuned via changing prefixed variables (AM_ here)
|
|
AM_INCPATH += $(AM_HOME)/am/include $(AM_HOME)/am/src $(AM_HOME)/klib/include
|
|
AM_CFLAGS += $(COMMON_CFLAGS) $(addprefix -I, $(AM_INCPATH))
|
|
AM_INTERFACE_INCPATH += $(AM_HOME)/am/include $(AM_HOME)/klib/include
|
|
AM_INTERFACE_CFLAGS +=
|
|
|
|
AM_INTERFACE_LDFLAGS += -lam-$(ARCH)
|
|
|
|
$(eval $(call ADD_LIBRARY,$(LIB_BUILDDIR)/libam-$(ARCH).a,AM_))
|
|
|
|
### Build klib
|
|
|
|
KLIB_SRCS := $(shell find klib/src/ -name "*.c")
|
|
|
|
KLIB_INCPATH += $(AM_HOME)/am/include $(AM_HOME)/klib/include
|
|
KLIB_CFLAGS += $(COMMON_CFLAGS) $(addprefix -I, $(KLIB_INCPATH))
|
|
KLIB_INTERFACE_INCPATH += $(AM_HOME)/am/include $(AM_HOME)/klib/include
|
|
KLIB_INTERFACE_CFLAGS +=
|
|
KLIB_INTERFACE_LDFLAGS += -lklib-$(ARCH)
|
|
|
|
$(eval $(call ADD_LIBRARY,$(LIB_BUILDDIR)/libklib-$(ARCH).a,KLIB_))
|
|
|
|
LIBS := am klib
|
|
libs: $(addsuffix -$(ARCH).a, $(addprefix $(LIB_BUILDDIR)/lib, $(ALL)))
|
|
$(LIBS): %: $(addsuffix -$(ARCH).a, $(addprefix $(LIB_BUILDDIR)/lib, %))
|
|
|
|
## 6. Install rules
|
|
INTERFACE_INCPATH += $(sort $(KLIB_INTERFACE_INCPATH) $(AM_INTERFACE_INCPATH))
|
|
# TODO: Use sort here will cause error on seperated flags, such as: -e _start
|
|
# but without sort, duplicated flags will not be removed.
|
|
INTERFACE_CFLAGS += $(addprefix -I, $(INTERFACE_INCPATH:%=$(INC_INSTALLDIR))) $(sort $(KLIB_INTERFACE_CFLAGS) $(AM_INTERFACE_CFLAGS))
|
|
INTERFACE_CXXFLAGS += $(INTERFACE_CFLAGS) $(addprefix -I, $(INTERFACE_INCPATH:%=$(INC_INSTALLDIR)))
|
|
INTERFACE_LDFLAGS += -L$(LIB_INSTALLDIR) $(sort $(KLIB_INTERFACE_LDFLAGS) $(AM_INTERFACE_LDFLAGS))
|
|
|
|
EXPORT_FLAGS_FILE := $(LIB_INSTALLDIR)/make/flags-$(ARCH).mk
|
|
EXPORT_FLAGS_TEMPLATE := $(file < $(AM_HOME)/scripts/templates/flags.tmpl)
|
|
HELPERS := $(wildcard find scripts/helpers/*.mk)
|
|
EXPORT_HELPERS := $(HELPERS:scripts/helpers/%=$(LIB_INSTALLDIR)/make/%)
|
|
|
|
EXPORTS := $(EXPORT_FLAGS_FILE) $(EXPORT_HELPERS)
|
|
|
|
$(EXPORT_HELPERS): $(LIB_INSTALLDIR)/make/%: scripts/helpers/%
|
|
@echo + INSTALL $(patsubst $(INSTALLDIR)/%,%,$@)
|
|
@install -dm755 $(dir $@)
|
|
@install -Dm644 $< $(dir $@)
|
|
|
|
export INTERFACE_CFLAGS INTERFACE_CXXFLAGS INTERFACE_ASFLAGS INTERFACE_INCPATH INTERFACE_LDFLAGS
|
|
$(EXPORT_FLAGS_FILE):
|
|
@echo + INSTALL $(patsubst $(INSTALLDIR)/%,%,$@)
|
|
@install -Dm644 <(printf $(EXPORT_FLAGS_TEMPLATE)) $(EXPORT_FLAGS_FILE)
|
|
|
|
LDSCRIPTS := $(patsubst $(AM_HOME)/scripts/%, $(LIB_INSTALLDIR)/ldscripts/%, $(shell find $(AM_HOME)/scripts -name "*.ld"))
|
|
|
|
$(LDSCRIPTS): $(LIB_INSTALLDIR)/ldscripts/%: $(AM_HOME)/scripts/%
|
|
@echo + INSTALL $(patsubst $(INSTALLDIR)/%,%,$@)
|
|
@mkdir -p $(LIB_INSTALLDIR)/ldscripts
|
|
@install -Dm644 $< $(dir $@)
|
|
|
|
install-libs: $(LIBS)
|
|
@echo + INSTALL LIBS: $(LIBS)
|
|
@install -dm755 $(LIB_INSTALLDIR)
|
|
@install -Dm644 $(addsuffix -$(ARCH).a, $(addprefix $(LIB_BUILDDIR)/lib, $(LIBS))) $(LIB_INSTALLDIR)
|
|
|
|
install-headers: HEADERS := $(shell find $(INTERFACE_INCPATH) -name '*.h')
|
|
install-headers: $(HEADERS) # Headers needs to be reinstalled if they are changed
|
|
@echo + INSTALL HEADERS: $(INTERFACE_INCPATH)
|
|
@install -dm755 $(INC_INSTALLDIR)
|
|
@cp -r $(addsuffix /*, $(INTERFACE_INCPATH)) $(INC_INSTALLDIR)
|
|
|
|
install: $(EXPORTS) install-libs install-headers $(LDSCRIPTS)
|
|
|
|
.PHONY: libs $(LIBS) install
|
|
|
|
### 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 $@ cleaear
|
|
|