Bug 844288 - Dual link libxul.so and libxul-unit.so and replace enable-gtest by enable-test r=ted,glandium
authorBenoit Girard <b56girard@gmail.com>
Mon, 11 Mar 2013 14:47:40 -0400
changeset 146385 1c257409f5a696e9f07e8881569179d8685beb7d
parent 146384 a0e3d36a4acb9f566f5c614b82c6bf17c48a36a9
child 146386 e76b81594e4e95462f7c07249236638e08b776d9
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted, glandium
bugs844288
milestone24.0a1
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 844288 - Dual link libxul.so and libxul-unit.so and replace enable-gtest by enable-test r=ted,glandium - Remove enable GTest - Add a general target to create gtestxul - Update mach target - Run GTest from make check
config/config.mk
configure.in
gfx/2d/Makefile.in
gfx/2d/unittest/GTestMain.cpp
gfx/layers/Makefile.in
gfx/layers/TestTiledLayerBuffer.cpp
gfx/moz.build
gfx/tests/gtest/Makefile.in
gfx/tests/gtest/TestMoz2D.cpp
gfx/tests/gtest/TestTiledLayerBuffer.cpp
gfx/tests/gtest/moz.build
js/src/config/config.mk
js/src/configure.in
python/mozbuild/mozbuild/mach_commands.py
testing/gtest/Makefile.in
testing/gtest/mozilla/GTestRunner.cpp
testing/gtest/mozilla/GTestRunner.h
toolkit/library/Makefile.in
toolkit/library/winvccorlib/Makefile.in
toolkit/toolkit.mozbuild
toolkit/xre/nsAppRunner.cpp
xpcom/glue/standalone/nsXPCOMGlue.cpp
--- a/config/config.mk
+++ b/config/config.mk
@@ -742,18 +742,18 @@ ifdef MOZ_DEBUG
 JAVAC_FLAGS += -g
 endif
 
 CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py)
 
 # MDDEPDIR is the subdirectory where dependency files are stored
 MDDEPDIR := .deps
 
-EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(@F).pp --target $@)
-EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(@F).pp)
+EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(dir $@)/$(@F).pp --target $@)
+EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(dir $@)/$(@F).pp)
 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_ARGS = --uselist
 ifdef SYMBOL_ORDER
 EXPAND_MKSHLIB_ARGS += --symbol-order $(SYMBOL_ORDER)
 endif
--- a/configure.in
+++ b/configure.in
@@ -1325,18 +1325,18 @@ dnl ====================================
 dnl GNU specific defaults
 dnl ========================================================
 if test "$GNU_CC"; then
     # Per bug 719659 comment 2, some of the headers on ancient build machines
     # may require gnu89 inline semantics.  But otherwise, we use C99.
     CFLAGS="$CFLAGS -std=gnu99 -fgnu89-inline"
     # FIXME: Let us build with strict aliasing. bug 414641.
     CFLAGS="$CFLAGS -fno-strict-aliasing"
-    MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@'
-    MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@'
+    MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(notdir $@) -o $@'
+    MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(notdir $@) -o $@'
     DSO_LDOPTS='-shared'
     if test "$GCC_USE_GNU_LD"; then
         # Some tools like ASan use a runtime library that is only
         # linked against executables, so we must allow undefined
         # symbols for shared objects in some cases.
         if test -z "$MOZ_NO_WLZDEFS"; then
             # Don't allow undefined symbols in libraries
             DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
@@ -1436,18 +1436,18 @@ elif test "$SOLARIS_SUNPRO_CC"; then
     if test "$CPU_ARCH" = "sparc"; then
         # for Sun Studio on Solaris/SPARC
         DSO_PIC_CFLAGS='-xcode=pic32'
     else
         DSO_PIC_CFLAGS='-KPIC'
     fi
     _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
 else
