Bug 1240134 - Incorporate the interfaces.xpt from downloaded artifacts instead of building XPIDL during an artifact build. draft
authorChris Manchester <cmanchester@mozilla.com>
Tue, 16 Aug 2016 15:27:38 -0700
changeset 401346 d44d97d4ab7e2ad63a8408a7bd5233bdd4abe0fc
parent 401345 2b07820788d02f0486f68116bf40f6721e1885b4
child 528472 2ea066bded4714ab805665720285e9cc5ffb64bf
push id26441
push usercmanchester@mozilla.com
push dateTue, 16 Aug 2016 22:27:47 +0000
bugs1240134
milestone51.0a1
Bug 1240134 - Incorporate the interfaces.xpt from downloaded artifacts instead of building XPIDL during an artifact build. MozReview-Commit-ID: 8oEyS1xLOwV
browser/installer/Makefile.in
browser/installer/package-manifest.in
browser/moz.build
build/moz.build
build/prebuilt-interfaces.manifest
config/makefiles/xpidl/Makefile.in
js/xpconnect/tests/moz.build
mobile/android/installer/Makefile.in
mobile/android/installer/package-manifest.in
python/mozbuild/mozbuild/artifacts.py
xpcom/tests/moz.build
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -13,16 +13,22 @@ MOZ_PKG_MANIFEST = $(srcdir)/package-man
 
 # Some files have been already bundled with xulrunner
 ifndef MOZ_MULET
 MOZ_PKG_FATAL_WARNINGS = 1
 else
 DEFINES += -DMOZ_MULET
 endif
 
+# When packaging an artifact build not all xpt files expected by the
+# packager will be present.
+ifdef MOZ_ARTIFACT_BUILDS
+MOZ_PKG_FATAL_WARNINGS =
+endif
+
 DEFINES += -DMOZ_APP_NAME=$(MOZ_APP_NAME) -DPREF_DIR=$(PREF_DIR)
 
 ifdef MOZ_DEBUG
 DEFINES += -DMOZ_DEBUG=1
 endif
 
 ifneq (,$(filter gtk%,$(MOZ_WIDGET_TOOLKIT)))
 DEFINES += -DMOZ_GTK=1
@@ -38,16 +44,20 @@ endif
 ifdef MOZ_SYSTEM_NSS
 DEFINES += -DMOZ_SYSTEM_NSS=1
 endif
 
 ifdef NSS_DISABLE_DBM
 DEFINES += -DNSS_DISABLE_DBM=1
 endif
 
+ifdef MOZ_ARTIFACT_BUILDS
+DEFINES += -DMOZ_ARTIFACT_BUILDS=1
+endif
+
 DEFINES += -DJAREXT=
 
 ifdef MOZ_ANGLE_RENDERER
 DEFINES += -DMOZ_ANGLE_RENDERER=$(MOZ_ANGLE_RENDERER)
 ifdef MOZ_D3DCOMPILER_VISTA_DLL
 DEFINES += -DMOZ_D3DCOMPILER_VISTA_DLL=$(MOZ_D3DCOMPILER_VISTA_DLL)
 endif
 ifdef MOZ_D3DCOMPILER_XP_DLL
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -138,16 +138,22 @@
 @RESPATH@/browser/blocklist.xml
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 @RESPATH@/run-mozilla.sh
 #endif
 #endif
 
 ; [Components]
+#ifdef MOZ_ARTIFACT_BUILDS
+@RESPATH@/components/prebuilt-interfaces.manifest
+@RESPATH@/components/interfaces.xpt
+@RESPATH@/browser/components/prebuilt-interfaces.manifest
+@RESPATH@/browser/components/interfaces.xpt
+#endif
 @RESPATH@/browser/components/components.manifest
 @RESPATH@/components/alerts.xpt
 #ifdef ACCESSIBILITY
 #ifdef XP_WIN32
 @BINPATH@/AccessibleMarshal.dll
 @BINPATH@/IA2Marshal.dll
 #endif
 @RESPATH@/components/accessibility.xpt
--- a/browser/moz.build
+++ b/browser/moz.build
@@ -27,8 +27,15 @@ if CONFIG['MAKENSISU']:
     DIRS += ['installer/windows']
 
 TEST_DIRS += [
     'tools/mozscreenshots',
 ]
 
 DIST_SUBDIR = 'browser'
 export('DIST_SUBDIR')
