Bug 584474 part 9 - Replace fakelibs with a more sophisticated library expansion system. r=ted
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 25 Feb 2011 15:05:08 +0100
changeset 63472 143c8e9082afef42caf66f7916e9bef0fd720cf3
parent 63471 528d6def0f976350ee2696401ea6e7c23058124b
child 63473 8a4aff2236ededebf0163462d7948bc60e8be6bf
push idunknown
push userunknown
push dateunknown
reviewersted
bugs584474
milestone2.0b12pre
Bug 584474 part 9 - Replace fakelibs with a more sophisticated library expansion system. r=ted
allmakefiles.sh
config/Makefile.in
config/autoconf.mk.in
config/config.mk
config/expandlibs.py
config/expandlibs_config.py.in
config/expandlibs_exec.py
config/expandlibs_gen.py
config/rules.mk
config/tests/unit-expandlibs.py
configure.in
gfx/cairo/cairo/src/Makefile.in
intl/unicharutil/util/internal/Makefile.in
ipc/chromium/Makefile.in
js/src/config/Makefile.in
js/src/config/autoconf.mk.in
js/src/config/config.mk
js/src/config/expandlibs.py
js/src/config/expandlibs_config.py.in
js/src/config/expandlibs_exec.py
js/src/config/expandlibs_gen.py
js/src/config/pythonpath.py
js/src/config/rules.mk
js/src/configure.in
other-licenses/bsdiff/Makefile.in
toolkit/components/url-classifier/src/Makefile.in
xpcom/glue/Makefile.in
xpcom/glue/nomozalloc/Makefile.in
xpcom/glue/standalone/Makefile.in
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -64,16 +64,17 @@ build/pgo/js-input/Makefile
 build/unix/Makefile
 build/win32/Makefile
 build/win32/crashinjectdll/Makefile
 config/Makefile
 config/autoconf.mk
 config/mkdepend/Makefile
 config/nspr/Makefile
 config/doxygen.cfg
+config/expandlibs_config.py
 config/tests/src-simple/Makefile
 probes/Makefile
 extensions/Makefile
 "
 
 if [ "$WINCE" ]; then
   add_makefiles "
     build/wince/tools/Makefile
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -163,17 +163,17 @@ export:: $(STL_WRAPPERS_SENTINEL)
 GARBAGE += $(STL_WRAPPERS_SENTINEL)
 GARBAGE_DIRS += stl_wrappers
 endif
 
 install::
 	$(SYSINSTALL) $(IFLAGS1) $(DEPTH)/mozilla-config.h $(DESTDIR)$(includedir)
 
 GARBAGE += \
