Bug 522770: Link directly to object files instead of intermediate static libs. Patch originally written by Ted Mielczarek. Checking into a CLOSED TREE as a bustage fix. reviews pending.
authorKyle Huey <me@kylehuey.com>
Sun, 01 Aug 2010 01:48:21 -0700
changeset 48661 e9c9b7d21a0c7be2a1061173a91e18a64999963e
parent 48660 b91faba6e48f6e66a210fb84a9d4374478a8c9d1
child 48662 d71692333564952f38f125484a9bab0df68c5cc9
push idunknown
push userunknown
push dateunknown
bugs522770
milestone2.0b3pre
Bug 522770: Link directly to object files instead of intermediate static libs. Patch originally written by Ted Mielczarek. Checking into a CLOSED TREE as a bustage fix. reviews pending.
accessible/src/Makefile.in
config/config.mk
config/rules.mk
configure.in
embedding/components/printingui/src/Makefile.in
gfx/cairo/cairo/src/Makefile.in
ipc/chromium/Makefile.in
js/src/config/config.mk
js/src/config/rules.mk
storage/test/Makefile.in
toolkit/components/url-classifier/src/Makefile.in
xpcom/glue/Makefile.in
xpcom/glue/standalone/Makefile.in
xpcom/reflect/xptcall/src/md/os2/Makefile.in
xpcom/reflect/xptcall/src/md/unix/Makefile.in
xpcom/reflect/xptcall/src/md/win32/Makefile.in
xpcom/tests/Makefile.in
--- a/accessible/src/Makefile.in
+++ b/accessible/src/Makefile.in
@@ -70,9 +70,9 @@ endif
 
 ifndef DISABLE_XFORMS_HOOKS
 DIRS +=   xforms
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 libs::
-	$(INSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) .
+	$(INSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) $(wildcard $(PLATFORM_DIR)/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX).fake) .
--- a/config/config.mk
+++ b/config/config.mk
@@ -75,16 +75,21 @@ CHECK_VARS := \
 # checks for internal spaces or trailing spaces in the variable
 # named by $x
 check-variable = $(if $(filter-out 0 1,$(words $($(x))z)),$(error Spaces are not allowed in $(x)))
 
 $(foreach x,$(CHECK_VARS),$(check-variable))
 
 core_abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))
 
+nullstr :=
+space :=$(nullstr) # EOL
+
+core_winabspath = $(firstword $(subst /, ,$(call core_abspath,$(1)))):$(subst $(space),,$(patsubst %,\\%,$(wordlist 2,$(words $(subst /, ,$(call core_abspath,$(1)))), $(strip $(subst /, ,$(call core_abspath,$(1)))))))
+
 # FINAL_TARGET specifies the location into which we copy end-user-shipped
 # build products (typelibs, components, chrome).
 #
 # It will usually be the well-loved $(DIST)/bin, today, but can also be an
 # XPI-contents staging directory for ambitious and right-thinking extensions.
 FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)
 
 ifdef XPI_NAME
@@ -313,16 +318,22 @@ endif
 endif
 
 ifndef STATIC_LIBRARY_NAME
 ifdef LIBRARY_NAME
 STATIC_LIBRARY_NAME=$(LIBRARY_NAME)
 endif
 endif
 
+# GNU make on Windows can't handle using fake libs, because the path
+# munging gets confused when we pass response files like @file to the linker.
+#ifneq (WINNT_,$(OS_ARCH)_$(.PYMAKE))
+MOZ_FAKELIBS = 1
+#endif
+
 # This comes from configure
 ifdef MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 endif
 
 # No sense in profiling tools
 ifdef INTERNAL_TOOLS
 NO_PROFILE_GUIDED_OPTIMIZE = 1
@@ -714,17 +725,17 @@ endif
 ######################################################################
 # Now test variables that might have been set or overridden by $(MY_CONFIG).
 
 DEFINES		+= -DOSTYPE=\"$(OS_CONFIG)\"
 DEFINES		+= -DOSARCH=$(OS_ARCH)
 
 ######################################################################
 
