aboutsummaryrefslogtreecommitdiff
path: root/make
diff options
context:
space:
mode:
Diffstat (limited to 'make')
-rw-r--r--make/AppleBI.mk84
-rw-r--r--make/config.mk36
-rwxr-xr-xmake/filter-inputs25
-rw-r--r--make/lib_info.mk51
-rw-r--r--make/lib_platforms.mk82
-rw-r--r--make/lib_util.mk65
-rw-r--r--make/options.mk33
-rw-r--r--make/platform/clang_darwin.mk253
-rw-r--r--make/platform/darwin_bni.mk95
-rw-r--r--make/platform/darwin_fat.mk56
-rw-r--r--make/platform/multi_arch.mk16
-rw-r--r--make/subdir.mk90
-rw-r--r--make/test/test-util.mk66
-rw-r--r--make/util.mk114
14 files changed, 1066 insertions, 0 deletions
diff --git a/make/AppleBI.mk b/make/AppleBI.mk
new file mode 100644
index 000000000000..8cbce5fbaf56
--- /dev/null
+++ b/make/AppleBI.mk
@@ -0,0 +1,84 @@
+
+#
+# Make rules to build compiler_rt in Apple B&I infrastructure
+#
+
+# set ProjSrcRoot appropriately
+ProjSrcRoot := $(SRCROOT)
+# set ProjObjRoot appropriately
+ifdef OBJROOT
+ ProjObjRoot := $(OBJROOT)
+else
+ ProjObjRoot := $(ProjSrcRoot)
+endif
+
+ifeq (,$(SDKROOT))
+ INSTALL_TARGET = install-MacOSX
+else
+ INSTALL_TARGET = install-iOS
+endif
+
+
+# Log full compile lines in B&I logs and omit summary lines.
+Verb :=
+Summary := @true
+
+# List of functions needed for each architecture.
+
+# Copies any public headers to DSTROOT.
+installhdrs:
+
+
+# Copies source code to SRCROOT.
+installsrc:
+ cp -r . $(SRCROOT)
+
+
+install: $(INSTALL_TARGET)
+
+# Copy results to DSTROOT.
+install-MacOSX : $(SYMROOT)/libcompiler_rt.dylib
+ mkdir -p $(DSTROOT)/usr/lib/system
+ strip -S $(SYMROOT)/libcompiler_rt.dylib \
+ -o $(DSTROOT)/usr/lib/system/libcompiler_rt.dylib
+ cd $(DSTROOT)/usr/lib/system; \
+ ln -s libcompiler_rt.dylib libcompiler_rt_profile.dylib; \
+ ln -s libcompiler_rt.dylib libcompiler_rt_debug.dylib
+
+# Rule to make each dylib slice
+$(OBJROOT)/libcompiler_rt-%.dylib : $(OBJROOT)/darwin_bni/Release/%/libcompiler_rt.a
+ echo "const char vers[] = \"@(#) $(RC_ProjectName)-$(RC_ProjectSourceVersion)\"; " > $(OBJROOT)/version.c
+ cc $(OBJROOT)/version.c -arch $* -dynamiclib \
+ -install_name /usr/lib/system/libcompiler_rt.dylib \
+ -compatibility_version 1 -current_version $(RC_ProjectSourceVersion) \
+ -nodefaultlibs -lSystem -umbrella System -dead_strip \
+ -Wl,-force_load,$^ -o $@
+
+# Rule to make fat dylib
+$(SYMROOT)/libcompiler_rt.dylib: $(foreach arch,$(RC_ARCHS), \
+ $(OBJROOT)/libcompiler_rt-$(arch).dylib)
+ lipo -create $^ -o $@
+
+
+
+
+# Copy results to DSTROOT.
+install-iOS: $(SYMROOT)/libcompiler_rt.a $(SYMROOT)/libcompiler_rt-static.a
+ mkdir -p $(DSTROOT)/usr/local/lib/libgcc
+ cp $(SYMROOT)/libcompiler_rt.a \
+ $(DSTROOT)/usr/local/lib/libgcc/libcompiler_rt.a
+ mkdir -p $(DSTROOT)/usr/local/
+ cp $(SYMROOT)/libcompiler_rt-static.a \
+ $(DSTROOT)/usr/local/lib/libcompiler_rt-static.a
+
+
+# Rule to make fat archive
+$(SYMROOT)/libcompiler_rt.a : $(foreach arch,$(RC_ARCHS), \
+ $(OBJROOT)/darwin_bni/Release/$(arch)/libcompiler_rt.a)
+ lipo -create $^ -o $@
+
+# Rule to make fat archive
+$(SYMROOT)/libcompiler_rt-static.a : $(foreach arch,$(RC_ARCHS), \
+ $(OBJROOT)/darwin_bni/Static/$(arch)/libcompiler_rt.a)
+ lipo -create $^ -o $@
+
diff --git a/make/config.mk b/make/config.mk
new file mode 100644
index 000000000000..d96b1b4354ec
--- /dev/null
+++ b/make/config.mk
@@ -0,0 +1,36 @@
+###
+# Configuration variables.
+
+OS := $(shell uname)
+
+# Assume make is always run from top-level of source directory. Note than an
+# Apple style build overrides these variables later in the makefile.
+ProjSrcRoot := $(shell pwd)
+ProjObjRoot := $(ProjSrcRoot)
+
+###
+# Tool configuration variables.
+
+# FIXME: LLVM uses autoconf/mkinstalldirs ?
+MKDIR := mkdir -p
+DATE := date
+LIPO := lipo
+CP := cp
+
+VERBOSE := 0
+DEBUGMAKE :=
+
+###
+# Automatic and derived variables.
+
+# Adjust settings for verbose mode
+ifneq ($(VERBOSE),1)
+ Verb := @
+else
+ Verb :=
+endif
+
+Echo := @echo
+ifndef Summary
+ Summary = $(Echo)
+endif
diff --git a/make/filter-inputs b/make/filter-inputs
new file mode 100755
index 000000000000..8a6bbe2abdc9
--- /dev/null
+++ b/make/filter-inputs
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+
+#===- make/filter-inputs ---------------------------------------------------===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+# Given a list of files, return a new list of files taking only the
+# first file for any particular filename.
+def main():
+ import os,sys
+
+ seen = set()
+ for file in sys.argv[1:]:
+ base = os.path.basename(file)
+ if base not in seen:
+ seen.add(base)
+ print file
+
+if __name__ == '__main__':
+ main()
diff --git a/make/lib_info.mk b/make/lib_info.mk
new file mode 100644
index 000000000000..72bc4a17f152
--- /dev/null
+++ b/make/lib_info.mk
@@ -0,0 +1,51 @@
+# compiler-rt Library Info
+#
+# This should be included once the subdirectory information has been loaded, and
+# uses the utilities in 'util.mk'.
+#
+# This defines the following variables describing compiler-rt:
+# AvailableFunctions - The entire list of function names (unmangled) the
+# library can provide.
+# CommonFunctions - The list of generic functions available.
+# ArchFunctions.<arch> - The list of functions commonly available for
+# 'arch'. This does not include any config specific
+# functions.
+#
+# AvailableIn.<function> - The list of subdir keys where 'function' is
+# defined.
+
+AvailableArchs := $(sort $(foreach key,$(SubDirKeys),\
+ $($(key).OnlyArchs)))
+
+AvailableFunctions := $(sort $(foreach key,$(SubDirKeys),\
+ $(basename $($(key).ObjNames))))
+
+CommonFunctions := $(sort\
+ $(foreach key,$(SubDirKeys),\
+ $(if $(call strneq,,$(strip $($(key).OnlyArchs) $($(key).OnlyConfigs))),,\
+ $(basename $($(key).ObjNames)))))
+
+# Compute common arch functions.
+$(foreach key,$(SubDirKeys),\
+ $(if $(call strneq,,$($(key).OnlyConfigs)),,\
+ $(foreach arch,$($(key).OnlyArchs),\
+ $(call Append,ArchFunctions.$(arch),$(sort \
+ $(basename $($(key).ObjNames)))))))
+
+# Compute arch only functions.
+$(foreach arch,$(AvailableArchs),\
+ $(call Set,ArchFunctions.$(arch),$(sort $(ArchFunctions.$(arch))))\
+ $(call Set,ArchOnlyFunctions.$(arch),\
+ $(call set_difference,$(ArchFunctions.$(arch)),$(CommonFunctions))))
+
+# Compute lists of where each function is available.
+$(foreach key,$(SubDirKeys),\
+ $(foreach fn,$(basename $($(key).ObjNames)),\
+ $(call Append,AvailableIn.$(fn),$(key))))
+
+# The names of all the available options.
+AvailableOptions := AR ARFLAGS \
+ CC CFLAGS FUNCTIONS OPTIMIZED \
+ RANLIB RANLIBFLAGS \
+ VISIBILITY_HIDDEN \
+ KERNEL_USE
diff --git a/make/lib_platforms.mk b/make/lib_platforms.mk
new file mode 100644
index 000000000000..9cf9704fd174
--- /dev/null
+++ b/make/lib_platforms.mk
@@ -0,0 +1,82 @@
+# compiler-rt Configuration Support
+#
+# This should be included following 'lib_util.mk'.
+
+# The simple variables configurations can define.
+PlainConfigVariables := Configs Description
+PerConfigVariables := UniversalArchs Arch $(AvailableOptions)
+RequiredConfigVariables := Configs Description
+
+###
+# Load Platforms
+
+# Template: subdir_traverse_template subdir
+define load_platform_template
+$(call Set,PlatformName,$(basename $(notdir $(1))))
+ifneq ($(DEBUGMAKE),)
+ $$(info MAKE: $(PlatformName): Loading platform)
+endif
+
+# Construct the variable key for this directory.
+$(call Set,PlatformKey,Platform.$(PlatformName))
+$(call Append,PlatformKeys,$(PlatformKey))
+$(call Set,$(PlatformKey).Name,$(PlatformName))
+$(call Set,$(PlatformKey).Path,$(1))
+
+# Reset platform specific variables to sentinel value.
+$$(foreach var,$(PlainConfigVariables) $(PerConfigVariables),\
+ $$(call Set,$$(var),UNDEFINED))
+$$(foreach var,$(PerConfigVariables),\
+ $$(foreach config,$$(Configs),\
+ $$(call Set,$$(var).$$(config),UNDEFINED)))
+$$(foreach var,$(PerConfigVariables),\
+ $$(foreach arch,$(AvailableArchs),\
+ $$(call Set,$$(var).$$(arch),UNDEFINED)))
+
+# Get the platform variables.
+include make/options.mk
+include $(1)
+
+# Check for undefined required variables.
+$$(foreach var,$(RequiredConfigVariables),\
+ $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \
+ $$(error $(Dir): variable '$$(var)' was not undefined)))
+
+# Check that exactly one of UniversalArchs or Arch was defined.
+$$(if $$(and $$(call strneq,UNDEFINED,$$(UniversalArchs)),\
+ $$(call strneq,UNDEFINED,$$(Arch))),\
+ $$(error '$(1)': cannot define both 'UniversalArchs' and 'Arch'))
+$$(if $$(or $$(call strneq,UNDEFINED,$$(UniversalArchs)),\
+ $$(call strneq,UNDEFINED,$$(Arch))),,\
+ $$(error '$(1)': must define one of 'UniversalArchs' and 'Arch'))
+
+# Collect all the platform variables for subsequent use.
+$$(foreach var,$(PlainConfigVariables) $(PerConfigVariables),\
+ $$(if $$(call strneq,UNDEFINED,$$($$(var))),\
+ $$(call CopyVariable,$$(var),$(PlatformKey).$$(var))))
+$$(foreach var,$(PerConfigVariables),\
+ $$(foreach config,$$(Configs),\
+ $$(if $$(call strneq,UNDEFINED,$$($$(var).$$(config))),\
+ $$(call CopyVariable,$$(var).$$(config),$(PlatformKey).$$(var).$$(config))))\
+ $$(foreach arch,$(AvailableArchs),\
+ $$(if $$(call strneq,UNDEFINED,$$($$(var).$$(arch))),\
+ $$(call CopyVariable,$$(var).$$(arch),$(PlatformKey).$$(var).$$(arch))))\
+ $$(foreach config,$$(Configs),\
+ $$(foreach arch,$(AvailableArchs),\
+ $$(if $$(call strneq,UNDEFINED,$$($$(var).$$(config).$$(arch))),\
+ $$(call CopyVariable,$$(var).$$(config).$$(arch),\
+ $(PlatformKey).$$(var).$$(config).$$(arch))))))
+
+ifneq ($(DEBUGMAKE),)
+ $$(info MAKE: $(PlatformName): Done loading platform)
+endif
+endef
+
+# Evaluate this now so we do not have to worry about order of evaluation.
+PlatformFiles := $(wildcard make/platform/*.mk)
+ifneq ($(DEBUGMAKE),)
+ $(info MAKE: Loading platforms: $(PlatformFiles))
+endif
+
+$(foreach file,$(PlatformFiles),\
+ $(eval $(call load_platform_template,$(file))))
diff --git a/make/lib_util.mk b/make/lib_util.mk
new file mode 100644
index 000000000000..089a0e2eddc9
--- /dev/null
+++ b/make/lib_util.mk
@@ -0,0 +1,65 @@
+# Library Utility Functions
+#
+# This should be included following 'lib_info.mk'.
+
+# Function: GetCNAVar variable-name platform-key config arch
+#
+# Get a per-config-and-arch variable value.
+GetCNAVar = $(strip \
+ $(or $($(2).$(1).$(3).$(4)), \
+ $($(2).$(1).$(3)), \
+ $($(2).$(1).$(4)), \
+ $($(2).$(1))))
+
+# Function: SelectFunctionDir config arch function-name optimized
+#
+# Choose the appropriate implementation directory to use for 'function-name' in
+# the configuration 'config' and on given arch.
+SelectFunctionDir = $(strip \
+ $(call Set,Tmp.SelectFunctionDir,$(call SelectFunctionDirs,$(1),$(2),$(3),$(4)))\
+ $(if $(call streq,1,$(words $(Tmp.SelectFunctionDir))),\
+ $(Tmp.SelectFunctionDir),\
+ $(error SelectFunctionDir: invalid function name "$(3)" ($(strip\
+ $(if $(call streq,0,$(words $(Tmp.SelectFunctionDir))),\
+ no such function,\
+ function implemented in multiple directories!!!))))))
+
+# Helper functions that select the entire list of subdirs where a function is
+# defined with a certain specificity.
+SelectFunctionDirs_Opt_ConfigAndArch = $(strip \
+ $(foreach key,$(AvailableIn.$(3)),\
+ $(if $(and $(call streq,Optimized,$($(key).Implementation)),\
+ $(call contains,$($(key).OnlyConfigs),$(1)),\
+ $(call contains,$($(key).OnlyArchs),$(2))),$(key),)))
+SelectFunctionDirs_Opt_Config = $(strip \
+ $(foreach key,$(AvailableIn.$(3)),\
+ $(if $(and $(call streq,Optimized,$($(key).Implementation)),\
+ $(call contains,$($(key).OnlyConfigs),$(1))),$(key),)))
+SelectFunctionDirs_Opt_Arch = $(strip \
+ $(foreach key,$(AvailableIn.$(3)),\
+ $(if $(and $(call streq,Optimized,$($(key).Implementation)),\
+ $(call contains,$($(key).OnlyArchs),$(2))),$(key),)))
+SelectFunctionDirs_Gen = $(strip \
+ $(foreach key,$(AvailableIn.$(3)),\
+ $(if $(call streq,Generic,$($(key).Implementation)),$(key))))
+
+# Helper function to select the right set of dirs in generic priority order.
+SelectFunctions_Gen = \
+ $(or $(call SelectFunctionDirs_Gen,$(1),$(2),$(3)),\
+ $(call SelectFunctionDirs_Opt_ConfigAndArch,$(1),$(2),$(3)), \
+ $(call SelectFunctionDirs_Opt_Config,$(1),$(2),$(3)), \
+ $(call SelectFunctionDirs_Opt_Arch,$(1),$(2),$(3)))
+
+# Helper function to select the right set of dirs in optimized priority order.
+SelectFunctions_Opt = \
+ $(or $(call SelectFunctionDirs_Opt_ConfigAndArch,$(1),$(2),$(3)), \
+ $(call SelectFunctionDirs_Opt_Config,$(1),$(2),$(3)), \
+ $(call SelectFunctionDirs_Opt_Arch,$(1),$(2),$(3)), \
+ $(call SelectFunctionDirs_Gen,$(1),$(2),$(3)))
+
+# Helper function to select the right set of dirs (which should be exactly one)
+# for a function.
+SelectFunctionDirs = \
+ $(if $(call streq,1,$(4)),\
+ $(call SelectFunctions_Opt,$(1),$(2),$(3)),\
+ $(call SelectFunctions_Gen,$(1),$(2),$(3)))
diff --git a/make/options.mk b/make/options.mk
new file mode 100644
index 000000000000..f6a331bf0f55
--- /dev/null
+++ b/make/options.mk
@@ -0,0 +1,33 @@
+# Options which may be overriden for platforms, etc.
+#
+# This list of such variables should be kept up to date with AvailableOptions in
+# 'make/lib_info.mk'.
+
+# The compiler to use.
+CC := gcc
+
+# The compiler flags to use.
+CFLAGS := -Wall -Werror
+
+# The list of functions to include in the library.
+FUNCTIONS :=
+
+# Whether optimized function implementations should be used.
+OPTIMIZED := 1
+
+# Whether function definitions should use hidden visibility. This adds the
+# -fvisibility=hidden compiler option and uses .private_extern annotations in
+# assembly files.
+#
+# FIXME: Make this more portable. When that is done, it should probably be the
+# default.
+VISIBILITY_HIDDEN := 0
+
+# Miscellaneous tools.
+
+AR := ar
+# FIXME: Remove these pipes once ranlib errors are fixed.
+ARFLAGS := cru 2> /dev/null
+RANLIB := ranlib
+# FIXME: Remove these pipes once ranlib errors are fixed.
+RANLIBFLAGS := 2> /dev/null
diff --git a/make/platform/clang_darwin.mk b/make/platform/clang_darwin.mk
new file mode 100644
index 000000000000..23cd3a42f86a
--- /dev/null
+++ b/make/platform/clang_darwin.mk
@@ -0,0 +1,253 @@
+# These are the functions which clang needs when it is targetting a previous
+# version of the OS. The issue is that the backend may use functions which were
+# not present in the libgcc that shipped on the platform. In such cases, we link
+# with a version of the library which contains private_extern definitions of all
+# the extra functions which might be referenced.
+
+Description := Static runtime libraries for clang/Darwin.
+
+Configs :=
+UniversalArchs :=
+
+# Configuration solely for providing access to an eprintf symbol, which may
+# still be referenced from Darwin system headers. This symbol is only ever
+# needed on i386.
+Configs += eprintf
+UniversalArchs.eprintf := i386
+
+# Configuration for targetting 10.4. We need a few functions missing from
+# libgcc_s.10.4.dylib. We only build x86 slices since clang doesn't really
+# support targetting PowerPC.
+Configs += 10.4
+UniversalArchs.10.4 := i386 x86_64
+
+# Configuration for targetting armv6. We need a few additional functions which
+# must be in the same linkage unit.
+Configs += armv6
+UniversalArchs.armv6 := armv6
+
+# Configuration for use with kernel/kexts.
+Configs += cc_kext
+UniversalArchs.cc_kext := armv6 i386 x86_64
+
+# FIXME: Don't build an armv7 slice currently, they have the same functions.
+#
+#UniversalArchs.cc_kext := armv6 armv7 i386 x86_64
+
+###
+
+CC := gcc
+
+# Forcibly strip off any -arch, as that totally breaks our universal support.
+override CC := $(subst -arch ,-arch_,$(CC))
+override CC := $(patsubst -arch_%,,$(CC))
+
+CFLAGS := -Wall -Werror -O3 -fomit-frame-pointer
+
+FUNCTIONS.eprintf := eprintf
+FUNCTIONS.10.4 := eprintf floatundidf floatundisf floatundixf
+FUNCTIONS.armv6 := switch16 switch32 switch8 switchu8 \
+ save_vfp_d8_d15_regs restore_vfp_d8_d15_regs
+
+CCKEXT_COMMON_FUNCTIONS := \
+ absvdi2 \
+ absvsi2 \
+ addvdi3 \
+ addvsi3 \
+ ashldi3 \
+ ashrdi3 \
+ bswapdi2 \
+ bswapsi2 \
+ clear_cache \
+ clzdi2 \
+ clzsi2 \
+ cmpdi2 \
+ ctzdi2 \
+ ctzsi2 \
+ divdc3 \
+ divdi3 \
+ divsc3 \
+ do_global_dtors \
+ eprintf \
+ ffsdi2 \
+ fixdfdi \
+ fixsfdi \
+ fixunsdfdi \
+ fixunsdfsi \
+ fixunssfdi \
+ fixunssfsi \
+ floatdidf \
+ floatdisf \
+ floatundidf \
+ floatundisf \
+ gcc_bcmp \
+ lshrdi3 \
+ moddi3 \
+ muldc3 \
+ muldi3 \
+ mulsc3 \
+ mulvdi3 \
+ mulvsi3 \
+ negdi2 \
+ negvdi2 \
+ negvsi2 \
+ paritydi2 \
+ paritysi2 \
+ popcountdi2 \
+ popcountsi2 \
+ powidf2 \
+ powisf2 \
+ subvdi3 \
+ subvsi3 \
+ ucmpdi2 \
+ udiv_w_sdiv \
+ udivdi3 \
+ udivmoddi4 \
+ umoddi3
+
+CCKEXT_ARM_FUNCTIONS := $(CCKEXT_COMMON_FUNCTONS) \
+ adddf3 \
+ addsf3 \
+ aeabi_cdcmpeq \
+ aeabi_cdrcmple \
+ aeabi_cfcmpeq \
+ aeabi_cfrcmple \
+ aeabi_dcmpeq \
+ aeabi_dcmpge \
+ aeabi_dcmpgt \
+ aeabi_dcmple \
+ aeabi_dcmplt \
+ aeabi_drsub \
+ aeabi_fcmpeq \
+ aeabi_fcmpge \
+ aeabi_fcmpgt \
+ aeabi_fcmple \
+ aeabi_fcmplt \
+ aeabi_frsub \
+ aeabi_idivmod \
+ aeabi_uidivmod \
+ cmpdf2 \
+ cmpsf2 \
+ div0 \
+ divdf3 \
+ divsf3 \
+ divsi3 \
+ extendsfdf2 \
+ ffssi2 \
+ fixdfsi \
+ fixsfsi \
+ floatsidf \
+ floatsisf \
+ floatunsidf \
+ floatunsisf \
+ gtdf2 \
+ gtsf2 \
+ ltdf2 \
+ ltsf2 \
+ modsi3 \
+ muldf3 \
+ mulsf3 \
+ negdf2 \
+ negsf2 \
+ subdf3 \
+ subsf3 \
+ switch16 \
+ switch32 \
+ switch8 \
+ switchu8 \
+ truncdfsf2 \
+ udivsi3 \
+ umodsi3 \
+ unorddf2 \
+ unordsf2
+
+FUNCTIONS.cc_kext.armv6 := $(CCKEXT_ARM_FUNCTIONS)
+FUNCTIONS.cc_kext.armv7 := $(CCKEXT_ARM_FUNCTIONS)
+
+CCKEXT_X86_FUNCTIONS := $(CCKEXT_COMMON_FUNCTIONS) \
+ divxc3 \
+ fixunsxfdi \
+ fixunsxfsi \
+ fixxfdi \
+ floatdixf \
+ floatundixf \
+ mulxc3 \
+ powixf2
+
+FUNCTIONS.cc_kext.i386 := $(CCKEXT_X86_FUNCTIONS) \
+ ffssi2 \
+ i686.get_pc_thunk.eax \
+ i686.get_pc_thunk.ebp \
+ i686.get_pc_thunk.ebx \
+ i686.get_pc_thunk.ecx \
+ i686.get_pc_thunk.edi \
+ i686.get_pc_thunk.edx \
+ i686.get_pc_thunk.esi
+
+FUNCTIONS.cc_kext.x86_64 := $(CCKEXT_X86_FUNCTIONS) \
+ absvti2 \
+ addvti3 \
+ ashlti3 \
+ ashrti3 \
+ clzti2 \
+ cmpti2 \
+ ctzti2 \
+ divti3 \
+ ffsti2 \
+ fixdfti \
+ fixsfti \
+ fixunsdfti \
+ fixunssfti \
+ fixunsxfti \
+ fixxfti \
+ floattidf \
+ floattisf \
+ floattixf \
+ floatuntidf \
+ floatuntisf \
+ floatuntixf \
+ lshrti3 \
+ modti3 \
+ multi3 \
+ mulvti3 \
+ negti2 \
+ negvti2 \
+ parityti2 \
+ popcountti2 \
+ subvti3 \
+ ucmpti2 \
+ udivmodti4 \
+ udivti3 \
+ umodti3
+
+# FIXME: Currently, compiler-rt is missing implementations for a number of the
+# functions that need to go into libcc_kext.a. Filter them out for now.
+CCKEXT_MISSING_FUNCTIONS := \
+ adddf3 addsf3 cmpdf2 cmpsf2 div0 divdf3 divsf3 \
+ extendsfdf2 ffssi2 fixdfsi fixsfsi floatsidf floatsisf \
+ floatunsidf floatunsisf gtdf2 gtsf2 ltdf2 ltsf2 \
+ muldf3 mulsf3 negdf2 negsf2 subdf3 subsf3 \
+ truncdfsf2 udiv_w_sdiv unorddf2 unordsf2 bswapdi2 \
+ bswapsi2 \
+ gcc_bcmp \
+ do_global_dtors \
+ i686.get_pc_thunk.eax i686.get_pc_thunk.ebp i686.get_pc_thunk.ebx \
+ i686.get_pc_thunk.ecx i686.get_pc_thunk.edi i686.get_pc_thunk.edx \
+ i686.get_pc_thunk.esi \
+ aeabi_cdcmpeq aeabi_cdrcmple aeabi_cfcmpeq aeabi_cfrcmple aeabi_dcmpeq \
+ aeabi_dcmpge aeabi_dcmpgt aeabi_dcmple aeabi_dcmplt aeabi_drsub aeabi_fcmpeq \
+ aeabi_fcmpge aeabi_fcmpgt aeabi_fcmple aeabi_fcmplt aeabi_frsub aeabi_idivmod \
+ aeabi_uidivmod
+
+FUNCTIONS.cc_kext.armv6 := \
+ $(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.armv6))
+FUNCTIONS.cc_kext.armv7 := \
+ $(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.armv7))
+FUNCTIONS.cc_kext.i386 := \
+ $(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.i386))
+FUNCTIONS.cc_kext.x86_64 := \
+ $(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.x86_64))
+
+KERNEL_USE.cc_kext := 1
+
+VISIBILITY_HIDDEN := 1
diff --git a/make/platform/darwin_bni.mk b/make/platform/darwin_bni.mk
new file mode 100644
index 000000000000..ec859f3b5d6e
--- /dev/null
+++ b/make/platform/darwin_bni.mk
@@ -0,0 +1,95 @@
+
+Description := Target for Darwin using an Apple-style build.
+
+Configs := Debug Release Profile Static
+
+# We override this with RC_ARCHS because B&I may want to build on an ARCH we
+# haven't explicitly defined support for. If all goes well, this will just work
+# and the resulting lib will just have generic versions for anything unknown.
+UniversalArchs := $(RC_ARCHS)
+
+ifeq (,$(SDKROOT))
+else
+ CC.Release := /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cc
+ CC.Static := /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cc
+endif
+
+
+CFLAGS := -Wall -Os -fomit-frame-pointer -g
+CFLAGS.Static := $(CFLAGS) -static
+
+VISIBILITY_HIDDEN := 0
+VISIBILITY_HIDDEN.Static := 1
+
+
+FUNCTIONS := absvdi2 absvsi2 addvdi3 addvsi3 ashldi3 ashrdi3 \
+ clzdi2 clzsi2 cmpdi2 ctzdi2 ctzsi2 \
+ divdc3 divdi3 divsc3 ffsdi2 \
+ fixdfdi fixsfdi fixunsdfdi fixunsdfsi fixunssfdi \
+ fixunssfsi floatdidf floatdisf floatundidf floatundisf \
+ gcc_personality_v0 lshrdi3 moddi3 muldc3 muldi3 \
+ mulsc3 mulvdi3 mulvsi3 negdi2 negvdi2 negvsi2 \
+ paritydi2 paritysi2 popcountdi2 popcountsi2 powidf2 \
+ powisf2 subvdi3 subvsi3 ucmpdi2 udivdi3 \
+ udivmoddi4 umoddi3 apple_versioning eprintf
+
+FUNCTIONS.i386 := $(FUNCTIONS) \
+ divxc3 fixunsxfdi fixunsxfsi fixxfdi floatdixf \
+ floatundixf mulxc3 powixf2 clear_cache \
+ enable_execute_stack
+FUNCTIONS.ppc := $(FUNCTIONS) \
+ divtc3 fixtfdi fixunstfdi floatditf floatunditf \
+ gcc_qadd gcc_qdiv gcc_qmul gcc_qsub multc3 \
+ powitf2 restFP saveFP trampoline_setup \
+ clear_cache enable_execute_stack
+FUNCTIONS.x86_64 := $(FUNCTIONS) \
+ absvti2 addvti3 ashlti3 ashrti3 clzti2 cmpti2 \
+ ctzti2 divti3 divxc3 ffsti2 fixdfti fixsfti \
+ fixunsdfti fixunssfti fixunsxfdi fixunsxfsi \
+ fixunsxfti fixxfdi fixxfti floatdixf floattidf \
+ floattisf floattixf floatundixf floatuntidf \
+ floatuntisf floatuntixf lshrti3 modti3 multi3 \
+ mulvti3 mulxc3 negti2 negvti2 parityti2 \
+ popcountti2 powixf2 subvti3 ucmpti2 udivmodti4 \
+ udivti3 umodti3 clear_cache enable_execute_stack
+FUNCTIONS.armv5 := $(FUNCTIONS) \
+ adddf3 addsf3 bswapdi2 bswapsi2 \
+ comparedf2 comparesf2 extendsfdf2 \
+ divdf3 divsf3 \
+ fixdfsi fixsfsi fixunsdfsi fixunssfsi \
+ floatsidf floatsisf floatunsidf floatunsisf \
+ muldf3 mulsf3 \
+ negdf2 negsf2 \
+ truncdfsf2 \
+ modsi3 umodsi3 udivsi3 divsi3 \
+ switch8 switchu8 switch16 switch32 \
+ sync_synchronize
+
+FUNCTIONS.armv6 := $(FUNCTIONS) \
+ comparedf2 comparesf2 \
+ adddf3vfp addsf3vfp bswapdi2 bswapsi2 divdf3vfp \
+ divsf3vfp eqdf2vfp eqsf2vfp extendsfdf2vfp \
+ fixdfsivfp fixsfsivfp fixunsdfsivfp fixunssfsivfp \
+ floatsidfvfp floatsisfvfp floatunssidfvfp floatunssisfvfp \
+ gedf2vfp gesf2vfp gtdf2vfp gtsf2vfp \
+ ledf2vfp lesf2vfp ltdf2vfp ltsf2vfp \
+ muldf3vfp mulsf3vfp \
+ nedf2vfp nesf2vfp \
+ subdf3vfp subsf3vfp truncdfsf2vfp unorddf2vfp unordsf2vfp \
+ modsi3 umodsi3 udivsi3 divsi3 \
+ switch8 switchu8 switch16 switch32 \
+ restore_vfp_d8_d15_regs save_vfp_d8_d15_regs \
+ sync_synchronize
+FUNCTIONS.armv7 := $(FUNCTIONS) \
+ comparedf2 comparesf2 \
+ adddf3vfp addsf3vfp bswapdi2 bswapsi2 divdf3vfp \
+ divsf3vfp eqdf2vfp eqsf2vfp extendsfdf2vfp \
+ fixdfsivfp fixsfsivfp fixunsdfsivfp fixunssfsivfp \
+ floatsidfvfp floatsisfvfp floatunssidfvfp floatunssisfvfp \
+ gedf2vfp gesf2vfp gtdf2vfp gtsf2vfp \
+ ledf2vfp lesf2vfp ltdf2vfp ltsf2vfp \
+ muldf3vfp mulsf3vfp \
+ nedf2vfp nesf2vfp \
+ subdf3vfp subsf3vfp truncdfsf2vfp unorddf2vfp unordsf2vfp \
+ modsi3 umodsi3 udivsi3 divsi3
+
diff --git a/make/platform/darwin_fat.mk b/make/platform/darwin_fat.mk
new file mode 100644
index 000000000000..30e57a198e2e
--- /dev/null
+++ b/make/platform/darwin_fat.mk
@@ -0,0 +1,56 @@
+# Configurations to build
+#
+# This section must define:
+# Description - A description of this target.
+# Configs - The names of each configuration to build; this is used to build
+# multiple libraries inside a single configuration file (for
+# example, Debug and Release builds, or builds with and without
+# software floating point).
+#
+# This section must define one of:
+# UniveralArchs - A list of architectures to build for, when using universal build
+# support (e.g., on Darwin). This should only be used to build fat
+# libraries, simply building multiple libraries for different
+# architectures should do so using distinct configs, with the
+# appropriate choices for CC and CFLAGS.
+#
+# Arch - The target architecture; this must match the compiler-rt name for the
+# architecture and is used to find the appropriate function
+# implementations.
+#
+# When not universal builds, this section may define:
+# Arch.<Config Name> - Set the target architecture on a per-config basis.
+
+Description := Target for building universal libraries for Darwin.
+
+Configs := Debug Release Profile
+UniversalArchs := i386 ppc x86_64
+
+# Platform Options
+#
+# This section may override any of the variables in make/options.mk, using:
+# <Option Name> := ... option value ...
+#
+# See make/options.mk for the available options and their meanings. Options can
+# be override on a per-config, per-arch, or per-config-and-arch basis using:
+# <Option Name>.<Config Name> := ...
+# <Option Name>.<Arch Name> := ...
+# <Option Name>.<Config Name>.<Arch Name> := ...
+
+CC := gcc
+
+CFLAGS := -Wall -Werror
+CFLAGS.Debug := $(CFLAGS) -g
+CFLAGS.Release := $(CFLAGS) -O3 -fomit-frame-pointer
+CFLAGS.Profile := $(CFLAGS) -pg -g
+
+FUNCTIONS.i386 := $(CommonFunctions) $(ArchFunctions.i386)
+FUNCTIONS.ppc := $(CommonFunctions) $(ArchFunctions.ppc)
+FUNCTIONS.x86_64 := $(CommonFunctions) $(ArchFunctions.x86_64)
+FUNCTIONS.armv5 := $(CommonFunctions) $(ArchFunctions.armv5)
+FUNCTIONS.armv6 := $(CommonFunctions) $(ArchFunctions.armv6)
+FUNCTIONS.armv7 := $(CommonFunctions) $(ArchFunctions.armv7)
+
+OPTIMIZED.Debug := 0
+
+VISIBILITY_HIDDEN := 1
diff --git a/make/platform/multi_arch.mk b/make/platform/multi_arch.mk
new file mode 100644
index 000000000000..eebc7b2f80d7
--- /dev/null
+++ b/make/platform/multi_arch.mk
@@ -0,0 +1,16 @@
+Description := Example configuration for build two libraries for separate \
+architectures.
+
+Configs := m32 m64
+Arch := i386
+Arch.m64 := x86_64
+
+CC := gcc
+CC.m32 := clang
+
+CFLAGS := -Wall -Werror
+CFLAGS.m32 := $(CFLAGS) -m32 -O3
+CFLAGS.m64 := $(CFLAGS) -m64 -O3
+
+FUNCTIONS := moddi3 floatundixf udivdi3
+FUNCTIONS.m64 := $(FUNCTIONS) lshrdi3
diff --git a/make/subdir.mk b/make/subdir.mk
new file mode 100644
index 000000000000..900f7e6ab7bd
--- /dev/null
+++ b/make/subdir.mk
@@ -0,0 +1,90 @@
+# This file is intended to be included from each subdirectory makefile.
+#
+# Subdirectory makefiles must define:
+# SubDirs - The subdirectories to traverse.
+# ObjNames - The objects available in that directory.
+# Implementation - The library configuration the objects should go in (Generic or
+# Optimized)
+# Dependencies - Any dependences for the object files.
+#
+# Subdirectory makefiles may define:
+# OnlyArchs - Only build the objects for the listed archs.
+# OnlyConfigs - Only build the objects for the listed configurations.
+
+ifeq ($(Dir),)
+ $(error "No Dir variable defined.")
+endif
+
+###
+# Include child makefile fragments
+
+# The list of variables which are intended to be overridden in a subdirectory
+# makefile.
+RequiredSubdirVariables := SubDirs ObjNames Implementation Dependencies
+OptionalSubdirVariables := OnlyArchs OnlyConfigs
+
+# Template: subdir_traverse_template subdir
+define subdir_traverse_template
+$(call Set,Dir,$(1))
+ifneq ($(DEBUGMAKE),)
+ $$(info MAKE: $(Dir): Processing subdirectory)
+endif
+
+# Construct the variable key for this directory.
+$(call Set,DirKey,SubDir.$(subst .,,$(subst /,__,$(1))))
+$(call Append,SubDirKeys,$(DirKey))
+$(call Set,$(DirKey).Dir,$(Dir))
+
+# Reset subdirectory specific variables to sentinel value.
+$$(foreach var,$$(RequiredSubdirVariables) $$(OptionalSubdirVariables),\
+ $$(call Set,$$(var),UNDEFINED))
+
+# Get the subdirectory variables.
+include $(1)/Makefile.mk
+
+ifeq ($(DEBUGMAKE),2)
+$$(foreach var,$(RequiredSubdirVariables) $(OptionalSubdirVariables),\
+ $$(if $$(call strneq,UNDEFINED,$$($$(var))), \
+ $$(info MAKE: $(Dir): $$(var) is defined), \
+ $$(info MAKE: $(Dir): $$(var) is undefined)))
+endif
+
+# Check for undefined required variables, and unset sentinel value from optional
+# variables.
+$$(foreach var,$(RequiredSubdirVariables),\
+ $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \
+ $$(error $(Dir): variable '$$(var)' was not undefined)))
+$$(foreach var,$(OptionalSubdirVariables),\
+ $$(if $$(call strneq,UNDEFINED,$$($$(var))),, \
+ $$(call Set,$$(var),)))
+
+# Collect all subdirectory variables for subsequent use.
+$$(foreach var,$(RequiredSubdirVariables) $(OptionalSubdirVariables),\
+ $$(call Set,$(DirKey).$$(var),$$($$(var))))
+
+# Recurse.
+include make/subdir.mk
+
+# Restore directory variable, for cleanliness.
+$$(call Set,Dir,$(1))
+
+ifneq ($(DEBUGMAKE),)
+ $$(info MAKE: $$(Dir): Done processing subdirectory)
+endif
+endef
+
+# Evaluate this now so we do not have to worry about order of evaluation.
+
+SubDirsList := $(strip \
+ $(if $(call streq,.,$(Dir)),\
+ $(SubDirs),\
+ $(SubDirs:%=$(Dir)/%)))
+ifeq ($(SubDirsList),)
+else
+ ifneq ($(DEBUGMAKE),)
+ $(info MAKE: Descending into subdirs: $(SubDirsList))
+ endif
+
+ $(foreach subdir,$(SubDirsList),\
+ $(eval $(call subdir_traverse_template,$(subdir))))
+endif
diff --git a/make/test/test-util.mk b/make/test/test-util.mk
new file mode 100644
index 000000000000..c80c28d0342c
--- /dev/null
+++ b/make/test/test-util.mk
@@ -0,0 +1,66 @@
+include make/util.mk
+
+streq_t0 = $(call streq,,)
+$(call AssertEqual,streq_t0,true)
+streq_t1 = $(call streq,b,)
+$(call AssertEqual,streq_t1,)
+streq_t2 = $(call streq,,b)
+$(call AssertEqual,streq_t2,)
+streq_t3 = $(call streq,b,b)
+$(call AssertEqual,streq_t3,true)
+streq_t4 = $(call streq,bb,b)
+$(call AssertEqual,streq_t4,)
+streq_t5 = $(call streq,b,bb)
+$(call AssertEqual,streq_t5,)
+streq_t6 = $(call streq,bb,bb)
+$(call AssertEqual,streq_t6,true)
+
+strneq_t7 = $(call strneq,,)
+$(call AssertEqual,strneq_t7,)
+strneq_t8 = $(call strneq,b,)
+$(call AssertEqual,strneq_t8,true)
+strneq_t9 = $(call strneq,,b)
+$(call AssertEqual,strneq_t9,true)
+strneq_t10 = $(call strneq,b,b)
+$(call AssertEqual,strneq_t10,)
+strneq_t11 = $(call strneq,bb,b)
+$(call AssertEqual,strneq_t11,true)
+strneq_t12 = $(call strneq,b,bb)
+$(call AssertEqual,strneq_t12,true)
+strneq_t13 = $(call strneq,bb,bb)
+$(call AssertEqual,strneq_t13,)
+
+contains_t0 = $(call contains,a b b c,a)
+$(call AssertEqual,contains_t0,true)
+contains_t1 = $(call contains,a b b c,b)
+$(call AssertEqual,contains_t1,true)
+contains_t2 = $(call contains,a b b c,c)
+$(call AssertEqual,contains_t2,true)
+contains_t3 = $(call contains,a b b c,d)
+$(call AssertEqual,contains_t3,)
+
+isdefined_t0_defined_var := 0
+isdefined_t0 = $(call IsDefined,isdefined_t0_defined_var)
+$(call AssertEqual,isdefined_t0,true)
+isdefined_t1 = $(call IsDefined,isdefined_t1_never_defined_var)
+$(call AssertEqual,isdefined_t1,)
+
+varordefault_t0_var := 1
+varordefault_t0 = $(call VarOrDefault,varordefault_t0_var.opt,$(varordefault_t0_var))
+$(call AssertEqual,varordefault_t0,1)
+varordefault_t1_var := 1
+varordefault_t1_var.opt := 2
+varordefault_t1 = $(call VarOrDefault,varordefault_t1_var.opt,$(varordefault_t1_var))
+$(call AssertEqual,varordefault_t1,2)
+
+$(call CopyVariable,copyvariable_t0_src,copyvariable_t0_dst)
+copyvariable_t0 = $(call IsUndefined,copyvariable_t0_dst)
+$(call AssertEqual,copyvariable_t0,true)
+copyvariable_t1_src = 1
+$(call CopyVariable,copyvariable_t1_src,copyvariable_t1)
+$(call AssertEqual,copyvariable_t1,1)
+
+all:
+ @true
+.PHONY: all
+
diff --git a/make/util.mk b/make/util.mk
new file mode 100644
index 000000000000..0687755faa55
--- /dev/null
+++ b/make/util.mk
@@ -0,0 +1,114 @@
+# Generic Makefile Utilities
+
+###
+# Utility functions
+
+# Function: streq LHS RHS
+#
+# Return "true" if LHS == RHS, otherwise "".
+#
+# LHS == RHS <=> (LHS subst RHS is empty) and (RHS subst LHS is empty)
+streq = $(if $(1),$(if $(subst $(1),,$(2))$(subst $(2),,$(1)),,true),$(if $(2),,true))
+
+# Function: strneq LHS RHS
+#
+# Return "true" if LHS != RHS, otherwise "".
+strneq = $(if $(call streq,$(1),$(2)),,true)
+
+# Function: contains list item
+#
+# Return "true" if 'list' contains the value 'item'.
+contains = $(if $(strip $(foreach i,$(1),$(if $(call streq,$(2),$(i)),T,))),true,)
+
+# Function: is_subset a b
+# Return "true" if 'a' is a subset of 'b'.
+is_subset = $(if $(strip $(set_difference $(1),$(2))),,true)
+
+# Function: set_difference a b
+# Return a - b.
+set_difference = $(foreach i,$(1),$(if $(call contains,$(2),$(i)),,$(i)))
+
+# Function: Set variable value
+#
+# Set the given make variable to the given value.
+Set = $(eval $(1) := $(2))
+
+# Function: Append variable value
+#
+# Append the given value to the given make variable.
+Append = $(eval $(1) += $(2))
+
+# Function: IsDefined variable
+#
+# Check whether the given variable is defined.
+IsDefined = $(call strneq,undefined,$(flavor $(1)))
+
+# Function: IsUndefined variable
+#
+# Check whether the given variable is undefined.
+IsUndefined = $(call streq,undefined,$(flavor $(1)))
+
+# Function: VarOrDefault variable default-value
+#
+# Get the value of the given make variable, or the default-value if the variable
+# is undefined.
+VarOrDefault = $(if $(call IsDefined,$(1)),$($(1)),$(2))
+
+# Function: CheckValue variable
+#
+# Print the name, definition, and value of a variable, for testing make
+# utilities.
+#
+# Example:
+# foo = $(call streq,a,a)
+# $(call CheckValue,foo)
+# Example Output:
+# CHECKVALUE: foo: $(call streq,,) - true
+CheckValue = $(info CHECKVALUE: $(1): $(value $(1)) - $($(1)))
+
+# Function: CopyVariable src dst
+#
+# Copy the value of the variable 'src' to 'dst', taking care to not define 'dst'
+# if 'src' is undefined. The destination variable must be undefined.
+CopyVariable = \
+ $(call AssertValue,$(call IsUndefined,$(2)),destination is already defined)\
+ $(if $(call IsUndefined,$(1)),,\
+ $(call Set,$(2),$($(1))))
+
+# Function: Assert value message
+#
+# Check that a value is true, or give an error including the given message
+Assert = $(if $(1),,\
+ $(error Assertion failed: $(2)))
+
+# Function: AssertEqual variable expected-value
+#
+# Check that the value of a variable is 'expected-value'.
+AssertEqual = \
+ $(if $(call streq,$($(1)),$(2)),,\
+ $(error Assertion failed: $(1): $(value $(1)) - $($(1)) != $(2)))
+
+# Function: CheckCommandLineOverrides list
+#
+# Check that all command line variables are in the given list. This routine is
+# useful for validating that users aren't trying to override something which
+# will not work.
+CheckCommandLineOverrides = \
+ $(foreach arg,$(MAKEOVERRIDES),\
+ $(call Set,varname,$(firstword $(subst =, ,$(arg)))) \
+ $(if $(call contains,$(1),$(varname)),,\
+ $(error "Invalid command line override: $(1) $(varname) (not supported)")))
+
+###
+# Clean up make behavior
+
+# Cancel all suffix rules. We don't want no stinking suffix rules.
+.SUFFIXES:
+
+###
+# Debugging
+
+# General debugging rule, use 'make print-XXX' to print the definition, value
+# and origin of XXX.
+make-print-%:
+ $(error PRINT: $(value $*) = "$($*)" (from $(origin $*)))