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 id19231
push userkhuey@kylehuey.com
push dateWed, 23 Mar 2011 00:22:04 +0000
treeherdermozilla-central@57a0f8967cce [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs584474
milestone2.0b12pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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