-    MKSHLIB='$(LD) $(DSO_LDOPTS) -h $@ -o $@'
-    MKCSHLIB='$(LD) $(DSO_LDOPTS) -h $@ -o $@'
+    MKSHLIB='$(LD) $(DSO_LDOPTS) -h $(notdir $@) -o $@'
+    MKCSHLIB='$(LD) $(DSO_LDOPTS) -h $(notdir $@) -o $@'
 
     DSO_LDOPTS='-shared'
     if test "$GNU_LD"; then
         # Don't allow undefined symbols in libraries
         DSO_LDOPTS="$DSO_LDOPTS -z defs"
     fi
 
     DSO_CFLAGS=''
@@ -2296,18 +2296,18 @@ ia64*-hpux*)
     	DSO_LDOPTS='-shared'
     fi
     # This will fail on a.out systems prior to 1.5.1_ALPHA.
     MKSHLIB_FORCE_ALL='-Wl,--whole-archive'
     MKSHLIB_UNFORCE_ALL='-Wl,--no-whole-archive'
     if test "$LIBRUNPATH"; then
 	DSO_LDOPTS="-Wl,-R$LIBRUNPATH $DSO_LDOPTS"
     fi
-    MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,lib$(LIBRARY_NAME)$(DLL_SUFFIX) -o $@'
-    MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,lib$(LIBRARY_NAME)$(DLL_SUFFIX) -o $@'
+    MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(notdir $@) -o $@'
+    MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(notdir $@)) -o $@'
     ;;
 
 *-openbsd*)
     if test "$SO_VERSION"; then
         DLL_SUFFIX=".so.$SO_VERSION"
     else
         DLL_SUFFIX=".so.1.0"
     fi
