ugfx/tools/gmake_scripts/compiler_gcc.mk

373 lines
9.7 KiB
Makefile

#
# This file is subject to the terms of the GFX License. If a copy of
# the license was not distributed with this file, you can obtain one at:
#
# http://ugfx.io/license.html
#
#
# See readme.txt for the make API
#
# Copy this pseudo variable so we can path expand it
MLIST := $(MAKEFILE_LIST)
# Win32 Nasty - must convert all paths into a format make can handle
ifeq ($(basename $(OPT_OS)),win32)
PATHEXPAND := ARCH XCC XCXX XAS XLD XOC XOD XSZ XAR PROJECT BUILDDIR SRC DEFS LIBS INCPATH LIBPATH MLIST $(PATHLIST)
# First convert \'s to /'s
$(foreach var,$(PATHEXPAND),$(eval $(var):=$$(subst \,/,$($(var)))))
# For cygwin gmake - need to convert all absolute paths (mingw gmake doesn't need this)
ifneq ($(findstring cygdrive,$(PATH)),)
DRIVELETTERS := a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
$(foreach drv,$(DRIVELETTERS),$(foreach var,$(PATHEXPAND),$(eval $(var):=$$(patsubst $(drv):%,/cygdrive/$(drv)%,$($(var))))))
endif
endif
# Where are we
CURRENTDIR := $(dir $(abspath $(lastword $(MLIST))))
# Handle cpu specific options
ifneq ($(OPT_CPU),)
include $(CURRENTDIR)cpu_$(OPT_CPU).mk
endif
# Path resolution - Functions to convert a source path to a object path and visa-versa
src_obj_fn := $$(1)
obj_src_fn := $$(1)
$(foreach var,$(PATHLIST),$(eval obj_src_fn := $$$$(patsubst $(var)/%,$$$$($(var))/%,$$(obj_src_fn))))
$(foreach var,$(PATHLIST),$(eval src_obj_fn := $$$$(patsubst $$$$($(var))/%,$(var)/%,$$(src_obj_fn))))
src_obj_fn := $$(subst :,_drv_drv_,$$(subst ../,_dot_dot/,$(src_obj_fn)))
obj_src_fn := $$(subst _drv_drv_,:,$$(subst _dot_dot/,../,$(obj_src_fn)))
$(eval src_obj=$(src_obj_fn))
$(eval obj_src=$(obj_src_fn))
# Add ARCH to each of the compiler programs
ifeq ($(XCC),)
XCC = $(ARCH)gcc
endif
ifeq ($(XCXX),)
XCXX = $(ARCH)g++
endif
ifeq ($(XAS),)
XAS = $(ARCH)gcc -x assembler-with-cpp
endif
ifeq ($(XLD),)
XLD = $(ARCH)gcc
endif
ifeq ($(XOC),)
XOC = $(ARCH)objcopy
endif
ifeq ($(XOD),)
XOD = $(ARCH)objdump
endif
ifeq ($(XSZ),)
XSZ = $(ARCH)size
endif
ifeq ($(XAR),)
XAR = $(ARCH)ar
endif
# Default project name is the project directory name
ifeq ($(PROJECT),)
ifneq ($(firstword $(abspath $(firstword $(MLIST)))),$(lastword $(abspath $(firstword $(MLIST)))))
$(error Your directory contains spaces. Gmake barfs at that. Please define PROJECT)
endif
PROJECT := $(notdir $(patsubst %/,%,$(dir $(abspath $(firstword $(MLIST))))))
endif
# Output directories
ifeq ($(BUILDDIR),)
ifeq ($(MAKECMDGOALS),Debug)
BUILDDIR = bin/Debug
endif
ifeq ($(MAKECMDGOALS),Release)
BUILDDIR = bin/Release
endif
ifeq ($(MAKECMDGOALS),cleanDebug)
BUILDDIR = bin/Debug
endif
ifeq ($(MAKECMDGOALS),cleanRelease)
BUILDDIR = bin/Release
endif
ifeq ($(BUILDDIR),)
BUILDDIR = .build
endif
endif
OBJDIR = $(BUILDDIR)/obj
DEPDIR = $(BUILDDIR)/dep
# Output files
MAPFILE = $(BUILDDIR)/$(PROJECT).map
LIBFILE = $(BUILDDIR)/lib$(PROJECT).a
FAKEFILE= fakefile.o
EXEFILE =
ifeq ($(basename $(OPT_OS)),win32)
EXEFILE = $(BUILDDIR)/$(PROJECT).exe
TARGETS = $(EXEFILE)
endif
ifeq ($(basename $(OPT_OS)),linux)
EXEFILE = $(BUILDDIR)/$(PROJECT)
TARGETS = $(EXEFILE)
endif
ifeq ($(basename $(OPT_OS)),osx)
EXEFILE = $(BUILDDIR)/$(PROJECT)
TARGETS = $(EXEFILE)
endif
ifeq ($(basename $(OPT_OS)),freebsd)
EXEFILE = $(BUILDDIR)/$(PROJECT)
TARGETS = $(EXEFILE)
endif
ifeq ($(EXEFILE),)
LDFLAGS += -nostartfiles
EXEFILE = $(BUILDDIR)/$(PROJECT).elf
TARGETS = $(EXEFILE) $(BUILDDIR)/$(PROJECT).hex $(BUILDDIR)/$(PROJECT).bin $(BUILDDIR)/$(PROJECT).dmp elfstats
endif
# Generate our object file lists
OBJS_THUMB += $(addprefix $(OBJDIR)/,$(call src_obj,$(addsuffix .o,$(basename $(SRC_THUMB)))))
OBJS_NOTHUMB += $(addprefix $(OBJDIR)/,$(call src_obj,$(addsuffix .o,$(basename $(SRC_NOTHUMB)))))
ifeq ($(OPT_THUMB),yes)
OBJS_THUMB += $(OBJS) $(addprefix $(OBJDIR)/,$(call src_obj,$(addsuffix .o,$(basename $(SRC)))))
else
OBJS_NOTHUMB += $(OBJS) $(addprefix $(OBJDIR)/,$(call src_obj,$(addsuffix .o,$(basename $(SRC)))))
endif
ifneq ($(OBJS_THUMB),)
ifneq ($(OBJS_NOTHUMB),)
# Mixed ARM and THUMB mode - enabled only if needed because it kills performance.
SRCFLAGS += -mthumb-interwork
LDFLAGS += -mthumb-interwork
DEFS += THUMB_PRESENT
else
# Pure THUMB mode, THUMB C code cannot be called by ARM asm code directly.
LDFLAGS += -mthumb
DEFS += THUMB_PRESENT THUMB_NO_INTERWORKING
FAKEFILE= fakethumbfile.o
endif
endif
# Handle make API options that affect compiler arguments
ifneq ($(OPT_NONSTANDARD_FLAGS),yes)
SRCFLAGS += -fomit-frame-pointer -Wall -Wextra -Wstrict-prototypes -fverbose-asm
endif
ifeq ($(OPT_LINK_OPTIMIZE),yes)
SRCFLAGS += -ffunction-sections -fdata-sections -fno-common -flto
LDFLAGS += -Wl,--gc-sections
endif
ifeq ($(OPT_GENERATE_MAP),yes)
LDFLAGS += -Wl,-Map=$(MAPFILE),--cref
endif
ifeq ($(OPT_GENERATE_LISTINGS),yes)
CFLAGS += -Wa,-alms=$(@:.o=.lst)
CXXFLAGS += -Wa,-alms=$(@:.o=.lst)
ASFLAGS += -Wa,-amhls=$(@:.o=.lst)
endif
ifneq ($(LDSCRIPT),)
LDFLAGS += -T$(LDSCRIPT)
endif
# Generate dependency information
SRCFLAGS += -MMD -MP -MF $(DEPDIR)/$(@F).d
# Combine all our compiler arguments
SRCFLAGS += -I. $(patsubst %,-I%,$(INCPATH)) $(patsubst %,-D%,$(patsubst -D%,%,$(DEFS)))
LDFLAGS += $(patsubst %,-L%,$(LIBPATH)) $(patsubst %,-l%,$(patsubst -l%,%,$(LIBS)))
################# Targets ######################
.PHONY: builddirs fakefile.o fakethumbfile.o elfstats all exe lib clean Debug Release cleanDebug cleanRelease
# Many IDE's use these targets instead.
Debug Release: all
cleanDebug cleanRelease: clean
# Make a program or a library?
ifeq ($(OPT_MAKE_LIB),yes)
all: lib
else
all: exe
endif
exe: builddirs $(FAKEFILE) $(TARGETS)
lib: builddirs $(FAKEFILE) $(LIBFILE)
builddirs:
@mkdir -p $(BUILDDIR)
@mkdir -p $(OBJDIR)
@mkdir -p $(DEPDIR)
$(FAKEFILE):
ifneq ($(OPT_VERBOSE_COMPILE),yes)
ifneq ($(filter %.cpp,$(SRC) $(SRC_NOTHUMB) $(SRC_THUMB)),)
@echo .
@echo C++ Compiler Options..
@echo $(XCXX) -c $(CPPFLAGS) $(CXXFLAGS) $(SRCFLAGS) $(@:.o=.cpp) -o $(OBJDIR)/$@
else
ifneq ($(filter %.c++,$(SRC) $(SRC_NOTHUMB) $(SRC_THUMB)),)
@echo .
@echo C++ Compiler Options..
@echo $(XCXX) -c $(CPPFLAGS) $(CXXFLAGS) $(SRCFLAGS) $(@:.o=.c++) -o $(OBJDIR)/$@
endif
endif
ifneq ($(filter %.c,$(SRC) $(SRC_NOTHUMB) $(SRC_THUMB)),)
@echo .
@echo C Compiler Options....
@echo $(XCC) -c $(CPPFLAGS) $(CFLAGS) $(SRCFLAGS) $(@:.o=.c) -o $(OBJDIR)/$@
endif
ifneq ($(filter %.s,$(SRC) $(SRC_NOTHUMB) $(SRC_THUMB)),)
@echo .
@echo Assembler Options.....
@echo $(XAS) -c $(CPPFLAGS) $(CFLAGS) $(SRCFLAGS) $(@:.o=.s) -o $(OBJDIR)/$@
else
ifneq ($(filter %.S,$(SRC) $(SRC_NOTHUMB) $(SRC_THUMB)),)
@echo .
@echo Assembler Options.....
@echo $(XAS) -c $(CPPFLAGS) $(CFLAGS) $(SRCFLAGS) $(@:.o=.S) -o $(OBJDIR)/$@
endif
endif
ifneq ($(OPT_MAKE_LIB),yes)
@echo .
@echo Linker Options........
@echo $(XLD) $(LDFLAGS) $(OBJDIR)/$@ -o $(EXEFILE)
endif
@echo .
endif
fakethumbfile.o $(OBJS_THUMB): SRCFLAGS += -mthumb -DTHUMB
elfstats: $(EXEFILE)
@echo .
ifeq ($(USE_VERBOSE_COMPILE),yes)
$(XSZ) $<
else
@$(XSZ) $<
endif
# Implicit Rules
.SECONDEXPANSION:
$(OBJDIR)/%.o : $$(call obj_src,%.c)
@mkdir -p $(dir $@)
ifeq ($(OPT_VERBOSE_COMPILE),yes)
@echo .
$(XCC) -c $(CPPFLAGS) $(CFLAGS) $(SRCFLAGS) $< -o $@
else
@echo Compiling $<
@$(XCC) -c $(CPPFLAGS) $(CFLAGS) $(SRCFLAGS) $< -o $@
endif
$(OBJDIR)/%.o : $$(call obj_src,%.cpp)
@mkdir -p $(dir $@)
ifeq ($(OPT_VERBOSE_COMPILE),yes)
@echo .
$(XCXX) -c $(CPPFLAGS) $(CXXFLAGS) $(SRCFLAGS) $< -o $@
else
@echo Compiling $<
@$(XCXX) -c $(CPPFLAGS) $(CXXFLAGS) $(SRCFLAGS) $< -o $@
endif
$(OBJDIR)/%.o : $$(call obj_src,%.c++)
@mkdir -p $(dir $@)
ifeq ($(OPT_VERBOSE_COMPILE),yes)
@echo .
$(XCXX) -c $(CPPFLAGS) $(CXXFLAGS) $(SRCFLAGS) $< -o $@
else
@echo Compiling $<
@$(XCXX) -c $(CPPFLAGS) $(CXXFLAGS) $(SRCFLAGS) $< -o $@
endif
$(OBJDIR)/%.o : $$(call obj_src,%.s)
@mkdir -p $(dir $@)
ifeq ($(OPT_VERBOSE_COMPILE),yes)
@echo .
$(XAS) -c $(CPPFLAGS) $(ASFLAGS) $(SRCFLAGS) $< -o $@
else
@echo Compiling $<
@$(XAS) -c $(CPPFLAGS) $(ASFLAGS) $(SRCFLAGS) $< -o $@
endif
$(OBJDIR)/%.o : $$(call obj_src,%.S)
@mkdir -p $(dir $@)
ifeq ($(OPT_VERBOSE_COMPILE),yes)
@echo .
$(XAS) -c $(CPPFLAGS) $(ASFLAGS) $(SRCFLAGS) $< -o $@
else
@echo Compiling $<
@$(XAS) -c $(CPPFLAGS) $(ASFLAGS) $(SRCFLAGS) $< -o $@
endif
$(EXEFILE): $(OBJS_THUMB) $(OBJS_NOTHUMB) $(LDSCRIPT)
@mkdir -p $(dir $@)
ifeq ($(OPT_VERBOSE_COMPILE),yes)
@echo .
$(XLD) $(OBJS_THUMB) $(OBJS_NOTHUMB) $(LDFLAGS) -o $@
else
@echo Linking $@
@$(XLD) $(OBJS_THUMB) $(OBJS_NOTHUMB) $(LDFLAGS) -o $@
endif
ifeq ($(OPT_COPY_EXE),yes)
@cp $@ .
endif
$(LIBFILE): $(OBJS_THUMB) $(OBJS_NOTHUMB)
ifeq ($(OPT_VERBOSE_COMPILE),yes)
@echo .
$(XAR) -r $@ $^
else
@echo Creating Library $@
@$(XAR) -r $@ $^
endif
ifeq ($(OPT_COPY_EXE),yes)
@cp $@ .
endif
%.hex: %.elf
ifeq ($(OPT_VERBOSE_COMPILE),yes)
$(XOC) -O ihex $< $@
else
@echo Creating $@
@$(XOC) -O ihex $< $@
endif
ifeq ($(OPT_COPY_EXE),yes)
@cp $@ .
endif
%.bin: %.elf
ifeq ($(OPT_VERBOSE_COMPILE),yes)
$(XOC) -O binary $< $@
else
@echo Creating $@
@$(XOC) -O binary $< $@
endif
ifeq ($(OPT_COPY_EXE),yes)
@cp $@ .
endif
%.dmp: %.elf
ifeq ($(OPT_VERBOSE_COMPILE),yes)
$(XOD) -x --syms $< > $@
else
@echo Creating $@
@$(XOD) -x --syms $< > $@
endif
ifeq ($(OPT_COPY_EXE),yes)
@cp $@ .
endif
# Goodness knows why we would want this.
gcov:
-mkdir gcov
$(COV) -u $(subst /,\,$(SRC_NOTHUMB) $(SRC_THUMB))
-mv *.gcov ./gcov
# Include the dependency files, should be the last of the makefile except for clean
-include $(shell mkdir -p $(DEPDIR) 2>/dev/null) $(wildcard $(DEPDIR)/*)
# Clean
clean:
-rm -fR $(BUILDDIR)
# *** EOF ***