-	$(FINAL_LINK_COMPS) $(FINAL_LINK_LIBS) $(FINAL_LINK_COMP_NAMES) buildid $(srcdir)/*.pyc
+  $(FINAL_LINK_COMPS) $(FINAL_LINK_LIBS) $(FINAL_LINK_COMP_NAMES) buildid $(srcdir)/*.pyc *.pyc
 
 ifndef CROSS_COMPILE
 ifdef USE_ELF_DYNSTR_GC
 elf-dynstr-gc: elf-dynstr-gc.c $(GLOBAL_DEPS)
 	$(CC) $(COMPILE_CFLAGS) $(GLIB_CFLAGS) -o $@ $< $(LDFLAGS) $(GLIB_LIBS) 
 endif
 endif
 
@@ -186,16 +186,17 @@ endif
 
 PYUNITS := \
   unit-Expression.py \
   unit-Preprocessor.py \
   unit-nsinstall.py \
   unit-printprereleasesuffix.py \
   unit-JarMaker.py \
   unit-buildlist.py \
+  unit-expandlibs.py \
   $(NULL)
 
 check:: check-python-modules check-jar-mn
 
 check-python-modules::
 	@$(EXIT_ON_ERROR) \
 	for test in $(PYUNITS); do \
 	  $(PYTHON) $(srcdir)/tests/$$test ; \
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -363,16 +363,17 @@ MIDL_FLAGS	= @MIDL_FLAGS@
 DLL_PREFIX	= @DLL_PREFIX@
 LIB_PREFIX	= @LIB_PREFIX@
 OBJ_SUFFIX	= @OBJ_SUFFIX@
 LIB_SUFFIX	= @LIB_SUFFIX@
 DLL_SUFFIX	= @DLL_SUFFIX@
 BIN_SUFFIX	= @BIN_SUFFIX@
 ASM_SUFFIX	= @ASM_SUFFIX@
 IMPORT_LIB_SUFFIX = @IMPORT_LIB_SUFFIX@
+LIBS_DESC_SUFFIX = @LIBS_DESC_SUFFIX@
 USE_N32		= @USE_N32@
 HAVE_64BIT_OS	= @HAVE_64BIT_OS@
 
 # Temp hack.  It is not my intention to leave this crap in here for ever.
 # Im talking to fur right now to solve the problem without introducing 
 # NS_USE_NATIVE to the build system -ramiro.
 NS_USE_NATIVE = @NS_USE_NATIVE@
 
--- a/config/config.mk
+++ b/config/config.mk
@@ -78,21 +78,16 @@ 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
@@ -334,20 +329,16 @@ endif
 endif
 
 ifndef STATIC_LIBRARY_NAME
 ifdef LIBRARY_NAME
 STATIC_LIBRARY_NAME=$(LIBRARY_NAME)
 endif
 endif
 
-ifeq (WINNT,$(OS_ARCH))
-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
@@ -733,17 +724,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 $(FAKE_LIBRARY)
+GARBAGE		+= $(DEPENDENCIES) $(MKDEPENDENCIES) $(MKDEPENDENCIES).bak core $(wildcard core.[0-9]*) $(wildcard *.err) $(wildcard *.pure) $(wildcard *_pure_*.o) Templates.DB
 
 ifeq ($(OS_ARCH),Darwin)
 ifndef NSDISTMODE
 NSDISTMODE=absolute_symlink
 endif
 PWD := $(CURDIR)
 endif
 
@@ -837,8 +828,17 @@ JAVAC_FLAGS += -g
 endif
 
 ifdef TIERS
 DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_dirs))
 STATIC_DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_staticdirs))
 endif
 
 OPTIMIZE_JARS_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/optimizejars.py)
+
+EXPAND_LIBS = $(PYTHON) -I$(DEPTH)/config $(topsrcdir)/config/expandlibs.py
+EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_exec.py
+EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_gen.py
+EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR)
+EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC)
+EXPAND_CCC = $(EXPAND_LIBS_EXEC) --uselist -- $(CCC)
+EXPAND_LD = $(EXPAND_LIBS_EXEC) --uselist -- $(LD)
+EXPAND_MKSHLIB = $(EXPAND_LIBS_EXEC) --uselist -- $(MKSHLIB)
new file mode 100644
--- /dev/null
+++ b/config/expandlibs.py
@@ -0,0 +1,125 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+'''Expandlibs is a system that allows to replace some libraries with a
+descriptor file containing some linking information about them.
+
+The descriptor file format is as follows:
+---8<-----
+OBJS = a.o b.o ...
+LIBS = libfoo.a libbar.a ...
+--->8-----
+
+(In the example above, OBJ_SUFFIX is o and LIB_SUFFIX is a).
+
+Expandlibs also canonicalizes how to pass libraries to the linker, such
+that only the ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} form needs to be used:
+given a list of files, expandlibs will replace items with the form
+${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} following these rules:
+
+- If a ${DLL_PREFIX}${ROOT}.${DLL_SUFFIX} or
+  ${DLL_PREFIX}${ROOT}.${IMPORT_LIB_SUFFIX} file exists, use that instead
+- If the ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} file exists, use it
+- If a ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX}.${LIB_DESC_SUFFIX} file exists,
+  replace ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} with the OBJS and LIBS the
+  descriptor contains. And for each of these LIBS, also apply the same
+  rules.
+'''
+from __future__ import with_statement
+import sys, os
+import expandlibs_config as conf
+
+class LibDescriptor(dict):
+    KEYS = ['OBJS', 'LIBS']
+
+    def __init__(self, content=None):
+        '''Creates an instance of a lib descriptor, initialized with contents
+        from a list of strings when given. This is intended for use with
+        file.readlines()'''
+        if isinstance(content, list) and all([isinstance(item, str) for item in content]):
+            pass
+        elif content is not None:
+            raise TypeError("LibDescriptor() arg 1 must be None or a list of strings")
+        super(LibDescriptor, self).__init__()
+        for key in self.KEYS:
+            self[key] = []
+        if not content:
+            return
+        for key, value in [(s.strip() for s in item.split('=', 2)) for item in content if item.find('=') >= 0]:
+            if key in self.KEYS:
+                self[key] = value.split()
+
+    def __str__(self):
+        '''Serializes the lib descriptor'''
+        return '\n'.join('%s = %s' % (k, ' '.join(self[k])) for k in self.KEYS if len(self[k]))
+
+class ExpandArgs(list):
+    def __init__(self, args):
+        '''Creates a clone of the |args| list and performs file expansion on
+        each item it contains'''
+        super(ExpandArgs, self).__init__()
+        for arg in args:
+            self += self._expand(arg)
+
+    def _expand(self, arg):
+        '''Internal function doing the actual work'''
+        (root, ext) = os.path.splitext(arg)
+        if ext != conf.LIB_SUFFIX or not os.path.basename(root).startswith(conf.LIB_PREFIX):
+            return [arg]
+        if len(conf.IMPORT_LIB_SUFFIX):
+            dll = root + conf.IMPORT_LIB_SUFFIX
+        else:
+            dll = root.replace(conf.LIB_PREFIX, conf.DLL_PREFIX, 1) + conf.DLL_SUFFIX
+        if os.path.exists(dll):
+            return [dll]
+        if os.path.exists(arg):
+            return [arg]
+        return self._expand_desc(arg)
+
+    def _expand_desc(self, arg):
+        '''Internal function taking care of lib descriptor expansion only'''
+        if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
+            with open(arg + conf.LIBS_DESC_SUFFIX, 'r') as f:
+                desc = LibDescriptor(f.readlines())
+            objs = desc['OBJS']
+            for lib in desc['LIBS']:
+                objs += self._expand(lib)
+            return objs
+        return [arg]
+
+if __name__ == '__main__':
+    print " ".join(ExpandArgs(sys.argv[1:]))
new file mode 100644
--- /dev/null
+++ b/config/expandlibs_config.py.in
@@ -0,0 +1,56 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+def normalize_suffix(suffix):
+    '''Returns a normalized suffix, i.e. ensures it starts with a dot and
+    doesn't starts or ends with whitespace characters'''
+    value = suffix.strip()
+    if len(value) and not value.startswith('.'):
+        value = '.' + value
+    return value
+
+# Variables from the build system
+AR = "@AR@"
+AR_EXTRACT = "@AR_EXTRACT@".replace('$(AR)', AR)
+DLL_PREFIX = "@DLL_PREFIX@"
+LIB_PREFIX = "@LIB_PREFIX@"
+OBJ_SUFFIX = normalize_suffix("@OBJ_SUFFIX@")
+LIB_SUFFIX = normalize_suffix("@LIB_SUFFIX@")
+DLL_SUFFIX = normalize_suffix("@DLL_SUFFIX@")
+IMPORT_LIB_SUFFIX = normalize_suffix("@IMPORT_LIB_SUFFIX@")
+LIBS_DESC_SUFFIX = normalize_suffix("@LIBS_DESC_SUFFIX@")
+EXPAND_LIBS_LIST_STYLE = "@EXPAND_LIBS_LIST_STYLE@"
new file mode 100644
--- /dev/null
+++ b/config/expandlibs_exec.py
@@ -0,0 +1,152 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+'''expandlibs-exec.py applies expandlibs rules, and some more (see below) to
+a given command line, and executes that command line with the expanded
+arguments.
+
+With the --extract argument (useful for e.g. $(AR)), it extracts object files
+from static libraries (or use those listed in library descriptors directly).
+
+With the --uselist argument (useful for e.g. $(CC)), it replaces all object
+files with a list file. This can be used to avoid limitations in the length
+of a command line. The kind of list file format used depends on the
+EXPAND_LIBS_LIST_STYLE variable: 'list' for MSVC style lists (@file.list)
+or 'linkerscript' for GNU ld linker scripts.
+See https://bugzilla.mozilla.org/show_bug.cgi?id=584474#c59 for more details.
+'''
+from __future__ import with_statement
+import sys
+import os
+from expandlibs import ExpandArgs
+import expandlibs_config as conf
+from optparse import OptionParser
+import subprocess
+import tempfile
+import shutil
+
+class ExpandArgsMore(ExpandArgs):
+    ''' Meant to be used as 'with ExpandArgsMore(args) as ...: '''
+    def __enter__(self):
+        self.tmp = []
+        return self
+        
+    def __exit__(self, type, value, tb):
+        '''Automatically remove temporary files'''
+        for tmp in self.tmp:
+            if os.path.isdir(tmp):
+                shutil.rmtree(tmp, True)
+            else:
+                os.remove(tmp)
+
+    def extract(self):
+        self[0:] = self._extract(self)
+
+    def _extract(self, args):
+        '''When a static library name is found, either extract its contents
+        in a temporary directory or use the information found in the
+        corresponding lib descriptor.
+        '''
+        ar_extract = conf.AR_EXTRACT.split()
+        newlist = []
+        for arg in args:
+            if os.path.splitext(arg)[1] == conf.LIB_SUFFIX:
+                if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
+                    newlist += self._extract(self._expand_desc(arg))
+                elif os.path.exists(arg) and len(ar_extract):
+                    tmp = tempfile.mkdtemp(dir=os.curdir)
+                    self.tmp.append(tmp)
+                    subprocess.call(ar_extract + [os.path.abspath(arg)], cwd=tmp)
+                    objs = []
+                    for root, dirs, files in os.walk(tmp):
+                        objs += [os.path.join(root, f) for f in files if os.path.splitext(f)[1] == conf.OBJ_SUFFIX]
+                    newlist += objs
+                else:
+                    newlist += [arg]
+            else:
+                newlist += [arg]
+        return newlist
+
+    def makelist(self):
+        '''Replaces object file names with a temporary list file, using a
+        list format depending on the EXPAND_LIBS_LIST_STYLE variable
+        '''
+        objs = [o for o in self if os.path.splitext(o)[1] == conf.OBJ_SUFFIX]
+        if not len(objs): return
+        fd, tmp = tempfile.mkstemp(suffix=".list",dir=os.curdir)
+        if conf.EXPAND_LIBS_LIST_STYLE == "linkerscript":
+            content = ["INPUT(%s)\n" % obj for obj in objs]
+            ref = tmp
+        elif conf.EXPAND_LIBS_LIST_STYLE == "list":
+            content = ["%s\n" % obj for obj in objs]
+            ref = "@" + tmp
+        else:
+            os.remove(tmp)
+            return
+        self.tmp.append(tmp)
+        f = os.fdopen(fd, "w")
+        f.writelines(content)
+        f.close()
+        idx = self.index(objs[0])
+        newlist = self[0:idx] + [ref] + [item for item in self[idx:] if item not in objs]
+        self[0:] = newlist
+
+def main():
+    parser = OptionParser()
+    parser.add_option("--extract", action="store_true", dest="extract",
+        help="when a library has no descriptor file, extract it first, when possible")
+    parser.add_option("--uselist", action="store_true", dest="uselist",
+        help="use a list file for objects when executing a command")
+
+    (options, args) = parser.parse_args()
+
+    with ExpandArgsMore(args) as args:
+        if options.extract:
+            args.extract()
+        if options.uselist:
+            args.makelist()
+
+        print >>sys.stderr, "Executing: " + " ".join(args)
+        for tmp in [f for f in args.tmp if os.path.isfile(f)]:
+            print >>sys.stderr, tmp + ":"
+            with open(tmp) as file:
+                print >>sys.stderr, "".join(["    " + l for l in file.readlines()])
+        sys.stderr.flush()
+        exit(subprocess.call(args))
+
+if __name__ == '__main__':
+    main()
new file mode 100644
--- /dev/null
+++ b/config/expandlibs_gen.py
@@ -0,0 +1,57 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+'''Given a list of object files and library names, prints a library
+descriptor to standard output'''
+
+import sys
+import os
+import expandlibs_config as conf
+from expandlibs import LibDescriptor
+
+def generate(args):
+    desc = LibDescriptor()
+    for arg in args:
+        if os.path.splitext(arg)[1] == conf.OBJ_SUFFIX:
+            desc['OBJS'].append(os.path.abspath(arg))
+        elif os.path.splitext(arg)[1] == conf.LIB_SUFFIX and \
+             (os.path.exists(arg) or os.path.exists(arg + conf.LIBS_DESC_SUFFIX)):
+            desc['LIBS'].append(os.path.abspath(arg))
+    return desc
+
+if __name__ == '__main__':
+    print generate(sys.argv[1:])
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -78,22 +78,16 @@ endif
 # ELOG prints out failed command when building silently (gmake -s).
 ifneq (,$(findstring s, $(filter-out --%, $(MAKEFLAGS))))
   ELOG := $(EXEC) sh $(BUILD_TOOLS)/print-failed-commands.sh
 else
   ELOG :=
 endif
 
 ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
-ifndef GNU_CC
-_LIBNAME_RELATIVE_PATHS=1
-endif
-endif
-
-ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
 _VPATH_SRCS = $(abspath $<)
 else
 _VPATH_SRCS = $<
 endif
 
 # Add $(DIST)/lib to VPATH so that -lfoo dependencies are followed
 VPATH += $(DIST)/lib
 ifdef LIBXUL_SDK
@@ -106,40 +100,19 @@ endif
 # EXPAND_LIBNAME_PATH - $(call EXPAND_LIBNAME_PATH,foo,dir)
 # expands to dir/foo.lib on platforms with import libs and
 # -Ldir -lfoo otherwise
 
 # EXPAND_MOZLIBNAME - $(call EXPAND_MOZLIBNAME,foo)
 # expands to $(DIST)/lib/foo.lib on platforms with import libs and
 # -lfoo otherwise
 
-ifdef _LIBNAME_RELATIVE_PATHS
 EXPAND_LIBNAME = $(foreach lib,$(1),$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 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
 ################################################################################
@@ -219,17 +192,17 @@ endif # XPCSHELL_TESTS
 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
-LIBS += $(XPCOM_GLUE_LDOPTS) $(NSPR_LIBS) -ljs_static
+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
 
@@ -244,22 +217,23 @@ 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
+_LIBRARY		:= $(LIB_PREFIX)$(STATIC_LIBRARY_NAME).$(LIB_SUFFIX)
+# Only build actual library if it is installed in DIST/lib or SDK
+ifeq (,$(SDK_LIBRARY)$(DIST_INSTALL)$(NO_EXPAND_LIBS))
+LIBRARY			:= $(_LIBRARY).$(LIBS_DESC_SUFFIX)
+else
+LIBRARY			:= $(_LIBRARY) $(_LIBRARY).$(LIBS_DESC_SUFFIX)
+endif
 endif # STATIC_LIBRARY_NAME
 endif # LIBRARY
 
 ifndef HOST_LIBRARY
 ifdef HOST_LIBRARY_NAME
 HOST_LIBRARY		:= $(LIB_PREFIX)$(HOST_LIBRARY_NAME).$(LIB_SUFFIX)
 endif
 endif
@@ -556,26 +530,16 @@ TAG_PROGRAM		= xargs etags -a
 ifneq ($(CPPSRCS)$(CMMSRCS),)
 CPP_PROG_LINK		= 1
 endif
 ifneq ($(HOST_CPPSRCS)$(HOST_CMMSRCS),)
 HOST_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) $(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
 EXTRA_DSO_LDOPTS += $(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
 endif # IS_COMPONENT
 
 #
@@ -850,37 +814,26 @@ ifdef MODULE_NAME
 endif
 endif # BUILD_STATIC_LIBS
 else # !IS_COMPONENT
 	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
 endif # IS_COMPONENT
 endif # EXPORT_LIBRARY
 endif # LIBRARY_NAME
 
-# Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
-LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
-HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
-DSO_LDOPTS_DEPS = $(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS))
-
-ifndef _LIBNAME_RELATIVE_PATHS
-
-LIBS_DEPS += $(filter -l%, $(LIBS))
-HOST_LIBS_DEPS += $(filter -l%, $(HOST_LIBS))
-DSO_LDOPTS_DEPS += $(filter -l%, $(EXTRA_DSO_LDOPTS))
+ifneq (,$(filter-out %.$(LIB_SUFFIX),$(SHARED_LIBRARY_LIBS)))
+$(error SHARED_LIBRARY_LIBS must contain .$(LIB_SUFFIX) files only)
+endif
 
-_LIBDIRS = $(patsubst -L%,%,$(filter -L%, $(LIBS) $(HOST_LIBS) $(EXTRA_DSO_LDOPTS)))
-ifneq (,$(_LIBDIRS))
-vpath $(LIB_PREFIX)%.$(LIB_SUFFIX) $(_LIBDIRS)
-ifdef IMPORT_LIB_SUFFIX
-vpath $(LIB_PREFIX)%.$(IMPORT_LIB_SUFFIX) $(_LIBDIRS)
-endif # IMPORT_LIB_SUFFIX
-vpath $(DLL_PREFIX)%$(DLL_SUFFIX) $(_LIBDIRS)
-endif # _LIBDIRS
-
-endif # _LIBNAME_RELATIVE_PATHS
+# Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
+DO_EXPAND_LIBS = $(foreach f,$(1),$(if $(filter %.$(LIB_SUFFIX),$(f)),$(if $(wildcard $(f).$(LIBS_DESC_SUFFIX)),$(f).$(LIBS_DESC_SUFFIX),$(if $(wildcard $(f)),$(f)))))
+LIBS_DEPS = $(call DO_EXPAND_LIBS,$(filter %.$(LIB_SUFFIX),$(LIBS)))
+SHARED_LIBRARY_LIBS_DEPS = $(call DO_EXPAND_LIBS,$(SHARED_LIBRARY_LIBS))
+HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX),$(HOST_LIBS))
+DSO_LDOPTS_DEPS = $(call DO_EXPAND_LIBS,$(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS)))
 
 # Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 
 ##############################################
 ifdef PARALLEL_DIRS
 libs:: $(PARALLEL_DIRS_libs)
 
@@ -892,25 +845,25 @@ ifdef EXPORT_LIBRARY
 ifeq ($(EXPORT_LIBRARY),1)
 ifdef IS_COMPONENT
 EXPORT_LIBRARY = $(DEPTH)/staticlib/components
 else
 EXPORT_LIBRARY = $(DEPTH)/staticlib
 endif
 else
 # If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there
-GARBAGE += $(foreach lib,$(LIBRARY) $(FAKE_LIBRARY),$(EXPORT_LIBRARY)/$(lib))
+GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib))
 endif
 endif # EXPORT_LIBRARY
 
 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
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(EXPORT_LIBRARY)
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(EXPORT_LIBRARY)
 endif # EXPORT_LIBRARY
 ifdef DIST_INSTALL
 ifdef IS_COMPONENT
 	$(error Shipping static component libs makes no sense.)
 else
 	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
 endif
 endif # DIST_INSTALL
@@ -1020,20 +973,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) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
+	$(EXPAND_LD) -NOLOGO -OUT:$@ $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
+	$(EXPAND_LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(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; \
@@ -1045,19 +998,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) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(call EXPAND_FAKELIBS,$(WRAP_MALLOC_LIB)) $(EXE_DEF_FILE)
+	$(EXPAND_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)
 else # ! CPP_PROG_LINK
-	$(CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(EXE_DEF_FILE)
+	$(EXPAND_CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(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
@@ -1098,31 +1051,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) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
+	$(EXPAND_LD) -nologo  -entry:mainACRTStartup -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
+	$(EXPAND_LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(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) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB)) $(BIN_FLAGS)
+	$(EXPAND_CCC) $(WRAP_MALLOC_CFLAGS) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB) $(BIN_FLAGS)
 else
-	$(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)
+	$(EXPAND_CC) $(WRAP_MALLOC_CFLAGS) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(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
@@ -1164,83 +1117,27 @@ ifeq ($(CPP_PROG_LINK),1)
 	$(QUANTIFY) $(CCC) -o $^.quantify $(CXXFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
 else
 	$(QUANTIFY) $(CC) -o $^.quantify $(CFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
 endif
 ifndef NO_DIST_INSTALL
 	$(INSTALL) $(IFLAGS2) $^.quantify $(FINAL_TARGET)
 endif
 
-#
-# This allows us to create static versions of the shared libraries
-# 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 # EXPAND_FAKELIBS
-endif # SHARED_LIBRARY_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)
+$(filter %.$(LIB_SUFFIX),$(LIBRARY)): $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
+	rm -f $(LIBRARY)
+	$(EXPAND_AR) $(AR_FLAGS) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS)
 	$(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_,$(HOST_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
+
+$(filter-out %.$(LIB_SUFFIX),$(LIBRARY)): $(filter %.$(LIB_SUFFIX),$(LIBRARY)) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
+	$(EXPAND_LIBS_GEN) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS) > $@
 
 ifeq (,$(filter-out WINNT WINCE, $(OS_ARCH)))
 $(IMPORT_LIBRARY): $(SHARED_LIBRARY)
 endif
 
 ifeq ($(OS_ARCH),OS2)
 $(DEF_FILE): $(OBJS) $(SHARED_LIBRARY_LIBS)
 	rm -f $@
@@ -1258,37 +1155,33 @@ ifeq ($(OS_ARCH),OS2)
 	$(RANLIB) $@
 endif # OS/2
 
 $(HOST_LIBRARY): $(HOST_OBJS) Makefile
 	rm -f $@
 	$(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
 	$(HOST_RANLIB) $@
 
-ifdef NO_LD_ARCHIVE_FLAGS
-SUB_SHLOBJS = $(SUB_LOBJS)
-endif
-
 ifdef HAVE_DTRACE
 ifndef XP_MACOSX
 ifdef DTRACE_PROBE_OBJ
 ifndef DTRACE_LIB_DEPENDENT
 $(DTRACE_PROBE_OBJ): $(OBJS)
 	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(OBJS)
 endif
 endif
 endif
 endif
 
 # On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files,
 # so instead of deleting .o files after repacking them into a dylib, we make
 # symlinks back to the originals. The symlinks are a no-op for stabs debugging,
 # so no need to conditionalize on OS version or debugging format.
 
-$(SHARED_LIBRARY): $(OBJS) $(LOBJS) $(DEF_FILE) $(RESFILE) $(SHARED_LIBRARY_LIBS) $(LIBRARY) $(EXTRA_DEPS) $(DSO_LDOPTS_DEPS) $(GLOBAL_DEPS)
+$(SHARED_LIBRARY): $(OBJS) $(LOBJS) $(DEF_FILE) $(RESFILE) $(SHARED_LIBRARY_LIBS_DEPS) $(LIBRARY) $(EXTRA_DEPS) $(DSO_LDOPTS_DEPS) $(GLOBAL_DEPS)
 ifndef INCREMENTAL_LINKER
 	rm -f $@
 endif
 ifeq ($(OS_ARCH),OpenVMS)
 	@if test ! -f $(VMS_SYMVEC_FILE); then \
 	  if test -f $(VMS_SYMVEC_FILE_MODULE); then \
 	    echo Creating specific component options file $(VMS_SYMVEC_FILE); \
 	    cp $(VMS_SYMVEC_FILE_MODULE) $(VMS_SYMVEC_FILE); \
@@ -1296,73 +1189,39 @@ ifeq ($(OS_ARCH),OpenVMS)
 	fi
 ifdef IS_COMPONENT
 	@if test ! -f $(VMS_SYMVEC_FILE); then \
 	  echo Creating generic component options file $(VMS_SYMVEC_FILE); \
 	  cp $(VMS_SYMVEC_FILE_COMP) $(VMS_SYMVEC_FILE); \
 	fi
 endif
 endif # OpenVMS
-ifdef NO_LD_ARCHIVE_FLAGS
-ifdef SHARED_LIBRARY_LIBS
-	@rm -f $(SUB_SHLOBJS)
-	@for lib in $(SHARED_LIBRARY_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
-ifeq ($(OS_ARCH),Darwin)
-	@echo Making symlinks to the original object files in the archive libraries $(SHARED_LIBRARY_LIBS)
-	@for lib in $(SHARED_LIBRARY_LIBS); do \
-		libdir=`echo $$lib|sed -e 's,/[^/]*\.a,,'`; \
-		ofiles=`$(AR_LIST) $${lib}`; \
-		for ofile in $$ofiles; do \
-			if [ -f $$libdir/$$ofile ]; then \
-				rm -f $$ofile; \
-				ln -s $$libdir/$$ofile $$ofile; \
-			fi; \
-		done; \
-	done
+ifdef DTRACE_LIB_DEPENDENT
+ifndef XP_MACOSX
+	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(shell $(EXPAND_LIBS) $(MOZILLA_PROBE_LIBS))
 endif
-endif # SHARED_LIBRARY_LIBS
-endif # NO_LD_ARCHIVE_FLAGS
-ifdef DTRACE_LIB_DEPENDENT
-	@rm -f $(PROBE_LOBJS)
-	@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) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
-	@rm -f $(PROBE_LOBJS)
+	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
 	@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) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
+	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(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; \
 	fi
 endif   # EMBED_MANIFEST_AT
 endif	# MSVC with manifest tool
 ifdef MOZ_PROFILE_GENERATE
 	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
 endif
 endif	# WINNT && !GCC
-ifneq ($(OS_ARCH),Darwin)
-	@rm -f $(SUB_SHLOBJS)
-endif # Darwin
 	@rm -f foodummyfilefoo $(DELETE_AFTER_LINK)
 	chmod +x $@
 ifdef ENABLE_STRIP
 	$(STRIP) $@
 endif
 ifdef MOZ_POST_DSO_LIB_COMMAND
 	$(MOZ_POST_DSO_LIB_COMMAND) $@
 endif
new file mode 100644
--- /dev/null
+++ b/config/tests/unit-expandlibs.py
@@ -0,0 +1,247 @@
+from __future__ import with_statement
+import subprocess
+import unittest
+import sys
+import os
+import imp
+from tempfile import mkdtemp
+from shutil import rmtree
+sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+
+from UserString import UserString
+# Create a controlled configuration for use by expandlibs
+config_win = {
+    'AR_EXTRACT': '',
+    'DLL_PREFIX': '',
+    'LIB_PREFIX': '',
+    'OBJ_SUFFIX': '.obj',
+    'LIB_SUFFIX': '.lib',
+    'DLL_SUFFIX': '.dll',
+    'IMPORT_LIB_SUFFIX': '.lib',
+    'LIBS_DESC_SUFFIX': '.desc',
+    'EXPAND_LIBS_LIST_STYLE': 'list',
+}
+config_unix = {
+    'AR_EXTRACT': 'ar -x',
+    'DLL_PREFIX': 'lib',
+    'LIB_PREFIX': 'lib',
+    'OBJ_SUFFIX': '.o',
+    'LIB_SUFFIX': '.a',
+    'DLL_SUFFIX': '.so',
+    'IMPORT_LIB_SUFFIX': '',
+    'LIBS_DESC_SUFFIX': '.desc',
+    'EXPAND_LIBS_LIST_STYLE': 'linkerscript',
+}
+
+config = sys.modules['expandlibs_config'] = imp.new_module('expandlibs_config')
+
+from expandlibs import LibDescriptor, ExpandArgs
+from expandlibs_gen import generate
+from expandlibs_exec import ExpandArgsMore
+
+def Lib(name):
+    return config.LIB_PREFIX + name + config.LIB_SUFFIX
+
+def Obj(name):
+    return name + config.OBJ_SUFFIX
+
+def Dll(name):
+    return config.DLL_PREFIX + name + config.DLL_SUFFIX
+
+def ImportLib(name):
+    if not len(config.IMPORT_LIB_SUFFIX): return Dll(name)
+    return config.LIB_PREFIX + name + config.IMPORT_LIB_SUFFIX
+
+class TestLibDescriptor(unittest.TestCase):
+    def test_serialize(self):
+        '''Test LibDescriptor's serialization'''
+        desc = LibDescriptor()
+        desc[LibDescriptor.KEYS[0]] = ['a', 'b']
+        self.assertEqual(str(desc), "%s = a b" % LibDescriptor.KEYS[0])
+        desc['unsupported-key'] = ['a']
+        self.assertEqual(str(desc), "%s = a b" % LibDescriptor.KEYS[0])
+        desc[LibDescriptor.KEYS[1]] = ['c', 'd', 'e']
+        self.assertEqual(str(desc), "%s = a b\n%s = c d e" % (LibDescriptor.KEYS[0], LibDescriptor.KEYS[1]))
+        desc[LibDescriptor.KEYS[0]] = []
+        self.assertEqual(str(desc), "%s = c d e" % (LibDescriptor.KEYS[1]))
+
+    def test_read(self):
+        '''Test LibDescriptor's initialization'''
+        desc_list = ["# Comment",
+                     "%s = a b" % LibDescriptor.KEYS[1],
+                     "", # Empty line
+                     "foo = bar", # Should be discarded
+                     "%s = c d e" % LibDescriptor.KEYS[0]]
+        desc = LibDescriptor(desc_list)
+        self.assertEqual(desc[LibDescriptor.KEYS[1]], ['a', 'b'])
+        self.assertEqual(desc[LibDescriptor.KEYS[0]], ['c', 'd', 'e'])
+        self.assertEqual(False, 'foo' in desc)
+
+def wrap_method(conf, wrapped_method):
+    '''Wrapper used to call a test with a specific configuration'''
+    def _method(self):
+        for key in conf:
+            setattr(config, key, conf[key])
+        self.init()
+        wrapped_method(self)
+        self.cleanup()
+    return _method
+
+class ReplicateTests(type):
+    '''Replicates tests for unix and windows variants'''
+    def __new__(cls, clsName, bases, dict):
+        for name in [key for key in dict if key.startswith('test_')]:
+            dict[name + '_unix'] = wrap_method(config_unix, dict[name])
+            dict[name + '_unix'].__doc__ = dict[name].__doc__ + ' (unix)'
+            dict[name + '_win'] = wrap_method(config_win, dict[name])
+            dict[name + '_win'].__doc__ = dict[name].__doc__ + ' (win)'
+            del dict[name]
+        return type.__new__(cls, clsName, bases, dict)
+
+class TestCaseWithTmpDir(unittest.TestCase):
+    __metaclass__ = ReplicateTests
+    def init(self):
+        self.tmpdir = mkdtemp()
+
+    def cleanup(self):
+        rmtree(self.tmpdir)
+
+    def touch(self, files):
+        for f in files:
+            open(f, 'w').close()
+
+    def tmpfile(self, *args):
+        return os.path.join(self.tmpdir, *args)
+
+class TestExpandLibsGen(TestCaseWithTmpDir):
+    def test_generate(self):
+        '''Test library descriptor generation'''
+        files = [self.tmpfile(f) for f in
+                 [Lib('a'), Obj('b'), Lib('c'), Obj('d'), Obj('e'), Lib('f')]]
+        self.touch(files[:-1])
+        self.touch([files[-1] + config.LIBS_DESC_SUFFIX])
+
+        desc = generate(files)
+        self.assertEqual(desc['OBJS'], [self.tmpfile(Obj(s)) for s in ['b', 'd', 'e']])
+        self.assertEqual(desc['LIBS'], [self.tmpfile(Lib(s)) for s in ['a', 'c', 'f']])
+
+class TestExpandInit(TestCaseWithTmpDir):
+    def init(self):
+        ''' Initializes test environment for library expansion tests'''
+        super(TestExpandInit, self).init()
+        # Create 2 fake libraries, each containing 3 objects, and the second
+        # including the first one and another library.
+        os.mkdir(self.tmpfile('libx'))
+        os.mkdir(self.tmpfile('liby'))
+        self.libx_files = [self.tmpfile('libx', Obj(f)) for f in ['g', 'h', 'i']]
+        self.liby_files = [self.tmpfile('liby', Obj(f)) for f in ['j', 'k', 'l']] + [self.tmpfile('liby', Lib('z'))]
+        self.touch(self.libx_files + self.liby_files)
+        with open(self.tmpfile('libx', Lib('x') + config.LIBS_DESC_SUFFIX), 'w') as f:
+            f.write(str(generate(self.libx_files)))
+        with open(self.tmpfile('liby', Lib('y') + config.LIBS_DESC_SUFFIX), 'w') as f:
+            f.write(str(generate(self.liby_files + [self.tmpfile('libx', Lib('x'))])))
+
+        # Create various objects and libraries 
+        self.arg_files = [self.tmpfile(f) for f in [Lib('a'), Obj('b'), Obj('c'), Lib('d'), Obj('e')]]
+        # We always give library names (LIB_PREFIX/SUFFIX), even for
+        # dynamic/import libraries
+        self.files = self.arg_files + [self.tmpfile(ImportLib('f'))]
+        self.arg_files += [self.tmpfile(Lib('f'))]
+        self.touch(self.files)
+
+class TestExpandArgs(TestExpandInit):
+    def test_expand(self):
+        '''Test library expansion'''
+        # Expanding arguments means libraries with a descriptor are expanded
+        # with the descriptor content, and import libraries are used when
+        # a library doesn't exist
+        args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
+        self.assertEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 
+
+        # When a library exists at the same time as a descriptor, we just use
+        # the library
+        self.touch([self.tmpfile('libx', Lib('x'))])
+        args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
+        self.assertEqual(args, ['foo', '-bar'] + self.files + self.liby_files + [self.tmpfile('libx', Lib('x'))]) 
+
+        self.touch([self.tmpfile('liby', Lib('y'))])
+        args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
+        self.assertEqual(args, ['foo', '-bar'] + self.files + [self.tmpfile('liby', Lib('y'))])
+
+class TestExpandArgsMore(TestExpandInit):
+    def test_makelist(self):
+        '''Test grouping object files in lists'''
+        # ExpandArgsMore does the same as ExpandArgs
+        with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
+            self.assertEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 
+
+            # But also has an extra method replacing object files with a list
+            args.makelist()
+            # self.files has objects at #1, #2, #4
+            self.assertEqual(args[:3], ['foo', '-bar'] + self.files[:1])
+            self.assertEqual(args[4:], [self.files[3]] + self.files[5:] + [self.tmpfile('liby', Lib('z'))])
+
+            # Check the list file content
+            objs = [f for f in self.files + self.liby_files + self.libx_files if f.endswith(config.OBJ_SUFFIX)]
+            if config.EXPAND_LIBS_LIST_STYLE == "linkerscript":
+                self.assertNotEqual(args[3][0], '@')
+                filename = args[3]
+                content = ["INPUT(%s)" % f for f in objs]
+            elif config.EXPAND_LIBS_LIST_STYLE == "list":
+                self.assertEqual(args[3][0], '@')
+                filename = args[3][1:]
+                content = objs
+
+            with open(filename, 'r') as f:
+                self.assertEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
+
+            tmp = args.tmp
+        # Check that all temporary files are properly removed
+        self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
+
+    def test_extract(self):
+        '''Test library extraction'''
+        # Divert subprocess.call
+        subprocess_call = subprocess.call
+        extracted = {}
+        def call(args, **kargs):
+            # The command called is always AR_EXTRACT
+            ar_extract = config.AR_EXTRACT.split()
+            self.assertEqual(args[:len(ar_extract)], ar_extract)
+            # Remaining argument is always one library
+            self.assertEqual([os.path.splitext(arg)[1] for arg in args[len(ar_extract):]], [config.LIB_SUFFIX])
+            # Simulate AR_EXTRACT extracting one object file for the library
+            lib = os.path.splitext(os.path.basename(args[len(ar_extract)]))[0]
+            extracted[lib] = os.path.join(kargs['cwd'], "%s" % Obj(lib))
+            self.touch([extracted[lib]])
+        subprocess.call = call
+
+        # ExpandArgsMore does the same as ExpandArgs
+        self.touch([self.tmpfile('liby', Lib('y'))])
+        with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
+            self.assertEqual(args, ['foo', '-bar'] + self.files + [self.tmpfile('liby', Lib('y'))])
+
+            # ExpandArgsMore also has an extra method extracting static libraries
+            # when possible
+            args.extract()
+
+            files = self.files + self.liby_files + self.libx_files
+            if not len(config.AR_EXTRACT):
+                # If we don't have an AR_EXTRACT, extract() expands libraries with a
+                # descriptor when the corresponding library exists (which ExpandArgs
+                # alone doesn't)
+                self.assertEqual(args, ['foo', '-bar'] + files)
+            else:
+                # With AR_EXTRACT, it uses the descriptors when there are, and actually
+                # extracts the remaining libraries
+                self.assertEqual(args, ['foo', '-bar'] + [extracted[os.path.splitext(os.path.basename(f))[0]] if f.endswith(config.LIB_SUFFIX) else f for f in files])
+
+            tmp = args.tmp
+        # Check that all temporary files are properly removed
+        self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
+
+        # Restore subprocess.call
+        subprocess.call = subprocess_call
+
+if __name__ == '__main__':
+    unittest.main()
--- a/configure.in
+++ b/configure.in
@@ -1220,18 +1220,18 @@ MOZ_JPEG_CFLAGS=
 MOZ_JPEG_LIBS='$(call EXPAND_LIBNAME_PATH,mozjpeg,$(DEPTH)/jpeg)'
 MOZ_ZLIB_CFLAGS=
 MOZ_ZLIB_LIBS='$(call EXPAND_LIBNAME_PATH,mozz,$(DEPTH)/modules/zlib/src)'
 MOZ_BZ2_CFLAGS=
 MOZ_BZ2_LIBS='$(call EXPAND_LIBNAME_PATH,bz2,$(DEPTH)/modules/libbz2/src)'
 MOZ_PNG_CFLAGS=
 MOZ_PNG_LIBS='$(call EXPAND_LIBNAME_PATH,mozpng,$(DEPTH)/modules/libimg/png)'
 
-MOZ_JS_STATIC_LIBS='-L$(LIBXUL_DIST)/bin -ljs_static'
-MOZ_JS_SHARED_LIBS='-L$(LIBXUL_DIST)/bin -lmozjs'
+MOZ_JS_STATIC_LIBS='$(call EXPAND_LIBNAME_PATH,js_static,$(LIBXUL_DIST)/lib)'
+MOZ_JS_SHARED_LIBS='$(call EXPAND_LIBNAME_PATH,mozjs,$(LIBXUL_DIST)/lib)'
 DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/bin -lxpcom -lxpcom_core -lmozalloc'
 MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin -Wl,-rpath-link,$(prefix)/lib'
 XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/bin -lxpcom -lmozalloc'
 LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) -lxul'
 XPCOM_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
 XPCOM_STANDALONE_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue.$(LIB_SUFFIX)'
 
 MOZ_FS_LAYOUT=unix
@@ -2254,18 +2254,16 @@ ia64*-hpux*)
     MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ $(DSO_LDOPTS)'
     MKSHLIB_FORCE_ALL=
     MKSHLIB_UNFORCE_ALL=
     MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
     MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
     MOZ_DEBUG_FLAGS='-Zi'
     MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
     MOZ_FIX_LINK_PATHS=
-    MOZ_JS_STATIC_LIBS='$(LIBXUL_DIST)/lib/js_static.lib'
-    MOZ_JS_SHARED_LIBS='$(LIBXUL_DIST)/lib/mozjs.lib'
     OBJ_SUFFIX=obj
     RANLIB='echo not_ranlib'
     STRIP='echo not_strip'
     TARGET_NSPR_MDCPUCFG='\"md/_wince.cfg\"'
     UNZIP=unzip
     XARGS=xargs
     XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
     ZIP=zip
@@ -2314,18 +2312,16 @@ ia64*-hpux*)
         DSO_LDOPTS='-shared'
         MKSHLIB='$(CXX) $(DSO_LDOPTS) -o $@'
         MKCSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
         RC='$(WINDRES)'
         # Use temp file for windres (bug 213281)
         RCFLAGS='-O coff --use-temp-file'
         # mingw doesn't require kernel32, user32, and advapi32 explicitly
         LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32"
-        MOZ_JS_STATIC_LIBS='-L$(LIBXUL_DIST)/bin -ljs_static'
-        MOZ_JS_SHARED_LIBS='-L$(LIBXUL_DIST)/bin -lmozjs'
         MOZ_FIX_LINK_PATHS=
         DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib -lxpcom -lxpcom_core -lmozalloc'
         XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/lib -lxpcom -lmozalloc'
         DLL_PREFIX=
         IMPORT_LIB_SUFFIX=dll.a
         GCC_VERSION=`$CC -v 2>&1 | awk '/^gcc version/ { print $3 }'`
     else
         TARGET_COMPILER_ABI=msvc
@@ -2368,18 +2364,16 @@ ia64*-hpux*)
         MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
         WARNINGS_AS_ERRORS='-WX'
         # If we're building with --enable-profiling, we need -Oy-, which forces a frame pointer.
         if test -z "$MOZ_PROFILING"; then
             MOZ_OPTIMIZE_FLAGS='-O1'
         else
             MOZ_OPTIMIZE_FLAGS='-O1 -Oy-'
         fi
-        MOZ_JS_STATIC_LIBS='$(LIBXUL_DIST)/lib/js_static.lib'
-        MOZ_JS_SHARED_LIBS='$(LIBXUL_DIST)/lib/mozjs.lib'
         MOZ_FIX_LINK_PATHS=
         DYNAMIC_XPCOM_LIBS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xpcom_core.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
         XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
         LIBXUL_LIBS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
         MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
         if test $_MSC_VER -ge 1400; then
             LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE -NXCOMPAT"
             dnl For profile-guided optimization
@@ -8189,16 +8183,48 @@ if test -n "$MIPSPRO_CXX" -o -n "$COMPAQ
     AC_DEFINE(CPP_THROW_NEW, [])
 else
     AC_DEFINE(CPP_THROW_NEW, [throw()])
 fi
 AC_LANG_C
 
 dnl ========================================================
 dnl =
+dnl = Check what kind of list files are supported by the
+dnl = linker
+dnl =
+dnl ========================================================
+
+AC_CACHE_CHECK(what kind of list files are supported by the linker,
+    EXPAND_LIBS_LIST_STYLE,
+    [echo "int main() {return 0;}" > conftest.${ac_ext}
+     if AC_TRY_COMMAND(${CC-cc} -o conftest.${OBJ_SUFFIX} -c $CFLAGS $CPPFLAGS conftest.${ac_ext} 1>&2) && test -s conftest.${OBJ_SUFFIX}; then
+         echo "INPUT(conftest.${OBJ_SUFFIX})" > conftest.list
+         if AC_TRY_COMMAND(${CC-cc} -o conftest${ac_exeext} $LDFLAGS conftest.list $LIBS 1>&2) && test -s conftest${ac_exeext}; then
+             EXPAND_LIBS_LIST_STYLE=linkerscript
+         else
+             echo "conftest.${OBJ_SUFFIX}" > conftest.list
+             if AC_TRY_COMMAND(${CC-cc} -o conftest${ac_exeext} $LDFLAGS @conftest.list $LIBS 1>&2) && test -s conftest${ac_exeext}; then
+                 EXPAND_LIBS_LIST_STYLE=list
+             else
+                 EXPAND_LIBS_LIST_STYLE=none
+             fi
+         fi
+     else
+         dnl We really don't expect to get here, but just in case
+         AC_ERROR([couldn't compile a simple C file])
+     fi
+     rm -rf conftest*])
+
+LIBS_DESC_SUFFIX=desc
+AC_SUBST(LIBS_DESC_SUFFIX)
+AC_SUBST(EXPAND_LIBS_LIST_STYLE)
+
+dnl ========================================================
+dnl =
 dnl = Build depencency options
 dnl =
 dnl ========================================================
 MOZ_ARG_HEADER(Build dependencies)
 
 dnl ========================================================
 dnl = Do not auto generate dependency info
 dnl ========================================================
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -44,17 +44,16 @@ 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/intl/unicharutil/util/internal/Makefile.in
+++ b/intl/unicharutil/util/internal/Makefile.in
@@ -44,17 +44,16 @@ VPATH		= @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 # This makefile builds the version of unicharutils_s static library which uses
 # internal linkage. Components that use frozen (external) linkage should use
 # unicharutil_external_s.
 
 MODULE=unicharutil
 LIBRARY_NAME=unicharutil_s
-SUPPRESS_FAKELIB = 1
 DIST_INSTALL = 1
 EXPORT_LIBRARY = 1
 MOZILLA_INTERNAL_API = 1
 
 include $(srcdir)/../objs.mk
 
 EXTRA_DEPS += $(srcdir)/../objs.mk
 
--- a/ipc/chromium/Makefile.in
+++ b/ipc/chromium/Makefile.in
@@ -39,17 +39,16 @@ 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
 
 ACDEFINES =
 
 ifndef MOZ_NATIVE_LIBEVENT # {
 vpath %.c \
--- a/js/src/config/Makefile.in
+++ b/js/src/config/Makefile.in
@@ -96,14 +96,16 @@ export::
 	$(PERL) $(srcdir)/preprocessor.pl $(DEFINES) $(ACDEFINES) \
 		-DBUILD_STATIC_LIBS=$(BUILD_STATIC_LIBS) \
 		$(srcdir)/system-headers | $(PERL) $(srcdir)/make-system-wrappers.pl system_wrappers_js
 	$(INSTALL) system_wrappers_js $(DIST)
 
 GARBAGE_DIRS += system_wrappers_js
 endif
 
+GARBAGE += $(srcdir)/*.pyc *.pyc
+
 FORCE:
 
 ifdef MKDEPEND_DIR
 clean clobber realclean clobber_all::
 	cd $(MKDEPEND_DIR); $(MAKE) $@
 endif
--- a/js/src/config/autoconf.mk.in
+++ b/js/src/config/autoconf.mk.in
@@ -178,16 +178,17 @@ BIN_FLAGS	= @BIN_FLAGS@
 DLL_PREFIX	= @DLL_PREFIX@
 LIB_PREFIX	= @LIB_PREFIX@
 OBJ_SUFFIX	= @OBJ_SUFFIX@
 LIB_SUFFIX	= @LIB_SUFFIX@
 DLL_SUFFIX	= @DLL_SUFFIX@
 BIN_SUFFIX	= @BIN_SUFFIX@
 ASM_SUFFIX	= @ASM_SUFFIX@
 IMPORT_LIB_SUFFIX = @IMPORT_LIB_SUFFIX@
+LIBS_DESC_SUFFIX = @LIBS_DESC_SUFFIX@
 USE_N32		= @USE_N32@
 HAVE_64BIT_OS	= @HAVE_64BIT_OS@
 
 # Temp hack.  It is not my intention to leave this crap in here for ever.
 # Im talking to fur right now to solve the problem without introducing 
 # NS_USE_NATIVE to the build system -ramiro.
 NS_USE_NATIVE = @NS_USE_NATIVE@
 
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -78,21 +78,16 @@ 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
@@ -334,20 +329,16 @@ endif
 endif
 
 ifndef STATIC_LIBRARY_NAME
 ifdef LIBRARY_NAME
 STATIC_LIBRARY_NAME=$(LIBRARY_NAME)
 endif
 endif
 
-ifeq (WINNT,$(OS_ARCH))
-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
@@ -733,17 +724,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 $(FAKE_LIBRARY)
+GARBAGE		+= $(DEPENDENCIES) $(MKDEPENDENCIES) $(MKDEPENDENCIES).bak core $(wildcard core.[0-9]*) $(wildcard *.err) $(wildcard *.pure) $(wildcard *_pure_*.o) Templates.DB
 
 ifeq ($(OS_ARCH),Darwin)
 ifndef NSDISTMODE
 NSDISTMODE=absolute_symlink
 endif
 PWD := $(CURDIR)
 endif
 
@@ -837,8 +828,17 @@ JAVAC_FLAGS += -g
 endif
 
 ifdef TIERS
 DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_dirs))
 STATIC_DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_staticdirs))
 endif
 
 OPTIMIZE_JARS_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/optimizejars.py)
+
+EXPAND_LIBS = $(PYTHON) -I$(DEPTH)/config $(topsrcdir)/config/expandlibs.py
+EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_exec.py
+EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/pythonpath.py -I$(DEPTH)/config $(topsrcdir)/config/expandlibs_gen.py
+EXPAND_AR = $(EXPAND_LIBS_EXEC) --extract -- $(AR)
+EXPAND_CC = $(EXPAND_LIBS_EXEC) --uselist -- $(CC)
+EXPAND_CCC = $(EXPAND_LIBS_EXEC) --uselist -- $(CCC)
+EXPAND_LD = $(EXPAND_LIBS_EXEC) --uselist -- $(LD)
+EXPAND_MKSHLIB = $(EXPAND_LIBS_EXEC) --uselist -- $(MKSHLIB)
new file mode 100644
--- /dev/null
+++ b/js/src/config/expandlibs.py
@@ -0,0 +1,125 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+'''Expandlibs is a system that allows to replace some libraries with a
+descriptor file containing some linking information about them.
+
+The descriptor file format is as follows:
+---8<-----
+OBJS = a.o b.o ...
+LIBS = libfoo.a libbar.a ...
+--->8-----
+
+(In the example above, OBJ_SUFFIX is o and LIB_SUFFIX is a).
+
+Expandlibs also canonicalizes how to pass libraries to the linker, such
+that only the ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} form needs to be used:
+given a list of files, expandlibs will replace items with the form
+${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} following these rules:
+
+- If a ${DLL_PREFIX}${ROOT}.${DLL_SUFFIX} or
+  ${DLL_PREFIX}${ROOT}.${IMPORT_LIB_SUFFIX} file exists, use that instead
+- If the ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} file exists, use it
+- If a ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX}.${LIB_DESC_SUFFIX} file exists,
+  replace ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} with the OBJS and LIBS the
+  descriptor contains. And for each of these LIBS, also apply the same
+  rules.
+'''
+from __future__ import with_statement
+import sys, os
+import expandlibs_config as conf
+
+class LibDescriptor(dict):
+    KEYS = ['OBJS', 'LIBS']
+
+    def __init__(self, content=None):
+        '''Creates an instance of a lib descriptor, initialized with contents
+        from a list of strings when given. This is intended for use with
+        file.readlines()'''
+        if isinstance(content, list) and all([isinstance(item, str) for item in content]):
+            pass
+        elif content is not None:
+            raise TypeError("LibDescriptor() arg 1 must be None or a list of strings")
+        super(LibDescriptor, self).__init__()
+        for key in self.KEYS:
+            self[key] = []
+        if not content:
+            return
+        for key, value in [(s.strip() for s in item.split('=', 2)) for item in content if item.find('=') >= 0]:
+            if key in self.KEYS:
+                self[key] = value.split()
+
+    def __str__(self):
+        '''Serializes the lib descriptor'''
+        return '\n'.join('%s = %s' % (k, ' '.join(self[k])) for k in self.KEYS if len(self[k]))
+
+class ExpandArgs(list):
+    def __init__(self, args):
+        '''Creates a clone of the |args| list and performs file expansion on
+        each item it contains'''
+        super(ExpandArgs, self).__init__()
+        for arg in args:
+            self += self._expand(arg)
+
+    def _expand(self, arg):
+        '''Internal function doing the actual work'''
+        (root, ext) = os.path.splitext(arg)
+        if ext != conf.LIB_SUFFIX or not os.path.basename(root).startswith(conf.LIB_PREFIX):
+            return [arg]
+        if len(conf.IMPORT_LIB_SUFFIX):
+            dll = root + conf.IMPORT_LIB_SUFFIX
+        else:
+            dll = root.replace(conf.LIB_PREFIX, conf.DLL_PREFIX, 1) + conf.DLL_SUFFIX
+        if os.path.exists(dll):
+            return [dll]
+        if os.path.exists(arg):
+            return [arg]
+        return self._expand_desc(arg)
+
+    def _expand_desc(self, arg):
+        '''Internal function taking care of lib descriptor expansion only'''
+        if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
+            with open(arg + conf.LIBS_DESC_SUFFIX, 'r') as f:
+                desc = LibDescriptor(f.readlines())
+            objs = desc['OBJS']
+            for lib in desc['LIBS']:
+                objs += self._expand(lib)
+            return objs
+        return [arg]
+
+if __name__ == '__main__':
+    print " ".join(ExpandArgs(sys.argv[1:]))
new file mode 100644
--- /dev/null
+++ b/js/src/config/expandlibs_config.py.in
@@ -0,0 +1,56 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+def normalize_suffix(suffix):
+    '''Returns a normalized suffix, i.e. ensures it starts with a dot and
+    doesn't starts or ends with whitespace characters'''
+    value = suffix.strip()
+    if len(value) and not value.startswith('.'):
+        value = '.' + value
+    return value
+
+# Variables from the build system
+AR = "@AR@"
+AR_EXTRACT = "@AR_EXTRACT@".replace('$(AR)', AR)
+DLL_PREFIX = "@DLL_PREFIX@"
+LIB_PREFIX = "@LIB_PREFIX@"
+OBJ_SUFFIX = normalize_suffix("@OBJ_SUFFIX@")
+LIB_SUFFIX = normalize_suffix("@LIB_SUFFIX@")
+DLL_SUFFIX = normalize_suffix("@DLL_SUFFIX@")
+IMPORT_LIB_SUFFIX = normalize_suffix("@IMPORT_LIB_SUFFIX@")
+LIBS_DESC_SUFFIX = normalize_suffix("@LIBS_DESC_SUFFIX@")
+EXPAND_LIBS_LIST_STYLE = "@EXPAND_LIBS_LIST_STYLE@"
new file mode 100644
--- /dev/null
+++ b/js/src/config/expandlibs_exec.py
@@ -0,0 +1,152 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+'''expandlibs-exec.py applies expandlibs rules, and some more (see below) to
+a given command line, and executes that command line with the expanded
+arguments.
+
+With the --extract argument (useful for e.g. $(AR)), it extracts object files
+from static libraries (or use those listed in library descriptors directly).
+
+With the --uselist argument (useful for e.g. $(CC)), it replaces all object
+files with a list file. This can be used to avoid limitations in the length
+of a command line. The kind of list file format used depends on the
+EXPAND_LIBS_LIST_STYLE variable: 'list' for MSVC style lists (@file.list)
+or 'linkerscript' for GNU ld linker scripts.
+See https://bugzilla.mozilla.org/show_bug.cgi?id=584474#c59 for more details.
+'''
+from __future__ import with_statement
+import sys
+import os
+from expandlibs import ExpandArgs
+import expandlibs_config as conf
+from optparse import OptionParser
+import subprocess
+import tempfile
+import shutil
+
+class ExpandArgsMore(ExpandArgs):
+    ''' Meant to be used as 'with ExpandArgsMore(args) as ...: '''
+    def __enter__(self):
+        self.tmp = []
+        return self
+        
+    def __exit__(self, type, value, tb):
+        '''Automatically remove temporary files'''
+        for tmp in self.tmp:
+            if os.path.isdir(tmp):
+                shutil.rmtree(tmp, True)
+            else:
+                os.remove(tmp)
+
+    def extract(self):
+        self[0:] = self._extract(self)
+
+    def _extract(self, args):
+        '''When a static library name is found, either extract its contents
+        in a temporary directory or use the information found in the
+        corresponding lib descriptor.
+        '''
+        ar_extract = conf.AR_EXTRACT.split()
+        newlist = []
+        for arg in args:
+            if os.path.splitext(arg)[1] == conf.LIB_SUFFIX:
+                if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
+                    newlist += self._extract(self._expand_desc(arg))
+                elif os.path.exists(arg) and len(ar_extract):
+                    tmp = tempfile.mkdtemp(dir=os.curdir)
+                    self.tmp.append(tmp)
+                    subprocess.call(ar_extract + [os.path.abspath(arg)], cwd=tmp)
+                    objs = []
+                    for root, dirs, files in os.walk(tmp):
+                        objs += [os.path.join(root, f) for f in files if os.path.splitext(f)[1] == conf.OBJ_SUFFIX]
+                    newlist += objs
+                else:
+                    newlist += [arg]
+            else:
+                newlist += [arg]
+        return newlist
+
+    def makelist(self):
+        '''Replaces object file names with a temporary list file, using a
+        list format depending on the EXPAND_LIBS_LIST_STYLE variable
+        '''
+        objs = [o for o in self if os.path.splitext(o)[1] == conf.OBJ_SUFFIX]
+        if not len(objs): return
+        fd, tmp = tempfile.mkstemp(suffix=".list",dir=os.curdir)
+        if conf.EXPAND_LIBS_LIST_STYLE == "linkerscript":
+            content = ["INPUT(%s)\n" % obj for obj in objs]
+            ref = tmp
+        elif conf.EXPAND_LIBS_LIST_STYLE == "list":
+            content = ["%s\n" % obj for obj in objs]
+            ref = "@" + tmp
+        else:
+            os.remove(tmp)
+            return
+        self.tmp.append(tmp)
+        f = os.fdopen(fd, "w")
+        f.writelines(content)
+        f.close()
+        idx = self.index(objs[0])
+        newlist = self[0:idx] + [ref] + [item for item in self[idx:] if item not in objs]
+        self[0:] = newlist
+
+def main():
+    parser = OptionParser()
+    parser.add_option("--extract", action="store_true", dest="extract",
+        help="when a library has no descriptor file, extract it first, when possible")
+    parser.add_option("--uselist", action="store_true", dest="uselist",
+        help="use a list file for objects when executing a command")
+
+    (options, args) = parser.parse_args()
+
+    with ExpandArgsMore(args) as args:
+        if options.extract:
+            args.extract()
+        if options.uselist:
+            args.makelist()
+
+        print >>sys.stderr, "Executing: " + " ".join(args)
+        for tmp in [f for f in args.tmp if os.path.isfile(f)]:
+            print >>sys.stderr, tmp + ":"
+            with open(tmp) as file:
+                print >>sys.stderr, "".join(["    " + l for l in file.readlines()])
+        sys.stderr.flush()
+        exit(subprocess.call(args))
+
+if __name__ == '__main__':
+    main()
new file mode 100644
--- /dev/null
+++ b/js/src/config/expandlibs_gen.py
@@ -0,0 +1,57 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is a build helper for libraries
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mike Hommey <mh@glandium.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+'''Given a list of object files and library names, prints a library
+descriptor to standard output'''
+
+import sys
+import os
+import expandlibs_config as conf
+from expandlibs import LibDescriptor
+
+def generate(args):
+    desc = LibDescriptor()
+    for arg in args:
+        if os.path.splitext(arg)[1] == conf.OBJ_SUFFIX:
+            desc['OBJS'].append(os.path.abspath(arg))
+        elif os.path.splitext(arg)[1] == conf.LIB_SUFFIX and \
+             (os.path.exists(arg) or os.path.exists(arg + conf.LIBS_DESC_SUFFIX)):
+            desc['LIBS'].append(os.path.abspath(arg))
+    return desc
+
+if __name__ == '__main__':
+    print generate(sys.argv[1:])
new file mode 100644
--- /dev/null
+++ b/js/src/config/pythonpath.py
@@ -0,0 +1,40 @@
+"""
+Run a python script, adding extra directories to the python path.
+"""
+
+import sys, os
+
+def usage():
+    print >>sys.stderr, "pythonpath.py -I directory script.py [args...]"
+    sys.exit(150)
+
+paths = []
+
+while True:
+    try:
+        arg = sys.argv[1]
+    except IndexError:
+        usage()
+
+    if arg == '-I':
+        del sys.argv[1]
+        try:
+            path = sys.argv.pop(1)
+        except IndexError:
+            usage()
+
+        paths.append(path)
+        continue
+
+    if arg.startswith('-I'):
+        path = sys.argv.pop(1)[2:]
+        paths.append(path)
+        continue
+
+    break
+
+sys.argv.pop(0)
+script = sys.argv[0]
+
+sys.path[0:0] = [os.path.dirname(script)] + paths
+execfile(script, {'__name__': '__main__', '__file__': script})
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -78,22 +78,16 @@ endif
 # ELOG prints out failed command when building silently (gmake -s).
 ifneq (,$(findstring s, $(filter-out --%, $(MAKEFLAGS))))
   ELOG := $(EXEC) sh $(BUILD_TOOLS)/print-failed-commands.sh
 else
   ELOG :=
 endif
 
 ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
-ifndef GNU_CC
-_LIBNAME_RELATIVE_PATHS=1
-endif
-endif
-
-ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
 _VPATH_SRCS = $(abspath $<)
 else
 _VPATH_SRCS = $<
 endif
 
 # Add $(DIST)/lib to VPATH so that -lfoo dependencies are followed
 VPATH += $(DIST)/lib
 ifdef LIBXUL_SDK
@@ -106,40 +100,19 @@ endif
 # EXPAND_LIBNAME_PATH - $(call EXPAND_LIBNAME_PATH,foo,dir)
 # expands to dir/foo.lib on platforms with import libs and
 # -Ldir -lfoo otherwise
 
 # EXPAND_MOZLIBNAME - $(call EXPAND_MOZLIBNAME,foo)
 # expands to $(DIST)/lib/foo.lib on platforms with import libs and
 # -lfoo otherwise
 
-ifdef _LIBNAME_RELATIVE_PATHS
 EXPAND_LIBNAME = $(foreach lib,$(1),$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 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
 ################################################################################
@@ -219,17 +192,17 @@ endif # XPCSHELL_TESTS
 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
-LIBS += $(XPCOM_GLUE_LDOPTS) $(NSPR_LIBS) -ljs_static
+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
 
@@ -244,22 +217,23 @@ 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
+_LIBRARY		:= $(LIB_PREFIX)$(STATIC_LIBRARY_NAME).$(LIB_SUFFIX)
+# Only build actual library if it is installed in DIST/lib or SDK
+ifeq (,$(SDK_LIBRARY)$(DIST_INSTALL)$(NO_EXPAND_LIBS))
+LIBRARY			:= $(_LIBRARY).$(LIBS_DESC_SUFFIX)
+else
+LIBRARY			:= $(_LIBRARY) $(_LIBRARY).$(LIBS_DESC_SUFFIX)
+endif
 endif # STATIC_LIBRARY_NAME
 endif # LIBRARY
 
 ifndef HOST_LIBRARY
 ifdef HOST_LIBRARY_NAME
 HOST_LIBRARY		:= $(LIB_PREFIX)$(HOST_LIBRARY_NAME).$(LIB_SUFFIX)
 endif
 endif
@@ -556,26 +530,16 @@ TAG_PROGRAM		= xargs etags -a
 ifneq ($(CPPSRCS)$(CMMSRCS),)
 CPP_PROG_LINK		= 1
 endif
 ifneq ($(HOST_CPPSRCS)$(HOST_CMMSRCS),)
 HOST_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) $(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
 EXTRA_DSO_LDOPTS += $(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
 endif # IS_COMPONENT
 
 #
@@ -850,37 +814,26 @@ ifdef MODULE_NAME
 endif
 endif # BUILD_STATIC_LIBS
 else # !IS_COMPONENT
 	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
 endif # IS_COMPONENT
 endif # EXPORT_LIBRARY
 endif # LIBRARY_NAME
 
-# Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
-LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
-HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
-DSO_LDOPTS_DEPS = $(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS))
-
-ifndef _LIBNAME_RELATIVE_PATHS
-
-LIBS_DEPS += $(filter -l%, $(LIBS))
-HOST_LIBS_DEPS += $(filter -l%, $(HOST_LIBS))
-DSO_LDOPTS_DEPS += $(filter -l%, $(EXTRA_DSO_LDOPTS))
+ifneq (,$(filter-out %.$(LIB_SUFFIX),$(SHARED_LIBRARY_LIBS)))
+$(error SHARED_LIBRARY_LIBS must contain .$(LIB_SUFFIX) files only)
+endif
 
-_LIBDIRS = $(patsubst -L%,%,$(filter -L%, $(LIBS) $(HOST_LIBS) $(EXTRA_DSO_LDOPTS)))
-ifneq (,$(_LIBDIRS))
-vpath $(LIB_PREFIX)%.$(LIB_SUFFIX) $(_LIBDIRS)
-ifdef IMPORT_LIB_SUFFIX
-vpath $(LIB_PREFIX)%.$(IMPORT_LIB_SUFFIX) $(_LIBDIRS)
-endif # IMPORT_LIB_SUFFIX
-vpath $(DLL_PREFIX)%$(DLL_SUFFIX) $(_LIBDIRS)
-endif # _LIBDIRS
-
-endif # _LIBNAME_RELATIVE_PATHS
+# Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
+DO_EXPAND_LIBS = $(foreach f,$(1),$(if $(filter %.$(LIB_SUFFIX),$(f)),$(if $(wildcard $(f).$(LIBS_DESC_SUFFIX)),$(f).$(LIBS_DESC_SUFFIX),$(if $(wildcard $(f)),$(f)))))
+LIBS_DEPS = $(call DO_EXPAND_LIBS,$(filter %.$(LIB_SUFFIX),$(LIBS)))
+SHARED_LIBRARY_LIBS_DEPS = $(call DO_EXPAND_LIBS,$(SHARED_LIBRARY_LIBS))
+HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX),$(HOST_LIBS))
+DSO_LDOPTS_DEPS = $(call DO_EXPAND_LIBS,$(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS)))
 
 # Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 
 ##############################################
 ifdef PARALLEL_DIRS
 libs:: $(PARALLEL_DIRS_libs)
 
@@ -892,25 +845,25 @@ ifdef EXPORT_LIBRARY
 ifeq ($(EXPORT_LIBRARY),1)
 ifdef IS_COMPONENT
 EXPORT_LIBRARY = $(DEPTH)/staticlib/components
 else
 EXPORT_LIBRARY = $(DEPTH)/staticlib
 endif
 else
 # If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there
-GARBAGE += $(foreach lib,$(LIBRARY) $(FAKE_LIBRARY),$(EXPORT_LIBRARY)/$(lib))
+GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib))
 endif
 endif # EXPORT_LIBRARY
 
 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
-	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(FAKE_LIBRARY) $(EXPORT_LIBRARY)
+	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(EXPORT_LIBRARY)
 endif # EXPORT_LIBRARY
 ifdef DIST_INSTALL
 ifdef IS_COMPONENT
 	$(error Shipping static component libs makes no sense.)
 else
 	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
 endif
 endif # DIST_INSTALL
@@ -1020,20 +973,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) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
+	$(EXPAND_LD) -NOLOGO -OUT:$@ $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
+	$(EXPAND_LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(PROGOBJS) $(RESFILE) $(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; \
@@ -1045,19 +998,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) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(call EXPAND_FAKELIBS,$(WRAP_MALLOC_LIB)) $(EXE_DEF_FILE)
+	$(EXPAND_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)
 else # ! CPP_PROG_LINK
-	$(CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS)) $(BIN_FLAGS) $(EXE_DEF_FILE)
+	$(EXPAND_CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(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
@@ -1098,31 +1051,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) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
+	$(EXPAND_LD) -nologo  -entry:mainACRTStartup -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(call EXPAND_FAKELIBS,$(LIBS) $(EXTRA_LIBS) $(OS_LIBS))
+	$(EXPAND_LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(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) $(call EXPAND_FAKELIBS,$(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB)) $(BIN_FLAGS)
+	$(EXPAND_CCC) $(WRAP_MALLOC_CFLAGS) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(WRAP_MALLOC_LIB) $(BIN_FLAGS)
 else
-	$(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)
+	$(EXPAND_CC) $(WRAP_MALLOC_CFLAGS) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS_DIR) $(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
@@ -1164,83 +1117,27 @@ ifeq ($(CPP_PROG_LINK),1)
 	$(QUANTIFY) $(CCC) -o $^.quantify $(CXXFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
 else
 	$(QUANTIFY) $(CC) -o $^.quantify $(CFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
 endif
 ifndef NO_DIST_INSTALL
 	$(INSTALL) $(IFLAGS2) $^.quantify $(FINAL_TARGET)
 endif
 
-#
-# This allows us to create static versions of the shared libraries
-# 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 # EXPAND_FAKELIBS
-endif # SHARED_LIBRARY_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)
+$(filter %.$(LIB_SUFFIX),$(LIBRARY)): $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
+	rm -f $(LIBRARY)
+	$(EXPAND_AR) $(AR_FLAGS) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS)
 	$(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_,$(HOST_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
+
+$(filter-out %.$(LIB_SUFFIX),$(LIBRARY)): $(filter %.$(LIB_SUFFIX),$(LIBRARY)) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
+	$(EXPAND_LIBS_GEN) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS) > $@
 
 ifeq (,$(filter-out WINNT WINCE, $(OS_ARCH)))
 $(IMPORT_LIBRARY): $(SHARED_LIBRARY)
 endif
 
 ifeq ($(OS_ARCH),OS2)
 $(DEF_FILE): $(OBJS) $(SHARED_LIBRARY_LIBS)
 	rm -f $@
@@ -1258,37 +1155,33 @@ ifeq ($(OS_ARCH),OS2)
 	$(RANLIB) $@
 endif # OS/2
 
 $(HOST_LIBRARY): $(HOST_OBJS) Makefile
 	rm -f $@
 	$(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
 	$(HOST_RANLIB) $@
 
-ifdef NO_LD_ARCHIVE_FLAGS
-SUB_SHLOBJS = $(SUB_LOBJS)
-endif
-
 ifdef HAVE_DTRACE
 ifndef XP_MACOSX
 ifdef DTRACE_PROBE_OBJ
 ifndef DTRACE_LIB_DEPENDENT
 $(DTRACE_PROBE_OBJ): $(OBJS)
 	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(OBJS)
 endif
 endif
 endif
 endif
 
 # On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files,
 # so instead of deleting .o files after repacking them into a dylib, we make
 # symlinks back to the originals. The symlinks are a no-op for stabs debugging,
 # so no need to conditionalize on OS version or debugging format.
 
-$(SHARED_LIBRARY): $(OBJS) $(LOBJS) $(DEF_FILE) $(RESFILE) $(SHARED_LIBRARY_LIBS) $(LIBRARY) $(EXTRA_DEPS) $(DSO_LDOPTS_DEPS) $(GLOBAL_DEPS)
+$(SHARED_LIBRARY): $(OBJS) $(LOBJS) $(DEF_FILE) $(RESFILE) $(SHARED_LIBRARY_LIBS_DEPS) $(LIBRARY) $(EXTRA_DEPS) $(DSO_LDOPTS_DEPS) $(GLOBAL_DEPS)
 ifndef INCREMENTAL_LINKER
 	rm -f $@
 endif
 ifeq ($(OS_ARCH),OpenVMS)
 	@if test ! -f $(VMS_SYMVEC_FILE); then \
 	  if test -f $(VMS_SYMVEC_FILE_MODULE); then \
 	    echo Creating specific component options file $(VMS_SYMVEC_FILE); \
 	    cp $(VMS_SYMVEC_FILE_MODULE) $(VMS_SYMVEC_FILE); \
@@ -1296,73 +1189,39 @@ ifeq ($(OS_ARCH),OpenVMS)
 	fi
 ifdef IS_COMPONENT
 	@if test ! -f $(VMS_SYMVEC_FILE); then \
 	  echo Creating generic component options file $(VMS_SYMVEC_FILE); \
 	  cp $(VMS_SYMVEC_FILE_COMP) $(VMS_SYMVEC_FILE); \
 	fi
 endif
 endif # OpenVMS
-ifdef NO_LD_ARCHIVE_FLAGS
-ifdef SHARED_LIBRARY_LIBS
-	@rm -f $(SUB_SHLOBJS)
-	@for lib in $(SHARED_LIBRARY_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
-ifeq ($(OS_ARCH),Darwin)
-	@echo Making symlinks to the original object files in the archive libraries $(SHARED_LIBRARY_LIBS)
-	@for lib in $(SHARED_LIBRARY_LIBS); do \
-		libdir=`echo $$lib|sed -e 's,/[^/]*\.a,,'`; \
-		ofiles=`$(AR_LIST) $${lib}`; \
-		for ofile in $$ofiles; do \
-			if [ -f $$libdir/$$ofile ]; then \
-				rm -f $$ofile; \
-				ln -s $$libdir/$$ofile $$ofile; \
-			fi; \
-		done; \
-	done
+ifdef DTRACE_LIB_DEPENDENT
+ifndef XP_MACOSX
+	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(shell $(EXPAND_LIBS) $(MOZILLA_PROBE_LIBS))
 endif
-endif # SHARED_LIBRARY_LIBS
-endif # NO_LD_ARCHIVE_FLAGS
-ifdef DTRACE_LIB_DEPENDENT
-	@rm -f $(PROBE_LOBJS)
-	@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) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
-	@rm -f $(PROBE_LOBJS)
+	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
 	@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) $(call EXPAND_FAKELIBS,$(OS_LIBS) $(EXTRA_LIBS)) $(DEF_FILE) $(SHLIB_LDENDFILE)
+	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(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; \
 	fi
 endif   # EMBED_MANIFEST_AT
 endif	# MSVC with manifest tool
 ifdef MOZ_PROFILE_GENERATE
 	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
 endif
 endif	# WINNT && !GCC
-ifneq ($(OS_ARCH),Darwin)
-	@rm -f $(SUB_SHLOBJS)
-endif # Darwin
 	@rm -f foodummyfilefoo $(DELETE_AFTER_LINK)
 	chmod +x $@
 ifdef ENABLE_STRIP
 	$(STRIP) $@
 endif
 ifdef MOZ_POST_DSO_LIB_COMMAND
 	$(MOZ_POST_DSO_LIB_COMMAND) $@
 endif
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -5440,16 +5440,48 @@ if test -n "$MIPSPRO_CXX" -o -n "$COMPAQ
     AC_DEFINE(CPP_THROW_NEW, [])
 else
     AC_DEFINE(CPP_THROW_NEW, [throw()])
 fi
 AC_LANG_C
 
 dnl ========================================================
 dnl =
+dnl = Check what kind of list files are supported by the
+dnl = linker
+dnl =
+dnl ========================================================
+
+AC_CACHE_CHECK(what kind of list files are supported by the linker,
+    EXPAND_LIBS_LIST_STYLE,
+    [echo "int main() {return 0;}" > conftest.${ac_ext}
+     if AC_TRY_COMMAND(${CC-cc} -o conftest.${OBJ_SUFFIX} -c $CFLAGS $CPPFLAGS conftest.${ac_ext} 1>&2) && test -s conftest.${OBJ_SUFFIX}; then
+         echo "INPUT(conftest.${OBJ_SUFFIX})" > conftest.list
+         if AC_TRY_COMMAND(${CC-cc} -o conftest${ac_exeext} $LDFLAGS conftest.list $LIBS 1>&2) && test -s conftest${ac_exeext}; then
+             EXPAND_LIBS_LIST_STYLE=linkerscript
+         else
+             echo "conftest.${OBJ_SUFFIX}" > conftest.list
+             if AC_TRY_COMMAND(${CC-cc} -o conftest${ac_exeext} $LDFLAGS @conftest.list $LIBS 1>&2) && test -s conftest${ac_exeext}; then
+                 EXPAND_LIBS_LIST_STYLE=list
+             else
+                 EXPAND_LIBS_LIST_STYLE=none
+             fi
+         fi
+     else
+         dnl We really don't expect to get here, but just in case
+         AC_ERROR([couldn't compile a simple C file])
+     fi
+     rm -rf conftest*])
+
+LIBS_DESC_SUFFIX=desc
+AC_SUBST(LIBS_DESC_SUFFIX)
+AC_SUBST(EXPAND_LIBS_LIST_STYLE)
+
+dnl ========================================================
+dnl =
 dnl = Build depencency options
 dnl =
 dnl ========================================================
 MOZ_ARG_HEADER(Build dependencies)
 
 dnl ========================================================
 dnl = Do not auto generate dependency info
 dnl ========================================================
@@ -5944,16 +5976,17 @@ mv confdefs.h.save confdefs.h
 MAKEFILES="
   Makefile
   shell/Makefile
   lirasm/Makefile
   jsapi-tests/Makefile
   tests/Makefile
   config/Makefile
   config/autoconf.mk
+  config/expandlibs_config.py
   config/mkdepend/Makefile
 "
 
 if test -n "$JS_NATIVE_EDITLINE"; then
    MAKEFILES="$MAKEFILES
 editline/Makefile
 "
 fi
--- a/other-licenses/bsdiff/Makefile.in
+++ b/other-licenses/bsdiff/Makefile.in
@@ -43,21 +43,17 @@ VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 # This program is output to dist/host/bin because it is only needed by the
 # build system and is not intended to be included in Mozilla distributions.
 HOST_PROGRAM = mbsdiff$(BIN_SUFFIX)
 HOST_CSRCS = bsdiff.c
 
-ifdef CROSS_COMPILE
 HOST_LIBS += $(DIST)/host/lib/$(LIB_PREFIX)hostbz2.$(LIB_SUFFIX)
-else
-HOST_LIBS += $(BZ2_LIBS)
-endif
 
 ifneq (,$(filter WINCE WINNT,$(HOST_OS_ARCH)))
 HOST_EXTRA_LIBS += $(call EXPAND_LIBNAME,Ws2_32)
 endif
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/mozapps/update/updater
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/components/url-classifier/src/Makefile.in
+++ b/toolkit/components/url-classifier/src/Makefile.in
@@ -2,17 +2,16 @@ 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,17 +44,16 @@ include $(DEPTH)/config/autoconf.mk
 include $(srcdir)/objs.mk
 
 EXTRA_DEPS += $(srcdir)/objs.mk
 
 DIRS            = standalone nomozalloc
 
 MODULE		= xpcom
 LIBRARY_NAME	= xpcomglue_s
-SUPPRESS_FAKELIB = 1
 DIST_INSTALL	= 1
 
 LOCAL_INCLUDES	= \
 		-I$(srcdir)/../build \
 		$(NULL)
 
 CSRCS		= \
 		$(XPCOM_GLUE_SRC_LCSRCS) \
--- a/xpcom/glue/nomozalloc/Makefile.in
+++ b/xpcom/glue/nomozalloc/Makefile.in
@@ -42,17 +42,16 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 include $(srcdir)/../objs.mk
 
 EXTRA_DEPS += $(srcdir)/../objs.mk
 
 MODULE		= xpcom
 LIBRARY_NAME	= xpcomglue_s_nomozalloc
-SUPPRESS_FAKELIB = 1
 DIST_INSTALL	= 1
 
 
 LOCAL_INCLUDES	= \
 		-I$(srcdir)/../../build \
 		$(NULL)
 
 CSRCS		= \
--- a/xpcom/glue/standalone/Makefile.in
+++ b/xpcom/glue/standalone/Makefile.in
@@ -42,17 +42,16 @@ 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))
 LINKSRC = nsGlueLinkingOSX.cpp