-GARBAGE		+= $(DEPENDENCIES) $(MKDEPENDENCIES) $(MKDEPENDENCIES).bak core $(wildcard core.[0-9]*) $(wildcard *.err) $(wildcard *.pure) $(wildcard *_pure_*.o) Templates.DB
+GARBAGE		+= $(DEPENDENCIES) $(MKDEPENDENCIES) $(MKDEPENDENCIES).bak core $(wildcard core.[0-9]*) $(wildcard *.err) $(wildcard *.pure) $(wildcard *_pure_*.o) Templates.DB $(FAKE_LIBRARY)
 
 ifeq ($(OS_ARCH),Darwin)
 ifndef NSDISTMODE
 NSDISTMODE=absolute_symlink
 endif
 PWD := $(CURDIR)
 endif
 
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -116,16 +116,31 @@ EXPAND_LIBNAME = $(foreach lib,$(1),$(LI
 EXPAND_LIBNAME_PATH = $(foreach lib,$(1),$(2)/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 EXPAND_MOZLIBNAME = $(foreach lib,$(1),$(DIST)/lib/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 else
 EXPAND_LIBNAME = $(addprefix -l,$(1))
 EXPAND_LIBNAME_PATH = -L$(2) $(addprefix -l,$(1))
 EXPAND_MOZLIBNAME = $(addprefix -l,$(1))
 endif
 
+ifdef MOZ_FAKELIBS
+# If a lib.fake is present, replace it with @lib.fake, otherwise just pass
+# the library name through unchanged.
+EXPAND_FAKELIBS = $(foreach f,$(1),$(if $(wildcard $(f).fake),@$(wildcard $(f).fake),$(f)))
+
+# Also override EXPAND_LIBNAME_PATH and EXPAND_MOZLIBNAME on non-RELATIVE_PATH
+# platforms, so we can shortcut linking -lfoo if we have foo.a.fake
+ifndef _LIBNAME_RELATIVE_PATHS
+EXPAND_LIBNAME_PATH = $(if $(wildcard $(2)/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake),@$(2)/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake,-L$(2) $(addprefix -l,$(1)))
+EXPAND_MOZLIBNAME = $(if $(wildcard $(DIST)/lib/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake),@$(DIST)/lib/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake,$(addprefix -l,$(1)))
+endif
+else
+EXPAND_FAKELIBS = $1
+endif
+
 ifdef EXTRA_DSO_LIBS
 EXTRA_DSO_LIBS	:= $(call EXPAND_MOZLIBNAME,$(EXTRA_DSO_LIBS))
 endif
 
 ################################################################################
 # Testing frameworks support
 ################################################################################
 
@@ -230,16 +245,21 @@ endif # ENABLE_TESTS
 #
 # If BUILD_STATIC_LIBS or FORCE_STATIC_LIB is set, build a static library.
 # Otherwise, build a shared library.
 #
 
 ifndef LIBRARY
 ifdef STATIC_LIBRARY_NAME
 LIBRARY			:= $(LIB_PREFIX)$(STATIC_LIBRARY_NAME).$(LIB_SUFFIX)
+ifdef MOZ_FAKELIBS
+ifndef SUPPRESS_FAKELIB
+FAKE_LIBRARY = $(LIBRARY).fake
+endif # SUPPRESS_FAKELIB
+endif # MOZ_FAKELIBS
 endif # STATIC_LIBRARY_NAME
 endif # LIBRARY
 
 ifndef HOST_LIBRARY
 ifdef HOST_LIBRARY_NAME
 HOST_LIBRARY		:= $(LIB_PREFIX)$(HOST_LIBRARY_NAME).$(LIB_SUFFIX)
 endif
 endif
@@ -538,17 +558,17 @@ CPP_PROG_LINK		= 1
 endif
 
 #
 # Make sure to wrap static libs inside linker specific flags to turn on & off
 # inclusion of all symbols inside the static libs
 #
 ifndef NO_LD_ARCHIVE_FLAGS
 ifdef SHARED_LIBRARY_LIBS
-EXTRA_DSO_LDOPTS := $(MKSHLIB_FORCE_ALL) $(SHARED_LIBRARY_LIBS) $(MKSHLIB_UNFORCE_ALL) $(EXTRA_DSO_LDOPTS)
+EXTRA_DSO_LDOPTS := $(MKSHLIB_FORCE_ALL) $(call EXPAND_FAKELIBS,$(SHARED_LIBRARY_LIBS)) $(MKSHLIB_UNFORCE_ALL) $(EXTRA_DSO_LDOPTS)
 endif
 endif
 
 #
 # This will strip out symbols that the component should not be 
 # exporting from the .dynsym section.
 #
 ifdef IS_COMPONENT
@@ -865,26 +885,26 @@ libs:: $(PARALLEL_DIRS_libs)
 	+@$(call SUBMAKE,libs,$*)
 endif
 
 libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
 ifndef NO_DIST_INSTALL
 ifdef LIBRARY
 ifdef EXPORT_LIBRARY # Stage libs that will be linked into a static build
 ifdef IS_COMPONENT
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DEPTH)/staticlib/components
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(DEPTH)/staticlib/components
 else
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DEPTH)/staticlib
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(DEPTH)/staticlib
 endif
 endif # EXPORT_LIBRARY
 ifdef DIST_INSTALL
 ifdef IS_COMPONENT
 	$(error Shipping static component libs makes no sense.)
 else
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(DIST)/lib
 endif
 endif # DIST_INSTALL
 endif # LIBRARY
 ifdef SHARED_LIBRARY
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
 	$(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY)
 ifndef NO_COMPONENTS_MANIFEST
@@ -993,20 +1013,20 @@ alltags:
 
 #
 # PROGRAM = Foo
 # creates OBJS, links with LIBS to create Foo
 #
 $(PROGRAM): $(PROGOBJS) $(LIBS_DEPS) $(EXTRA_DEPS) $(EXE_DEF_FILE) $(RESFILE) $(GLOBAL_DEPS)
 	@rm -f $@.manifest
 ifeq (WINCE,$(OS_ARCH))
-	$(LD) -NOLOGO -OUT:$@ $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -NOLOGO -OUT:$@ $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		if test -f "$(srcdir)/$@.manifest"; then \
 			echo "Embedding manifest from $(srcdir)/$@.manifest and $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		else \
 			echo "Embedding manifest from $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
@@ -1018,19 +1038,19 @@ ifdef MSMANIFEST_TOOL
 endif	# MSVC with manifest tool
 ifdef MOZ_PROFILE_GENERATE
 # touch it a few seconds into the future to work around FAT's
 # 2-second granularity
 	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
 endif
 else # !WINNT || GNU_CC
 ifeq ($(CPP_PROG_LINK),1)
-	$(CCC) -o $@ $(CXXFLAGS) $(WRAP_MALLOC_CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(WRAP_MALLOC_LIB) $(EXE_DEF_FILE)
+	$(CCC) -o $@ $(CXXFLAGS) $(WRAP_MALLOC_CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(call EXPAND_FAKELIBS,$(WRAP_MALLOC_LIB)) $(EXE_DEF_FILE)
 else # ! CPP_PROG_LINK
-	$(CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE)
+	$(CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(EXE_DEF_FILE)
 endif # CPP_PROG_LINK
 endif # WINNT && !GNU_CC
 endif # WINCE
 
 ifdef ENABLE_STRIP
 	$(STRIP) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
@@ -1077,31 +1097,31 @@ endif
 # in one directory, it assumes everything to compile Foo is in
 # Foo.o (from either Foo.c or Foo.cpp).
 #
 # SIMPLE_PROGRAMS = Foo Bar
 # creates Foo.o Bar.o, links with LIBS to create Foo, Bar.
 #
 $(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
 ifeq (WINCE,$(OS_ARCH))
-	$(LD) -nologo  -entry:mainACRTStartup -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -nologo  -entry:mainACRTStartup -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 else
 ifeq ($(CPP_PROG_LINK),1)
-	$(CCC) $(WRAP_MALLOC_CFLAGS) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB) $(BIN_FLAGS)
+	$(CCC) $(WRAP_MALLOC_CFLAGS) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB)) $(BIN_FLAGS)
 else
-	$(CC) $(WRAP_MALLOC_CFLAGS) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB) $(BIN_FLAGS)
+	$(CC) $(WRAP_MALLOC_CFLAGS) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB)) $(BIN_FLAGS)
 endif # CPP_PROG_LINK
 endif # WINNT && !GNU_CC
 endif # WINCE
 
 ifdef ENABLE_STRIP
 	$(STRIP) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
