Add support for "platform" configurations, which define a suite of compiler-rt
libraries to generate.
 - Each library may be built with different flags and for different
   architectures, and there is support for building Darwin style fat archives.

 - Uses an ambituous amount of make programming, but should be hidden to
   users and developers.

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@93720 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Makefile b/Makefile
index a5c0be3..5a6f017 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 SubDirs := lib
 
 # Set default rule before anything else.
-all::
+all: help
 
 include make/config.mk
 include make/util.mk
@@ -32,14 +32,22 @@
 	@echo "  VERBOSE=1: Use to show all commands [default=0]"
 	@echo
 	@echo "Available targets:"
-	@echo "  clean: clean all configurations"
-	@echo "  test:  run unit tests"
-	@echo "  all:   build all configurations"
+	@echo "  <platform name>: build the libraries for 'platform'"
+	@echo "  clean:           clean all configurations"
+	@echo "  test:            run unit tests"
+	@echo
+	@echo "  info-platforms:  list available platforms"
+	@echo "  help-devel:      print additional help for developers"
 	@echo
 
 help-devel: help
 	@echo "Development targets:"
+	@echo "  <platform name>-<config name>:"
+	@echo "    build the libraries for a single platform config"
+	@echo "  <platform name>-<config name>-<arch name>:"
+	@echo "    build the libraries for a single config and arch"
 	@echo "  info-functions: list available compiler-rt functions"
+	@echo "  help-hidden: print help for Makefile debugging"
 	@echo
 
 help-hidden: help-devel
@@ -59,6 +67,15 @@
 	  printf "  %-20s - available in (%s)\n" $(fn)\
 	    "$(foreach key,$(AvailableIn.$(fn)),$($(key).Dir))";)
 
+info-platforms:
+	@echo "compiler-rt Available Platforms"
+	@echo
+	@echo "Platforms:"
+	@$(foreach key,$(PlatformKeys),\
+	  printf "  %s - from '%s'\n" $($(key).Name) $($(key).Path);\
+	  printf "    %s\n" "$($(key).Description)";\
+	  printf "    Configurations: %s\n\n" "$($(key).Configs)";)
+
 # Provide default clean target which is extended by other templates.
 .PHONY: clean
 clean::
@@ -88,6 +105,128 @@
 include make/subdir.mk
 include make/lib_info.mk
 include make/lib_util.mk
