From e0f8be10d303d7e22ec4417b9e0d20b440f7b222 Mon Sep 17 00:00:00 2001 From: ken Date: Thu, 22 Sep 2016 19:34:33 -0700 Subject: [PATCH] fixed a bunch of crap about linking order in the final product of the driver --- src/Makefile | 87 +++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/src/Makefile b/src/Makefile index 1c6dad7..93f90e8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -109,8 +109,8 @@ endef 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 @@ -126,38 +126,29 @@ $(eval $3_ILDO += $(firstword $(subst /, ,$(mfile))))) # 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 @@ -277,7 +268,6 @@ $(error $2.mk must specifically set LIBLANGS := $1 if it is compatible with $1)) # 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)\ )) @@ -286,7 +276,7 @@ $(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 ###################################### @@ -308,7 +298,7 @@ $(eval $1_SOURCES += $($(srcl)_SOURCES))\ $(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)) @@ -355,28 +345,27 @@ $(eval $1_LIBS := $(shell echo "$($1_LIBS)" | awk \ } ' )) -# 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),\ -- 2.18.0