Files
lk/engine.mk
Travis Geiselbrecht 6462cbf51c [arch][fpu] add ability to specify per file or module if code needs fpu
Have the arch define additional compiler flags to explicit support or
not support a floating point unit.

Add ability for modules to per file or for the whole module mark code
as needing floating point support.

Add default flags for arm64, riscv, and x86 toolchains.

Needed because gcc 12 is getting much more aggressive about using vector
instructions for non float code, so getting away with avoiding it was
no longer working.

Still not perfect: printf code is being compiled with float, so it's
possible to use floating point instructions inside core kernel or
interrupt handling code if a printf is used.

Possibly will have problems on architectures where mixing float and non
float code at the linker generates issues, but so far seems to be okay.
2022-07-17 16:32:24 -07:00

311 lines
9.3 KiB
Makefile

LOCAL_MAKEFILE:=$(MAKEFILE_LIST)
# macros used all over the build system
include make/macros.mk
BUILDROOT ?= .
# 'make spotless' is a special rule that skips most of the rest of the build system and
# simply deletes everything in build-*
ifeq ($(MAKECMDGOALS),spotless)
spotless:
rm -rf -- "$(BUILDROOT)"/build-*
else
ifndef LKROOT
$(error please define LKROOT to the root of the lk build system)
endif
# any local environment overrides can optionally be placed in local.mk
-include local.mk
# If one of our goals (from the commandline) happens to have a
# matching project/goal.mk, then we should re-invoke make with
# that project name specified...
project-name := $(firstword $(MAKECMDGOALS))
ifneq ($(project-name),)
ifneq ($(strip $(foreach d,$(LKINC),$(wildcard $(d)/project/$(project-name).mk))),)
do-nothing := 1
$(MAKECMDGOALS) _all: make-make
@:
make-make:
@PROJECT=$(project-name) $(MAKE) -rR -f $(LOCAL_MAKEFILE) $(filter-out $(project-name), $(MAKECMDGOALS))
.PHONY: make-make
endif # expansion of project-name
endif # project-name == null
# some additional rules to print some help
include make/help.mk
ifeq ($(do-nothing),)
ifeq ($(PROJECT),)
ifneq ($(DEFAULT_PROJECT),)
PROJECT := $(DEFAULT_PROJECT)
else
$(error No project specified. Use 'make list' for a list of projects or 'make help' for additional help)
endif # DEFAULT_PROJECT == something
endif # PROJECT == null
DEBUG ?= 2
BUILDDIR := $(BUILDROOT)/build-$(PROJECT)
OUTBIN := $(BUILDDIR)/lk.bin
OUTELF := $(BUILDDIR)/lk.elf
CONFIGHEADER := $(BUILDDIR)/config.h
GLOBAL_INCLUDES := $(BUILDDIR) $(addsuffix /include,$(LKINC))
GLOBAL_OPTFLAGS ?= $(ARCH_OPTFLAGS)
GLOBAL_COMPILEFLAGS := -g -include $(CONFIGHEADER)
GLOBAL_COMPILEFLAGS += -Wextra -Wall -Werror=return-type -Wshadow -Wdouble-promotion
GLOBAL_COMPILEFLAGS += -Wno-multichar -Wno-unused-parameter -Wno-unused-function -Wno-unused-label -Wno-nonnull-compare
GLOBAL_COMPILEFLAGS += -fno-common
GLOBAL_CFLAGS := --std=gnu11 -Werror-implicit-function-declaration -Wstrict-prototypes -Wwrite-strings
GLOBAL_CPPFLAGS := --std=c++14 -fno-exceptions -fno-rtti -fno-threadsafe-statics
GLOBAL_ASMFLAGS := -DASSEMBLY
GLOBAL_LDFLAGS :=
# flags that are sometimes nice to enable to catch problems but too strict to have on all the time
#GLOBAL_COMPILEFLAGS += -Wmissing-declarations
# if WERROR is set, add to the compile args
ifeq (true,$(call TOBOOL,$(WERROR)))
GLOBAL_COMPILEFLAGS += -Werror
endif
GLOBAL_LDFLAGS += $(addprefix -L,$(LKINC))
# Architecture specific compile flags
ARCH_COMPILEFLAGS :=
ARCH_COMPILEFLAGS_NOFLOAT := # flags used when compiling with floating point support
ARCH_COMPILEFLAGS_FLOAT := # flags for when not compiling with floating point support
ARCH_CFLAGS :=
ARCH_CPPFLAGS :=
ARCH_ASMFLAGS :=
ARCH_LDFLAGS :=
# top level rule
all:: $(OUTBIN) $(OUTELF).lst $(OUTELF).debug.lst $(OUTELF).sym $(OUTELF).sym.sorted $(OUTELF).size $(OUTELF).dump $(BUILDDIR)/srcfiles.txt $(BUILDDIR)/include_paths.txt
# master module object list
ALLOBJS_MODULE :=
# master object list (for dep generation)
ALLOBJS :=
# master source file list
ALLSRCS :=
# a linker script needs to be declared in one of the project/target/platform files
LINKER_SCRIPT :=
# anything you add here will be deleted in make clean
GENERATED := $(CONFIGHEADER)
# anything added to GLOBAL_DEFINES will be put into $(BUILDDIR)/config.h
GLOBAL_DEFINES := LK=1
# Anything added to GLOBAL_SRCDEPS will become a dependency of every source file in the system.
# Useful for header files that may be included by one or more source files.
GLOBAL_SRCDEPS := $(CONFIGHEADER)
# these need to be filled out by the project/target/platform rules.mk files
TARGET :=
PLATFORM :=
ARCH :=
ALLMODULES :=
# add any external module dependencies
MODULES := $(EXTERNAL_MODULES)
# any .mk specified here will be included before build.mk
EXTRA_BUILDRULES :=
# any rules you put here will also be built by the system before considered being complete
EXTRA_BUILDDEPS :=
# any rules you put here will be depended on in clean builds
EXTRA_CLEANDEPS :=
# any objects you put here get linked with the final image
EXTRA_OBJS :=
# any extra linker scripts to be put on the command line
EXTRA_LINKER_SCRIPTS :=
# if someone defines this, the build id will be pulled into lib/version
BUILDID ?=
# comment out or override if you want to see the full output of each command
NOECHO ?= @
# try to include the project file
-include project/$(PROJECT).mk
ifndef TARGET
$(error couldn't find project or project doesn't define target)
endif
include target/$(TARGET)/rules.mk
ifndef PLATFORM
$(error couldn't find target or target doesn't define platform)
endif
include platform/$(PLATFORM)/rules.mk
ifndef ARCH
$(error couldn't find arch or platform doesn't define arch)
endif
include arch/$(ARCH)/rules.mk
ifndef TOOLCHAIN_PREFIX
$(error TOOLCHAIN_PREFIX not set in the arch rules.mk)
endif
$(info PROJECT = $(PROJECT))
$(info PLATFORM = $(PLATFORM))
$(info TARGET = $(TARGET))
$(info ARCH = $(ARCH))
$(info TOOLCHAIN_PREFIX = $(TOOLCHAIN_PREFIX))
$(info DEBUG = $(DEBUG))
# include the top level module that includes basic always-there modules
include top/rules.mk
# recursively include any modules in the MODULE variable, leaving a trail of included
# modules in the ALLMODULES list
include make/recurse.mk
# add some automatic configuration defines
GLOBAL_DEFINES += \
PROJECT_$(PROJECT)=1 \
PROJECT=\"$(PROJECT)\" \
TARGET_$(TARGET)=1 \
TARGET=\"$(TARGET)\" \
PLATFORM_$(PLATFORM)=1 \
PLATFORM=\"$(PLATFORM)\" \
ARCH_$(ARCH)=1 \
ARCH=\"$(ARCH)\" \
$(addsuffix =1,$(addprefix WITH_,$(ALLMODULES)))
# debug build?
ifneq ($(DEBUG),)
GLOBAL_DEFINES += \
LK_DEBUGLEVEL=$(DEBUG)
endif
# allow additional defines from outside the build system
ifneq ($(EXTERNAL_DEFINES),)
GLOBAL_DEFINES += $(EXTERNAL_DEFINES)
$(info EXTERNAL_DEFINES = $(EXTERNAL_DEFINES))
endif
# prefix all of the paths in GLOBAL_INCLUDES with -I
GLOBAL_INCLUDES := $(addprefix -I,$(GLOBAL_INCLUDES))
# test for some old variables
ifneq ($(INCLUDES),)
$(error INCLUDES variable set, please move to GLOBAL_INCLUDES: $(INCLUDES))
endif
ifneq ($(DEFINES),)
$(error DEFINES variable set, please move to GLOBAL_DEFINES: $(DEFINES))
endif
# default to no ccache
CCACHE ?=
CC := $(CCACHE) $(TOOLCHAIN_PREFIX)gcc
LD := $(TOOLCHAIN_PREFIX)ld
OBJDUMP := $(TOOLCHAIN_PREFIX)objdump
OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy
CPPFILT := $(TOOLCHAIN_PREFIX)c++filt
SIZE := $(TOOLCHAIN_PREFIX)size
NM := $(TOOLCHAIN_PREFIX)nm
STRIP := $(TOOLCHAIN_PREFIX)strip
# try to have the compiler output colorized error messages if available
export GCC_COLORS ?= 1
# the logic to compile and link stuff is in here
include make/build.mk
DEPS := $(ALLOBJS:%o=%d)
# put all of the global build flags in config.h to force a rebuild if any change
GLOBAL_DEFINES += GLOBAL_INCLUDES=\"$(subst $(SPACE),_,$(GLOBAL_INCLUDES))\"
GLOBAL_DEFINES += GLOBAL_COMPILEFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_COMPILEFLAGS))\"
GLOBAL_DEFINES += GLOBAL_OPTFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_OPTFLAGS))\"
GLOBAL_DEFINES += GLOBAL_CFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_CFLAGS))\"
GLOBAL_DEFINES += GLOBAL_CPPFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_CPPFLAGS))\"
GLOBAL_DEFINES += GLOBAL_ASMFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_ASMFLAGS))\"
GLOBAL_DEFINES += GLOBAL_LDFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_LDFLAGS))\"
GLOBAL_DEFINES += ARCH_COMPILEFLAGS=\"$(subst $(SPACE),_,$(ARCH_COMPILEFLAGS))\"
GLOBAL_DEFINES += ARCH_CFLAGS=\"$(subst $(SPACE),_,$(ARCH_CFLAGS))\"
GLOBAL_DEFINES += ARCH_CPPFLAGS=\"$(subst $(SPACE),_,$(ARCH_CPPFLAGS))\"
GLOBAL_DEFINES += ARCH_ASMFLAGS=\"$(subst $(SPACE),_,$(ARCH_ASMFLAGS))\"
GLOBAL_DEFINES += ARCH_LDFLAGS=\"$(subst $(SPACE),_,$(ARCH_LDFLAGS))\"
GLOBAL_DEFINES += TOOLCHAIN_PREFIX=\"$(subst $(SPACE),_,$(TOOLCHAIN_PREFIX))\"
ifneq ($(OBJS),)
$(warning OBJS=$(OBJS))
$(error OBJS is not empty, please convert to new module format)
endif
ifneq ($(OPTFLAGS),)
$(warning OPTFLAGS=$(OPTFLAGS))
$(error OPTFLAGS is not empty, please use GLOBAL_OPTFLAGS or MODULE_OPTFLAGS)
endif
ifneq ($(CFLAGS),)
$(warning CFLAGS=$(CFLAGS))
$(error CFLAGS is not empty, please use GLOBAL_CFLAGS or MODULE_CFLAGS)
endif
ifneq ($(CPPFLAGS),)
$(warning CPPFLAGS=$(CPPFLAGS))
$(error CPPFLAGS is not empty, please use GLOBAL_CPPFLAGS or MODULE_CPPFLAGS)
endif
$(info LIBGCC = $(LIBGCC))
$(info GLOBAL_COMPILEFLAGS = $(GLOBAL_COMPILEFLAGS))
$(info GLOBAL_OPTFLAGS = $(GLOBAL_OPTFLAGS))
# make all object files depend on any targets in GLOBAL_SRCDEPS
$(ALLOBJS): $(GLOBAL_SRCDEPS)
# any extra top level build dependencies that someone declared.
# build.mk may add to EXTRA_BUILDDEPS, this must be evalauted after build.mk.
all:: $(EXTRA_BUILDDEPS)
clean: $(EXTRA_CLEANDEPS)
rm -f $(ALLOBJS) $(DEPS) $(GENERATED) $(OUTBIN) $(OUTELF) $(OUTELF).lst $(OUTELF).debug.lst $(OUTELF).sym $(OUTELF).sym.sorted $(OUTELF).size $(OUTELF).hex $(OUTELF).dump
install: all
scp $(OUTBIN) 192.168.0.4:/tftpboot
list-arch:
@echo ARCH = ${ARCH}
list-toolchain:
@echo TOOLCHAIN_PREFIX = ${TOOLCHAIN_PREFIX}
.PHONY: all clean install list-arch list-toolchain
# generate a config.h file with all of the GLOBAL_DEFINES laid out in #define format
configheader:
$(CONFIGHEADER): configheader
@$(call MAKECONFIGHEADER,$@,GLOBAL_DEFINES)
.PHONY: configheader
# Empty rule for the .d files. The above rules will build .d files as a side
# effect. Only works on gcc 3.x and above, however.
%.d:
ifeq ($(filter $(MAKECMDGOALS), clean), )
-include $(DEPS)
endif
endif # do-nothing = 1
endif # make spotless