+
+if CONFIG['MOZ_ARTIFACT_BUILDS']:
+    # Ensure a pre-built interfaces.xpt installed to the objdir by the artifact
+    # code is included by the top-level chrome.manifest.
+    EXTRA_COMPONENTS += [
+        '../build/prebuilt-interfaces.manifest',
+    ]
--- a/build/moz.build
+++ b/build/moz.build
@@ -96,8 +96,15 @@ OBJDIR_FILES += ['!/dist/bin/.lldbinit']
 OBJDIR_FILES += ['/.ycm_extra_conf.py']
 
 if CONFIG['MOZ_VALGRIND']:
     OBJDIR_FILES._valgrind += [
         'valgrind/cross-architecture.sup',
         'valgrind/i386-redhat-linux-gnu.sup',
         'valgrind/x86_64-redhat-linux-gnu.sup',
     ]
+
+if CONFIG['MOZ_ARTIFACT_BUILDS']:
+    # Ensure a pre-built interfaces.xpt installed to the objdir by the artifact
+    # code is included by the top-level chrome.manifest.
+    EXTRA_COMPONENTS += [
+        'prebuilt-interfaces.manifest',
+    ]
new file mode 100644
--- /dev/null
+++ b/build/prebuilt-interfaces.manifest
@@ -0,0 +1,1 @@
+interfaces interfaces.xpt
--- a/config/makefiles/xpidl/Makefile.in
+++ b/config/makefiles/xpidl/Makefile.in
@@ -67,17 +67,19 @@ registered_xpt_files := @registered_xpt_
 xpt_files := $(registered_xpt_files) @xpt_files@
 
 @xpidl_rules@
 
 depends_files := $(foreach root,$(xpidl_modules),$(idl_deps_dir)/$(root).pp)
 
 GARBAGE += $(xpt_files) $(depends_files)
 
+ifdef COMPILE_ENVIRONMENT
 xpidl:: $(xpt_files) $(chrome_manifests) $(interfaces_manifests)
+endif
 
 $(xpt_files): $(process_py) $(call mkdir_deps,$(idl_deps_dir) $(dist_include_dir))
 
 -include $(depends_files)
 
 define xpt_deps
 $(1): $(call mkdir_deps,$(dir $(1)))
 $(1): $(addsuffix .idl,$(addprefix $(dist_idl_dir)/,$($(basename $(notdir $(1)))_deps)))
--- a/js/xpconnect/tests/moz.build
+++ b/js/xpconnect/tests/moz.build
@@ -1,22 +1,26 @@
 # -*- Mode: python; 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/.
 
 TEST_DIRS += [
-    'idl',
     'mochitest',
     'chrome',
     'browser',
     'components/native',
 ]
 
