#! /usr/bin/make -f #--- # # fxlibc project Makefile # # This makefile is grandly inspired by the Gint unikernel # projet, many thanks to Lephenixnoir ! # # Build architecture: # build/ # |-- objects/ # | |-- string_strlen.o # | |-- string_strcmp.o # | ... # | `-- signal_kill.o # |-- debug/ # | |-- fxlibc.map (ELF link map informations) # | ... # | `-- otherinfo.txt # |-- Makefile # |-- fxlibc.cfg # `-- ouptut/ # |-- static/ # | |--- libfxlibc.a # | |--- libfxlibc-casio-abi-fx9860.a # | `--- libfxlibc-casio-abi-fxcg50.a # `--- dynamic/ # |--- libfxlibc.so # |--- libfxlibc-casio-abi-fx9860.so # `--- libfxlibc-casio-abi-fxcg50.so # # TODO: # * handle versionning #--- MAJOR := 0 MINOR := 2 PATCH := 3 EXTRAVERSION := -alpha #--- # Build configuration #--- # Require configuration file (if you want to clean up and lost the file, you # can either reconfigure or just delete the build directory) CONFIG := fxlibc.cfg ifeq "$(wildcard $(CONFIG))" "" $(error "config file $(CONFIG) does not exist (reconfigure or wipe directory)") endif include $(CONFIG) # Compiler flags, assembler flags, dependency generation, archiving header := ../include cflags := $(machine) -ffreestanding -nostdlib -Wall -Wextra -std=c11 -Os \ -fstrict-volatile-bitfields -I$(header) $(CONFIG.CFLAGS) # color definition red := \033[1;31m green := \033[1;32m blue := \033[1;34m white := \033[1;37m nocolor := \033[1;0m # This is a workaround to force a newline when the "eval" keyword is involved define n # Force newline character endef # Define all directory used to stored informations dir_object := object dir_output := output # Output configurations name := fxlibc # automated variable directory := $(shell find ../src -not -path "*/\.*" -type d) src := $(foreach path,$(directory), \ $(wildcard $(path)/*.c) \ $(wildcard $(path)/*.S) \ $(wildcard $(path)/*.s)) #--- # Toolchain #--- gcc = $(CONFIG.TOOLCHAIN)-gcc as = $(CONFIG.TOOLCHAIN)-as ld = $(CONFIG.TOOLCHAIN)-ld ar = $(CONFIG.TOOLCHAIN)-ar objcopy = $(CONFIG.TOOLCHAIN)-objcopy #--- # Build rules #--- # (Make selects the first rule when you type "make" and I don't want the first # rule to be "%/" so here's a placeholder) first: all # Create directory helper # @note: Just use "$*" and "$@" to refer to the directory being created. %/: @ printf "Create $(blue)$*$(nocolor) directory\n" @ mkdir -p $@ .PRECIOUS: %/ #--- # Automated rules #--- # common part used to compile source file # @params: # *1 - source file path # *2 - build directory path (output) # *3 - build flags # TODO: # * handle verbose option define compile-src $(patsubst .._src_%,$2%.o,$(subst /,_,$(basename $1))): $1 | $2/ @ printf "$(green)>$(nocolor) $(white)$$@$(nocolor)\n" @ $(gcc) $3 -o $$@ -c $$< -lgcc endef # common part used by all library geneation # @params: # * 1 - library name # * 2 - format (dynamic/static) # * 3 - source file list define generate-target # generate the library name based on the wanted formats lib-output-dir := $(dir_output)/$2/ lib-build-dir := $(dir_object)/$2/$1/ ifeq ($2,dynamic) lib-name := $$(lib-output-dir)lib$1.so.$$(lib-version) lib-cflags := -fPIC $(cflags) else lib-name := $$(lib-output-dir)lib$1.a lib-cflags := $(cflags) endif # indicate the new lib that will be ouputed generated-libs += $$(lib-name) # add custom flags based on the target ABI ifeq ($1,fxlibc-vhex) lib-cflags += -D __SUPPORT_VHEX_KERNEL else ifeq ($1,fxlibc-casio-abi-fx9860g) lib-cflags += -D __SUPPORT_CASIO_ABI_FX9860G else ifeq ($1,fxlibc-casio-abi-fxcf50) lib-cflags += -D __SUPPORT_CASIO_ABI_FXCG50 endif # generate all file object name $$(foreach source,$3,$$(eval \ $$(call compile-src,$$(source),$$(lib-build-dir),$$(lib-cflags)) \ )) # link the library # @note: we need to generate the library verion information manually # TODO: find a better way to generate the version symbols $$(lib-name): $$(patsubst .._src_%,$$(lib-build-dir)%.o,$$(subst /,_,$$(basename $3))) | $$(lib-output-dir) ifeq ($2,dynamic) $(gcc) -shared -Wl,-soname=$$@ -o $$@ $$^ -nostdlib -lgcc else $(ar) crs $$@ $$^ endif endef # create all "target" variable used to determine which format # and which libraries will be generated. # @note: # * we force default variable if nothing is set target-formats := $(if $(CONFIG.FORMAT),$(CONFIG.FORMAT),static) target-libs := $(if $(CONFIG.TARGET),$(CONFIG.TARGET),fxlibc) # create a variable that will be updated during the generation of # the dynamic make code generation (generated by the "foreach") generated-libs := # generate the library version lib-version := $(MAJOR).$(MINOR).$(PATCH)$(EXTRAVERSION) # Generate all targets $(foreach format,$(target-formats), \ $(foreach lib,$(target-libs),$(eval \ $(call generate-target,$(lib),$(format),$(src)) \ )) \ ) #--- # Build rule #--- all: $(generated-libs) version: @ echo "$(lib-version)" DEBUG=$(call generate-target,fxlibc-vhex,static,$(dir_objects),$(src)) export DEBUG debug: @ echo "$$DEBUG" @ echo "target-lib: $(target-libs)" @ echo "generated lib: $(generated-libs)" @ echo "target format: $(target-formats)" #--- # clean rules #--- clean: rm -rf $(dir_object) fclean: clean rm -rf $(dir_output) re: fclean all .PHONY: clean fclean re