#! /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 := 5 EXTRAVERSION := -rc #--- # 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 # 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: %/ #--- # Generate building 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)" #--- # Generate installation rules #--- # Common rules generated for the installation of each libraries. # Basically, it will generate -install and -uninstall rules # @note: # *1 - library pathname define generate-install-rule # generate the rulename # @note: basically, it is the library name lib-basename := $(notdir $1) # genetate rule name lib-install-rule := $$(basename $$(lib-basename))-install lib-uninstall-rule := $$(basename $$(lib-basename))-uninstall $$(lib-install-rule): install -d $(CONFIG.PREFIX) install $1 -m 644 $(CONFIG.PREFIX) $$(lib-uninstall-rule): rm -f $(CONFIG.PREFIX)$$(lib-basename) # register generated rules into appropriate variable lib-installation-rules += $$(lib-install-rule) lib-uninstallation-rules += $$(lib-uninstall-rule) endef # internal variable used to store all rules about installation/uninstallation lib-installation-rules := lib-uninstallation-rules := # generate all installation/ unstallation rules $(foreach libs,$(generated-libs),$(eval \ $(call generate-install-rule,$(libs)) \ )) # Generate the include install directory. lib-install-header-dir := $(CONFIG.PREFIX)include/fxlibc #--- # Installation rules #--- install: $(generated-libs) $(lib-installation-rules) rm -rf $(lib-install-header-dir) cp -r ../include $(lib-install-header-dir) uninstall: $(lib-uninstallation-rules) rm -rf $(lib-install-header-dir) #--- # debug rule #--- #DEBUG=$(call generate-target,fxlibc-vhex,static,$(dir_objects),$(src)) DEBUG=$(call generate-install-rule,/output/static/fxlibc.a) export DEBUG debug: @ echo "$$DEBUG" @ echo "target-lib: $(target-libs)" @ echo "generated lib: $(generated-libs)" @ echo "target format: $(target-formats)" @ echo "install-rules: $(lib-installation-rules)" @ echo "uninstall-rules: $(lib-uninstallation-rules)" #--- # clean rules #--- clean: rm -rf $(dir_object) fclean: clean rm -rf $(dir_output) re: fclean all .PHONY: clean fclean re