# binaries.
MODULES := $(filter-out $(DRIVER_DIR),$(subst /,,$(shell ls -d */)))
+# Backup the CVS password and CVSROOT environment vars in case we change them
+$(if $(wildcard ~/.cvspass),\
+$(eval CVSPASS_BAK := $(file <~/.cvspass)))
+$(if $(CVSROOT),\
+$(eval CVSROOT_BAK := $(CVSROOT)))
+
+# 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.
+define AWK_REVERSE_SQUASH =
+awk \
+'
+{ for(i=NF;i>0;i--)
+ printf (!a[$$i]++) ? $$i FS : "";
+ i=split("",a);
+ print ""
+}
+'
+endef
+
# 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
# reliable way to automatically link an internal module, but if desired an
# associated '.ld' file for the driver can contain a list of whitespace
# separated module names to ensure they link properly
-$(eval MODULE_FILES := $(filter-out .% $(DRIVER_DIR)/%,$($3_DEP)))
-$(eval MODULE_FILES := $(basename $(MODULE_FILES)))
-$(foreach mfile,$(MODULE_FILES),\
-$(eval $3_ILDO += $(firstword $(subst /, ,$(mfile)))))
+$(foreach mfile,$(filter $(MODULES:%=%/%),$($3_DRV_DEP)),\
+$(eval $3_MODULES += $(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))))
+$(eval $3_MODULES += $(basename $(strip $(file <$(1:.$2=.ld))))))
+# Remove duplicates and sort the module list
+$(eval $3_MODULES := $(sort $($3_MODULES)))
# If the compiler supports linking, distinguish static from dynamic linking
$(if $($($2_C)_LD),\
$(eval $3_STLIBS := $(filter-out $($($2_C)_LDLIBS),$($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))))
-$(eval $3_SRC += $($3_LDO))
+$(eval $3_SRC += $($3_MODULES:%=%.$($2_AROBJ)))
# Output the driver object file rule
$(eval $2_TARGETS += $($3_DRV_OBJ))
# Filter the dependencies of the object to only include deps inside our modules
# Construct the download method, or error if there isn't a valid one
$(if $(GITADDR),$(eval LIBDL := git clone $(GITADDR) $2),\
$(if $(HGADDR),$(eval LIBDL := hg clone $(HGADDR) $2),\
-$(if $(CVSADDR),$(shell echo $(CVSPASS) > ~/.cvspass)\
-$(eval LIBDL := export CVSROOT=$(CVSADDR) && cvs $($2_CVSGET)),\
+$(if $(CVSADDR),\
+$(eval LIBDL := export CVSROOT=$(CVSADDR))\
+$(eval LIBDL += && echo '$(CVSPASS)' > ~/.cvspass)\
+$(eval LIBDL += && cvs $($2_CVSGET))
+$(eval LIBDL += && $(if $(CVSPASS_BAK),echo $(CVSPASS_BAK) > ~/.cvspass,rm ~/.cvspass)),\
$(if $(WEBADDR),$(eval LIBDL := wget -O $(WEBTARG) $(WEBADDR)),\
$(eval $(error No way to download $2 needed by $3 for $1 language ))))))
# '$2' Download Rule
# during the clean rule.
$(foreach srcl,$($1_SRCL),\
$(eval $(srcl)_SOURCES := $(shell find -name "*.$(srcl)" | \
-sed -e 's@^\(.*\).$(srcl)@\1$($(srcl)_STEM:%=.%).$1@g' -e 's@\./@@'))\
+sed -e 's@^\(.*\)\.$(srcl)@\1$($(srcl)_STEM:%=.%).$1@g' -e 's@\./@@'))\
$1_SOURCES += $($(srcl)_SOURCES)
$(srcl)_TARGETS += $($(srcl)_SOURCES:%.$(srcl)=.$1)
$(foreach dup,$($(srcl)_DUP),\
# by depth, so when reading backwards and compressing repeats we are left with a
# reliable build order for library interlinking. this awk program just looks
# through a list of space separated words backwards failing to print when it
-# encounters a repeat (which is suitable as a kind of ad-hoc make lisp function)
-$1_LIBS := $(shell echo "$($1_LIBS)" | awk \
-'
-{ for(i=NF;i>0;i--)
- printf (!a[$$i]++) ? $$i FS : "";
- i=split("",a);
- print ""
-}
-'
-)
+# encounters a repeat
+$1_LIBS := $(shell echo "$($1_LIBS)" | $(call AWK_REVERSE_SQUASH))
#/LANG_INIT######################################################################
endef
-# 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.
-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
$(eval $(foreach lang,$(LANGS),\
$(eval $(call LANG_INIT,$(lang)))\
-$(eval $(lang)_LIBS := $(shell echo $($(lang)_LIBS) | $(call AWK_REVERSE_SQUASH)))))
+$(eval $(lang)_LIBS := $(shell echo $($(lang)_LIBS) | $(call AWK_REVERSE_SQUASH)))\
+))
# Create module object rules for each module
$(foreach module,$(MODULES),\