bug 1239083 - use moz.build files to build ICU. r?glandium,waldo draft
authorTed Mielczarek <ted@mielczarek.org>
Wed, 30 Mar 2016 06:37:24 -0400
changeset 345797 35d34666dfc4d63d02f5663ca68cdab4f05ccf3b
parent 345796 41c2516bf65ca4594a68084a61d9a737680cfc9f
child 517269 70508e20b929b79cdad04ab1f93dcca19635b481
push id14175
push usertmielczarek@mozilla.com
push dateWed, 30 Mar 2016 12:05:03 +0000
reviewersglandium, waldo
bugs1239083, 926980
milestone48.0a1
bug 1239083 - use moz.build files to build ICU. r?glandium,waldo Also fixes bug 926980 - load ICU data from an archive file. Stop invoking ICU's autoconf build system. Instead, have hand-authored moz.build files under config/external/icu to build what we need. In addition, we'll commit a pre-built copy of the ICU data file (currently icudt56l.dat) under config/external/icu/data to avoid having to build ICU host tools to generate it. config/external/icu/data also contains some assembly files which can generate an object file containing the ICU data file contents so that the JS shell (or standalone JS builds) can be linked directly to the data without having to deal with the external data file. This requires yasm or GNU as. Various bits of packaging have been updated to account for the ICU data file. XPCOM initialization now sets the ICU data directory so ICU can locate its data file. The update-icu.sh script has been modified to read the list of C/C++ source files out of the ICU Makefiles and update `sources.mozbuild` files under config/external/icu, as well as build a local copy of ICU using its autoconf build system to generate the ICU data file to be committed in-tree. MozReview-Commit-ID: 8Pfkzqt6S1W
b2g/installer/Makefile.in
b2g/installer/package-manifest.in
browser/installer/Makefile.in
browser/installer/package-manifest.in
build/autoconf/codeset.m4
build/autoconf/icu.m4
config/external/icu/Makefile.in
config/external/icu/common/moz.build
config/external/icu/common/sources.mozbuild
config/external/icu/data/icudata.s
config/external/icu/data/icudata_gas.S
config/external/icu/data/moz.build
config/external/icu/defs.mozbuild
config/external/icu/i18n/moz.build
config/external/icu/i18n/sources.mozbuild
config/external/icu/moz.build
config/external/icu/stubdata/moz.build
intl/icu_sources_data.py
intl/update-icu.sh
js/src/gdb/moz.build
js/src/jsapi-tests/moz.build
js/src/moz.build
js/src/old-configure.in
js/src/shell/moz.build
old-configure.in
xpcom/build/XPCOMInit.cpp
xpcom/build/moz.build
--- a/b2g/installer/Makefile.in
+++ b/b2g/installer/Makefile.in
@@ -98,16 +98,17 @@ ifneq (,$(filter rtsp,$(NECKO_PROTOCOLS)
 DEFINES += -DMOZ_RTSP
 endif
 
 DEFINES += -DMOZ_ICU_VERSION=$(MOZ_ICU_VERSION)
 ifdef MOZ_SYSTEM_ICU
 DEFINES += -DMOZ_SYSTEM_ICU
 endif
 DEFINES += -DMOZ_ICU_DBG_SUFFIX=$(MOZ_ICU_DBG_SUFFIX)
+DEFINES += -DICU_DATA_FILE=$(ICU_DATA_FILE)
 
 ifneq (,$(filter gtk%,$(MOZ_WIDGET_TOOLKIT)))
 DEFINES += -DMOZ_GTK=1
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk3)
 DEFINES += -DMOZ_GTK3=1
 endif
 endif
 
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -67,16 +67,17 @@
 @BINPATH@/@MSVC_CXX_RUNTIME_DLL@
 #endif
 #if MOZ_PACKAGE_WIN_UCRT_DLLS
 @BINPATH@/api-ms-win-*.dll
 @BINPATH@/ucrtbase.dll
 #endif
 #endif
 #ifndef MOZ_SYSTEM_ICU
+@RESPATH@/@ICU_DATA_FILE@
 #endif
 #ifdef MOZ_SHARED_MOZGLUE
 @BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
 #endif
 #ifdef ANDROID
 @RESPATH@/AndroidManifest.xml
 @RESPATH@/resources.arsc
 @RESPATH@/classes.dex
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -117,16 +117,17 @@ endif
 endif
 DEFINES += -DLPROJ_ROOT=$(LPROJ_ROOT)
 
 DEFINES += -DMOZ_ICU_VERSION=$(MOZ_ICU_VERSION)
 ifdef MOZ_SYSTEM_ICU
 DEFINES += -DMOZ_SYSTEM_ICU
 endif
 DEFINES += -DMOZ_ICU_DBG_SUFFIX=$(MOZ_ICU_DBG_SUFFIX)
+DEFINES += -DICU_DATA_FILE=$(ICU_DATA_FILE)
 ifdef CLANG_CXX
 DEFINES += -DCLANG_CXX
 endif
 ifdef CLANG_CL
 DEFINES += -DCLANG_CL
 endif
 ifeq (x86,$(CPU_ARCH))
 ifdef _MSC_VER
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -93,16 +93,17 @@
 @BINPATH@/@MSVC_CXX_RUNTIME_DLL@
 #endif
 #if MOZ_PACKAGE_WIN_UCRT_DLLS
 @BINPATH@/api-ms-win-*.dll
 @BINPATH@/ucrtbase.dll
 #endif
 #endif
 #ifndef MOZ_SYSTEM_ICU
+@RESPATH@/@ICU_DATA_FILE@
 #endif
 #ifdef MOZ_GTK3
 @BINPATH@/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
 @BINPATH@/gtk2/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
 #endif
 
 [browser]
 ; [Base Browser Files]
--- a/build/autoconf/codeset.m4
+++ b/build/autoconf/codeset.m4
@@ -16,9 +16,10 @@ AC_DEFUN([AM_LANGINFO_CODESET],
       am_cv_langinfo_codeset=yes,
       am_cv_langinfo_codeset=no)
     ])
   if test $am_cv_langinfo_codeset = yes; then
     AC_DEFINE(HAVE_LANGINFO_CODESET, 1,
       [Define if you have <langinfo.h> and nl_langinfo(CODESET).])
       HAVE_LANGINFO_CODESET=1
   fi
+  AC_SUBST(HAVE_LANGINFO_CODESET)
 ])
--- a/build/autoconf/icu.m4
+++ b/build/autoconf/icu.m4
@@ -71,217 +71,40 @@ if test -n "$USE_ICU"; then
     fi
 
     version=`sed -n 's/^[[:space:]]*#[[:space:]]*define[[:space:]][[:space:]]*U_ICU_VERSION_MAJOR_NUM[[:space:]][[:space:]]*\([0-9][0-9]*\)[[:space:]]*$/\1/p' "$icudir/common/unicode/uvernum.h"`
     if test x"$version" = x; then
        AC_MSG_ERROR([cannot determine icu version number from uvernum.h header file $lineno])
     fi
     MOZ_ICU_VERSION="$version"
 
-    AC_SUBST(MOZ_ICU_VERSION)
+    #TODO: the l is actually endian-dependent, but we don't currently
+    # have an endianness check in configure. If someone adds one,
+    # we could make this set as 'l' or 'b' for little or big, respectively.
+    ICU_DATA_FILE="icudt${version}l.dat"
 
-    if test -z "$MOZ_SYSTEM_ICU"; then
-        case "$OS_TARGET" in
-            WINNT)
-                ICU_LIB_NAMES="sicuin sicuuc sicudt"
-                MOZ_ICU_DBG_SUFFIX=
-                if test -n "$MOZ_DEBUG" -a -z "$MOZ_NO_DEBUG_RTL"; then
-                    MOZ_ICU_DBG_SUFFIX=d
-                fi
-                ;;
-            Darwin|Linux|DragonFly|FreeBSD|NetBSD|OpenBSD|GNU/kFreeBSD|SunOS|Android)
-                ICU_LIB_NAMES="icui18n icuuc icudata"
-                ;;
-            *)
-                AC_MSG_ERROR([ECMAScript Internationalization API is not yet supported on this platform])
-        esac
+    dnl We won't build ICU data as a separate file when building
+    dnl JS standalone so that embedders don't have to deal with it.
+    if test -z "$JS_STANDALONE" -a -z "$MOZ_SYSTEM_ICU"; then
+        MOZ_ICU_DATA_ARCHIVE=1
+        AC_DEFINE(MOZ_ICU_DATA_ARCHIVE)
+    else
+        MOZ_ICU_DATA_ARCHIVE=
     fi
 fi
 