@@ -1153,43 +1173,73 @@ endif
 # that are built using other static libraries.  Confused...?
 #
 ifdef SHARED_LIBRARY_LIBS
 ifeq (,$(GNU_LD)$(filter-out OS2 WINNT WINCE, $(OS_ARCH)))
 ifneq (,$(BUILD_STATIC_LIBS)$(FORCE_STATIC_LIB))
 LOBJS	+= $(SHARED_LIBRARY_LIBS)
 endif
 else
+NONFAKE_SHARED_LIBRARY_LIBS = $(filter-out %.fake,$(call EXPAND_FAKELIBS,$(SHARED_LIBRARY_LIBS)))
+ifeq (,$(NONFAKE_SHARED_LIBRARY_LIBS))
+# All of our SHARED_LIBRARY_LIBS have fake equivalents. Score!
+# Just pass the original object files around.
+# For shared libraries, these are already included in EXTRA_DSO_LDOPTS
+# above.
+ifndef SHARED_LIBRARY
+LOBJS += $(shell cat $(addsuffix .fake,$(SHARED_LIBRARY_LIBS)))
+endif
+SKIP_SUB_LOBJS := 1
+else
 ifneq (,$(filter OSF1 BSD_OS FreeBSD NetBSD OpenBSD SunOS Darwin,$(OS_ARCH)))
 CLEANUP1	:= | egrep -v '(________64ELEL_|__.SYMDEF)'
 CLEANUP2	:= rm -f ________64ELEL_ __.SYMDEF
 else
 CLEANUP2	:= true
 endif
 SUB_LOBJS	= $(shell for lib in $(SHARED_LIBRARY_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
-endif
+endif # EXPAND_FAKELIBS
+endif # SHARED_LIBARY_LIBS
 endif
 ifdef MOZILLA_PROBE_LIBS
 PROBE_LOBJS	= $(shell for lib in $(MOZILLA_PROBE_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
 endif
 ifdef DTRACE_PROBE_OBJ
 EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
 endif
 
 $(LIBRARY): $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
 	rm -f $@
+ifndef SKIP_SUB_LOBJS
 ifneq (,$(GNU_LD)$(filter-out OS2 WINNT WINCE, $(OS_ARCH)))
 ifdef SHARED_LIBRARY_LIBS
 	@rm -f $(SUB_LOBJS)
 	@for lib in $(SHARED_LIBRARY_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
 endif
 endif
+endif # SKIP_SUB_LOBJS
 	$(AR) $(AR_FLAGS) $(OBJS) $(LOBJS) $(SUB_LOBJS)
 	$(RANLIB) $@
+ifndef MOZ_FAKELIBS
+# Don't clean these up if we're building a fake lib, because then
+# we'll reference nonexistent object files in our fake lib.
 	@rm -f foodummyfilefoo $(SUB_LOBJS)
+endif
+# Also produce a .fake file that just contains the names of the object files.
+# This can be used as a response file to the linker later instead of
+# linking the actual static library.
+ifdef MOZ_FAKELIBS
+ifndef SUPPRESS_FAKELIB
+ifeq (WINNT_,$(OS_ARCH)_$(.PYMAKE))
+	echo "$(strip $(foreach f,$(OBJS) $(SEPARATE_OBJS) $(LOBJS) $(SUB_LOBJS),$(subst \,\\,$(call core_winabspath,$(f))))) " > $@.fake
+else
+	echo "$(strip $(foreach f,$(OBJS) $(SEPARATE_OBJS) $(LOBJS) $(SUB_LOBJS),$(call core_abspath,$(f)))) " > $@.fake
+endif
+endif
+endif
 
 ifeq (,$(filter-out WINNT WINCE, $(OS_ARCH)))
 $(IMPORT_LIBRARY): $(SHARED_LIBRARY)
 endif
 
 ifeq ($(OS_ARCH),OS2)
 $(DEF_FILE): $(OBJS) $(SHARED_LIBRARY_LIBS)
 	rm -f $@
@@ -1290,26 +1340,26 @@ ifdef DTRACE_LIB_DEPENDENT
 	@for lib in $(MOZILLA_PROBE_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
 ifndef XP_MACOSX
 	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS)
 endif
 	@for lib in $(MOZILLA_PROBE_LIBS); do \
 		ofiles=`$(AR_LIST) $${lib}`; \
 		$(AR_DELETE) $${lib} $$ofiles; \
 	done
-	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
+	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
 	@rm -f $(PROBE_LOBJS)
 	@rm -f $(DTRACE_PROBE_OBJ)
 	@for lib in $(MOZILLA_PROBE_LIBS); do \
 		if [ -L $${lib} ]; then rm -f `readlink $${lib}`; fi; \
 	done
 	@rm -f $(MOZILLA_PROBE_LIBS)
 
 else # ! DTRACE_LIB_DEPENDENT
-	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
+	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
 endif # DTRACE_LIB_DEPENDENT
 
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
 ifdef MSMANIFEST_TOOL
 ifdef EMBED_MANIFEST_AT
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;$(EMBED_MANIFEST_AT); \
 		rm -f $@.manifest; \
--- a/configure.in
+++ b/configure.in
@@ -8383,24 +8383,19 @@ if test "$MOZ_TREE_CAIRO"; then
     AC_SUBST(FC_FONT_FEATURE)
     AC_SUBST(WIN32_FONT_FEATURE)
     AC_SUBST(WIN32_DWRITE_FONT_FEATURE)
     AC_SUBST(WIN32_D2D_SURFACE_FEATURE)
     AC_SUBST(QUARTZ_FONT_FEATURE)
     AC_SUBST(PNG_FUNCTIONS_FEATURE)
     AC_SUBST(QT_SURFACE_FEATURE)
 
-    if test "$_WIN32_MSVC"; then
-        MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/mozcairo.lib $(DEPTH)/gfx/cairo/libpixman/src/mozlibpixman.lib'
-    else
-        MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/$(LIB_PREFIX)mozcairo.$(LIB_SUFFIX) $(DEPTH)/gfx/cairo/libpixman/src/$(LIB_PREFIX)mozlibpixman.$(LIB_SUFFIX)'" $CAIRO_FT_LIBS"
-
-        if test "$MOZ_X11"; then
-            MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS -lXrender -lfreetype -lfontconfig"
-        fi
+    MOZ_CAIRO_LIBS='$(call EXPAND_LIBNAME_PATH,mozcairo,$(DEPTH)/gfx/cairo/cairo/src) $(call EXPAND_LIBNAME_PATH,mozlibpixman,$(DEPTH)/gfx/cairo/libpixman/src)' $CAIRO_FT_LIBS
+    if test "$MOZ_X11"; then
+        MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS -lXrender -lfreetype -lfontconfig"
     fi
 
     CAIRO_FEATURES_H=gfx/cairo/cairo/src/cairo-features.h
     mv -f $CAIRO_FEATURES_H "$CAIRO_FEATURES_H".orig 2> /dev/null
 
 else
    PKG_CHECK_MODULES(CAIRO, cairo >= $CAIRO_VERSION pixman-1 freetype2 fontconfig)
    MOZ_CAIRO_CFLAGS=$CAIRO_CFLAGS
@@ -8415,17 +8410,17 @@ fi
 AC_SUBST(MOZ_TREE_CAIRO)
 AC_SUBST(MOZ_CAIRO_CFLAGS)
 AC_SUBST(MOZ_CAIRO_LIBS)
 
 dnl ========================================================
 dnl qcms
 dnl ========================================================
 
-QCMS_LIBS='$(DEPTH)/gfx/qcms/$(LIB_PREFIX)mozqcms.$(LIB_SUFFIX)'
+QCMS_LIBS='$(call EXPAND_LIBNAME_PATH,mozqcms,$(DEPTH)/gfx/qcms)'
 AC_SUBST(QCMS_LIBS)
 
 dnl ========================================================
 dnl HarfBuzz
 dnl ========================================================
 MOZ_HARFBUZZ_LIBS='$(DEPTH)/gfx/harfbuzz/src/$(LIB_PREFIX)mozharfbuzz.$(LIB_SUFFIX)'
 AC_SUBST(MOZ_HARFBUZZ_LIBS)
 
--- a/embedding/components/printingui/src/Makefile.in
+++ b/embedding/components/printingui/src/Makefile.in
@@ -58,9 +58,9 @@ ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 PLATFORM_DIR = mac
 endif
 
 DIRS = $(PLATFORM_DIR)
 
 include $(topsrcdir)/config/rules.mk
 
 libs::
-	$(INSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)printingui_s.$(LIB_SUFFIX) .
+	$(INSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)printingui_s.$(LIB_SUFFIX) $(wildcard $(PLATFORM_DIR)/$(LIB_PREFIX)printingui_s.$(LIB_SUFFIX).fake) .
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -44,16 +44,17 @@ VPATH           = @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 ifndef MOZ_ENABLE_LIBXUL
 VISIBILITY_FLAGS =
 endif
 
 MODULE          = cairo
 LIBRARY_NAME    = mozcairo
+SUPPRESS_FAKELIB = 1 # cairo isn't awesome enough for fakelibs yet
 LIBXUL_LIBRARY = 1
 
 ifdef GNU_CC
 OS_CXXFLAGS := $(filter-out -pedantic,$(OS_CXXFLAGS))
 MODULE_OPTIMIZE_FLAGS = -O2
 else
 ifeq ($(OS_ARCH),SunOS)
 MODULE_OPTIMIZE_FLAGS = -xO5
--- a/ipc/chromium/Makefile.in
+++ b/ipc/chromium/Makefile.in
@@ -39,16 +39,17 @@ topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 OS_CXXFLAGS := $(filter-out -fshort-wchar,$(OS_CXXFLAGS))
 
 LIBRARY_NAME = chromium_s
+SUPPRESS_FAKELIB = 1 # Chromium is not ready for the awesomeness of fakelibs
 FORCE_STATIC_LIB = 1
 LIBXUL_LIBRARY = 1
 EXPORT_LIBRARY = 1
 
 ENABLE_CXX_EXCEPTIONS = 1
 ACDEFINES =
 
 ifndef MOZ_NATIVE_LIBEVENT # {
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -75,16 +75,21 @@ CHECK_VARS := \
 # checks for internal spaces or trailing spaces in the variable
 # named by $x
 check-variable = $(if $(filter-out 0 1,$(words $($(x))z)),$(error Spaces are not allowed in $(x)))
 
 $(foreach x,$(CHECK_VARS),$(check-variable))
 
 core_abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))
 
+nullstr :=
+space :=$(nullstr) # EOL
+
+core_winabspath = $(firstword $(subst /, ,$(call core_abspath,$(1)))):$(subst $(space),,$(patsubst %,\\%,$(wordlist 2,$(words $(subst /, ,$(call core_abspath,$(1)))), $(strip $(subst /, ,$(call core_abspath,$(1)))))))
+
 # FINAL_TARGET specifies the location into which we copy end-user-shipped
 # build products (typelibs, components, chrome).
 #
 # It will usually be the well-loved $(DIST)/bin, today, but can also be an
 # XPI-contents staging directory for ambitious and right-thinking extensions.
 FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)
 
 ifdef XPI_NAME
@@ -313,16 +318,22 @@ endif
 endif
 
 ifndef STATIC_LIBRARY_NAME
 ifdef LIBRARY_NAME
 STATIC_LIBRARY_NAME=$(LIBRARY_NAME)
 endif
 endif
 
+# GNU make on Windows can't handle using fake libs, because the path
+# munging gets confused when we pass response files like @file to the linker.
+#ifneq (WINNT_,$(OS_ARCH)_$(.PYMAKE))
+MOZ_FAKELIBS = 1
+#endif
+
 # This comes from configure
 ifdef MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 endif
 
 # No sense in profiling tools
 ifdef INTERNAL_TOOLS
 NO_PROFILE_GUIDED_OPTIMIZE = 1
@@ -714,17 +725,17 @@ endif
 ######################################################################
 # Now test variables that might have been set or overridden by $(MY_CONFIG).
 
 DEFINES		+= -DOSTYPE=\"$(OS_CONFIG)\"
 DEFINES		+= -DOSARCH=$(OS_ARCH)
 
 ######################################################################
 
-GARBAGE		+= $(DEPENDENCIES) $(MKDEPENDENCIES) $(MKDEPENDENCIES).bak core $(wildcard core.[0-9]*) $(wildcard *.err) $(wildcard *.pure) $(wildcard *_pure_*.o) Templates.DB
+GARBAGE		+= $(DEPENDENCIES) $(MKDEPENDENCIES) $(MKDEPENDENCIES).bak core $(wildcard core.[0-9]*) $(wildcard *.err) $(wildcard *.pure) $(wildcard *_pure_*.o) Templates.DB $(FAKE_LIBRARY)
 
 ifeq ($(OS_ARCH),Darwin)
 ifndef NSDISTMODE
 NSDISTMODE=absolute_symlink
 endif
 PWD := $(CURDIR)
 endif
 
@@ -822,8 +833,12 @@ JAVAC_FLAGS += -source 1.4
 ifdef MOZ_DEBUG
 JAVAC_FLAGS += -g
 endif
 
 ifdef TIERS
 DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_dirs))
 STATIC_DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_staticdirs))
 endif