+if CONFIG['COMPILE_ENVIRONMENT']:
+    TEST_DIRS += [
+        'idl',
+    ]
+
 XPCSHELL_TESTS_MANIFESTS += [
     'unit/xpcshell.ini',
 ]
 
 TEST_HARNESS_FILES.xpcshell.js.xpconnect.tests.components.js += [
     'components/js/xpctest.manifest',
     'components/js/xpctest_attributes.js',
     'components/js/xpctest_bug809674.js',
--- a/mobile/android/installer/Makefile.in
+++ b/mobile/android/installer/Makefile.in
@@ -40,16 +40,20 @@ endif
 ifdef MOZ_ANDROID_EXCLUDE_FONTS
 DEFINES += -DMOZ_ANDROID_EXCLUDE_FONTS=1
 endif
 
 ifdef MOZ_ANDROID_GCM
 DEFINES += -DMOZ_ANDROID_GCM=1
 endif
 
+ifdef MOZ_ARTIFACT_BUILDS
+DEFINES += -DMOZ_ARTIFACT_BUILDS=1
+endif
+
 MOZ_PACKAGER_MINIFY=1
 
 include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
 
 # Note that JS_BINARY can be defined in packager.mk, so this test must come
 # after including that file. MOZ_PACKAGER_MINIFY_JS is used in packager.mk, but
 # since recipe evaluation is deferred, we can set it here after the inclusion.
 ifneq (,$(JS_BINARY))
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -81,16 +81,20 @@
 
 [browser]
 ; [Base Browser Files]
 @BINPATH@/application.ini
 @BINPATH@/platform.ini
 @BINPATH@/blocklist.xml
 
 ; [Components]
+#ifdef MOZ_ARTIFACT_BUILDS
+@BINPATH@/components/interfaces.xpt
+@BINPATH@/components/prebuilt-interfaces.manifest
+#endif
 @BINPATH@/components/components.manifest
 @BINPATH@/components/alerts.xpt
 #ifdef ACCESSIBILITY
 @BINPATH@/components/accessibility.xpt
 #endif
 @BINPATH@/components/appshell.xpt
 @BINPATH@/components/appstartup.xpt
 @BINPATH@/components/autocomplete.xpt
--- a/python/mozbuild/mozbuild/artifacts.py
+++ b/python/mozbuild/mozbuild/artifacts.py
@@ -63,21 +63,25 @@ import zipfile
 import pylru
 import taskcluster
 
 from mozbuild.util import (
     ensureParentDir,
     FileAvoidWrite,
 )
 import mozinstall
-from mozpack.files import FileFinder
+from mozpack.files import (
+    JarFinder,
+    TarFinder,
+)
 from mozpack.mozjar import (
     JarReader,
     JarWriter,
 )
+from mozpack.packager.unpack import UnpackFinder
 import mozpack.path as mozpath
 from mozregression.download_manager import (
     DownloadManager,
 )
 from mozregression.persist_limit import (
     PersistLimit,
 )
 
@@ -179,68 +183,77 @@ class ArtifactJob(object):
                     writer.add(destpath.encode('utf-8'), reader[filename], mode=mode)
                     added_entry = True
 
         if not added_entry:
             raise ValueError('Archive format changed! No pattern from "{patterns}"'
                              'matched an archive path.'.format(
                                  patterns=LinuxArtifactJob.test_artifact_patterns))
 
+
 class AndroidArtifactJob(ArtifactJob):
+
+    package_artifact_patterns = {
+        'application.ini',
+        'platform.ini',
+        '**/*.so',
+        '**/interfaces.xpt',
+    }
+
     def process_artifact(self, filename, processed_filename):
         # Extract all .so files into the root, which will get copied into dist/bin.
         with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer:
-            for f in JarReader(filename):
-                if not f.filename.endswith('.so') and \
-                   not f.filename in ('platform.ini', 'application.ini'):
+            for p, f in UnpackFinder(JarFinder(filename, JarReader(filename))):
+                if not any(mozpath.match(p, pat) for pat in self.package_artifact_patterns):
                     continue
 
-                basename = os.path.basename(f.filename)
+                dirname, basename = os.path.split(p)
                 self.log(logging.INFO, 'artifact',
                     {'basename': basename},
                    'Adding {basename} to processed archive')
 
-                basename = mozpath.join('bin', basename)
-                writer.add(basename.encode('utf-8'), f)
+                basedir = 'bin'
+                if not basename.endswith('.so'):
+                    basedir = mozpath.join('bin', dirname.lstrip('assets/'))
+                basename = mozpath.join(basedir, basename)
+                writer.add(basename.encode('utf-8'), f.open())
 
 
 class LinuxArtifactJob(ArtifactJob):
 
     package_artifact_patterns = {
         'firefox/application.ini',
         'firefox/crashreporter',
         'firefox/dependentlibs.list',
         'firefox/firefox',
         'firefox/firefox-bin',
         'firefox/platform.ini',
         'firefox/plugin-container',
         'firefox/updater',
         'firefox/**/*.so',
+        'firefox/**/interfaces.xpt',
     }
 
     def process_package_artifact(self, filename, processed_filename):
         added_entry = False
 
         with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer:
             with tarfile.open(filename) as reader:
-                for f in reader:
-                    if not f.isfile():
-                        continue
-
-                    if not any(mozpath.match(f.name, p) for p in self.package_artifact_patterns):
+                for p, f in UnpackFinder(TarFinder(filename, reader)):
+                    if not any(mozpath.match(p, pat) for pat in self.package_artifact_patterns):
                         continue
 
                     # We strip off the relative "firefox/" bit from the path,
                     # but otherwise preserve it.
                     destpath = mozpath.join('bin',
-                                            mozpath.relpath(f.name, "firefox"))
+                                            mozpath.relpath(p, "firefox"))
                     self.log(logging.INFO, 'artifact',
                              {'destpath': destpath},
                              'Adding {destpath} to processed archive')
-                    writer.add(destpath.encode('utf-8'), reader.extractfile(f), mode=f.mode)
+                    writer.add(destpath.encode('utf-8'), f.open(), mode=f.mode)
                     added_entry = True
 
         if not added_entry:
             raise ValueError('Archive format changed! No pattern from "{patterns}" '
                              'matched an archive path.'.format(
                                  patterns=LinuxArtifactJob.package_artifact_patterns))
 
 
@@ -302,38 +315,39 @@ class MacArtifactJob(ArtifactJob):
             # These get copied into dist/bin with the path, so "root/a/b/c" -> "dist/bin/a/b/c".
             paths_keep_path = ('Contents/Resources', [
                 'browser/components/libbrowsercomps.dylib',
                 'dependentlibs.list',
                 # 'firefox',
                 'gmp-clearkey/0.1/libclearkey.dylib',
                 # 'gmp-fake/1.0/libfake.dylib',
                 # 'gmp-fakeopenh264/1.0/libfakeopenh264.dylib',
+                '**/interfaces.xpt',
             ])
 
             with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer:
                 root, paths = paths_no_keep_path
-                finder = FileFinder(mozpath.join(source, root))
+                finder = UnpackFinder(mozpath.join(source, root))
                 for path in paths:
                     for p, f in finder.find(path):
                         self.log(logging.INFO, 'artifact',
-                            {'path': path},
+                            {'path': p},
                             'Adding {path} to processed archive')
                         destpath = mozpath.join('bin', os.path.basename(p))