@@ -2403,18 +2403,18 @@ ia64*-hpux*)
            _SAVE_LDFLAGS=$LDFLAGS
            LDFLAGS="-M /usr/lib/ld/map.noexstk $LDFLAGS"
            AC_TRY_LINK([#include <stdio.h>],
                        [printf("Hello World\n");],
                        ,
                        [LDFLAGS=$_SAVE_LDFLAGS])
        fi
        MOZ_OPTIMIZE_FLAGS="-xO4"
-       MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $@ -o $@'
-       MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $@ -o $@'
+       MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $(notdir $@) -o $@'
+       MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $(notdir $@) -o $@'
        MKSHLIB_FORCE_ALL='-z allextract'
        MKSHLIB_UNFORCE_ALL='-z defaultextract'
        DSO_LDOPTS='-G'
        AR_LIST="$AR t"
        AR_EXTRACT="$AR x"
        AR_DELETE="$AR d"
        AR='$(CXX) -xar'
        AR_FLAGS='-o $@'
@@ -6412,35 +6412,25 @@ AC_SUBST(MOZ_UPDATE_PACKAGING)
 dnl ========================================================
 dnl build the tests by default
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(tests,
 [  --disable-tests         Do not build test libraries & programs],
     ENABLE_TESTS=,
     ENABLE_TESTS=1 )
 
-# Currently GTest is linked into libxul. This means it must be off by default.
-# Follow up will be to generate libxul.so and libxul-test.so to let GTest
-# be compiled along with ENABLE_TESTS
-MOZ_ARG_ENABLE_BOOL(gtest,
-[  --enable-gtest
-                          Enable GTest libxul unit test.],
-    MOZ_ENABLE_GTEST=1,
-    MOZ_ENABLE_GTEST= )
-
-if test -n "$MOZ_ENABLE_GTEST"; then
-    if test "${OS_TARGET}" = "WINNT" -o "${OS_TARGET}" = "Darwin" -o "${OS_TARGET}" = "Linux" -o "${OS_TARGET}" = "Android"; then
-        MOZ_ENABLE_GTEST=1
-        GTEST_HAS_RTTI=0
-        AC_DEFINE(MOZ_ENABLE_GTEST)
-        AC_DEFINE_UNQUOTED(GTEST_HAS_RTTI, 0)
-        AC_SUBST(MOZ_ENABLE_GTEST)
-        AC_SUBST(GTEST_HAS_RTTI)
-    else
-        AC_MSG_ERROR([Cannot build with --enable-gtest on this platform.])
+if test -n "$ENABLE_TESTS"; then
+    MOZ_ENABLE_GTEST=1
+    GTEST_HAS_RTTI=0
+    AC_DEFINE(MOZ_ENABLE_GTEST)
+    AC_DEFINE_UNQUOTED(GTEST_HAS_RTTI, 0)
+    AC_SUBST(MOZ_ENABLE_GTEST)
+    AC_SUBST(GTEST_HAS_RTTI)
+    if test -n "$_WIN32_MSVC"; then
+          AC_DEFINE_UNQUOTED(_VARIADIC_MAX, 10)
     fi
     if test "${OS_TARGET}" = "Android"; then
         AC_DEFINE(GTEST_OS_LINUX_ANDROID)
         AC_DEFINE(GTEST_USE_OWN_TR1_TUPLE)
         AC_DEFINE_UNQUOTED(GTEST_HAS_CLONE, 0)
         AC_SUBST(GTEST_OS_LINUX_ANDROID)
         AC_SUBST(GTEST_USE_OWN_TR1_TUPLE)
         AC_SUBST(GTEST_HAS_CLONE)
--- a/gfx/2d/Makefile.in
+++ b/gfx/2d/Makefile.in
@@ -10,24 +10,16 @@ VPATH		=  $(srcdir) $(srcdir)/unittest
 
 include $(DEPTH)/config/autoconf.mk
 
 LIBRARY_NAME	= gfx2d
 MSVC_ENABLE_PGO := 1
 LIBXUL_LIBRARY	= 1
 EXPORT_LIBRARY	= 1
 
-GTEST_CPPSRCS = \
-        GTestMain.cpp \
-        TestBase.cpp \
-        TestPoint.cpp \
-        TestScaling.cpp \
-        TestCairo.cpp \
-        $(NULL)
-
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CMMSRCS = \
 	   QuartzSupport.mm \
 	   $(NULL)
 endif
 
 DEFINES += -DMOZ_GFX -DUSE_CAIRO -DGFX2D_INTERNAL
 
--- a/gfx/layers/Makefile.in
+++ b/gfx/layers/Makefile.in
@@ -25,20 +25,16 @@ MSVC_ENABLE_PGO := 1
 LIBXUL_LIBRARY = 1
 FORCE_STATIC_LIB = 1
 
 DEFINES += -DIMPL_THEBES
 ifdef MOZ_DEBUG
 DEFINES += -DD3D_DEBUG_INFO
 endif
 
-GTEST_CPPSRCS = \
-        TestTiledLayerBuffer.cpp \
-        $(NULL)
-
 ifdef MOZ_ENABLE_D3D10_LAYER
 DEFINES	+= -DMOZ_ENABLE_D3D10_LAYER
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 
--- a/gfx/moz.build
+++ b/gfx/moz.build
@@ -20,12 +20,15 @@ DIRS += [
     'ots/src',
     'thebes',
     'ipc',
 ]
 
 if CONFIG['MOZ_ENABLE_SKIA']:
     DIRS += ['skia']
 
+if CONFIG['ENABLE_TESTS']:
+    DIRS += ['tests/gtest']
+
 TEST_TOOL_DIRS += ['tests']
 
 MODULE = 'gfx'
 
new file mode 100644
--- /dev/null
+++ b/gfx/tests/gtest/Makefile.in
@@ -0,0 +1,43 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH          = @DEPTH@
+topsrcdir      = @top_srcdir@
+srcdir         = @srcdir@
+VPATH          = @srcdir@ $(srcdir)/$(DEPTH)/gfx/2d/unittest
+relativesrcdir = @relativesrcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+# Create a GTest library
+MODULE_NAME    = gfxtest
+LIBRARY_NAME   = gfxtest
+LIBXUL_LIBRARY = 1
+IS_COMPONENT   = 1
+EXPORT_LIBRARY = 1
+
+LOCAL_INCLUDES = \
+  -I$(topsrcdir)/gfx/layers \
+  -I$(topsrcdir)/gfx/2d \
+  -I$(topsrcdir)/gfx/2d/unittest \
+  $(NULL)
+
+GTEST_CPPSRCS = \
+  TestTiledLayerBuffer.cpp \
+  $(NULL)
+
+# Because of gkmedia on windows we wont find these
+# symbols in xul.dll.
+ifneq ($(MOZ_WIDGET_TOOLKIT),windows)
+GTEST_CPPSRCS += \
+  TestMoz2D.cpp \
+  TestBase.cpp \
+  TestPoint.cpp \
+  TestScaling.cpp \
+  $(NULL)
+endif
+
+include $(topsrcdir)/config/rules.mk
+
rename from gfx/2d/unittest/GTestMain.cpp
rename to gfx/tests/gtest/TestMoz2D.cpp
rename from gfx/layers/TestTiledLayerBuffer.cpp
rename to gfx/tests/gtest/TestTiledLayerBuffer.cpp
new file mode 100644
--- /dev/null
+++ b/gfx/tests/gtest/moz.build
@@ -0,0 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+MODULE = 'gfxtest'
+
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -742,18 +742,18 @@ ifdef MOZ_DEBUG
 JAVAC_FLAGS += -g
 endif
 
 CREATE_PRECOMPLETE_CMD = $(PYTHON) $(call core_abspath,$(topsrcdir)/config/createprecomplete.py)
 
 # MDDEPDIR is the subdirectory where dependency files are stored
 MDDEPDIR := .deps
 
-EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(@F).pp --target $@)
-EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(@F).pp)
+EXPAND_LIBS_EXEC = $(PYTHON) $(topsrcdir)/config/expandlibs_exec.py $(if $@,--depend $(MDDEPDIR)/$(dir $@)/$(@F).pp --target $@)
+EXPAND_LIBS_GEN = $(PYTHON) $(topsrcdir)/config/expandlibs_gen.py $(if $@,--depend $(MDDEPDIR)/$(dir $@)/$(@F).pp)
 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_ARGS = --uselist
 ifdef SYMBOL_ORDER
 EXPAND_MKSHLIB_ARGS += --symbol-order $(SYMBOL_ORDER)
 endif
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -1146,18 +1146,18 @@ fi
 
 dnl ========================================================
 dnl GNU specific defaults
 dnl ========================================================
 if test "$GNU_CC"; then
     # Per bug 719659 comment 2, some of the headers on ancient build machines
     # may require gnu89 inline semantics.  But otherwise, we use C99.
     CFLAGS="$CFLAGS -std=gnu99 -fgnu89-inline"