+
+ifdef BUILD_STATIC_LIBS
+include $(topsrcdir)/config/static-config.mk
+endif
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -116,16 +116,31 @@ EXPAND_LIBNAME = $(foreach lib,$(1),$(LI
 EXPAND_LIBNAME_PATH = $(foreach lib,$(1),$(2)/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 EXPAND_MOZLIBNAME = $(foreach lib,$(1),$(DIST)/lib/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 else
 EXPAND_LIBNAME = $(addprefix -l,$(1))
 EXPAND_LIBNAME_PATH = -L$(2) $(addprefix -l,$(1))
 EXPAND_MOZLIBNAME = $(addprefix -l,$(1))
 endif
 
+ifdef MOZ_FAKELIBS
+# If a lib.fake is present, replace it with @lib.fake, otherwise just pass
+# the library name through unchanged.
+EXPAND_FAKELIBS = $(foreach f,$(1),$(if $(wildcard $(f).fake),@$(wildcard $(f).fake),$(f)))
+
+# Also override EXPAND_LIBNAME_PATH and EXPAND_MOZLIBNAME on non-RELATIVE_PATH
+# platforms, so we can shortcut linking -lfoo if we have foo.a.fake
+ifndef _LIBNAME_RELATIVE_PATHS
+EXPAND_LIBNAME_PATH = $(if $(wildcard $(2)/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake),@$(2)/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake,-L$(2) $(addprefix -l,$(1)))
+EXPAND_MOZLIBNAME = $(if $(wildcard $(DIST)/lib/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake),@$(DIST)/lib/$(LIB_PREFIX)$(1).$(LIB_SUFFIX).fake,$(addprefix -l,$(1)))
+endif
+else
+EXPAND_FAKELIBS = $1
+endif
+
 ifdef EXTRA_DSO_LIBS
 EXTRA_DSO_LIBS	:= $(call EXPAND_MOZLIBNAME,$(EXTRA_DSO_LIBS))
 endif
 
 ################################################################################
 # Testing frameworks support
 ################################################################################
 
@@ -196,16 +211,17 @@ check-one:
           --profile-name=$(MOZ_APP_NAME) \
           --verbose \
           $(EXTRA_TEST_ARGS) \
           $(DIST)/bin/xpcshell \
           $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(MODULE)/$(dir))
 
 endif # XPCSHELL_TESTS
 
+ifndef BUILD_STATIC_LIBS
 ifdef CPP_UNIT_TESTS
 
 # Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
 # through TestHarness.h, by modifying the list of includes and the libs against
 # which stuff links.
 CPPSRCS += $(CPP_UNIT_TESTS)
 SIMPLE_PROGRAMS += $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX))
 INCLUDES += -I$(DIST)/include/testing
@@ -214,32 +230,38 @@ LIBS += $(XPCOM_GLUE_LDOPTS) $(NSPR_LIBS
 # ...and run them the usual way
 check::
 	@$(EXIT_ON_ERROR) \
 	  for f in $(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)); do \
 	    XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \
 	  done
 
 endif # CPP_UNIT_TESTS
+endif # !BUILD_STATIC_LIBS
 
 .PHONY: check xpcshell-tests check-interactive check-one
 
 endif # ENABLE_TESTS
 
 
 #
 # Library rules
 #
 # If BUILD_STATIC_LIBS or FORCE_STATIC_LIB is set, build a static library.
 # Otherwise, build a shared library.
 #
 
 ifndef LIBRARY
 ifdef STATIC_LIBRARY_NAME
 LIBRARY			:= $(LIB_PREFIX)$(STATIC_LIBRARY_NAME).$(LIB_SUFFIX)
+ifdef MOZ_FAKELIBS
+ifndef SUPPRESS_FAKELIB
+FAKE_LIBRARY = $(LIBRARY).fake
+endif # SUPPRESS_FAKELIB
+endif # MOZ_FAKELIBS
 endif # STATIC_LIBRARY_NAME
 endif # LIBRARY
 
 ifndef HOST_LIBRARY
 ifdef HOST_LIBRARY_NAME
 HOST_LIBRARY		:= $(LIB_PREFIX)$(HOST_LIBRARY_NAME).$(LIB_SUFFIX)
 endif
 endif
@@ -538,17 +560,17 @@ CPP_PROG_LINK		= 1
 endif
 
 #
 # Make sure to wrap static libs inside linker specific flags to turn on & off
 # inclusion of all symbols inside the static libs
 #
 ifndef NO_LD_ARCHIVE_FLAGS
 ifdef SHARED_LIBRARY_LIBS
-EXTRA_DSO_LDOPTS := $(MKSHLIB_FORCE_ALL) $(SHARED_LIBRARY_LIBS) $(MKSHLIB_UNFORCE_ALL) $(EXTRA_DSO_LDOPTS)
+EXTRA_DSO_LDOPTS := $(MKSHLIB_FORCE_ALL) $(call EXPAND_FAKELIBS,$(SHARED_LIBRARY_LIBS)) $(MKSHLIB_UNFORCE_ALL) $(EXTRA_DSO_LDOPTS)
 endif
 endif
 
 #
 # This will strip out symbols that the component should not be 
 # exporting from the .dynsym section.
 #
 ifdef IS_COMPONENT
@@ -865,26 +887,26 @@ libs:: $(PARALLEL_DIRS_libs)
 	+@$(call SUBMAKE,libs,$*)
 endif
 
 libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
 ifndef NO_DIST_INSTALL
 ifdef LIBRARY
 ifdef EXPORT_LIBRARY # Stage libs that will be linked into a static build
 ifdef IS_COMPONENT
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DEPTH)/staticlib/components
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(DEPTH)/staticlib/components
 else
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DEPTH)/staticlib
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(DEPTH)/staticlib
 endif
 endif # EXPORT_LIBRARY
 ifdef DIST_INSTALL
 ifdef IS_COMPONENT
 	$(error Shipping static component libs makes no sense.)
 else
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(DIST)/lib
 endif
 endif # DIST_INSTALL
 endif # LIBRARY
 ifdef SHARED_LIBRARY
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
 	$(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY)
 ifndef NO_COMPONENTS_MANIFEST