-                        writer.add(destpath.encode('utf-8'), f, mode=os.stat(mozpath.join(finder.base, p)).st_mode)
+                        writer.add(destpath.encode('utf-8'), f, mode=f.mode)
 
                 root, paths = paths_keep_path
-                finder = FileFinder(mozpath.join(source, root))
+                finder = UnpackFinder(mozpath.join(source, root))
                 for path in paths:
                     for p, f in finder.find(path):
                         self.log(logging.INFO, 'artifact',
-                            {'path': path},
+                            {'path': p},
                             'Adding {path} to processed archive')
                         destpath = mozpath.join('bin', p)
-                        writer.add(destpath.encode('utf-8'), f, mode=os.stat(mozpath.join(finder.base, p)).st_mode)
+                        writer.add(destpath.encode('utf-8'), f.open(), mode=f.mode)
 
         finally:
             try:
                 shutil.rmtree(tempdir)
             except (OSError, IOError):
                 self.log(logging.WARN, 'artifact',
                     {'tempdir': tempdir},
                     'Unable to delete {tempdir}')
@@ -342,16 +356,17 @@ class MacArtifactJob(ArtifactJob):
 
 class WinArtifactJob(ArtifactJob):
     package_artifact_patterns = {
         'firefox/dependentlibs.list',
         'firefox/platform.ini',
         'firefox/application.ini',
         'firefox/**/*.dll',
         'firefox/*.exe',
+        'firefox/**/interfaces.xpt',
     }
     # These are a subset of TEST_HARNESS_BINS in testing/mochitest/Makefile.in.
     test_artifact_patterns = {
         ('bin/BadCertServer.exe', ('bin', 'bin')),
         ('bin/GenerateOCSPResponse.exe', ('bin', 'bin')),
         ('bin/OCSPStaplingServer.exe', ('bin', 'bin')),
         ('bin/certutil.exe', ('bin', 'bin')),
         ('bin/fileid.exe', ('bin', 'bin')),
@@ -359,27 +374,27 @@ class WinArtifactJob(ArtifactJob):
         ('bin/ssltunnel.exe', ('bin', 'bin')),
         ('bin/xpcshell.exe', ('bin', 'bin')),
         ('bin/plugins/*', ('bin/plugins', 'plugins'))
     }
 
     def process_package_artifact(self, filename, processed_filename):
         added_entry = False
         with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer:
-            for f in JarReader(filename):
-                if not any(mozpath.match(f.filename, p) for p in self.package_artifact_patterns):
+            for p, f in UnpackFinder(JarFinder(filename, JarReader(filename))):
+                if not any(mozpath.match(p, pat) for pat in self.package_artifact_patterns):
                     continue
 
                 # strip off the relative "firefox/" bit from the path:
-                basename = mozpath.relpath(f.filename, "firefox")
+                basename = mozpath.relpath(p, "firefox")
                 basename = mozpath.join('bin', basename)
                 self.log(logging.INFO, 'artifact',
                     {'basename': basename},
                     'Adding {basename} to processed archive')
-                writer.add(basename.encode('utf-8'), f)
+                writer.add(basename.encode('utf-8'), f.open(), mode=f.mode)
                 added_entry = True
 
         if not added_entry:
             raise ValueError('Archive format changed! No pattern from "{patterns}"'
                              'matched an archive path.'.format(
                                  patterns=self.artifact_patterns))
 
 # Keep the keys of this map in sync with the |mach artifact| --job
--- a/xpcom/tests/moz.build
+++ b/xpcom/tests/moz.build
@@ -79,19 +79,20 @@ if CONFIG['MOZ_MEMORY']:
 if CONFIG['MOZ_DEBUG'] and CONFIG['OS_ARCH'] not in ('WINNT'):
     # FIXME bug 523392: TestDeadlockDetector doesn't like Windows
     # FIXME bug 523378: also fails on OS X
     GeckoCppUnitTests([
         'TestDeadlockDetector',
         'TestDeadlockDetectorScalability',
     ])
 
-TEST_HARNESS_FILES.xpcshell.xpcom.tests.unit += [
-    '!/dist/bin/components/xpcomtest.xpt',
-]
+if CONFIG['COMPILE_ENVIRONMENT']:
+    TEST_HARNESS_FILES.xpcshell.xpcom.tests.unit += [
+        '!/dist/bin/components/xpcomtest.xpt',
+    ]
 
 XPIDL_MODULE = 'xpcomtest'
 XPIDL_SOURCES += [
     'NotXPCOMTest.idl',
 ]
 
 # Don't add our test-only .xpt files to the normal manifests
 XPIDL_NO_MANIFEST = True