-    MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@'
-    MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@'
+    MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(notdir $@) -o $@'
+    MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$(notdir $@) -o $@'
     DSO_LDOPTS='-shared'
     if test "$GCC_USE_GNU_LD"; then
         # Some tools like ASan use a runtime library that is only
         # linked against executables, so we must allow undefined
         # symbols for shared objects in some cases.
         if test -z "$MOZ_NO_WLZDEFS"; then
             # Don't allow undefined symbols in libraries
             DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
@@ -1220,18 +1220,18 @@ elif test "$SOLARIS_SUNPRO_CC"; then
     if test "$CPU_ARCH" = "sparc"; then
         # for Sun Studio on Solaris/SPARC
         DSO_PIC_CFLAGS='-xcode=pic32'
     else
         DSO_PIC_CFLAGS='-KPIC'
     fi
     _DEFINES_CFLAGS='$(ACDEFINES) -D_JS_CONFDEFS_H_ -DMOZILLA_CLIENT'
 else
-    MKSHLIB='$(LD) $(DSO_LDOPTS) -h $@ -o $@'
-    MKCSHLIB='$(LD) $(DSO_LDOPTS) -h $@ -o $@'
+    MKSHLIB='$(LD) $(DSO_LDOPTS) -h $(notdir $@) -o $@'
+    MKCSHLIB='$(LD) $(DSO_LDOPTS) -h $(notdir $@) -o $@'
 
     DSO_LDOPTS='-shared'
     if test "$GNU_LD"; then
         # Don't allow undefined symbols in libraries
         DSO_LDOPTS="$DSO_LDOPTS -z defs"
     fi
 
     DSO_CFLAGS=''
