X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fwebcc.git;a=blobdiff_plain;f=src%2FMakefile;h=b4c8225f63ee3947010f64490400292d4c1b21a1;hp=7b718b5b11c292483d020aca6af51e6f6d672576;hb=522656e8b68f7189d1c221e19211946ba7774ab5;hpb=2dfdc5653b9f85952119122cff72320540a342d2 diff --git a/src/Makefile b/src/Makefile index 7b718b5..b4c8225 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,14 +6,14 @@ # This makefile manages a build environment targeting native platforms with gcc # and web platforms with either emscripten or binaryen (js or wasm). ################################################################################ -# Each .c file is automatically compiled into an environment-dependent object +# Each .c file is autopresidential debate california timematically compiled into an environment-dependent object # file of compiler-specific format (.o for gcc, .bc for llvm/emcc/em++). ################################################################################ default: all # Source languages handled by this build system LANGS := c cpp go # Source-to-source languages handled by this build system -SLANGS := y +SLANGS := y rl # Language-specific compilers and flags passed in from environment c_C := $(strip $(notdir $(CC))) c_FLAGS := $(strip $(CFLAGS)) -I. @@ -25,10 +25,15 @@ cpp_LIBS := $(c_LIBS) go_C := gccgo go_FLAGS := $(c_FLAGS) # Source to source languages +# Bison y_C := bison y_FLAGS := -d y_STEM := tab y_TRG := c h +# Ragel +rl_C := ragel +rl_FLAGS := -C +rl_TRG := c # Compiler-specific associations. Each compiler has a binary object suffix # (OBJ), an archiver (AR), and an archiver object suffix (AROBJ). Each compiler # may optionally have defined a linker (LD), and a binary output suffix (OUT). @@ -81,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 \ ' @@ -94,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 ./%,%,$(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)=%.$($(slang)_STEM:%=%.)$(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 @@ -122,18 +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) $(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)) -)) +) +#/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 @@ -152,17 +174,18 @@ 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)))))\ -$(eval FLG := $($2_FLAGS) $(MOD:%=-I% ))\ +$(eval FLG := $(MOD:%=-I% ))\ $(if $(wildcard $1), $(eval DEPS := $(filter-out \ %:,$(shell $($2_C) $(FLG) -M -MG $1)))\ $(eval MDEPS := $(filter $(MODULES:%=%/%),$(DEPS)))\ @@ -172,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 @@ -181,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))) @@ -208,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))) @@ -237,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 @@ -272,25 +308,28 @@ $(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))\ +$(eval MAKE_TARGETS+= $1.$(c_AROBJ))\ + $1.$(c_AROBJ): $(ARCDEPS) $(c_AR) cr $$@ $$^ $(if $(c_DBG), $(eval undefine DBGARCDEPS) $(foreach arcdep,$(ARCDEPS),$(eval DBGARCDEPS += $(dir $(arcdep)).$(c_DBG)/$(notdir $(arcdep)))) -$(eval MAKE_TARGETS += .$(c_DBG)/$1.$(c_AROBJ))\ +$(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###################################################### @@ -514,7 +553,7 @@ all: $(basename $(DRV_FNAMES)) @echo Build Complete # Rule to make any dirs that we're in charge of -$(MAKE_DIRS): +$(sort $(MAKE_DIRS)): @mkdir -p $@ # Cleaning rules.