-AC_SUBST(MOZ_ICU_DBG_SUFFIX)
+AC_SUBST(MOZ_ICU_VERSION)
 AC_SUBST(ENABLE_INTL_API)
 AC_SUBST(USE_ICU)
-AC_SUBST_LIST(ICU_LIB_NAMES)
+AC_SUBST(ICU_DATA_FILE)
+AC_SUBST(MOZ_ICU_DATA_ARCHIVE)
 
 if test -n "$USE_ICU" -a -z "$MOZ_SYSTEM_ICU"; then
+    if test -z "$YASM" -a -z "$GNU_AS"; then
+      AC_MSG_ERROR([Building ICU requires either yasm or a GNU assembler. If you do not have either of those available for this platform you must use --without-intl-api])
+    fi
     dnl We build ICU as a static library.
     AC_DEFINE(U_STATIC_IMPLEMENTATION)
     dnl Source files that use ICU should have control over which parts of the ICU
     dnl namespace they want to use.
     AC_DEFINE(U_USING_ICU_NAMESPACE,0)
 fi
-
-
 ])
-
-AC_DEFUN([MOZ_SUBCONFIGURE_ICU], [
-
-if test "$MOZ_BUILD_APP" != js -o -n "$JS_STANDALONE"; then
-
-    if test -n "$USE_ICU" -a -z "$MOZ_SYSTEM_ICU"; then
-        # Set ICU compile options
-        ICU_CPPFLAGS=""
-        # don't use icu namespace automatically in client code
-        ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_USING_ICU_NAMESPACE=0"
-        # don't include obsolete header files
-        ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1"
-        # remove chunks of the library that we don't need (yet)
-        ICU_CPPFLAGS="$ICU_CPPFLAGS -DUCONFIG_NO_LEGACY_CONVERSION"
-        ICU_CPPFLAGS="$ICU_CPPFLAGS -DUCONFIG_NO_TRANSLITERATION"
-        ICU_CPPFLAGS="$ICU_CPPFLAGS -DUCONFIG_NO_REGULAR_EXPRESSIONS"
-        ICU_CPPFLAGS="$ICU_CPPFLAGS -DUCONFIG_NO_BREAK_ITERATION"
-        # we don't need to pass data to and from legacy char* APIs
-        ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_CHARSET_IS_UTF8"
-        # make sure to not accidentally pick up system-icu headers
-        ICU_CPPFLAGS="$ICU_CPPFLAGS -I$icudir/common -I$icudir/i18n"
-
-        ICU_CROSS_BUILD_OPT=""
-
-        if test "$CROSS_COMPILE"; then
-            # Remove _DEPEND_CFLAGS from HOST_FLAGS to avoid configure error
-            HOST_ICU_CFLAGS="$HOST_CFLAGS"
-            HOST_ICU_CXXFLAGS="$HOST_CXXFLAGS"
-
-            HOST_ICU_CFLAGS=`echo $HOST_ICU_CFLAGS | sed "s|$_DEPEND_CFLAGS||g"`
-            HOST_ICU_CXXFLAGS=`echo $HOST_ICU_CFXXLAGS | sed "s|$_DEPEND_CFLAGS||g"`
-
-            # ICU requires RTTI
-            if test "$GNU_CC"; then
-                HOST_ICU_CXXFLAGS=`echo $HOST_ICU_CXXFLAGS | sed 's|-fno-rtti|-frtti|g'`
-            elif test "$_MSC_VER"; then
-                HOST_ICU_CXXFLAGS=`echo $HOST_ICU_CXXFLAGS | sed 's|-GR-|-GR|g'`
-            fi
-
-            HOST_ICU_BUILD_OPTS=""
-            if test -n "$MOZ_DEBUG"; then
-                HOST_ICU_BUILD_OPTS="$HOST_ICU_BUILD_OPTS --enable-debug"
-            fi
-
-            abs_srcdir=`(cd $srcdir; pwd)`
-            mkdir -p $_objdir/intl/icu/host
-            (export AR="$HOST_AR"
-             export RANLIB="$HOST_RANLIB"
-             export CC="$HOST_CC"
-             export CXX="$HOST_CXX"
-             export CPP="$HOST_CPP"
-             export LD="$HOST_LD"
-             export CFLAGS="$HOST_ICU_CFLAGS $HOST_OPTIMIZE_FLAGS"
-             export CPPFLAGS="$ICU_CPPFLAGS"
-             export CXXFLAGS="$HOST_ICU_CXXFLAGS $HOST_OPTIMIZE_FLAGS"
-             export LDFLAGS="$HOST_LDFLAGS"
-             ac_configure_args="$HOST_ICU_BUILD_OPTS"
-             ac_configure_args="$ac_configure_args --enable-static --disable-shared --enable-extras=no --enable-icuio=no --enable-layout=no --enable-tests=no --enable-samples=no"
-             AC_OUTPUT_SUBDIRS_NOW(intl/icu/source:intl/icu/host)
-            ) || exit 1
-            # generate config/icucross.mk
-            $GMAKE -C $_objdir/intl/icu/host/ config/icucross.mk
-
-            # --with-cross-build requires absolute path
-            ICU_HOST_PATH=`cd $_objdir/intl/icu/host && pwd`
-            ICU_CROSS_BUILD_OPT="--with-cross-build=$ICU_HOST_PATH --disable-tools"
-            ICU_TARGET_OPT="--build=$build --host=$target"
-        else
-            # CROSS_COMPILE isn't set build and target are i386 and x86-64.
-            # So we must set target for --build and --host.
-            ICU_TARGET_OPT="--build=$target --host=$target"
-        fi
-
-        # To reduce library size, use static linking
-        ICU_LINK_OPTS="--enable-static --disable-shared"
-
-        # Force the ICU static libraries to be position independent code
-        ICU_CFLAGS="$DSO_PIC_CFLAGS $CFLAGS"
-        ICU_CXXFLAGS="$DSO_PIC_CFLAGS $CXXFLAGS"
-
-        ICU_BUILD_OPTS=""
-        if test -n "$MOZ_DEBUG" -o "MOZ_DEBUG_SYMBOLS"; then
-            ICU_CFLAGS="$ICU_CFLAGS $MOZ_DEBUG_FLAGS"
-            ICU_CXXFLAGS="$ICU_CXXFLAGS $MOZ_DEBUG_FLAGS"
-            if test -n "$CROSS_COMPILE" -a "$OS_TARGET" = "Darwin" \
-                    -a "$HOST_OS_ARCH" != "Darwin"
-            then
-                # Bug 951758: Cross-OSX builds with non-Darwin hosts have issues
-                # with -g and friends (like -gdwarf and -gfull) because they try
-                # to run dsymutil
-                changequote(,)
-                ICU_CFLAGS=`echo $ICU_CFLAGS | sed 's|-g[^ \t]*||g'`
-                ICU_CXXFLAGS=`echo $ICU_CXXFLAGS | sed 's|-g[^ \t]*||g'`
-                changequote([,])
-            fi
-
-            ICU_LDFLAGS="$MOZ_DEBUG_LDFLAGS"
-            if test -z "$MOZ_DEBUG"; then
-                # To generate debug symbols, it requires MOZ_DEBUG_FLAGS.
-                # But, not debug build.
-                ICU_CFLAGS="$ICU_CFLAGS -UDEBUG -DNDEBUG"
-                ICU_CXXFLAGS="$ICU_CXXFLAGS -UDEBUG -DNDEBUG"
-            elif test -z "$MOZ_NO_DEBUG_RTL"; then
-                ICU_BUILD_OPTS="$ICU_BUILD_OPTS --enable-debug"
-            fi
-        fi
-        if test -z "$MOZ_OPTIMIZE"; then
-            ICU_BUILD_OPTS="$ICU_BUILD_OPTS --disable-release"
-        else
-            ICU_CFLAGS="$ICU_CFLAGS $MOZ_OPTIMIZE_FLAGS"
-            ICU_CXXFLAGS="$ICU_CXXFLAGS $MOZ_OPTIMIZE_FLAGS"
-        fi
-
-        if test "$am_cv_langinfo_codeset" = "no"; then
-            # ex. Android
-            ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_HAVE_NL_LANGINFO_CODESET=0"
-        fi
-
-        # ICU requires RTTI
-        if test "$GNU_CC"; then
-            ICU_CXXFLAGS=`echo $ICU_CXXFLAGS | sed 's|-fno-rtti|-frtti|g'`
-        else
-            if test "$_MSC_VER"; then
-                ICU_CXXFLAGS=`echo $ICU_CXXFLAGS | sed 's|-GR-|-GR|g'`
-            fi
-
-            # Add RTL flags for MSVCRT.DLL
-            if test -n "$MOZ_DEBUG" -a -z "$MOZ_NO_DEBUG_RTL"; then
-                ICU_CFLAGS="$ICU_CFLAGS -MDd"
-                ICU_CXXFLAGS="$ICU_CXXFLAGS -MDd"
-            else
-                ICU_CFLAGS="$ICU_CFLAGS -MD"
-                ICU_CXXFLAGS="$ICU_CXXFLAGS -MD"
-            fi
-
-            # add disable optimize flag for workaround for bug 899948
-            if test -z "$MOZ_OPTIMIZE"; then
-                ICU_CFLAGS="$ICU_CFLAGS -Od"
-                ICU_CXXFLAGS="$ICU_CXXFLAGS -Od"
-            fi
-        fi
-
-        if test -n "$gonkdir"; then
-            ICU_CXXFLAGS="-I$gonkdir/abi/cpp/include $ICU_CXXFLAGS"
-        elif test "$OS_TARGET" = Android -a "$MOZ_ANDROID_CXX_STL" = mozstlport; then
-            ICU_CXXFLAGS="-I$_topsrcdir/build/gabi++/include $ICU_CXXFLAGS"
-        fi
-
-        ICU_CXXFLAGS="$ICU_CXXFLAGS -DU_STATIC_IMPLEMENTATION"
-        ICU_CFLAGS="$ICU_CFLAGS -DU_STATIC_IMPLEMENTATION"
-        if test "$GNU_CC"; then
-          ICU_CFLAGS="$ICU_CFLAGS -fvisibility=hidden"
-          ICU_CXXFLAGS="$ICU_CXXFLAGS -fvisibility=hidden"
-        fi
-
-        (export AR="$AR"
-         export RANLIB="$RANLIB"
-         export CC="$CC"
-         export CXX="$CXX"
-         export LD="$LD"
-         export ARFLAGS="$ARFLAGS"
-         export CPPFLAGS="$ICU_CPPFLAGS $CPPFLAGS"
-         export CFLAGS="$ICU_CFLAGS"
-         export CXXFLAGS="$ICU_CXXFLAGS"
-         export LDFLAGS="$ICU_LDFLAGS $LDFLAGS"
-         ac_configure_args="$ICU_BUILD_OPTS $ICU_CROSS_BUILD_OPT $ICU_LINK_OPTS $ICU_TARGET_OPT"
-         ac_configure_args="$ac_configure_args --disable-extras --disable-icuio --disable-layout --disable-tests --disable-samples --disable-strict"
-         AC_OUTPUT_SUBDIRS(intl/icu/source:intl/icu/target)
-        ) || exit 1
-    fi
-
-fi
-
-])
deleted file mode 100644
--- a/config/external/icu/Makefile.in
+++ /dev/null
@@ -1,46 +0,0 @@
-# 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/.
-
-# Ensure that this happens before including rules.mk
-ifdef USE_ICU
-  ifndef MOZ_SYSTEM_ICU
-    ifdef MOZ_ICU_DATA_ARCHIVE
-      ICU_FILES += $(DEPTH)/intl/icu/target/data/out/$(ICU_DATA_FILE)
-    endif
-    ifdef ICU_FILES
-      ICU_DEST := $(DIST)/bin
-      INSTALL_TARGETS += ICU
-      $(ICU_FILES): buildicu
-     ICU_TARGET := target
-    endif
-  endif # !MOZ_SYSTEM_ICU
-endif # USE_ICU
-
-include $(topsrcdir)/config/rules.mk
-
-ifdef USE_ICU
-ifndef MOZ_SYSTEM_ICU
-target:: buildicu
-$(STATIC_LIBS): buildicu
-
-# - Force ICU to use the standard suffix for object files because expandlibs
-#   will discard all files with a non-standard suffix (bug 857450).
-# - Options for genrb: -k strict parsing; -R omit collation tailoring rules.
-buildicu::
-# ICU's build system is full of races, so force non-parallel build.
-# Msys screws up GENRBOPTS when it contains spaces, so all genrb flags need
-# to be stuck together. See https://bugzilla.mozilla.org/show_bug.cgi?id=1034594#c34
-ifdef CROSS_COMPILE
-	+ASAN_OPTIONS=detect_leaks=0 $(MAKE) -j1 -C $(DEPTH)/intl/icu/host STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-kRC'
-endif
-	+ASAN_OPTIONS=detect_leaks=0 $(MAKE) -j1 -C $(DEPTH)/intl/icu/target STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-kR'
-
-distclean clean::
-ifdef CROSS_COMPILE
-	+$(MAKE) -C $(DEPTH)/intl/icu/host $@ STATIC_O=$(OBJ_SUFFIX)
-endif
-	+$(MAKE) -C $(DEPTH)/intl/icu/target $@ STATIC_O=$(OBJ_SUFFIX)
-
-endif
-endif
new file mode 100644
--- /dev/null
+++ b/config/external/icu/common/moz.build
@@ -0,0 +1,27 @@
+# -*- 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/.
+
+Library('icuuc')
+FINAL_LIBRARY = 'icu'
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
+    OS_LIBS += [
+        'gabi++',
+    ]
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android' and CONFIG['MOZ_ANDROID_CXX_STL'] == 'mozstlport':
+    USE_LIBS += [
+        'gabi++'
+    ]
+
+DEFINES['U_COMMON_IMPLEMENTATION'] = True
+# This normally gets defined in the SDK but our WINVER is too low.
+#FIXME: should probably stop including mozilla-config.h
+DEFINES['LOCALE_SNAME'] = 0x5c
+
+LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
+
+include('../defs.mozbuild')
+include('sources.mozbuild')
new file mode 100644
--- /dev/null
+++ b/config/external/icu/common/sources.mozbuild
@@ -0,0 +1,183 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# THIS FILE IS GENERATED BY /intl/icusources.py DO NOT EDIT
+SOURCES += [
+   '/intl/icu/source/common/appendable.cpp',
+   '/intl/icu/source/common/bmpset.cpp',
+   '/intl/icu/source/common/brkeng.cpp',
+   '/intl/icu/source/common/brkiter.cpp',
+   '/intl/icu/source/common/bytestream.cpp',
+   '/intl/icu/source/common/bytestrie.cpp',
+   '/intl/icu/source/common/bytestriebuilder.cpp',
+   '/intl/icu/source/common/bytestrieiterator.cpp',
+   '/intl/icu/source/common/caniter.cpp',
+   '/intl/icu/source/common/chariter.cpp',
+   '/intl/icu/source/common/charstr.cpp',
+   '/intl/icu/source/common/cmemory.c',
+   '/intl/icu/source/common/cstring.c',
+   '/intl/icu/source/common/cwchar.c',
+   '/intl/icu/source/common/dictbe.cpp',
+   '/intl/icu/source/common/dictionarydata.cpp',
+   '/intl/icu/source/common/dtintrv.cpp',
+   '/intl/icu/source/common/errorcode.cpp',
+   '/intl/icu/source/common/filteredbrk.cpp',
+   '/intl/icu/source/common/filterednormalizer2.cpp',
+   '/intl/icu/source/common/icudataver.c',
+   '/intl/icu/source/common/icuplug.cpp',
+   '/intl/icu/source/common/listformatter.cpp',
+   '/intl/icu/source/common/loadednormalizer2impl.cpp',
+   '/intl/icu/source/common/locavailable.cpp',
+   '/intl/icu/source/common/locbased.cpp',
+   '/intl/icu/source/common/locdispnames.cpp',
+   '/intl/icu/source/common/locid.cpp',
+   '/intl/icu/source/common/loclikely.cpp',
+   '/intl/icu/source/common/locmap.c',
+   '/intl/icu/source/common/locresdata.cpp',
+   '/intl/icu/source/common/locutil.cpp',
+   '/intl/icu/source/common/messagepattern.cpp',
+   '/intl/icu/source/common/normalizer2.cpp',
+   '/intl/icu/source/common/normalizer2impl.cpp',
+   '/intl/icu/source/common/normlzr.cpp',
+   '/intl/icu/source/common/parsepos.cpp',
+   '/intl/icu/source/common/patternprops.cpp',
+   '/intl/icu/source/common/pluralmap.cpp',
+   '/intl/icu/source/common/propname.cpp',
+   '/intl/icu/source/common/propsvec.c',
+   '/intl/icu/source/common/punycode.cpp',
+   '/intl/icu/source/common/putil.cpp',
+   '/intl/icu/source/common/rbbi.cpp',
+   '/intl/icu/source/common/rbbidata.cpp',
+   '/intl/icu/source/common/rbbinode.cpp',
+   '/intl/icu/source/common/rbbirb.cpp',
+   '/intl/icu/source/common/rbbiscan.cpp',
+   '/intl/icu/source/common/rbbisetb.cpp',
+   '/intl/icu/source/common/rbbistbl.cpp',
+   '/intl/icu/source/common/rbbitblb.cpp',
+   '/intl/icu/source/common/resbund.cpp',
+   '/intl/icu/source/common/resbund_cnv.cpp',
+   '/intl/icu/source/common/ruleiter.cpp',
+   '/intl/icu/source/common/schriter.cpp',
+   '/intl/icu/source/common/serv.cpp',
+   '/intl/icu/source/common/servlk.cpp',
+   '/intl/icu/source/common/servlkf.cpp',
+   '/intl/icu/source/common/servls.cpp',
+   '/intl/icu/source/common/servnotf.cpp',
+   '/intl/icu/source/common/servrbf.cpp',
+   '/intl/icu/source/common/servslkf.cpp',
+   '/intl/icu/source/common/sharedobject.cpp',
+   '/intl/icu/source/common/simplepatternformatter.cpp',
+   '/intl/icu/source/common/stringpiece.cpp',
+   '/intl/icu/source/common/stringtriebuilder.cpp',
+   '/intl/icu/source/common/uarrsort.c',
+   '/intl/icu/source/common/ubidi.c',
+   '/intl/icu/source/common/ubidi_props.c',
+   '/intl/icu/source/common/ubidiln.c',
+   '/intl/icu/source/common/ubidiwrt.c',
+   '/intl/icu/source/common/ubrk.cpp',
+   '/intl/icu/source/common/ucase.cpp',
+   '/intl/icu/source/common/ucasemap.cpp',
+   '/intl/icu/source/common/ucasemap_titlecase_brkiter.cpp',
+   '/intl/icu/source/common/ucat.c',
+   '/intl/icu/source/common/uchar.c',
+   '/intl/icu/source/common/ucharstrie.cpp',
+   '/intl/icu/source/common/ucharstriebuilder.cpp',
+   '/intl/icu/source/common/ucharstrieiterator.cpp',
+   '/intl/icu/source/common/uchriter.cpp',
+   '/intl/icu/source/common/ucln_cmn.cpp',
+   '/intl/icu/source/common/ucmndata.c',
+   '/intl/icu/source/common/ucnv.c',
+   '/intl/icu/source/common/ucnv2022.cpp',
+   '/intl/icu/source/common/ucnv_bld.cpp',
+   '/intl/icu/source/common/ucnv_cb.c',
+   '/intl/icu/source/common/ucnv_cnv.c',
+   '/intl/icu/source/common/ucnv_ct.c',
+   '/intl/icu/source/common/ucnv_err.c',
+   '/intl/icu/source/common/ucnv_ext.cpp',
+   '/intl/icu/source/common/ucnv_io.cpp',
+   '/intl/icu/source/common/ucnv_lmb.c',
+   '/intl/icu/source/common/ucnv_set.c',
+   '/intl/icu/source/common/ucnv_u16.c',
+   '/intl/icu/source/common/ucnv_u32.c',
+   '/intl/icu/source/common/ucnv_u7.c',
+   '/intl/icu/source/common/ucnv_u8.c',
+   '/intl/icu/source/common/ucnvbocu.cpp',
+   '/intl/icu/source/common/ucnvdisp.c',
+   '/intl/icu/source/common/ucnvhz.c',
+   '/intl/icu/source/common/ucnvisci.c',
+   '/intl/icu/source/common/ucnvlat1.c',
+   '/intl/icu/source/common/ucnvmbcs.cpp',
+   '/intl/icu/source/common/ucnvscsu.c',
+   '/intl/icu/source/common/ucnvsel.cpp',
+   '/intl/icu/source/common/ucol_swp.cpp',
+   '/intl/icu/source/common/udata.cpp',
+   '/intl/icu/source/common/udatamem.c',
+   '/intl/icu/source/common/udataswp.c',
+   '/intl/icu/source/common/uenum.c',
+   '/intl/icu/source/common/uhash.c',
+   '/intl/icu/source/common/uhash_us.cpp',
+   '/intl/icu/source/common/uidna.cpp',
+   '/intl/icu/source/common/uinit.cpp',
+   '/intl/icu/source/common/uinvchar.c',
+   '/intl/icu/source/common/uiter.cpp',
+   '/intl/icu/source/common/ulist.c',
+   '/intl/icu/source/common/ulistformatter.cpp',
+   '/intl/icu/source/common/uloc.cpp',
+   '/intl/icu/source/common/uloc_keytype.cpp',
+   '/intl/icu/source/common/uloc_tag.c',
+   '/intl/icu/source/common/umapfile.c',
+   '/intl/icu/source/common/umath.c',
+   '/intl/icu/source/common/umutex.cpp',
+   '/intl/icu/source/common/unames.cpp',
+   '/intl/icu/source/common/unifiedcache.cpp',
+   '/intl/icu/source/common/unifilt.cpp',
+   '/intl/icu/source/common/unifunct.cpp',
+   '/intl/icu/source/common/uniset.cpp',
+   '/intl/icu/source/common/uniset_closure.cpp',
+   '/intl/icu/source/common/uniset_props.cpp',
+   '/intl/icu/source/common/unisetspan.cpp',
+   '/intl/icu/source/common/unistr.cpp',
+   '/intl/icu/source/common/unistr_case.cpp',
+   '/intl/icu/source/common/unistr_case_locale.cpp',
+   '/intl/icu/source/common/unistr_cnv.cpp',
+   '/intl/icu/source/common/unistr_props.cpp',
+   '/intl/icu/source/common/unistr_titlecase_brkiter.cpp',
+   '/intl/icu/source/common/unorm.cpp',
+   '/intl/icu/source/common/unormcmp.cpp',
+   '/intl/icu/source/common/uobject.cpp',
+   '/intl/icu/source/common/uprops.cpp',
+   '/intl/icu/source/common/ures_cnv.c',
+   '/intl/icu/source/common/uresbund.cpp',
+   '/intl/icu/source/common/uresdata.c',
+   '/intl/icu/source/common/usc_impl.c',
+   '/intl/icu/source/common/uscript.c',
+   '/intl/icu/source/common/uscript_props.cpp',
+   '/intl/icu/source/common/uset.cpp',
+   '/intl/icu/source/common/uset_props.cpp',
+   '/intl/icu/source/common/usetiter.cpp',
+   '/intl/icu/source/common/ushape.cpp',
+   '/intl/icu/source/common/usprep.cpp',
+   '/intl/icu/source/common/ustack.cpp',
+   '/intl/icu/source/common/ustr_cnv.cpp',
+   '/intl/icu/source/common/ustr_titlecase_brkiter.cpp',
+   '/intl/icu/source/common/ustr_wcs.cpp',
+   '/intl/icu/source/common/ustrcase.cpp',
+   '/intl/icu/source/common/ustrcase_locale.cpp',
+   '/intl/icu/source/common/ustrenum.cpp',
+   '/intl/icu/source/common/ustrfmt.c',
+   '/intl/icu/source/common/ustring.cpp',
+   '/intl/icu/source/common/ustrtrns.cpp',
+   '/intl/icu/source/common/utext.cpp',
+   '/intl/icu/source/common/utf_impl.c',
+   '/intl/icu/source/common/util.cpp',
+   '/intl/icu/source/common/util_props.cpp',
+   '/intl/icu/source/common/utrace.c',
+   '/intl/icu/source/common/utrie.cpp',
+   '/intl/icu/source/common/utrie2.cpp',
+   '/intl/icu/source/common/utrie2_builder.cpp',
+   '/intl/icu/source/common/uts46.cpp',
+   '/intl/icu/source/common/utypes.c',
+   '/intl/icu/source/common/uvector.cpp',
+   '/intl/icu/source/common/uvectr32.cpp',
+   '/intl/icu/source/common/uvectr64.cpp',
+   '/intl/icu/source/common/wintz.c',
+]
new file mode 100644
--- /dev/null
+++ b/config/external/icu/data/icudata.s
@@ -0,0 +1,31 @@
+;; 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/.
+
+%ifdef PREFIX
+    %define DATA_SYMBOL _ %+ ICU_DATA_SYMBOL
+%else
+    %define DATA_SYMBOL ICU_DATA_SYMBOL
+%endif
+
+%ifidn __OUTPUT_FORMAT__,elf
+    %define FORMAT_ELF 1
+%elifidn __OUTPUT_FORMAT__,elf32
+    %define FORMAT_ELF 1
+%elifidn __OUTPUT_FORMAT__,elf64
+    %define FORMAT_ELF 1
+%else
+    %define FORMAT_ELF 0
+%endif
+
+%if FORMAT_ELF
+    global DATA_SYMBOL:data hidden
+    ; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default.
+    [SECTION .note.GNU-stack noalloc noexec nowrite progbits]
+%else
+    global DATA_SYMBOL
+%endif
+
+SECTION .rodata align=16
+DATA_SYMBOL:
+        incbin ICU_DATA_FILE
new file mode 100644
--- /dev/null
+++ b/config/external/icu/data/icudata_gas.S
@@ -0,0 +1,12 @@
+# 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/.
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",@progbits
+#endif
+.global ICU_DATA_SYMBOL
+.data
+.balign 16
+ICU_DATA_SYMBOL:
+        .incbin ICU_DATA_FILE
new file mode 100644
--- /dev/null
+++ b/config/external/icu/data/moz.build
@@ -0,0 +1,31 @@
+# -*- 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/.
+
+if CONFIG['MOZ_ICU_DATA_ARCHIVE']:
+    # Copy the pre-built ICU data file to dist/bin.
+    FINAL_TARGET_FILES += [CONFIG['ICU_DATA_FILE']]
+
+# Build a library containing the ICU data for use in the JS shell, so that
+# JSAPI consumers don't have to deal with setting ICU's data path.
+Library('icudata')
+
+if CONFIG['OS_ARCH'] == 'WINNT':
+    if CONFIG['CPU_ARCH'] == 'x86':
+        ASFLAGS += ['-DPREFIX']
+elif CONFIG['OS_ARCH'] == 'Darwin':
+    ASFLAGS += ['-DPREFIX']
+
+ASFLAGS += [
+    '-DICU_DATA_FILE="%s"' % CONFIG['ICU_DATA_FILE'],
+    '-DICU_DATA_SYMBOL=icudt%s_dat' % CONFIG['MOZ_ICU_VERSION'],
+]
+LOCAL_INCLUDES += ['.']
+
+if CONFIG['HAVE_YASM']:
+    USE_YASM = True
+    SOURCES += ['icudata.s']
+elif CONFIG['GNU_AS']:
+    SOURCES += ['icudata_gas.S']
new file mode 100644
--- /dev/null
+++ b/config/external/icu/defs.mozbuild
@@ -0,0 +1,35 @@
+# -*- 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/.
+
+DEFINES.update(
+    # Don't use icu namespace automatically in client code.
+    U_USING_ICU_NAMESPACE = 0,
+    # Don't include obsolete header files.
+    U_NO_DEFAULT_INCLUDE_UTF_HEADERS = 1,
+    # Remove chunks of the library that we don't need (yet).
+    UCONFIG_NO_LEGACY_CONVERSION = True,
+    UCONFIG_NO_TRANSLITERATION = True,
+    UCONFIG_NO_REGULAR_EXPRESSIONS = True,
+    UCONFIG_NO_BREAK_ITERATION = True,
+    # We don't need to pass data to and from legacy char* APIs.
+    U_CHARSET_IS_UTF8 = True,
+)
+if not CONFIG['HAVE_LANGINFO_CODESET']:
+    DEFINES['U_HAVE_NL_LANGINFO_CODESET'] = 0
+
+# ICU requires RTTI
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-frtti']
+elif CONFIG['OS_TARGET'] == 'WINNT':
+    CXXFLAGS += ['-GR']
+
+DISABLE_STL_WRAPPING = True
+ALLOW_COMPILER_WARNINGS = True
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android' and CONFIG['MOZ_ANDROID_CXX_STL'] == 'mozstlport':
+    LOCAL_INCLUDES += ['/build/gabi++/include']
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
+    LOCAL_INCLUDES += ['%' + CONFIG['ANDROID_SOURCE'] + '/abi/cpp/include']
new file mode 100644
--- /dev/null
+++ b/config/external/icu/i18n/moz.build
@@ -0,0 +1,15 @@
+# -*- 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/.
+
+Library('icui18n')
+FINAL_LIBRARY = 'icu'
+
+DEFINES['U_I18N_IMPLEMENTATION'] = True
+
+LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
+
+include('../defs.mozbuild')
+include('sources.mozbuild')
new file mode 100644
--- /dev/null
+++ b/config/external/icu/i18n/sources.mozbuild
@@ -0,0 +1,203 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# THIS FILE IS GENERATED BY /intl/icusources.py DO NOT EDIT
+SOURCES += [
+   '/intl/icu/source/i18n/affixpatternparser.cpp',
+   '/intl/icu/source/i18n/alphaindex.cpp',
+   '/intl/icu/source/i18n/anytrans.cpp',
+   '/intl/icu/source/i18n/astro.cpp',
+   '/intl/icu/source/i18n/basictz.cpp',
+   '/intl/icu/source/i18n/bocsu.cpp',
+   '/intl/icu/source/i18n/brktrans.cpp',
+   '/intl/icu/source/i18n/buddhcal.cpp',
+   '/intl/icu/source/i18n/calendar.cpp',
+   '/intl/icu/source/i18n/casetrn.cpp',
+   '/intl/icu/source/i18n/cecal.cpp',
+   '/intl/icu/source/i18n/chnsecal.cpp',
+   '/intl/icu/source/i18n/choicfmt.cpp',
+   '/intl/icu/source/i18n/coleitr.cpp',
+   '/intl/icu/source/i18n/coll.cpp',
+   '/intl/icu/source/i18n/collation.cpp',
+   '/intl/icu/source/i18n/collationbuilder.cpp',
+   '/intl/icu/source/i18n/collationcompare.cpp',
+   '/intl/icu/source/i18n/collationdata.cpp',
+   '/intl/icu/source/i18n/collationdatabuilder.cpp',
+   '/intl/icu/source/i18n/collationdatareader.cpp',
+   '/intl/icu/source/i18n/collationdatawriter.cpp',
+   '/intl/icu/source/i18n/collationfastlatin.cpp',
+   '/intl/icu/source/i18n/collationfastlatinbuilder.cpp',
+   '/intl/icu/source/i18n/collationfcd.cpp',
+   '/intl/icu/source/i18n/collationiterator.cpp',
+   '/intl/icu/source/i18n/collationkeys.cpp',
+   '/intl/icu/source/i18n/collationroot.cpp',
+   '/intl/icu/source/i18n/collationrootelements.cpp',
+   '/intl/icu/source/i18n/collationruleparser.cpp',
+   '/intl/icu/source/i18n/collationsets.cpp',
+   '/intl/icu/source/i18n/collationsettings.cpp',
+   '/intl/icu/source/i18n/collationtailoring.cpp',
+   '/intl/icu/source/i18n/collationweights.cpp',
+   '/intl/icu/source/i18n/compactdecimalformat.cpp',
+   '/intl/icu/source/i18n/coptccal.cpp',
+   '/intl/icu/source/i18n/cpdtrans.cpp',
+   '/intl/icu/source/i18n/csdetect.cpp',
+   '/intl/icu/source/i18n/csmatch.cpp',
+   '/intl/icu/source/i18n/csr2022.cpp',
+   '/intl/icu/source/i18n/csrecog.cpp',
+   '/intl/icu/source/i18n/csrmbcs.cpp',
+   '/intl/icu/source/i18n/csrsbcs.cpp',
+   '/intl/icu/source/i18n/csrucode.cpp',
+   '/intl/icu/source/i18n/csrutf8.cpp',
+   '/intl/icu/source/i18n/curramt.cpp',
+   '/intl/icu/source/i18n/currfmt.cpp',
+   '/intl/icu/source/i18n/currpinf.cpp',
+   '/intl/icu/source/i18n/currunit.cpp',
+   '/intl/icu/source/i18n/dangical.cpp',
+   '/intl/icu/source/i18n/datefmt.cpp',
+   '/intl/icu/source/i18n/dcfmtsym.cpp',
+   '/intl/icu/source/i18n/decContext.c',
+   '/intl/icu/source/i18n/decfmtst.cpp',
+   '/intl/icu/source/i18n/decimalformatpattern.cpp',
+   '/intl/icu/source/i18n/decimfmt.cpp',
+   '/intl/icu/source/i18n/decimfmtimpl.cpp',
+   '/intl/icu/source/i18n/decNumber.c',
+   '/intl/icu/source/i18n/digitaffix.cpp',
+   '/intl/icu/source/i18n/digitaffixesandpadding.cpp',
+   '/intl/icu/source/i18n/digitformatter.cpp',
+   '/intl/icu/source/i18n/digitgrouping.cpp',
+   '/intl/icu/source/i18n/digitinterval.cpp',
+   '/intl/icu/source/i18n/digitlst.cpp',
+   '/intl/icu/source/i18n/dtfmtsym.cpp',
+   '/intl/icu/source/i18n/dtitvfmt.cpp',
+   '/intl/icu/source/i18n/dtitvinf.cpp',
+   '/intl/icu/source/i18n/dtptngen.cpp',
+   '/intl/icu/source/i18n/dtrule.cpp',
+   '/intl/icu/source/i18n/esctrn.cpp',
+   '/intl/icu/source/i18n/ethpccal.cpp',
+   '/intl/icu/source/i18n/fmtable.cpp',
+   '/intl/icu/source/i18n/fmtable_cnv.cpp',
+   '/intl/icu/source/i18n/format.cpp',
+   '/intl/icu/source/i18n/fphdlimp.cpp',
+   '/intl/icu/source/i18n/fpositer.cpp',
+   '/intl/icu/source/i18n/funcrepl.cpp',
+   '/intl/icu/source/i18n/gender.cpp',
+   '/intl/icu/source/i18n/gregocal.cpp',
+   '/intl/icu/source/i18n/gregoimp.cpp',
+   '/intl/icu/source/i18n/hebrwcal.cpp',
+   '/intl/icu/source/i18n/identifier_info.cpp',
+   '/intl/icu/source/i18n/indiancal.cpp',
+   '/intl/icu/source/i18n/inputext.cpp',
+   '/intl/icu/source/i18n/islamcal.cpp',
+   '/intl/icu/source/i18n/japancal.cpp',
+   '/intl/icu/source/i18n/locdspnm.cpp',
+   '/intl/icu/source/i18n/measfmt.cpp',
+   '/intl/icu/source/i18n/measunit.cpp',
+   '/intl/icu/source/i18n/measure.cpp',
+   '/intl/icu/source/i18n/msgfmt.cpp',
+   '/intl/icu/source/i18n/name2uni.cpp',
+   '/intl/icu/source/i18n/nfrs.cpp',
+   '/intl/icu/source/i18n/nfrule.cpp',
+   '/intl/icu/source/i18n/nfsubs.cpp',
+   '/intl/icu/source/i18n/nortrans.cpp',
+   '/intl/icu/source/i18n/nultrans.cpp',
+   '/intl/icu/source/i18n/numfmt.cpp',
+   '/intl/icu/source/i18n/numsys.cpp',
+   '/intl/icu/source/i18n/olsontz.cpp',
+   '/intl/icu/source/i18n/persncal.cpp',
+   '/intl/icu/source/i18n/pluralaffix.cpp',
+   '/intl/icu/source/i18n/plurfmt.cpp',
+   '/intl/icu/source/i18n/plurrule.cpp',
+   '/intl/icu/source/i18n/precision.cpp',
+   '/intl/icu/source/i18n/quant.cpp',
+   '/intl/icu/source/i18n/quantityformatter.cpp',
+   '/intl/icu/source/i18n/rbnf.cpp',
+   '/intl/icu/source/i18n/rbt.cpp',
+   '/intl/icu/source/i18n/rbt_data.cpp',
+   '/intl/icu/source/i18n/rbt_pars.cpp',
+   '/intl/icu/source/i18n/rbt_rule.cpp',
+   '/intl/icu/source/i18n/rbt_set.cpp',
+   '/intl/icu/source/i18n/rbtz.cpp',
+   '/intl/icu/source/i18n/regexcmp.cpp',
+   '/intl/icu/source/i18n/regeximp.cpp',
+   '/intl/icu/source/i18n/regexst.cpp',
+   '/intl/icu/source/i18n/regextxt.cpp',
+   '/intl/icu/source/i18n/region.cpp',
+   '/intl/icu/source/i18n/reldatefmt.cpp',
+   '/intl/icu/source/i18n/reldtfmt.cpp',
+   '/intl/icu/source/i18n/rematch.cpp',
+   '/intl/icu/source/i18n/remtrans.cpp',
+   '/intl/icu/source/i18n/repattrn.cpp',
+   '/intl/icu/source/i18n/rulebasedcollator.cpp',
+   '/intl/icu/source/i18n/scientificnumberformatter.cpp',
+   '/intl/icu/source/i18n/scriptset.cpp',
+   '/intl/icu/source/i18n/search.cpp',
+   '/intl/icu/source/i18n/selfmt.cpp',
+   '/intl/icu/source/i18n/sharedbreakiterator.cpp',
+   '/intl/icu/source/i18n/simpletz.cpp',
+   '/intl/icu/source/i18n/smallintformatter.cpp',
+   '/intl/icu/source/i18n/smpdtfmt.cpp',
+   '/intl/icu/source/i18n/smpdtfst.cpp',
+   '/intl/icu/source/i18n/sortkey.cpp',
+   '/intl/icu/source/i18n/strmatch.cpp',
+   '/intl/icu/source/i18n/strrepl.cpp',
+   '/intl/icu/source/i18n/stsearch.cpp',
+   '/intl/icu/source/i18n/taiwncal.cpp',
+   '/intl/icu/source/i18n/timezone.cpp',
+   '/intl/icu/source/i18n/titletrn.cpp',
+   '/intl/icu/source/i18n/tmunit.cpp',
+   '/intl/icu/source/i18n/tmutamt.cpp',
+   '/intl/icu/source/i18n/tmutfmt.cpp',
+   '/intl/icu/source/i18n/tolowtrn.cpp',
+   '/intl/icu/source/i18n/toupptrn.cpp',
+   '/intl/icu/source/i18n/translit.cpp',
+   '/intl/icu/source/i18n/transreg.cpp',
+   '/intl/icu/source/i18n/tridpars.cpp',
+   '/intl/icu/source/i18n/tzfmt.cpp',
+   '/intl/icu/source/i18n/tzgnames.cpp',
+   '/intl/icu/source/i18n/tznames.cpp',
+   '/intl/icu/source/i18n/tznames_impl.cpp',
+   '/intl/icu/source/i18n/tzrule.cpp',
+   '/intl/icu/source/i18n/tztrans.cpp',
+   '/intl/icu/source/i18n/ucal.cpp',
+   '/intl/icu/source/i18n/ucln_in.cpp',
+   '/intl/icu/source/i18n/ucol.cpp',
+   '/intl/icu/source/i18n/ucol_res.cpp',
+   '/intl/icu/source/i18n/ucol_sit.cpp',
+   '/intl/icu/source/i18n/ucoleitr.cpp',
+   '/intl/icu/source/i18n/ucsdet.cpp',
+   '/intl/icu/source/i18n/ucurr.cpp',
+   '/intl/icu/source/i18n/udat.cpp',
+   '/intl/icu/source/i18n/udateintervalformat.cpp',
+   '/intl/icu/source/i18n/udatpg.cpp',
+   '/intl/icu/source/i18n/ufieldpositer.cpp',
+   '/intl/icu/source/i18n/uitercollationiterator.cpp',
+   '/intl/icu/source/i18n/ulocdata.c',
+   '/intl/icu/source/i18n/umsg.cpp',
+   '/intl/icu/source/i18n/unesctrn.cpp',
+   '/intl/icu/source/i18n/uni2name.cpp',
+   '/intl/icu/source/i18n/unum.cpp',
+   '/intl/icu/source/i18n/unumsys.cpp',
+   '/intl/icu/source/i18n/upluralrules.cpp',
+   '/intl/icu/source/i18n/uregex.cpp',
+   '/intl/icu/source/i18n/uregexc.cpp',
+   '/intl/icu/source/i18n/uregion.cpp',
+   '/intl/icu/source/i18n/usearch.cpp',
+   '/intl/icu/source/i18n/uspoof.cpp',
+   '/intl/icu/source/i18n/uspoof_build.cpp',
+   '/intl/icu/source/i18n/uspoof_conf.cpp',
+   '/intl/icu/source/i18n/uspoof_impl.cpp',
+   '/intl/icu/source/i18n/uspoof_wsconf.cpp',
+   '/intl/icu/source/i18n/utf16collationiterator.cpp',
+   '/intl/icu/source/i18n/utf8collationiterator.cpp',
+   '/intl/icu/source/i18n/utmscale.c',
+   '/intl/icu/source/i18n/utrans.cpp',
+   '/intl/icu/source/i18n/valueformatter.cpp',
+   '/intl/icu/source/i18n/visibledigits.cpp',
+   '/intl/icu/source/i18n/vtzone.cpp',
+   '/intl/icu/source/i18n/vzone.cpp',
+   '/intl/icu/source/i18n/windtfmt.cpp',
+   '/intl/icu/source/i18n/winnmfmt.cpp',
+   '/intl/icu/source/i18n/wintzimpl.cpp',
+   '/intl/icu/source/i18n/zonemeta.cpp',
+   '/intl/icu/source/i18n/zrule.cpp',
+   '/intl/icu/source/i18n/ztrans.cpp',
+]
--- a/config/external/icu/moz.build
+++ b/config/external/icu/moz.build
@@ -4,23 +4,18 @@
 # 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/.
 
 Library('icu')
 
 if CONFIG['MOZ_SYSTEM_ICU']:
     OS_LIBS += CONFIG['MOZ_ICU_LIBS']
 else:
-    # Order needs to be preserved
-    for l in CONFIG['ICU_LIB_NAMES']:
-        USE_LIBS += ['static:/intl/icu/target/lib/%s%s' % (
-            l,
-            CONFIG['MOZ_ICU_DBG_SUFFIX']
-        )]
-
-    if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
-        OS_LIBS += [
-            'gabi++',
-        ]
-    if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android' and CONFIG['MOZ_ANDROID_CXX_STL'] == 'mozstlport':
-        USE_LIBS += [
-            'gabi++'
-        ]
+    DIRS += [
+        'common',
+        'data',
+        'i18n',
+    ]
+    if CONFIG['MOZ_ICU_DATA_ARCHIVE']:
+        DIRS += ['stubdata']
+        USE_LIBS += ['icustubdata']
+    else:
+        USE_LIBS += ['icudata']
new file mode 100644
--- /dev/null
+++ b/config/external/icu/stubdata/moz.build
@@ -0,0 +1,15 @@
+# -*- 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/.
+
+# This builds the ICU stubdata library, since we are shipping ICU
+# data in a separate data file. ICU needs a data symbol to link against
+# even if you're loading its data from a file.
+
+Library('icustubdata')
+
+LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
+
+SOURCES += ['/intl/icu/source/stubdata/stubdata.c']
new file mode 100644
--- /dev/null
+++ b/intl/icu_sources_data.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+#
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+#
+# Generate SOURCES in sources.mozbuild files from ICU's Makefile.in
+# files, and also build a standalone copy of ICU using its build
+# system to generate a new copy of the in-tree ICU data file.
+#
+# This script expects to be run from `update-icu.sh` after the in-tree
+# copy of ICU has been updated.
+
+from __future__ import print_function
+
+import glob
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+
+
+def find_source_file(dir, filename):
+    base = os.path.splitext(filename)[0]
+    for ext in ('.cpp', '.c'):
+        f = os.path.join(dir, base + ext)
+        if os.path.isfile(f):
+            return f
+    raise Exception("Couldn't find source file for: %s" % filename)
+
+
+def get_sources_from_makefile(makefile):
+    import pymake.parser
+    from pymake.parserdata import SetVariable
+    srcdir = os.path.dirname(makefile)
+    for statement in pymake.parser.parsefile(makefile):
+        if (isinstance(statement, SetVariable) and
+                statement.vnameexp.is_static_string and
+                statement.vnameexp.s == 'OBJECTS'):
+            return sorted((find_source_file(srcdir, s)
+                           for s in statement.value.split()),
+                          key=lambda x: x.lower())
+
+
+def write_sources(mozbuild, sources):
+    with open(mozbuild, 'wb') as f:
+        f.write(('# -*- Mode: python; c-basic-offset: 4; ' +
+                 'indent-tabs-mode: nil; tab-width: 40 -*-'))
+        f.write('''
+# vim: set filetype=python:
+# THIS FILE IS GENERATED BY /intl/icusources.py DO NOT EDIT
+SOURCES += [
+''')
+        f.write(''.join("   '/%s',\n" % s for s in sources))
+        f.write(']\n')
+
+
+def update_sources(topsrcdir):
+    print('Updating ICU sources lists...')
+    sys.path.append(os.path.join(topsrcdir, 'build/pymake'))
+    for d in ['common', 'i18n']:
+        makefile = os.path.join(topsrcdir,
+                                'intl/icu/source/%s/Makefile.in' % d)
+        mozbuild = os.path.join(topsrcdir,
+                                'config/external/icu/%s/sources.mozbuild' % d)
+        sources = [os.path.relpath(s, topsrcdir)
+                   for s in get_sources_from_makefile(makefile)]
+        write_sources(mozbuild, sources)
+
+
+def try_run(name, command, cwd=None, **kwargs):
+    with tempfile.NamedTemporaryFile(prefix=name, delete=False) as f:
+        if subprocess.call(command,
+                           stdout=f,
+                           stderr=subprocess.STDOUT,
+                           cwd=cwd,
+                           **kwargs) == 0:
+            os.unlink(f.name)
+            return True
+    print('''Error running "{}" in directory {}
+See output in {}'''.format(' '.join(command), cwd, f.name),
+          file=sys.stderr)
+    return False
+
+
+def get_data_file(data_dir):
+    files = glob.glob(os.path.join(data_dir, 'icudt*.dat'))
+    return files[0] if files else None
+
+
+def update_data_file(topsrcdir):
+    objdir = tempfile.mkdtemp(prefix='icu-obj-')
+    configure = os.path.join(topsrcdir, 'intl/icu/source/configure')
+    env = dict(os.environ)
+    env.update({
+        'CFLAGS': '-DU_STATIC_IMPLEMENTATION',
+        'CXXFLAGS': '-DU_STATIC_IMPLEMENTATION',
+        'CPPFLAGS': ('-DU_USING_ICU_NAMESPACE=0 ' +
+                     '-DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1 ' +
+                     '-DUCONFIG_NO_LEGACY_CONVERSION ' +
+                     '-DUCONFIG_NO_TRANSLITERATION ' +
+                     '-DUCONFIG_NO_REGULAR_EXPRESSIONS ' +
+                     '-DUCONFIG_NO_BREAK_ITERATION ' +
+                     '-DU_CHARSET_IS_UTF8')
+    })
+    print('Running ICU configure...')
+    if not try_run(
+            'icu-configure',
+            [configure,
+             '--with-data-packaging=archive',
+             '--enable-static',
+             '--disable-shared',
+             '--disable-extras',
+             '--disable-icuio',
+             '--disable-layout',
+             '--disable-tests',
+             '--disable-samples',
+             '--disable-strict'],
+            cwd=objdir,
+            env=env):
+        return False
+    print('Running ICU make...')
+    if not try_run('icu-make', ['make'], cwd=objdir):
+        return False
+    print('Copying ICU data file...')
+    tree_data_path = os.path.join(topsrcdir,
+                                  'config/external/icu/data/')
+    old_data_file = get_data_file(tree_data_path)
+    if not old_data_file:
+        print('Error: no ICU data file in %s' % tree_data_path,
+              file=sys.stderr)
+        return False
+    new_data_file = get_data_file(os.path.join(objdir, 'data/out'))
+    if not new_data_file:
+        print('Error: no ICU data in ICU objdir', file=sys.stderr)
+        return False
+    if os.path.basename(old_data_file) != os.path.basename(new_data_file):
+        # Data file name has the major version number embedded.
+        os.unlink(old_data_file)
+    shutil.copy(new_data_file, tree_data_path)
+    shutil.rmtree(objdir)
+    return True
+
+
+def main():
+    if len(sys.argv) != 2:
+        print('Usage: icu_sources_data.py <mozilla topsrcdir>',
+              file=sys.stderr)
+        sys.exit(1)
+
+    topsrcdir = os.path.abspath(sys.argv[1])
+    update_sources(topsrcdir)
+    if not update_data_file(topsrcdir):
+        print('Error updating ICU data file', file=sys.stderr)
+        sys.exit(1)
+
+
+if __name__ == '__main__':
+    main()
--- a/intl/update-icu.sh
+++ b/intl/update-icu.sh
@@ -25,17 +25,17 @@ svn export $1/source/ ${icu_dir}/source
 
 # remove layout, tests, and samples, but leave makefiles in place
 find ${icu_dir}/source/layout -name '*Makefile.in' -prune -or -type f -print | xargs rm
 find ${icu_dir}/source/layoutex -name '*Makefile.in' -prune -or -type f -print | xargs rm
 find ${icu_dir}/source/test -name '*Makefile.in' -prune -or -type f -print | xargs rm
 find ${icu_dir}/source/samples -name '*Makefile.in' -prune -or -type f -print | xargs rm
 
 # remove data that we currently don't need