@@ -1840,18 +1840,18 @@ ia64*-hpux*)
     	DSO_LDOPTS='-shared'
     fi
     # This will fail on a.out systems prior to 1.5.1_ALPHA.
     MKSHLIB_FORCE_ALL='-Wl,--whole-archive'
     MKSHLIB_UNFORCE_ALL='-Wl,--no-whole-archive'
     if test "$LIBRUNPATH"; then
 	DSO_LDOPTS="-Wl,-R$LIBRUNPATH $DSO_LDOPTS"
     fi
-    MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,lib$(LIBRARY_NAME)$(DLL_SUFFIX) -o $@'
-    MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,lib$(LIBRARY_NAME)$(DLL_SUFFIX) -o $@'
+    MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(notdir $@) -o $@'
+    MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$(notdir $@) -o $@'
     ;;
 
 *-openbsd*)
     DLL_SUFFIX=".so.1.0"
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-fPIC'
     DSO_LDOPTS='-shared -fPIC'
     if test "$LIBRUNPATH"; then
@@ -1944,18 +1944,18 @@ ia64*-hpux*)
            _SAVE_LDFLAGS=$LDFLAGS
            LDFLAGS="-M /usr/lib/ld/map.noexstk $LDFLAGS"
            AC_TRY_LINK([#include <stdio.h>],
                        [printf("Hello World\n");],
                        ,
                        [LDFLAGS=$_SAVE_LDFLAGS])
        fi
        MOZ_OPTIMIZE_FLAGS="-xO4"
-       MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $@ -o $@'
-       MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $@ -o $@'
+       MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $(notdir $@) -o $@'
+       MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $(notdir $@) -o $@'
        MKSHLIB_FORCE_ALL='-z allextract'
        MKSHLIB_UNFORCE_ALL='-z defaultextract'
        DSO_LDOPTS='-G'
        AR_LIST="$AR t"
        AR_EXTRACT="$AR x"
        AR_DELETE="$AR d"
        AR='$(CXX) -xar'
        AR_FLAGS='-o $@'
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -459,23 +459,29 @@ class GTestCommands(MachCommandBase):
              "optionally followed by a '-' and another ':'-separated pattern list (called the negative patterns).")
     @CommandArgument('--jobs', '-j', default='1', nargs='?', metavar='jobs', type=int,
         help='Run the tests in parallel using multiple processes.')
     @CommandArgument('--tbpl-parser', '-t', action='store_true',
         help='Output test results in a format that can be parsed by TBPL.')
     @CommandArgument('--shuffle', '-s', action='store_true',
         help='Randomize the execution order of tests.')
     def gtest(self, shuffle, jobs, gtest_filter, tbpl_parser):
+
+        # We lazy build gtest because it's slow to link
+        self._run_make(directory="testing/gtest", target='gtest', ensure_exit_code=True)
+
         app_path = self.get_binary_path('app')
 
         # Use GTest environment variable to control test execution
         # For details see:
         # https://code.google.com/p/googletest/wiki/AdvancedGuide#Running_Test_Programs:_Advanced_Options
         gtest_env = {b'GTEST_FILTER': gtest_filter}
 
