define SRC_LANG_LINKRULE =
# turn the non-existent third argument into an identifier for our link data
$(eval 3 := $(notdir $(basename $1)))
-# generate the dependecies list
-$(eval $3_DEP := $(filter-out $1,$(call SRC_LANG_DEPS,$1,$2)))
+# generate the dependecies list of the driver itself
+$(eval $3_DRV_DEPS := $(filter-out $1,$(call SRC_LANG_DEPS,$1,$2)))
# Implicit and Manual LD Options to allow .ld files to specify manual linking to
# one of the built-in modules. Implicit LDOs are ones we can surmise from
# include rules generated with 'SRC_LANG_DEPS', but these are only caught if
# Find the .ld files, if present, and include their 'links' to our internal libs
$(if $(wildcard $(1:.$2=.ld)),\
$(eval $3_MLDO := $(basename $(strip $(file <$(1:.$2=.ld))))))
+# Combine the link info into a single list '$3_LDO'
$(eval $3_LDO := $(patsubst %,%.$($($2_C)_AROBJ),$(sort $($3_ILDO) $($3_MLDO))))
-# If we have any libs to generate, make sure their specific shared object file
-# is available, and that the linker is linking to our expected link directory
-# for our compiler and architecture (transpilation magic)
-$(eval $3_SRC_OBJS := $(filter-out $1 %.h,$($3_DEP) $($3_LDO)))
-# If the compiler supports linking, filter any shared objects out of the list
-# that can be linked (the -l command option should already be in $2_FLAGS)
-# otherwise, explicitly include all shared objects in the source objects, while
-# also putting them on the dep list
+# If the compiler supports linking, distinguish static from dynamic linking
$(if $($($2_C)_LD),\
-$(eval $3_SOB := $(filter-out $($2_LD_LIBS),$($2_LIBS))),\
-$(eval $3_SOB := $($2_LIBS:%=$(LIB_DIR)/lib%.so))\
-$(eval $3_SRC_OBJS += $($3_SOB)))
-$(eval $3_SOB += $(filter $(LIB_DIR)/lib%.so,$($2_FLAGS)))
+$(eval $3_STLIBS := $(filter-out $($($2_C)_LDLIBS),$($2_LIBS)))\
+$(eval $3_DLIBS := $(filter-out $($3_STLIBS),$($2_LIBS))),\
+$(eval $3_STLIBS := $(2_LIBS)))
# Directory setup
$(eval $3_DIR := $(dir $(1:%.$2=$(ROOT_DIR)/%)))
$(eval MAKE_DIRS += $($3_DIR))
-# Commandline setup. The recursive library dependecy traversal constructs a
-# tree ordered by nested dependency depth. when linking, this order is reversed
-# Establish the link tree:
-$(eval LINK_TREE := $(filter -l% %.so,$($2_FLAGS)) $($3_DEP) $($3_LDO) $1)
-$(eval LINK_TREE := $(shell echo $(filter-out %.h,$(LINK_TREE)) | awk \
-'
-BEGIN { OFS = " "; ORS = " " }
-{ for (i=NF; i>1; i--)
- printf("%s ",$$i);
- print $$1;
-}
-'))
-# The actual rule
-$($3_DIR)$3$($2_OUT): $($3_SOB) $($3_LDO) $($3_DEP) | $($3_DIR)
- $$($2_C) $$(filter-out $(LINK_TREE),$($2_FLAGS)) $(LINK_TREE) -o $$@
+# Setup the sources for this object
+$(eval $3_SRC := $($3_LDO))
+$(eval $3_SRC += $1)
+# Find the dependencies
+$(eval $3_DEP := $($3_DRV_DEPS))
+$(eval $3_DEP += $($3_SRC))
+# Preserver ordering and build out the linking order (don't use -Wstatic/dynamic)
+$(foreach lib,$($2_LIBS),\
+$(if $(findstring $(lib),$($3_STLIBS)),\
+$(eval $3_SRC := $(LIB_DIR)/lib$(lib).$($($2_C)_AROBJ) $($3_SRC)),\
+$(eval $3_SRC := -l$(lib) $($3_SRC))))
+$($3_DIR)$3$($2_OUT): $($3_DEP) | $($3_DIR)
+ $($2_C) $($2_FLAGS) $($3_SRC) -o $$@
#/SRC_LANG_LINKRULE##############################################################
endef
# Mark this lib as available for all its other compatible languages. This list
# is assumed to be sorted later, so we will ignore repeats for speed
$(foreach lang,$(LIBLANGS),\
-$(eval $(lang)_LD_LIBS += $2)\
$(if $(findstring $2,$($(lang)_LIBS)),,\
$(eval $(lang)_LIBS += $2)\
))
$(foreach libdep,$(LIBDEPS),\
$(eval $(call LANG_LIB_INIT,$1,$(libdep)))\
)
-#/LIB_INIT#######################################################################
+#/LANG_LIB_INIT##################################################################
endef
# Initialize data for supported lanaguages ######################################
$(eval $(srcl)_TARGETS += $($(srcl)_SOURCES:%.$(srcl)=.$1))\
$(foreach dup,$($(srcl)_DUP),\
$(eval $(srcl)_TARGETS += $($(srcl)_TARGETS:%.$1=%.$(dup)))\
-)
+))
$(eval $1_DRV_SRC := $(filter $(DRIVER_DIR)/%,$($1_SOURCES)))
$(eval DRV_SRC += $($1_DRV_SRC))
}
'
))
-# If our compiler has a linker, find its list of available links and start
-# adding '-lLIBNAME' options to the language flags if the linker has them, or to
-# the list of missing libraries for this language if the linker cannot find them.
-# If this compiler has no linker, mark all libs as missing
-# $($1_SOBS:$(LIB_DIR)/lib%.so=%))
-$(eval $1_LD_LIBS := $(sort $1_LD_LIBS))
-$(if $($($1_C)_LD),\
-$(eval $1_LD_LIBS := $($($1_C)_LDLIBS))\
-$(foreach lib,$($1_LIBS),\
-$(if $(findstring $(lib),$($1_LD_LIBS)),\
-$(eval $1_FLAGS += -l$(lib)),\
-$(eval $1_MISSING_LIBS += $(lib))\
-$(eval $1_FLAGS += $(LIB_DIR)/lib$(lib).a)\
-)),\
-$(eval $1_MISSING_LIBS := $(filter-out $($1_LD_LIBS),$($1_LIBS)))\
-)
#/LANG_INIT######################################################################
endef
+# The following awk program reverses the order of a list while also removing
+# duplicate entries.
+define AWK_REVERSE_SQUASH =
+awk \
+'
+BEGIN { OFS = " "; ORS = " " }
+{ for (i=NF; i>1; i--)
+ printf("%s ",$$i);
+ print $$1;
+}
+'
+endef
+# The recursive library dependecy traversal constructs a tree ordered by nested
+# dependency depth. when linking, this order is reversed.
# Initialize each language and look for its files
$(foreach lang,$(LANGS),\
-$(eval $(call LANG_INIT,$(lang))))
+$(eval $(call LANG_INIT,$(lang)))\
+$(eval $(lang)_LIBS := $(shell echo $($(lang)_LIBS) | $(call AWK_REVERSE_SQUASH))))
# Generate rules for making missing libs
$(foreach lang,$(LANGS),\
$(foreach lang,$(LANGS),$(if $($(lang)_SRCL),$(foreach srcl,$($(lang)_SRCL),\
$(eval $(call SRCLANG_TRGLANG_BUILDRULE,$(srcl),$(lang))))))
-clean:
- rm$(foreach lang,$(LANGS),$(foreach srclang,$($(lang)_SRCL), $($(srclang)_TARGETS)) $($(lang)_TARGETS))
+
+CLEANABLES := $(foreach lang,$(LANGS),$(foreach srclang,$($(lang)_SRCL), $($(srclang)_TARGETS)) $($(lang)_TARGETS))
+clean:
+ rm -f $(CLEANABLES)
scrub: clean
rm -Rf $(MAKE_DIRS)