-rm ${icu_dir}/source/data/brkitr/*
+rm -rf ${icu_dir}/source/data/brkitr/*
 rm ${icu_dir}/source/data/lang/*.mk
 rm ${icu_dir}/source/data/lang/*.txt
 rm ${icu_dir}/source/data/mappings/*.mk
 find ${icu_dir}/source/data/mappings \
     -name ibm-37_P100-1995.ucm -prune -or \
     -name ibm-1047_P100-1995.ucm -prune -or \
     -name '*.ucm' -print | xargs rm
 rm ${icu_dir}/source/data/rbnf/*
@@ -47,21 +47,29 @@ rm ${icu_dir}/source/data/unit/*.txt
 
 # Record `svn info`, eliding the line that changes every time the entire ICU
 # repository (not just the path within it we care about) receives a commit.
 # (This ensures that if ICU modifications are performed properly, it's always
 # possible to run the command at the top of this script and make no changes to
 # the tree.)
 svn info $1 | grep -v '^Revision: [[:digit:]]\+$' > ${icu_dir}/SVN-INFO
 
-patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/bug-915735
-patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/suppress-warnings.diff
-patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/bug-1172609-icu-fix.diff
-patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/bug-1172609-timezone-recreateDefault.diff
-patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/bug-1198952-workaround-make-3.82-bug.diff
-patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/icu-release-56-1-flagparser-fix.patch
-patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/bug-1228227-libc++-gcc_hidden.diff
+for patch in \
+ bug-915735 \
+ suppress-warnings.diff \
+ bug-1172609-icu-fix.diff \
+ bug-1172609-timezone-recreateDefault.diff \
+ bug-1198952-workaround-make-3.82-bug.diff \
+ icu-release-56-1-flagparser-fix.patch \
+ bug-1228227-libc++-gcc_hidden.diff \
+; do
+  echo "Applying local patch $patch"
+  patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/$patch
+done
 
-# NOTE: If you're updating this script for a new ICU version, you have to rerun
-# js/src/tests/ecma_6/String/make-normalize-generateddata-input.py for any
-# normalization changes the new ICU implements.
+topsrcdir=`dirname $0`/../
+python ${topsrcdir}/js/src/tests/ecma_6/String/make-normalize-generateddata-input.py $topsrcdir
 
-hg addremove ${icu_dir}
+# Update our moz.build files in config/external/icu, and
+# build a new ICU data file.
+python `dirname $0`/icu_sources_data.py $topsrcdir
+
+hg addremove ${icu_dir} ${topsrcdir}/config/external/icu
--- a/js/src/gdb/moz.build
+++ b/js/src/gdb/moz.build
@@ -28,16 +28,21 @@ LOCAL_INCLUDES += [
     '!..',
     '..',
 ]
 
 USE_LIBS += [
     'static:js',
 ]
 
+if CONFIG['ENABLE_INTL_API'] and CONFIG['MOZ_ICU_DATA_ARCHIVE']:
+    # The ICU libraries linked into libjs will not include the ICU data,
+    # so link it directly.
+    USE_LIBS += ['icudata']
+
 OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
 # This is intended as a temporary workaround to enable VS2015.
 if CONFIG['_MSC_VER']:
     CXXFLAGS += ['-wd4312']
 
 DEFINES['topsrcdir'] = '%s/js/src' % TOPSRCDIR
 FINAL_TARGET_PP_FILES += ['gdb-tests-gdb.py.in']
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -119,16 +119,21 @@ if CONFIG['SPIDERMONKEY_PROMISE']:
 
 DEFINES['EXPORT_JS_API'] = True
 
 LOCAL_INCLUDES += [
     '!..',
     '..',
 ]
 
+if CONFIG['ENABLE_INTL_API'] and CONFIG['MOZ_ICU_DATA_ARCHIVE']:
+    # The ICU libraries linked into libjs will not include the ICU data,
+    # so link it directly.
+    USE_LIBS += ['icudata']
+
 USE_LIBS += [
     'static:js',
 ]
 
 OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
 # This is intended as a temporary workaround to enable VS2015.
 if CONFIG['_MSC_VER']:
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -611,19 +611,27 @@ FORCE_STATIC_LIB = True
 STATIC_LIBRARY_NAME = 'js_static'
 
 if CONFIG['JS_HAS_CTYPES']:
     USE_LIBS += [
         'ffi',
     ]
 
 if CONFIG['ENABLE_INTL_API']:
-    USE_LIBS += [
-        'icu',
-    ]
+    if not CONFIG['MOZ_ICU_DATA_ARCHIVE']:
+        USE_LIBS += [
+            'icu',
+        ]
+    else:
+        # Linking 'icu' will pull in the stubdata library,
+        # which the shell doesn't want, so link the other bits.
+        USE_LIBS += [
+            'icui18n',
+            'icuuc',
+        ]
 
 USE_LIBS += [
     'nspr',
     'zlib',
 ]
 
 if CONFIG['MOZ_ETW']:
     GENERATED_FILES = [
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -2788,18 +2788,16 @@ dnl ====================================
 dnl ECMAScript Internationalization API Support (uses ICU)
 dnl ========================================================
 
 dnl top-level configure may override this with --without-intl-api
 _INTL_API=yes
 
 MOZ_CONFIG_ICU()
 
-MOZ_SUBCONFIGURE_ICU()
-
 dnl ========================================================
 dnl JavaScript shell
 dnl ========================================================
 
 MOZ_CHECK_ALLOCATOR
 
 AC_CHECK_FUNCS(setlocale localeconv)
 
--- a/js/src/shell/moz.build
+++ b/js/src/shell/moz.build
@@ -31,16 +31,21 @@ if CONFIG['_MSC_VER']:
 LOCAL_INCLUDES += [
     '!..',
     '..',
 ]
 
 OS_LIBS += CONFIG['EDITLINE_LIBS']
 OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
+if CONFIG['ENABLE_INTL_API'] and CONFIG['MOZ_ICU_DATA_ARCHIVE']:
+    # The ICU libraries linked into libjs will not include the ICU data,
+    # so link it directly.
+    USE_LIBS += ['icudata']
+
 # Prepare module loader JS code for embedding
 GENERATED_FILES += ['shellmoduleloader.out.h']
 shellmoduleloader = GENERATED_FILES['shellmoduleloader.out.h']
 shellmoduleloader.script = '../builtin/embedjs.py:generate_shellmoduleloader'
 shellmoduleloader.inputs = [
     '../js.msg',
     'ModuleLoader.js',
 ]
--- a/old-configure.in
+++ b/old-configure.in
@@ -7739,17 +7739,16 @@ fi
 AC_SUBST(MOZ_ENABLE_MASK_AS_SHORTHAND)
 
 # Avoid using obsolete NSPR features
 AC_DEFINE(NO_NSPR_10_SUPPORT)
 
 MOZ_CREATE_CONFIG_STATUS()
 
 if test "$COMPILE_ENVIRONMENT"; then
-  MOZ_SUBCONFIGURE_ICU()
   MOZ_SUBCONFIGURE_FFI()
   MOZ_SUBCONFIGURE_JEMALLOC()
 fi
 
 # Run freetype configure script
 
 if test "$MOZ_TREE_FREETYPE"; then
    export CFLAGS="$CFLAGS $MOZ_DEBUG_FLAGS -std=c99"
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -154,16 +154,20 @@ extern nsresult nsStringInputStreamConst
 
 #include "GeckoProfiler.h"
 
 #include "jsapi.h"
 #include "js/Initialization.h"
 
 #include "gfxPlatform.h"
 
+#if EXPOSE_INTL_API
+#include "unicode/putil.h"
+#endif
+
 using namespace mozilla;
 using base::AtExitManager;
 using mozilla::ipc::BrowserProcessSubThread;
 
 namespace {
 
 static AtExitManager* sExitManager;
 static MessageLoop* sMessageLoop;
@@ -683,16 +687,27 @@ NS_InitXPCOM2(nsIServiceManager** aResul
 #ifdef MOZ_WEBM
   // And for libnestegg.
   // libnestegg expects that its realloc implementation will free
   // the pointer argument when a size of 0 is passed in, so we need
   // the special version of the counting realloc.
   nestegg_set_halloc_func(NesteggReporter::CountingFreeingRealloc);
 #endif
 
+#if EXPOSE_INTL_API && defined(MOZ_ICU_DATA_ARCHIVE)
+  nsCOMPtr<nsIFile> greDir;
+  nsDirectoryService::gService->Get(NS_GRE_DIR,
+                                    NS_GET_IID(nsIFile),
+                                    getter_AddRefs(greDir));
+  MOZ_ASSERT(greDir);
+  nsAutoCString nativeGREPath;
+  greDir->GetNativePath(nativeGREPath);
+  u_setDataDirectory(nativeGREPath.get());
+#endif
+
   // Initialize the JS engine.
   if (!JS_Init()) {
     NS_RUNTIMEABORT("JS_Init failed");
   }
 
   rv = nsComponentManagerImpl::gComponentManager->Init();
   if (NS_FAILED(rv)) {
     NS_RELEASE(nsComponentManagerImpl::gComponentManager);
--- a/xpcom/build/moz.build
+++ b/xpcom/build/moz.build
@@ -95,8 +95,11 @@ LOCAL_INCLUDES += [
 
 if CONFIG['MOZ_VPX']:
     LOCAL_INCLUDES += [
         '/media/libvpx',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     CXXFLAGS += CONFIG['TK_CFLAGS']
+
+CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
+LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']