+        gtest_env[b"MOZ_RUN_GTEST"] = b"True"
+
         if shuffle:
             gtest_env[b"GTEST_SHUFFLE"] = b"True"
 
         if tbpl_parser:
             gtest_env[b"MOZ_TBPL_PARSER"] = b"True"
 
         if jobs == 1:
             return self.run_process([app_path, "-unittest"],
--- a/testing/gtest/Makefile.in
+++ b/testing/gtest/Makefile.in
@@ -31,8 +31,20 @@ LOCAL_INCLUDES += \
   -I$(srcdir)/gtest \
   -I$(srcdir)/gtest/include \
   -I$(srcdir)/gmock \
   -I$(srcdir)/gmock/include \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
+ifeq (browser,$(MOZ_BUILD_APP))
+# Disable because of metro linking error:
+# LNK1181: cannot open input file 'runtimeobject.lib'
+ifndef MOZ_METRO
+check gtest::
+	$(MAKE) -C $(DEPTH)/toolkit/library gtestxul
+ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
+	$(MAKE) -C $(DEPTH)/browser/app repackage
+endif
+endif
+endif
+
--- a/testing/gtest/mozilla/GTestRunner.cpp
+++ b/testing/gtest/mozilla/GTestRunner.cpp
@@ -1,16 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * * This Source Code Form is subject to the terms of the Mozilla Public
  * * License, v. 2.0. If a copy of the MPL was not distributed with this
  * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "GTestRunner.h"
 #include "gtest/gtest.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/NullPtr.h"
+#include "prenv.h"
 
 using ::testing::EmptyTestEventListener;
 using ::testing::InitGoogleTest;
 using ::testing::Test;
 using ::testing::TestCase;
 using ::testing::TestEventListeners;
 using ::testing::TestInfo;
 using ::testing::TestPartResult;
@@ -60,23 +62,34 @@ static void ReplaceGTestLogger()
   // Code is based on: http://googletest.googlecode.com/svn/trunk/samples/sample9_unittest.cc
   UnitTest& unitTest = *UnitTest::GetInstance();
   TestEventListeners& listeners = unitTest.listeners();
   delete listeners.Release(listeners.default_result_printer());
 
   listeners.Append(new MozillaPrinter);
 }
 
-int RunGTest()
+int RunGTestFunc()
 {
   int c = 0;
   InitGoogleTest(&c, static_cast<char**>(nullptr));
 
   if (getenv("MOZ_TBPL_PARSER")) {
     ReplaceGTestLogger();
   }
 
-  setenv("XPCOM_DEBUG_BREAK", "stack-and-abort", false);
+  PR_SetEnv("XPCOM_DEBUG_BREAK=stack-and-abort");
 
   return RUN_ALL_TESTS();
 }
 
+// We use a static var 'RunGTest' defined in nsAppRunner.cpp.
+// RunGTest is initialized to NULL but if GTest (this file)
+// is linked in then RunGTest will be set here indicating
+// GTest is supported.
+class _InitRunGTest {
+public:
+  _InitRunGTest() {
+    RunGTest = RunGTestFunc;
+  }
+} InitRunGTest;
+
 }
--- a/testing/gtest/mozilla/GTestRunner.h
+++ b/testing/gtest/mozilla/GTestRunner.h
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * * This Source Code Form is subject to the terms of the Mozilla Public
  * * License, v. 2.0. If a copy of the MPL was not distributed with this
  * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 namespace mozilla {
 
-int RunGTest();
+extern int (*RunGTest)();
 
 }
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -295,20 +295,16 @@ STATIC_LIBS += skia_npapi
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
 COMPONENT_LIBS += widget_gonk
 endif
 
 STATIC_LIBS += thebes gl ycbcr
 
-ifdef MOZ_ENABLE_GTEST
-COMPONENT_LIBS += gtest xpcom_glue_gtest
-endif
-
 ifdef MOZ_ENABLE_PROFILER_SPS
 COMPONENT_LIBS += profiler
 endif
 
 ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
 COMPONENT_LIBS += widget_windows
 ifdef MOZ_METRO
 COMPONENT_LIBS += widget_winrt
@@ -647,16 +643,25 @@ endif
 ifeq (Linux,$(OS_ARCH))
 # Create a GDB Python auto-load file alongside the libxul shared library in
 # the build directory.
 PP_TARGETS += LIBXUL_AUTOLOAD
 LIBXUL_AUTOLOAD = libxul.so-gdb.py.in
 LIBXUL_AUTOLOAD_FLAGS := -Dtopsrcdir=$(abspath $(topsrcdir))
 endif
 