@@ -993,20 +1015,20 @@ alltags:
 
 #
 # PROGRAM = Foo
 # creates OBJS, links with LIBS to create Foo
 #
 $(PROGRAM): $(PROGOBJS) $(LIBS_DEPS) $(EXTRA_DEPS) $(EXE_DEF_FILE) $(RESFILE) $(GLOBAL_DEPS)
 	@rm -f $@.manifest
 ifeq (WINCE,$(OS_ARCH))
-	$(LD) -NOLOGO -OUT:$@ $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -NOLOGO -OUT:$@ $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		if test -f "$(srcdir)/$@.manifest"; then \
 			echo "Embedding manifest from $(srcdir)/$@.manifest and $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		else \
 			echo "Embedding manifest from $@.manifest"; \
 			mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
@@ -1018,19 +1040,19 @@ ifdef MSMANIFEST_TOOL
 endif	# MSVC with manifest tool
 ifdef MOZ_PROFILE_GENERATE
 # touch it a few seconds into the future to work around FAT's
 # 2-second granularity
 	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
 endif
 else # !WINNT || GNU_CC
 ifeq ($(CPP_PROG_LINK),1)
-	$(CCC) -o $@ $(CXXFLAGS) $(WRAP_MALLOC_CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(WRAP_MALLOC_LIB) $(EXE_DEF_FILE)
+	$(CCC) -o $@ $(CXXFLAGS) $(WRAP_MALLOC_CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(call EXPAND_FAKELIBS,$(WRAP_MALLOC_LIB)) $(EXE_DEF_FILE)
 else # ! CPP_PROG_LINK
-	$(CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE)
+	$(CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(EXE_DEF_FILE)
 endif # CPP_PROG_LINK
 endif # WINNT && !GNU_CC
 endif # WINCE
 
 ifdef ENABLE_STRIP
 	$(STRIP) $@
 endif
 ifdef MOZ_POST_PROGRAM_COMMAND
@@ -1077,20 +1099,20 @@ endif
 # in one directory, it assumes everything to compile Foo is in
 # Foo.o (from either Foo.c or Foo.cpp).
 #
 # SIMPLE_PROGRAMS = Foo Bar
 # creates Foo.o Bar.o, links with LIBS to create Foo, Bar.
 #
 $(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
 ifeq (WINCE,$(OS_ARCH))
-	$(LD) -nologo  -entry:mainACRTStartup -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -nologo  -entry:mainACRTStartup -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 else
 ifeq ($(CPP_PROG_LINK),1)
@@ -1153,43 +1175,73 @@ endif
 # that are built using other static libraries.  Confused...?
 #
 ifdef SHARED_LIBRARY_LIBS
 ifeq (,$(GNU_LD)$(filter-out OS2 WINNT WINCE, $(OS_ARCH)))
 ifneq (,$(BUILD_STATIC_LIBS)$(FORCE_STATIC_LIB))
 LOBJS	+= $(SHARED_LIBRARY_LIBS)
 endif
 else
+NONFAKE_SHARED_LIBRARY_LIBS = $(filter-out %.fake,$(call EXPAND_FAKELIBS,$(SHARED_LIBRARY_LIBS)))
+ifeq (,$(NONFAKE_SHARED_LIBRARY_LIBS))
+# All of our SHARED_LIBRARY_LIBS have fake equivalents. Score!
+# Just pass the original object files around.
+# For shared libraries, these are already included in EXTRA_DSO_LDOPTS
+# above.
+ifndef SHARED_LIBRARY
+LOBJS += $(shell cat $(addsuffix .fake,$(SHARED_LIBRARY_LIBS)))
+endif
+SKIP_SUB_LOBJS := 1
+else
 ifneq (,$(filter OSF1 BSD_OS FreeBSD NetBSD OpenBSD SunOS Darwin,$(OS_ARCH)))
 CLEANUP1	:= | egrep -v '(________64ELEL_|__.SYMDEF)'
 CLEANUP2	:= rm -f ________64ELEL_ __.SYMDEF
 else
 CLEANUP2	:= true
 endif
 SUB_LOBJS	= $(shell for lib in $(SHARED_LIBRARY_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
-endif
+endif # EXPAND_FAKELIBS
+endif # SHARED_LIBARY_LIBS
 endif
 ifdef MOZILLA_PROBE_LIBS
 PROBE_LOBJS	= $(shell for lib in $(MOZILLA_PROBE_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
 endif
 ifdef DTRACE_PROBE_OBJ
 EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
 endif
 
 $(LIBRARY): $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
 	rm -f $@
+ifndef SKIP_SUB_LOBJS
 ifneq (,$(GNU_LD)$(filter-out OS2 WINNT WINCE, $(OS_ARCH)))
 ifdef SHARED_LIBRARY_LIBS
 	@rm -f $(SUB_LOBJS)
 	@for lib in $(SHARED_LIBRARY_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
 endif
 endif
+endif # SKIP_SUB_LOBJS
 	$(AR) $(AR_FLAGS) $(OBJS) $(LOBJS) $(SUB_LOBJS)
 	$(RANLIB) $@
+ifndef MOZ_FAKELIBS
+# Don't clean these up if we're building a fake lib, because then
+# we'll reference nonexistent object files in our fake lib.
 	@rm -f foodummyfilefoo $(SUB_LOBJS)
+endif
+# Also produce a .fake file that just contains the names of the object files.
+# This can be used as a response file to the linker later instead of
+# linking the actual static library.
+ifdef MOZ_FAKELIBS
+ifndef SUPPRESS_FAKELIB
+ifeq (WINNT_,$(OS_ARCH)_$(.PYMAKE))
+	echo "$(strip $(foreach f,$(OBJS) $(SEPARATE_OBJS) $(LOBJS) $(SUB_LOBJS),$(subst \,\\,$(call core_winabspath,$(f))))) " > $@.fake
+else
+	echo "$(strip $(foreach f,$(OBJS) $(SEPARATE_OBJS) $(LOBJS) $(SUB_LOBJS),$(call core_abspath,$(f)))) " > $@.fake
+endif
+endif
+endif
 
 ifeq (,$(filter-out WINNT WINCE, $(OS_ARCH)))
 $(IMPORT_LIBRARY): $(SHARED_LIBRARY)
 endif
 
 ifeq ($(OS_ARCH),OS2)
 $(DEF_FILE): $(OBJS) $(SHARED_LIBRARY_LIBS)
 	rm -f $@
@@ -1290,26 +1342,26 @@ ifdef DTRACE_LIB_DEPENDENT
 	@for lib in $(MOZILLA_PROBE_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
 ifndef XP_MACOSX
 	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS)
 endif
 	@for lib in $(MOZILLA_PROBE_LIBS); do \
 		ofiles=`$(AR_LIST) $${lib}`; \
 		$(AR_DELETE) $${lib} $$ofiles; \
 	done
-	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
+	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
 	@rm -f $(PROBE_LOBJS)
 	@rm -f $(DTRACE_PROBE_OBJ)
 	@for lib in $(MOZILLA_PROBE_LIBS); do \
 		if [ -L $${lib} ]; then rm -f `readlink $${lib}`; fi; \
 	done
 	@rm -f $(MOZILLA_PROBE_LIBS)
 
 else # ! DTRACE_LIB_DEPENDENT
-	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
+	$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
 endif # DTRACE_LIB_DEPENDENT
 
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
 ifdef MSMANIFEST_TOOL
 ifdef EMBED_MANIFEST_AT
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;$(EMBED_MANIFEST_AT); \
 		rm -f $@.manifest; \
--- a/storage/test/Makefile.in
+++ b/storage/test/Makefile.in
@@ -70,14 +70,13 @@ endif
 
 
 LOCAL_INCLUDES = \
   -I$(srcdir)/../src \
   $(NULL)
 
 LIBS = \
 	$(LIBS_DIR) \
-	$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
 	$(MOZ_COMPONENT_LIBS) \
 	$(SQLITE_LIBS) \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/components/url-classifier/src/Makefile.in
+++ b/toolkit/components/url-classifier/src/Makefile.in
@@ -2,16 +2,17 @@ DEPTH      = ../../../..
 topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = url-classifier
 LIBRARY_NAME = urlclassifier_s
+SUPPRESS_FAKELIB = 1 # The urlclassifier test chokes on fakelibs
 XPIDL_MODULE = url-classifier
 LIBXUL_LIBRARY = 1
 FORCE_STATIC_LIB = 1
 
 
 
 CPPSRCS = \
           nsUrlClassifierDBService.cpp \
--- a/xpcom/glue/Makefile.in
+++ b/xpcom/glue/Makefile.in
@@ -44,16 +44,17 @@ include $(DEPTH)/config/autoconf.mk
 include $(srcdir)/objs.mk
 
 EXTRA_DEPS += $(srcdir)/objs.mk
 
 DIRS            = standalone
 
 MODULE		= xpcom
 LIBRARY_NAME	= xpcomglue_s
+SUPPRESS_FAKELIB = 1
 DIST_INSTALL	= 1
 
 
 
 LOCAL_INCLUDES	= \
 		-I$(srcdir)/../build \
 		$(NULL)
 
--- a/xpcom/glue/standalone/Makefile.in
+++ b/xpcom/glue/standalone/Makefile.in
@@ -42,16 +42,17 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 include $(srcdir)/../objs.mk
 
 EXTRA_DEPS += $(srcdir)/../objs.mk
 
 MODULE		= xpcom
 LIBRARY_NAME	= xpcomglue
+SUPPRESS_FAKELIB = 1
 DIST_INSTALL	= 1
 
 
 LOCAL_INCLUDES	= \
 		-I$(srcdir)/../../build \
 		$(NULL)
 
 ifeq (Darwin,$(OS_ARCH))
--- a/xpcom/reflect/xptcall/src/md/os2/Makefile.in
+++ b/xpcom/reflect/xptcall/src/md/os2/Makefile.in
@@ -66,9 +66,9 @@ FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES		+= -DEXPORT_XPTC_API
 
 LOCAL_INCLUDES	+= -I$(srcdir)/../..
 
 libs:: $(LIBRARY)
-	$(INSTALL) $(LIBRARY) ../..
+	$(INSTALL) $(LIBRARY) $(FAKE_LIBRARY) ../..
--- a/xpcom/reflect/xptcall/src/md/unix/Makefile.in
+++ b/xpcom/reflect/xptcall/src/md/unix/Makefile.in
@@ -539,17 +539,18 @@ xptcstubs_asm_openvms_alpha.o: $(DIST)/i
 endif
 
 ifeq ($(OS_ARCH),SunOS)
 ifeq (86,$(findstring 86,$(OS_TEST)))
 ifndef GNU_CC
 ifeq (x86_64,$(OS_TEST))
 xptcstubs_asm_x86_64_solaris_SUNW.o: $(DIST)/include/xptcstubsdef.inc $(srcdir)/xptcstubs_asm_x86_64_solaris_SUNW.s
 	sed \
-	  -e 's/^\(STUB_ENTRY\)(\([0-9]\))/\11\(\2\)/' \
+	  -e 's/^\(STUB_ENTRY\)(\([0
+-9]\))/\11\(\2\)/' \
 	  -e 's/^\(STUB_ENTRY\)(\([0-9][0-9]\))/\12\(\2\)/' \
 	  -e 's/^\(STUB_ENTRY\)(\([0-9][0-9][0-9]\))/\13\(\2\)/' \
 	$(DIST)/include/xptcstubsdef.inc > ./xptcstubsdef_asm.solx86
 	$(AS) -o $@ -xarch=amd64 $(ASFLAGS) $(AS_DASH_C_FLAG) -I./ $(srcdir)/xptcstubs_asm_x86_64_solaris_SUNW.s
 else
 xptcstubs_asm_x86_solaris_SUNW.o: $(DIST)/include/xptcstubsdef.inc $(srcdir)/xptcstubs_asm_x86_solaris_SUNW.s
 	sed \
 	  -e 's/^\(STUB_ENTRY\)(\([0-9]\))/\11\(\2\)/' \
@@ -559,9 +560,9 @@ xptcstubs_asm_x86_solaris_SUNW.o: $(DIST
 	$(AS) -o $@ $(ASFLAGS) $(AS_DASH_C_FLAG) -I./ $(srcdir)/xptcstubs_asm_x86_solaris_SUNW.s
 endif
 	@rm -f ./xptcstubsdef_asm.solx86
 endif
 endif
 endif
 
 libs:: $(LIBRARY)
-	$(INSTALL) $(LIBRARY) ../..
+	$(INSTALL) $(LIBRARY) $(FAKE_LIBRARY) ../..
--- a/xpcom/reflect/xptcall/src/md/win32/Makefile.in
+++ b/xpcom/reflect/xptcall/src/md/win32/Makefile.in
@@ -104,9 +104,9 @@ FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES		+= -DEXPORT_XPTC_API -D_IMPL_NS_COM
 
 LOCAL_INCLUDES	+= -I$(srcdir)/../..
 
 libs:: $(LIBRARY)
-	$(INSTALL) $(LIBRARY) ../..
+	$(INSTALL) $(LIBRARY) $(FAKE_LIBRARY) ../..
--- a/xpcom/tests/Makefile.in
+++ b/xpcom/tests/Makefile.in
@@ -142,20 +142,16 @@ endif
 ifndef MOZILLA_INTERNAL_API
 CPP_UNIT_TESTS += \
                   TestStringAPI.cpp \
                   $(NULL)
 endif
 
 include $(topsrcdir)/config/config.mk
 
-ifndef MOZILLA_INTERNAL_API
-LIBS +=	$(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX)
-endif
-
 LIBS += $(XPCOM_LIBS)
 
 # Needed to resolve __yylex (?)
 ifeq ($(OS_ARCH)$(OS_RELEASE),FreeBSD2)
 LIBS		+= -lpcap
 endif
 
 XPCSHELL_TESTS = unit