#!/usr/bin/make -f # --- # Project: vxKernek - Vhex project kernel # Author: yann.magnin@protonmail.com # # TODO: # <> proper clean rule # --- #--- # environment check #--- ifeq ($(VXSDK_PREFIX_BUILD),) $(error "The vxKernel sould be build using the vxSDK") endif #--- # Build rules #--- # Make selects the first rule set when you type "make" but, in our case, we are # going to generate most of the rules. So, we set a placeholder to force the # "all" rule to be the "first" rule first: all # display the library version version: @echo "$(VXSDK_PKG_VERSION)" # Display helper help: @ echo 'Rules listing:' @ echo '... all the default, if no target is provided' @ echo '... clean remove build object' @ echo '... fclean remove all generated object' @ echo '... re same as `make fclean all`' @ echo '... version display version' @ echo '... install install the library' @ echo '... uninstall uninstall the library' .PHONY: help version first #--- # Check build validity #--- CONFIG := $(VXSDK_PREFIX_BUILD)/kernel.cfg ifeq "$(wildcard $(CONFIG))" "" $(error "config file $(CONFIG) does not exist (you should use `../configure`") endif include $(CONFIG) #--- # Variables definition #--- # Many variables will be provided by the "kernel.cfg" file (generated during # the configuration part). It will defines: # <> BOARD - indicate the target board list # <> {BOARD}-SRC-MODULE-PATH - list of all sources path for a specific board # <> {BOARD}-TOOLCHAIN-PREFIX - toolchain prefix for a board (sh-elf, ...) # <> FORMAT - format for the kernel (static, dynamic) # color definition, for swagg :D red := \033[1;31m green := \033[1;32m blue := \033[1;34m white := \033[1;37m nocolor := \033[1;0m #--- # Rules definition # # The objectif is to generate a building this build tree: # # /: # |-- kernel.cfg # |-- /: # | |-- /: # | | |-- obj/: # | | | |-- main.o # ... # | | | `-- initialize.o # | | `-- map # | |-- .ld # | `-- libvxkernel-.[so/a] # `-- Makefile #--- # Function that will generate a rule for one object file # @param # *1 - GCC name (with specific prefix if needed) # *2 - CFLAGS list # *3 - source file path # *4 - build root directory path # *5 - object file compilation rule list # *6 - dependencies file compilation rule list # *7 - unique id (used to generate unique variable name (workaround)) define generate-compile-file-rule # generate the object file path # @note # <> This is alse the generated rule name # <> step: # 1) ../board/path/file.c -> ../board/path/file # 2) .._board_path_file -> board_path_file # 3) board_path_file.o -> {build path}/board_path_file.o tname := $(strip $7) obj-$(tname)-name := $$(basename $3) obj-$(tname)-name := $$(subst /,_,$$(obj-$(tname)-name)) obj-$(tname)-name := $$(patsubst %,$4/%.o,$$(obj-$(tname)-name)) # generate the building rule $$(obj-$(tname)-name): $3 @ mkdir -p $$(dir $$@) ifeq ($(CONFIG.VERBOSE),false) @ printf "$(green)>$(nocolor) $(white)$$@$(nocolor)\n" @ $1 $2 -o $$@ -c $$< -MMD -MT $$@ -MF $$@.d -MP else $1 $2 -o $$@ -c $$< -MMD -MT $$@ -MF $$@.d -MP endif # register the build rules and dependencies file name $5 += $$(obj-$(tname)-name) $6 += $$(obj-$(tname)-name).d endef # Function that will generate all rules for a specific board and format # @params # *1 - board name # *2 - format name (static or dynamic) # *3 - rules list variable name define generate-target-lib # generate common information # @note: # Because we generate rule "on-the-fly" we need to create unique variable # definition because make is not a "scoped" language. (therefore, when a # variable is created, it will never be destroyed until the end of the script) t-$1-$2-build := $(VXSDK_PREFIX_BUILD)/$1/$2 # generate compilation flags t-$1-$2-ar := $$(CONFIG.$1.TOOLCHAIN.PREFIX)ar t-$1-$2-ld := $$(CONFIG.$1.TOOLCHAIN.PREFIX)ld t-$1-$2-gcc := $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc t-$1-$2-ldflags := $$(CONFIG.$1.TOOLCHAIN.LDFLAGS) t-$1-$2-cflags := $$(CONFIG.$1.TOOLCHAIN.CFLAGS) # generate compiler information (used to find some library like libgcc.a) t-$1-$2-gcc-base := $$(shell $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc --print-search-dirs | grep install | sed 's/install: //') t-$1-$2-gcc-header := -I$$(t-$1-$2-gcc-base)/include -I$$(t-$1-$2-gcc-base)/include/openlibm t-$1-$2-cflags += -Iinclude -I. -Isrc $$(t-$1-$2-gcc-header) t-$1-$2-cflags += -Llib -L. -L$$(t-$1-$2-gcc-base) # generate file's sources list, based on the configuration step t-$1-$2-src := $$(foreach path,$$(CONFIG.$1.SRC-MODULE-PATH),\ $$(wildcard $$(path)/*.c) \ $$(wildcard $$(path)/*.S) \ $$(wildcard $$(path)/*.s)) # generate format-specific flags t-$1-$2-exec := ifeq ($2,static) t-$1-$2-exec := $(VXSDK_PREFIX_BUILD)/libvhex-$1.a endif ifeq ($2,dynamic) t-$1-$2-ldflags += -shared t-$1-$2-ldflags += -soname=libvhex-$1-$(VXSDK_PKG_VERSION).so t-$1-$2-ldflags += -Map=$$(t-$1-$2-build)/map t-$1-$2-exec := $(VXSDK_PREFIX_BUILD)/libvhex-$1.so t-$1-$2-src := $(wildcard fake/*.c) endif # generate file's compilation rules and all object filename into an object # list variable, this will be used by the `main` rule t-$1-$2-obj := t-$1-$2-dep := $$(foreach source,$$(t-$1-$2-src),$$(eval \ $$(call generate-compile-file-rule,\ $$(t-$1-$2-gcc),\ $$(t-$1-$2-cflags),\ $$(source),\ $$(t-$1-$2-build),\ t-$1-$2-obj,\ t-$1-$2-dep,\ $1-$2\ ))\ ) # asset generation t-$1-$2-asset := $(patsubst \ $(VXSDK_ASSETS_SRC)/%,\ $(VXSDK_ASSETS_BUILD)/$1/$2/%.o,\ $(wildcard $(VXSDK_ASSETS_SRC)/*.c) \ ) $(VXSDK_ASSETS_BUILD)/$1/$2/%.o: $(VXSDK_ASSETS_SRC)/% ifeq ($(CONFIG.VERBOSE),true) @ mkdir -p $$(dir $$@) $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc $$(t-$1-$2-cflags) -o $$@ -c $$< else @ mkdir -p $$(dir $$@) @ printf "$(green)>$(nocolor) $(white)$@$(nocolor)\n" @ $$(CONFIG.$1.TOOLCHAIN.PREFIX)gcc $$(t-$1-$2-cflags) -o $$@ -c $$< endif # generate the "main" rule for this lib $$(t-$1-$2-exec): $$(t-$1-$2-obj) $$(t-$1-$2-asset) @ mkdir -p $$(dir $$@) @ echo "dep : $$(t-$1-$2-dep)" @ printf "$(blue)Create the library $(red)$$@$(nocolor)\n" ifeq ($2,dynamic) $$(t-$1-$2-gcc) -shared $$(t-$1-$2-cflags) $$(t-$1-$2-gcc-libs) -o $$@ $$^ else $$(t-$1-$2-ar) crs $$@ $$^ endif # register the "main" building rule for the lib $3 += $$(t-$1-$2-exec) # import dependencies rules -include $$(t-$1-$2-dep) $$(t-$1-$2-dep): ; .PRECIOUS: $$(t-$1-$2-dep) endef # Generate the "main" rules list target-lib-list := $(foreach board,$(CONFIG.BOARD-LIST),\ $(foreach format,$(CONFIG.FORMAT-LIST),$(eval\ $(call generate-target-lib,$(board),$(format),target-lib-list)\ ))\ ) #--- # Build rules #--- all: $(target-lib-list) .PHONY: all #--- # Generate installation rules #--- # Common rules generated for the installation of each libraries. # Basically, it will generate -install and -uninstall rules # @note: # *1 - library pathname # *2 - variable name (installation rules list) # *3 - variable name (uninstallation rules list) define generate-install-rule # Generate the installation rule $(basename $(notdir $1))-install: install -d $(VXSDK_PREFIX_LIB) install $1 -m 644 $(VXSDK_PREFIX_LIB) # Generate the uninstallation rule $(basename $(notdir $1))-uninstall: rm -f $(VXSDK_PREFIX_LIB)/$(notdir $1) # Register generated rules into their appropriate list $2 += $(basename $(notdir $1))-install $3 += $(basename $(notdir $1))-uninstall endef # Common rules generated for the installation of board-specific linker script # @note: # $1 - board name # $2 - variable name (installation rules list) # $3 - variable name (uninstallation rules list) define generate-board-install-rule $1-install: install -d $(VXSDK_PREFIX_LIB) install board/$(strip $1)/*.ld -m 644 $(VXSDK_PREFIX_LIB) $1-uninstall: rm -f $(VXSDK_PREFIX_LIB)/$(strip $1).ld rm -f $(VXSDK_PREFIX_LIB)/$(strip $1)-dynamic.ld $2 += $1-install $3 += $1-uninstall endef # Generate all installation/uninstallation rules target-install-rules := target-uninstall-rules := $(foreach target,$(target-lib-list),$(eval \ $(call generate-install-rule, \ $(target), \ target-install-rules, \ target-uninstall-rules \ ) \ )) $(foreach board,$(CONFIG.BOARD-LIST),$(eval \ $(call generate-board-install-rule, \ $(board), \ target-install-rules, \ target-uninstall-rules \ ) \ )) # Generate the path where include directory will be installed. target-install-hdr-dir := $(VXSDK_PREFIX_LIB)/include/ ifeq ($(wildcard $(target-install-header-dir)vhex/.*),) target-install-hdr-dir := $(target-install-hdr-dir)vhex endif #--- # Installation rules #--- install: $(target-install-rules) mkdir -p $(dir $(target-install-hdr-dir)) cp -r include/vhex $(target-install-hdr-dir) unsintall: $(target-uninstall_rules) rm -rf $(VXSDK_PREFIX_LIB)/include/vhex .PHONY: install uninstall #--- # cleaning rules #--- #clean: TODO: generate clean rule list fclean: clean rm -rf $(target-lib-list) re: fclean all .PHONY: clean fclean re all