+ifdef MAKE_FRAMEWORK
+EFFECTIVE_LIB_PREFIX=
+else
+EFFECTIVE_LIB_PREFIX=$(DLL_PREFIX)
+endif
+
+GTEST_LIB = $(EFFECTIVE_LIB_PREFIX)gtest/$(EFFECTIVE_LIB_PREFIX)$(LIBRARY_NAME).$(DLL_SUFFIX)
+EXTRA_MDDEPEND_FILES = $(GTEST_LIB).pp
+
 include $(topsrcdir)/config/rules.mk
 
 export:: $(RDF_UTIL_SRC_CPPSRCS) $(INTL_UNICHARUTIL_UTIL_CPPSRCS)
 	$(INSTALL) $^ .
 
 # need widget/windows for resource.h (included from widget.rc)
 LOCAL_INCLUDES += \
   -I$(topsrcdir)/config \
@@ -684,12 +689,42 @@ DEFINES += -DENABLE_LAYOUTDEBUG
 endif
 endif
 
 ifeq (WINNT_1,$(OS_TARGET)_$(MOZ_PROFILE_USE))
 # Wrap linker to measure peak virtual memory usage.
 LD := $(PYTHON) $(topsrcdir)/build/link.py $(CURDIR)/linker-vsize $(LD)
 endif
 
+ifndef LINK_GTEST
 libs:: $(FINAL_TARGET)/dependentlibs.list
+else
+libs::
+endif
+
+.PHONY: gtestxul
+
+$(FINAL_TARGET)/dependentlibs.list.gtest: $(FINAL_TARGET)/dependentlibs.list
+	sed -e "s|$(SHARED_LIBRARY)|gtest/$(SHARED_LIBRARY)|" $< > $@
+
+# Remove this target when actually linking gtest to prevent redefining
+# the implicit rules.mk target
+ifndef LINK_GTEST
+
+gtestxul: $(GTEST_LIB)
+
+$(GTEST_LIB): $(FINAL_TARGET)/dependentlibs.list.gtest
+	$(MKDIR) -p $(EFFECTIVE_LIB_PREFIX)gtest
+	$(MAKE) libs SHARED_LIBRARY_NAME=gtest/$(EFFECTIVE_LIB_PREFIX)$(LIBRARY_NAME) FINAL_TARGET=$(FINAL_TARGET)/gtest SDK_LIBRARY= IMPORT_LIB_DEST=$(IMPORT_LIB_DEST)/gtest LINK_GTEST=true
+endif
+
+ifdef LINK_GTEST
+
+COMPONENT_LIBS += \
+  gtest \
+  gfxtest \
+  $(NULL)
+endif
 
 $(FINAL_TARGET)/dependentlibs.list: dependentlibs.py $(SHARED_LIBRARY) $(wildcard $(if $(wildcard $(FINAL_TARGET)/dependentlibs.list),$(addprefix $(FINAL_TARGET)/,$(shell cat $(FINAL_TARGET)/dependentlibs.list))))
 	$(PYTHON) $< $(SHARED_LIBRARY) -L $(FINAL_TARGET) $(if $(TOOLCHAIN_PREFIX),$(addprefix -p ,$(TOOLCHAIN_PREFIX))) > $@
+
+
--- a/toolkit/library/winvccorlib/Makefile.in
+++ b/toolkit/library/winvccorlib/Makefile.in
@@ -2,16 +2,22 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH     = @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
+# When we're linking GTest we recurse into this directory but don't need
+# to generate this library
+ifndef LINK_GTEST
+
 LIBRARY_NAME	= dummyvccorlib
 
 include $(DEPTH)/config/autoconf.mk
 
 FORCE_SHARED_LIB=1
 
+endif
+
 include $(topsrcdir)/config/rules.mk
 
