#! /usr/bin/make -f # # gint project Makefile # #--- # # Build configuration # # Some rules don't care if config files are missing (eg. clean, etc) cfg := config/Makefile.cfg -include $(cfg) # Those that do may use this special dependency cfgdep := $(if $(shell [ -f $(cfg) ] || echo n),CFGDEP,$(cfg)) cf-fx := -m3 -mb -ffreestanding -nostdlib -Wall -Wextra -std=c11 -Os \ -I include $(cfg_macros) cf-cg := -m4 -mb -ffreestanding -nostdlib -Wall -Wextra -std=c11 -Os \ -I include $(cfg_macros) # On fx9860g, use the sh3eb-elf toolchain; on fxcg50, prefer sh4eb-elf toolchain := $(if $(filter $(cfg_target),fx),sh3eb-elf,sh4eb-elf) # Compiler flags, assembler flags, dependency generation, archiving cflags := $(cf-$(cfg_target)) sflags := $(cfg_macros) dflags = -MMD -MT $@ -MF $(@:.o=.d) -MP arflags := # # File listings # # Target file (cfg_target is either "fx" or "cg") target := bin/libgint-$(cfg_target).a # Automatic names for object and dependency files src2obj = build/$(1:src/%=%).o src2dep = build/$(1:src/%=%).d # Source files src := $(shell find src -name '*.[csS]') src_obj := $(foreach s,$(src),$(call src2obj,$s)) # Files with special handling # spe := build/version.o src/display/font.bmp spe := spe_obj := build/version.o $(foreach s,$(spe),$(call src2obj,$s)) # All object files obj := $(src_obj) $(spe_obj) # Version file version := config/version # # Toolchain # gcc = $(toolchain)-gcc as = $(toolchain)-as ld = $(toolchain)-ld ar = $(toolchain)-ar objcopy = $(toolchain)-objcopy conv = fxconv # # Version management # # Retrieve version information v_file = $(shell cat $(version) | sed 's/[-.]/ /g') v_type = $(word 1,$(v_file)) v_major = $(word 2,$(v_file)) v_minor = $(word 3,$(v_file)) v_build = $(word 4,$(v_file)) # Create the current version symbol and the new version integer v_newbuild = $(shell echo $$(($(v_build) + 1))) v_letter = $(shell echo -n $(v_type) | sed -r 's/^(.).*/\1/') v_symbol = $(shell printf '0x%02x%01x%01x%04x' "'$(v_letter)'" \ $(v_major) $(v_minor) $(v_build)) # # Build rules # all: $(target) $(target): $(obj) $(version) | $(dir $(target)) $(call cmd_l,ar,$@) $(ar) -crs $(arflags) $@ $(obj) # Assembler sources build/%.s.o: src/%.s build/%.s.d @ mkdir -p $(dir $@) $(call cmd_b,as,$<) $(gcc) -c $< -o $@ $(sflags) build/%.S.o: src/%.S build/%.S.d @ mkdir -p $(dir $@) $(call cmd_b,as,$<) $(gcc) -c $< -o $@ $(sflags) # C sources build/%.c.o: src/%.c build/%.c.d $(cfgdep) @ mkdir -p $(dir $@) $(call cmd_b,gcc,$<) $(gcc) -c $< -o $@ $(dflags) $(cflags) # Special files $(call src2obj,src/display/font.bmp): src/display/font.bmp @ mkdir -p $(dir $@) $(call cmd_m,fxconv,$<) $(conv) -font $< -n gint_font -o $@ # Version symbol. ld generates a .stack section for unknown reasons; I fall # back to removing it afterwards. build/version.o: @ mkdir -p $(dir $@) @ echo "_GINT_VERSION = $(v_symbol);" > $@.txt $(call cmd_b,ld,$@) $(ld) -r -R $@.txt -o $@ # # Cleaning # clean: @ rm -rf build/ distclean: clean @ rm -rf bin/ @ rm -f $(config) # # Utilities # $(version): $(src) $(wildcard include/**/*) @ echo '$(v_type)-$(v_major).$(v_minor)-$(v_newbuild)' > $@ # Evaluated when a rule requires the configuration file but it doesn't exist CFGDEP: @ echo "Configuration file $(cfg) is missing. Have you configured?" @ echo "See \`./configure --help\` for details." @ false # Make directories: make conveniently leaves a '/' at the end of $(dir ...) %/: @ mkdir -p $@ # Don't try to unlink directories once they're built (that wouldn't work =p) .PRECIOUS: %/ # Dependency information -include $(shell [ -d build ] && find build -name *.d) build/%.d: ; .PRECIOUS: build/%.d # Do not output full commands by default VERBOSE ?= # Simple command output method # $1 Program name # $2 Argument string to display # $3 Command color define cmd @ echo -e "\e[""$3"";1m>\e[0;1m $1\e[0m $2" $(if $(VERBOSE),,@) endef # Some pre-colored command kinds: misc, build, link, clean, install cmd_m = $(call cmd,$1,$2,30) cmd_b = $(call cmd,$1,$2,32) cmd_l = $(call cmd,$1,$2,36) cmd_c = $(call cmd,$1,$2,31) cmd_i = $(call cmd,$1,$2,33)