X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fwebcc.git;a=blobdiff_plain;f=src%2FMakefile;h=b4c8225f63ee3947010f64490400292d4c1b21a1;hp=b5e6754759adf9445ea3439bcc130b92d5409d8a;hb=522656e8b68f7189d1c221e19211946ba7774ab5;hpb=1f3b22e0c25b3b753143a7efa1b0d494b2a75200 diff --git a/src/Makefile b/src/Makefile index b5e6754..b4c8225 100644 --- a/src/Makefile +++ b/src/Makefile @@ -86,10 +86,11 @@ c_OBJ := $($(c_C)_OBJ) # binaries. MODULES := $(filter-out $(DRIVER_DIR),$(subst /,,$(shell ls -d */))) +#AWK_REVERSE_SQUASH############################################################## # The following awk program reverses the order of a list while also removing # duplicate entries. The effect of this when run on the dependency tree is that # it will remove duplicates occurring in reverse order, allowing the most deeply -# nested libraries to be built, and linked, first. +# nested libraries to be built, and linked, first. ############################## define AWK_REVERSE_SQUASH = awk \ ' @@ -99,19 +100,29 @@ awk \ print "" } ' +#/AWK_REVERSE_SQUASH############################################################# endef -# Compile any source-to-source languages before executing the majority of make +#PREMAKE_SOURCE_COMPILER######################################################### +# Compile any source-to-source languages before executing the majority of make ## +################################################################################# define PREMAKE_SOURCE_COMPILER = # Find the sources for each source-to-source language $(foreach slang,$(SLANGS), -$(eval SLANG_SRC := $(patsubst ./%,%,$(filter-out .%,$(shell find -name "*.$(slang)")))) +$(eval SLANG_SRC := $(patsubst ./%, %,$(shell find -name "*.$(slang)" -not -name ".*"))) # Foreach target type in the source-to-source language, add this source's # targets to the list of the current source-to-source language targets +$(eval undefine SLANG_TRG) $(foreach trg,$($(slang)_TRG), $(eval SLANG_TRG += $(SLANG_SRC:%.$(slang)=%.$(if $($(slang)_STEM),$($(slang)_STEM).)$(trg)))) # Stat the source file's last-modified time to the var SRC_TIME $(foreach src,$(SLANG_SRC), +# Establish a command to run for compiling this file +$(eval SHELL_CMD := cd $(dir $(src)) && $($(slang)_C) $($(slang)_FLAGS) $(notdir $(src))) +# Evaluate missing targets +$(eval FOUND_TRG := $(shell find $(dir $(src)) -name "$(basename $(notdir $(src))).*" -not -name ".*")) +$(eval MISSING_TRG := $(filter-out $(FOUND_TRG), $(SLANG_TRG))) +# Check timings of existing files $(eval SRC_TIME := $(shell stat -c %Y $(src))) # For each of the targets created by this source language, evaluate the # last-modified times of each potential target. If the file does not exist, set @@ -127,19 +138,24 @@ $(eval NEWEST_TRG_TIME := $(word 1,$(subst ==, ,$(TRG_TIMES)))) # Find the older of the two times (between SRC_TIME and NEWEST_TRG_TIME) $(eval OLDER_TIME := $(firstword $(sort $(NEWEST_TRG_TIME) $(SRC_TIME)))) # If the older of the two times is the newest target time found, then we need to -# rebuild, but only if our build rule intends to actually make something +# rebuild, but only if our build rule intends to actually make something. If it +# does not intend to make something, drop a functional rule to actually make the +# target $(if $(MAKECMDGOALS), $(eval BUILDGOALS := $(filter-out clean scrub purge uninstall,$(MAKECMDGOALS))), $(eval BUILDGOALS := all)) -$(if $(and $(BUILDGOALS),$(filter $(OLDER_TIME),$(NEWEST_TRG_TIME))), -$(eval SHELL_CMD := cd $(dir $(src)) && $($(slang)_C) $($(slang)_FLAGS) $(notdir $(src))) -$(info SHELL_CMD := cd $(dir $(src)) && $($(slang)_C) $($(slang)_FLAGS) $(notdir $(src))) -$(info $(SHELL_CMD) $(shell $(SHELL_CMD))) -) +$(if $(and $(BUILDGOALS),$(or $(MISSING_TRG), $(filter $(OLDER_TIME),$(NEWEST_TRG_TIME)))), +$(if $(findstring n,$(MAKEFLAGS)), +$(SLANG_TRG): + $(SHELL_CMD) +, +$(info $(SHELL_CMD) $(eval $(shell $(SHELL_CMD))))) +)) # Put these targets on the MAKE_TARGETS list to be removed during "clean", # regardless of whether or not they were built just now. -$(eval MAKE_TARGETS+= $(SLANG_TRG)) -)) +$(eval MAKE_TARGETS += $(SLANG_TRG)) +) +#/PREMAKE_SOURCE_COMPILER######################################################## endef # Compile a source language to a language that compiles to binary, but only if # our build rule intends to build some kind of target @@ -158,13 +174,14 @@ define SRC_LANG_FLAGS_OPT_DEPS = $(filter-out \ %:,$(shell $($2_C) $3 $4 -MG $1 2> /dev/null)) endef +#SRC_LANG_RULE################################################################### # Given a source and a language, generate a rule to make the object. The second # invocation of gcc per file lists only its local includes, and filters out # anything already caught. Anything remaining should be considered to be # available in the current working directory of the source file(i.e. if you # '#include "something.h"' in 'mymodule/horseradish.c', you would expect to # include 'mymodule/something.h'. this check lets that happen), otherwise it is -# some kind of user error +# some kind of user error ####################################################### define SRC_LANG_RULE = $(if $($1),,$(eval $1 := t)\ $(eval MOD := $(filter $(MODULES),$(firstword $(subst /, ,$(dir $1)))))\ @@ -178,8 +195,16 @@ $(eval MDEPS := $(shell echo $(MDEPS) | sed -e 's@[a-zA-Z0-9\-\+/]*\.\./include@ $(eval ALLDEPS := $(MDEPS) $(DEPS)),\ $(error Cannot generate deps for: $1, file not found))\ $(eval SRC_OBJ := $(basename $1).$($2_OBJ))\ -$(eval MAKE_TARGETS+= $(SRC_OBJ))\ - +$(eval MAKE_TARGETS += $(SRC_OBJ)) +# Assume that lost dependencies are in the folder with the source +$(foreach lost,$(LOST), +$(eval ALLDEPS := $(subst $(lost), $(dir $1)$(lost),$(ALLDEPS)))) + +# Find any deps that aren't built yet, which the compiler has flagged +# as missing, but which we know the expected location of libs for +# this language should have their includes in 'LIBINC_DIR' +$(eval BUILDDEPS := $(filter $($2_LIBS:%=%/%),$(ALLDEPS))) +$(eval ALLDEPS := $(filter-out $(BUILDDEPS),$(ALLDEPS)) $(BUILDDEPS:%=$(LIBINC_DIR)/%)) # Object for $1 $(SRC_OBJ): $(ALLDEPS) $($2_C) $$($2_FLAGS) $(FLG) -c -o $$@ $1 @@ -187,12 +212,15 @@ $(if $($2_DBG),\ $(eval DBG_OBJ := $(dir $1).$($2_DBG)/$(basename $(notdir $1)).$($2_OBJ))\ $(if $(findstring $(dir $(DBG_OBJ)),$(MAKE_DIRS)),,\ $(eval MAKE_DIRS += $(dir $(DBG_OBJ)))) +$(eval MAKE_TARGETS += $(DBG_OBJ)) # Object for $1 with $($2_DBG) symbols $(DBG_OBJ): $(ALLDEPS) | $(dir $(DBG_OBJ)) $($2_C) $$($2_FLAGS) $(FLG) -Og -g$($2_DBG) -c -o $$@ $1 )) +#/SRC_LANG_RULE################################################################## endef +#SRC_LANG_DRVRULE################################################################ # establish a build and link rule given a source driver and language ############ define SRC_LANG_DRVRULE = $(eval DRIVER_NAME := $(basename $(notdir $1))) @@ -214,7 +242,9 @@ $(eval DRIVER_MODULES := $(filter-out $(DRIVER_DIR) ..,$(sort $(DRIVER_MODULES)) # any internal modules, the developer may instead create a file with the same # basename as the driver, but with the '.ld' suffix, which contains a space # separated list of internal modules to link together during compilation -$(eval DRIVER_MODULES += $(file <$(1:%.$2=%.ld))) +$(eval DRIVER_LDVALS := $(file <$(1:%.$2=%.ld))) +$(eval DRIVER_LFLAGS := $(filter -l%,$(DRIVER_LDVALS))) +$(eval DRIVER_MODULES += $(filter-out -l%,$(DRIVER_LDVALS))) # List of module archives to link together during compilation $(eval DRIVER_ARCHIVES := $(DRIVER_MODULES:%=%.$($2_AROBJ))) @@ -243,8 +273,8 @@ $(if $($2_DBG),$(eval MAKE_DIRS += $(DRIVER_TARG_DIR).$($2_DBG))) # '_start'). This driver object is then simply linked to its libraries and # module archives to create an executable binary in the output folder. # ORDER MATTERS HERE, this is for the linker: -$(eval DRIVER_SRC := $(DRIVER_DEPS)) -$(eval DRIVER_DBGSRC := $(DRIVER_DBGDEPS)) +$(eval DRIVER_SRC := $(DRIVER_LFLAGS) $(DRIVER_DEPS)) +$(eval DRIVER_DBGSRC := $(DRIVER_LFLAGS) $(DRIVER_DBGDEPS)) # Iterate through the list of libraries in our language and stack commands from # left to right in the "sources" section of the LD command (or LD section of the # commandline for the compiler), to preserve ordering and also ensure that it is @@ -278,12 +308,13 @@ $(DRIVER_NAME)-run: $(DRIVER_TARG) $(DRIVER_TARG) $(DRIVER_NAME)-d: $(DRIVER_DBGTARG) -#/SRC_LANG_DRVRULE############################################################## +#/SRC_LANG_DRVRULE############################################################### endef +#MODULE_ARCRULE################################################################## # generate rule for turning an entire module's collection of binary objects into # a single locally-linked (no external -L libs) object (for simplified linking -# modules as static libs). +# modules as static libs).####################################################### define MODULE_ARCRULE = $(eval ARCDEPS := $(filter $1/%.$(c_OBJ),$(foreach lang,$(LANGS),$($(lang)_MOD_TRG))))\ $(eval MAKE_TARGETS+= $1.$(c_AROBJ))\ @@ -298,6 +329,7 @@ $(eval MAKE_TARGETS+= .$(c_DBG)/$1.$(c_AROBJ))\ .$(c_DBG)/$1.$(c_AROBJ): $(DBGARCDEPS) | .$(c_DBG)/ $(c_AR) cr $$@ $$^ ) +#/MODULE_ARCRULE################################################################# endef # LANG_LIB_PARENT_BUILDRULE######################################################