--- a/toolkit/toolkit.mozbuild
+++ b/toolkit/toolkit.mozbuild
@@ -123,19 +123,18 @@ if CONFIG['MOZ_OMX_PLUGIN']:
 if not CONFIG['MOZ_NATIVE_PNG']:
     add_tier_dir('platform', 'media/libpng')
 
 add_tier_dir('platform', 'media/kiss_fft')
 
 if CONFIG['ENABLE_TESTS']:
     add_tier_dir('platform', 'testing/specialpowers')
 
-if CONFIG['MOZ_ENABLE_GTEST']:
+if CONFIG['ENABLE_TESTS']:
     add_tier_dir('platform', 'testing/gtest')
-    add_tier_dir('platform', 'xpcom/glue/tests/gtest')
 
 add_tier_dir('platform', [
     'uriloader',
     'caps',
     'parser',
     'gfx',
     'image',
     'dom',
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -191,17 +191,17 @@ using mozilla::scache::StartupCache;
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #include "nsICrashReporter.h"
 #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
 #include "nsIPrefService.h"
 #endif
 
 #include "base/command_line.h"
-#ifdef MOZ_ENABLE_GTEST
+#ifdef MOZ_ENABLE_TESTS
 #include "GTestRunner.h"
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #endif
 
 extern uint32_t gRestartMode;
@@ -237,16 +237,20 @@ static char **gQtOnlyArgv;
 #include <gtk/gtk.h>
 #ifdef MOZ_X11
 #include <gdk/gdkx.h>
 #endif /* MOZ_X11 */
 #include "nsGTKToolkit.h"
 #endif
 #include "BinaryPath.h"
 
+namespace mozilla {
+int (*RunGTest)() = 0;
+}
+
 using mozilla::dom::ContentParent;
 using mozilla::dom::ContentChild;
 
 // Save literal putenv string to environment variable.
 static void
 SaveToEnv(const char *putenv)
 {
   char *expr = strdup(putenv);
@@ -3172,24 +3176,25 @@ XREMain::XRE_mainInit(bool* aExitFlag)
       NS_ENSURE_TRUE(chromeReg, 1);
 
       chromeReg->CheckForNewChrome();
     }
     *aExitFlag = true;
     return 0;
   }
 
-  ar = CheckArg("unittest", true);
-  if (ar == ARG_FOUND) {
-#if MOZ_ENABLE_GTEST
-    int result = mozilla::RunGTest();
-#else
-    int result = 1;
-    printf("TEST-UNEXPECTED-FAIL | Not compiled with GTest enabled\n");
-#endif
+  if (PR_GetEnv("MOZ_RUN_GTEST")) {
+    int result;
+    // RunGTest will only be set if we're in xul-unit
+    if (mozilla::RunGTest) {
+      result = mozilla::RunGTest();
+    } else {
+      result = 1;
+      printf("TEST-UNEXPECTED-FAIL | gtest | Not compiled with enable-tests\n");
+    }
     *aExitFlag = true;
     return result;
   }
 
   return 0;
 }
 
 namespace mozilla {
--- a/xpcom/glue/standalone/nsXPCOMGlue.cpp
+++ b/xpcom/glue/standalone/nsXPCOMGlue.cpp
@@ -411,16 +411,20 @@ XPCOMGlueLoad(const char *xpcomFile)
         strcpy(xpcomDir + len, XPCOM_FILE_PATH_SEPARATOR
                                XPCOM_DEPENDENT_LIBS_LIST);
         cursor = xpcomDir + len + 1;
     } else {
         strcpy(xpcomDir, XPCOM_DEPENDENT_LIBS_LIST);
         cursor = xpcomDir;
     }
 
+    if (getenv("MOZ_RUN_GTEST")) {
+        strcat(xpcomDir, ".gtest");
+    }
+
     ScopedCloseFile flist;
     flist = TS_tfopen(xpcomDir, READ_TEXTMODE);
     if (!flist) {
         return nullptr;
     }
 
     *cursor = '\0';