1LOCAL_MAKEFILE:=$(MAKEFILE_LIST) 2 3# macros used all over the build system 4include make/macros.mk 5 6BUILDROOT ?= . 7 8# 'make spotless' is a special rule that skips most of the rest of the build system and 9# simply deletes everything in build-* 10ifeq ($(MAKECMDGOALS),spotless) 11spotless: 12 rm -rf -- "$(BUILDROOT)"/build-* 13else 14 15ifndef LKROOT 16$(error please define LKROOT to the root of the lk build system) 17endif 18 19# any local environment overrides can optionally be placed in local.mk 20-include local.mk 21 22# If one of our goals (from the commandline) happens to have a 23# matching project/goal.mk, then we should re-invoke make with 24# that project name specified... 25 26project-name := $(firstword $(MAKECMDGOALS)) 27 28ifneq ($(project-name),) 29ifneq ($(strip $(foreach d,$(LKINC),$(wildcard $(d)/project/$(project-name).mk))),) 30do-nothing := 1 31$(MAKECMDGOALS) _all: make-make 32 @: 33make-make: 34 @PROJECT=$(project-name) $(MAKE) -rR -f $(LOCAL_MAKEFILE) $(filter-out $(project-name), $(MAKECMDGOALS)) 35 36.PHONY: make-make 37endif # expansion of project-name 38endif # project-name == null 39 40# some additional rules to print some help 41include make/help.mk 42 43ifeq ($(do-nothing),) 44 45ifeq ($(PROJECT),) 46 47ifneq ($(DEFAULT_PROJECT),) 48PROJECT := $(DEFAULT_PROJECT) 49else 50$(error No project specified. Use 'make list' for a list of projects or 'make help' for additional help) 51endif # DEFAULT_PROJECT == something 52 53endif # PROJECT == null 54 55DEBUG ?= 2 56 57BUILDDIR := $(BUILDROOT)/build-$(PROJECT) 58OUTBIN := $(BUILDDIR)/lk.bin 59OUTELF := $(BUILDDIR)/lk.elf 60CONFIGHEADER := $(BUILDDIR)/config.h 61 62GLOBAL_INCLUDES := $(BUILDDIR) $(addsuffix /include,$(LKINC)) 63GLOBAL_OPTFLAGS ?= $(ARCH_OPTFLAGS) 64GLOBAL_COMPILEFLAGS := -g -include $(CONFIGHEADER) 65GLOBAL_COMPILEFLAGS += -Wextra -Wall -Werror=return-type -Wshadow -Wdouble-promotion 66GLOBAL_COMPILEFLAGS += -Wno-multichar -Wno-unused-parameter -Wno-unused-function -Wno-unused-label -Wno-nonnull-compare 67GLOBAL_COMPILEFLAGS += -fno-common 68GLOBAL_CFLAGS := --std=gnu11 -Werror-implicit-function-declaration -Wstrict-prototypes -Wwrite-strings 69GLOBAL_CPPFLAGS := --std=c++14 -fno-exceptions -fno-rtti -fno-threadsafe-statics 70GLOBAL_ASMFLAGS := -DASSEMBLY 71GLOBAL_LDFLAGS := 72 73# flags that are sometimes nice to enable to catch problems but too strict to have on all the time 74#GLOBAL_COMPILEFLAGS += -Wmissing-declarations 75 76# if WERROR is set, add to the compile args 77ifeq (true,$(call TOBOOL,$(WERROR))) 78GLOBAL_COMPILEFLAGS += -Werror 79endif 80 81GLOBAL_LDFLAGS += $(addprefix -L,$(LKINC)) 82 83# Architecture specific compile flags 84ARCH_COMPILEFLAGS := 85ARCH_CFLAGS := 86ARCH_CPPFLAGS := 87ARCH_ASMFLAGS := 88ARCH_LDFLAGS := 89 90# top level rule 91all:: $(OUTBIN) $(OUTELF).lst $(OUTELF).debug.lst $(OUTELF).sym $(OUTELF).sym.sorted $(OUTELF).size $(OUTELF).dump $(BUILDDIR)/srcfiles.txt $(BUILDDIR)/include_paths.txt 92 93# master module object list 94ALLOBJS_MODULE := 95 96# master object list (for dep generation) 97ALLOBJS := 98 99# master source file list 100ALLSRCS := 101 102# a linker script needs to be declared in one of the project/target/platform files 103LINKER_SCRIPT := 104 105# anything you add here will be deleted in make clean 106GENERATED := $(CONFIGHEADER) 107 108# anything added to GLOBAL_DEFINES will be put into $(BUILDDIR)/config.h 109GLOBAL_DEFINES := LK=1 110 111# Anything added to GLOBAL_SRCDEPS will become a dependency of every source file in the system. 112# Useful for header files that may be included by one or more source files. 113GLOBAL_SRCDEPS := $(CONFIGHEADER) 114 115# these need to be filled out by the project/target/platform rules.mk files 116TARGET := 117PLATFORM := 118ARCH := 119ALLMODULES := 120 121# add any external module dependencies 122MODULES := $(EXTERNAL_MODULES) 123 124# any .mk specified here will be included before build.mk 125EXTRA_BUILDRULES := 126 127# any rules you put here will also be built by the system before considered being complete 128EXTRA_BUILDDEPS := 129 130# any rules you put here will be depended on in clean builds 131EXTRA_CLEANDEPS := 132 133# any objects you put here get linked with the final image 134EXTRA_OBJS := 135 136# any extra linker scripts to be put on the command line 137EXTRA_LINKER_SCRIPTS := 138 139# if someone defines this, the build id will be pulled into lib/version 140BUILDID ?= 141 142# comment out or override if you want to see the full output of each command 143NOECHO ?= @ 144 145# try to include the project file 146-include project/$(PROJECT).mk 147ifndef TARGET 148$(error couldn't find project or project doesn't define target) 149endif 150include target/$(TARGET)/rules.mk 151ifndef PLATFORM 152$(error couldn't find target or target doesn't define platform) 153endif 154include platform/$(PLATFORM)/rules.mk 155 156ifndef ARCH 157$(error couldn't find arch or platform doesn't define arch) 158endif 159include arch/$(ARCH)/rules.mk 160ifndef TOOLCHAIN_PREFIX 161$(error TOOLCHAIN_PREFIX not set in the arch rules.mk) 162endif 163 164$(info PROJECT = $(PROJECT)) 165$(info PLATFORM = $(PLATFORM)) 166$(info TARGET = $(TARGET)) 167$(info ARCH = $(ARCH)) 168$(info TOOLCHAIN_PREFIX = $(TOOLCHAIN_PREFIX)) 169$(info DEBUG = $(DEBUG)) 170 171# include the top level module that includes basic always-there modules 172include top/rules.mk 173 174# recursively include any modules in the MODULE variable, leaving a trail of included 175# modules in the ALLMODULES list 176include make/recurse.mk 177 178# add some automatic configuration defines 179GLOBAL_DEFINES += \ 180 PROJECT_$(PROJECT)=1 \ 181 PROJECT=\"$(PROJECT)\" \ 182 TARGET_$(TARGET)=1 \ 183 TARGET=\"$(TARGET)\" \ 184 PLATFORM_$(PLATFORM)=1 \ 185 PLATFORM=\"$(PLATFORM)\" \ 186 ARCH_$(ARCH)=1 \ 187 ARCH=\"$(ARCH)\" \ 188 $(addsuffix =1,$(addprefix WITH_,$(ALLMODULES))) 189 190# debug build? 191ifneq ($(DEBUG),) 192GLOBAL_DEFINES += \ 193 LK_DEBUGLEVEL=$(DEBUG) 194endif 195 196# allow additional defines from outside the build system 197ifneq ($(EXTERNAL_DEFINES),) 198GLOBAL_DEFINES += $(EXTERNAL_DEFINES) 199$(info EXTERNAL_DEFINES = $(EXTERNAL_DEFINES)) 200endif 201 202 203# prefix all of the paths in GLOBAL_INCLUDES with -I 204GLOBAL_INCLUDES := $(addprefix -I,$(GLOBAL_INCLUDES)) 205 206# test for some old variables 207ifneq ($(INCLUDES),) 208$(error INCLUDES variable set, please move to GLOBAL_INCLUDES: $(INCLUDES)) 209endif 210ifneq ($(DEFINES),) 211$(error DEFINES variable set, please move to GLOBAL_DEFINES: $(DEFINES)) 212endif 213 214# default to no ccache 215CCACHE ?= 216CC := $(CCACHE) $(TOOLCHAIN_PREFIX)gcc 217LD := $(TOOLCHAIN_PREFIX)ld 218OBJDUMP := $(TOOLCHAIN_PREFIX)objdump 219OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy 220CPPFILT := $(TOOLCHAIN_PREFIX)c++filt 221SIZE := $(TOOLCHAIN_PREFIX)size 222NM := $(TOOLCHAIN_PREFIX)nm 223STRIP := $(TOOLCHAIN_PREFIX)strip 224 225# try to have the compiler output colorized error messages if available 226export GCC_COLORS ?= 1 227 228# the logic to compile and link stuff is in here 229include make/build.mk 230 231DEPS := $(ALLOBJS:%o=%d) 232 233# put all of the global build flags in config.h to force a rebuild if any change 234GLOBAL_DEFINES += GLOBAL_INCLUDES=\"$(subst $(SPACE),_,$(GLOBAL_INCLUDES))\" 235GLOBAL_DEFINES += GLOBAL_COMPILEFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_COMPILEFLAGS))\" 236GLOBAL_DEFINES += GLOBAL_OPTFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_OPTFLAGS))\" 237GLOBAL_DEFINES += GLOBAL_CFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_CFLAGS))\" 238GLOBAL_DEFINES += GLOBAL_CPPFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_CPPFLAGS))\" 239GLOBAL_DEFINES += GLOBAL_ASMFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_ASMFLAGS))\" 240GLOBAL_DEFINES += GLOBAL_LDFLAGS=\"$(subst $(SPACE),_,$(GLOBAL_LDFLAGS))\" 241GLOBAL_DEFINES += ARCH_COMPILEFLAGS=\"$(subst $(SPACE),_,$(ARCH_COMPILEFLAGS))\" 242GLOBAL_DEFINES += ARCH_CFLAGS=\"$(subst $(SPACE),_,$(ARCH_CFLAGS))\" 243GLOBAL_DEFINES += ARCH_CPPFLAGS=\"$(subst $(SPACE),_,$(ARCH_CPPFLAGS))\" 244GLOBAL_DEFINES += ARCH_ASMFLAGS=\"$(subst $(SPACE),_,$(ARCH_ASMFLAGS))\" 245GLOBAL_DEFINES += ARCH_LDFLAGS=\"$(subst $(SPACE),_,$(ARCH_LDFLAGS))\" 246GLOBAL_DEFINES += TOOLCHAIN_PREFIX=\"$(subst $(SPACE),_,$(TOOLCHAIN_PREFIX))\" 247 248ifneq ($(OBJS),) 249$(warning OBJS=$(OBJS)) 250$(error OBJS is not empty, please convert to new module format) 251endif 252ifneq ($(OPTFLAGS),) 253$(warning OPTFLAGS=$(OPTFLAGS)) 254$(error OPTFLAGS is not empty, please use GLOBAL_OPTFLAGS or MODULE_OPTFLAGS) 255endif 256ifneq ($(CFLAGS),) 257$(warning CFLAGS=$(CFLAGS)) 258$(error CFLAGS is not empty, please use GLOBAL_CFLAGS or MODULE_CFLAGS) 259endif 260ifneq ($(CPPFLAGS),) 261$(warning CPPFLAGS=$(CPPFLAGS)) 262$(error CPPFLAGS is not empty, please use GLOBAL_CPPFLAGS or MODULE_CPPFLAGS) 263endif 264 265$(info LIBGCC = $(LIBGCC)) 266$(info GLOBAL_COMPILEFLAGS = $(GLOBAL_COMPILEFLAGS)) 267$(info GLOBAL_OPTFLAGS = $(GLOBAL_OPTFLAGS)) 268 269# make all object files depend on any targets in GLOBAL_SRCDEPS 270$(ALLOBJS): $(GLOBAL_SRCDEPS) 271 272# any extra top level build dependencies that someone declared. 273# build.mk may add to EXTRA_BUILDDEPS, this must be evalauted after build.mk. 274all:: $(EXTRA_BUILDDEPS) 275 276clean: $(EXTRA_CLEANDEPS) 277 rm -f $(ALLOBJS) $(DEPS) $(GENERATED) $(OUTBIN) $(OUTELF) $(OUTELF).lst $(OUTELF).debug.lst $(OUTELF).sym $(OUTELF).sym.sorted $(OUTELF).size $(OUTELF).hex $(OUTELF).dump 278 279install: all 280 scp $(OUTBIN) 192.168.0.4:/tftproot 281 282list-arch: 283 @echo ARCH = ${ARCH} 284 285list-toolchain: 286 @echo TOOLCHAIN_PREFIX = ${TOOLCHAIN_PREFIX} 287 288.PHONY: all clean install list-arch list-toolchain 289 290# generate a config.h file with all of the GLOBAL_DEFINES laid out in #define format 291configheader: 292 293$(CONFIGHEADER): configheader 294 @$(call MAKECONFIGHEADER,$@,GLOBAL_DEFINES) 295 296.PHONY: configheader 297 298# Empty rule for the .d files. The above rules will build .d files as a side 299# effect. Only works on gcc 3.x and above, however. 300%.d: 301 302ifeq ($(filter $(MAKECMDGOALS), clean), ) 303-include $(DEPS) 304endif 305 306endif # do-nothing = 1 307 308endif # make spotless 309