+include make/lib_platforms.mk
+
+###
+# Define Platform Rules
+
+define PerPlatform_template
+$(call Set,Tmp.Key,$(1))
+$(call Set,Tmp.Name,$($(Tmp.Key).Name))
+$(call Set,Tmp.Configs,$($(Tmp.Key).Configs))
+$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name))
+
+# Top-Level Platform Target
+$(Tmp.Name):: $(Tmp.Configs:%=$(Tmp.ObjPath)/%/libcompiler_rt.a)
+.PHONY: $(Tmp.Name)
+
+clean::
+	$(Verb) rm -rf $(Tmp.ObjPath)
+
+# Per-Config Libraries
+$(foreach config,$(Tmp.Configs),\
+  $(call PerPlatformConfig_template,$(config)))
+endef
+
+define PerPlatformConfig_template
+$(call Set,Tmp.Config,$(1))
+$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config))
+
+# Compute the archs to build, depending on whether this is a universal build or
+# not.
+$(call Set,Tmp.ArchsToBuild,\
+  $(if $(call IsDefined,$(Tmp.Key).UniversalArchs),\
+       $($(Tmp.Key).UniversalArchs),\
+       $(call VarOrDefault,$(Tmp.Key).Arch.$(Tmp.Config),$($(Tmp.Key).Arch))))
+
+# Copy or lipo to create the per-config library.
+$(call Set,Tmp.Inputs,$(Tmp.ArchsToBuild:%=$(Tmp.ObjPath)/%/libcompiler_rt.a))
+$(Tmp.ObjPath)/libcompiler_rt.a: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
+	$(Summary) "  FINAL-ARCHIVE: $(Tmp.Name)/$(Tmp.Config): $$@"
+	-$(Verb) $(RM) $$@
+	$(if $(call streq,1,$(words $(Tmp.ArchsToBuild))), \
+	  $(Verb) $(CP) $(Tmp.Inputs) $$@, \
+	  $(Verb) $(LIPO) -create -output $$@ $(Tmp.Inputs))
+.PRECIOUS: $(Tmp.ObjPath)/.dir
+
+# Per-Config Targets
+$(Tmp.Name)-$(Tmp.Config):: $(Tmp.ObjPath)/libcompiler_rt.a
+.PHONY: $(Tmp.Name)-$(Tmp.Config)
+
+# Per-Config-Arch Libraries
+$(foreach arch,$(Tmp.ArchsToBuild),\
+  $(call PerPlatformConfigArch_template,$(arch)))
+endef
+
+define PerPlatformConfigArch_template
+$(call Set,Tmp.Arch,$(1))
+$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch))
+$(call Set,Tmp.Functions,$(strip \
+  $(call GetCNAVar,FUNCTIONS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
+$(call Set,Tmp.Optimized,$(strip \
+  $(call GetCNAVar,OPTIMIZED,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
+$(call Set,Tmp.AR,$(strip \
+  $(call GetCNAVar,AR,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
+$(call Set,Tmp.ARFLAGS,$(strip \
+  $(call GetCNAVar,ARFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
+$(call Set,Tmp.RANLIB,$(strip \
+  $(call GetCNAVar,RANLIB,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
+$(call Set,Tmp.RANLIBFLAGS,$(strip \
+  $(call GetCNAVar,RANLIBFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
+
+# Compute the object inputs for this library.
+$(call Set,Tmp.Inputs,\
+  $(foreach fn,$(sort $(Tmp.Functions)),\
+    $(call Set,Tmp.FnDir,\
+      $(call SelectFunctionDir,$(Tmp.Config),$(Tmp.Arch),$(fn),$(Tmp.Optimized)))\
+    $(Tmp.ObjPath)/$(Tmp.FnDir)/$(fn).o))
+$(Tmp.ObjPath)/libcompiler_rt.a: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
+	$(Summary) "  ARCHIVE:   $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$@"
+	-$(Verb) $(RM) $$@
+	$(Verb) $(Tmp.AR) $(Tmp.ARFLAGS) $$@ $(Tmp.Inputs)
+	$(Verb) $(Tmp.RANLIB) $(Tmp.RANLIBFLAGS) $$@
+.PRECIOUS: $(Tmp.ObjPath)/.dir
+
+# Per-Config-Arch Targets
+$(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch):: $(Tmp.ObjPath)/libcompiler_rt.a
+.PHONY: $(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch)
+
+# Per-Config-Arch-SubDir Objects
+$(foreach key,$(SubDirKeys),\
+  $(call PerPlatformConfigArchSubDir_template,$(key)))
+endef
+
+define PerPlatformConfigArchSubDir_template
+$(call Set,Tmp.SubDirKey,$(1))
+$(call Set,Tmp.SubDir,$($(Tmp.SubDirKey).Dir))
+$(call Set,Tmp.SrcPath,$(ProjSrcRoot)/$(Tmp.SubDir))
+$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch)/$(Tmp.SubDirKey))
+$(call Set,Tmp.Dependencies,$($(Tmp.SubDirKey).Dependencies))
+$(call Set,Tmp.CC,$(strip \
+  $(call GetCNAVar,CC,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
+$(call Set,Tmp.CFLAGS,$(strip \
+  $(call GetCNAVar,CFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
+$(call Set,Tmp.ArchFlag,$(strip \
+  $(if $(call IsDefined,$(Tmp.Key).UniversalArchs),-arch $(Tmp.Arch),)))
+
+$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.s $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
+	$(Summary) "  ASSEMBLE:  $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
+	$(Verb) $(Tmp.CC) $(Tmp.ArchFlag) $(Tmp.CFLAGS)  -c -o $$@ $$<
+$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.S $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
+	$(Summary) "  ASSEMBLE:  $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
+	$(Verb) $(Tmp.CC) $(Tmp.ArchFlag) $(Tmp.CFLAGS) -c -o $$@ $$<
+$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.c $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
+	$(Summary) "  COMPILE:   $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
+	$(Verb) $(Tmp.CC) $(Tmp.ArchFlag) $(Tmp.CFLAGS) -c -o $$@ $$<
+.PRECIOUS: $(Tmp.ObjPath)/.dir
+
+endef
+
+# Run templates.
+$(foreach key,$(PlatformKeys),\
+  $(eval $(call PerPlatform_template,$(key))))
+
+###
 
 ifneq ($(DEBUGMAKE),)
   $(info MAKE: Done processing Makefile)