Bug 1229241 - Redirect EXTRA{_PP}_COMPONENTS to FINAL_TARGET{,_PP}_FILES.components. r=gps
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 27 Nov 2015 22:54:39 +0900
changeset 308993 88981a083ec91e7ff8b6cd3f91b91cb9d1246240
parent 308992 63bfa84f09aa6f7f510b44bc813e562e8456573e
child 308994 81d63799328b2ae690f7135586ea76d3fb911cad
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs1229241
milestone45.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 1229241 - Redirect EXTRA{_PP}_COMPONENTS to FINAL_TARGET{,_PP}_FILES.components. r=gps
config/rules.mk
dom/downloads/moz.build
python/mozbuild/mozbuild/backend/fastermake.py
python/mozbuild/mozbuild/backend/recursivemake.py
python/mozbuild/mozbuild/frontend/context.py
python/mozbuild/mozbuild/frontend/emitter.py
python/mozbuild/mozbuild/test/backend/data/variable_passthru/moz.build
python/mozbuild/mozbuild/test/backend/test_recursivemake.py
python/mozbuild/mozbuild/test/frontend/data/variable-passthru/moz.build
python/mozbuild/mozbuild/test/frontend/test_emitter.py
python/mozbuild/mozbuild/test/frontend/test_sandbox.py
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -1168,43 +1168,16 @@ ifndef NO_DIST_INSTALL
 AUTOCFG_JS_EXPORTS_FILES := $(AUTOCFG_JS_EXPORTS)
 AUTOCFG_JS_EXPORTS_DEST := $(FINAL_TARGET)/defaults/autoconfig
 AUTOCFG_JS_EXPORTS_TARGET := export
 INSTALL_TARGETS += AUTOCFG_JS_EXPORTS
 endif
 endif
 
 ################################################################################
-# Copy each element of EXTRA_COMPONENTS to $(FINAL_TARGET)/components
-ifdef EXTRA_COMPONENTS
-misc:: $(EXTRA_COMPONENTS)
-ifndef NO_DIST_INSTALL
-EXTRA_COMPONENTS_FILES := $(EXTRA_COMPONENTS)
-EXTRA_COMPONENTS_DEST := $(FINAL_TARGET)/components
-EXTRA_COMPONENTS_TARGET := misc
-INSTALL_TARGETS += EXTRA_COMPONENTS
-endif
-
-endif
-
-ifdef EXTRA_PP_COMPONENTS
-ifndef NO_DIST_INSTALL
-EXTRA_PP_COMPONENTS_PATH := $(FINAL_TARGET)/components
-EXTRA_PP_COMPONENTS_TARGET := misc
-PP_TARGETS += EXTRA_PP_COMPONENTS
-endif
-endif
-
-EXTRA_MANIFESTS = $(filter %.manifest,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS))
-ifneq (,$(EXTRA_MANIFESTS))
-misc:: $(call mkdir_deps,$(FINAL_TARGET))
-	$(call py_action,buildlist,$(FINAL_TARGET)/chrome.manifest $(patsubst %,'manifest components/%',$(notdir $(EXTRA_MANIFESTS))))
-endif
-
-################################################################################
 # SDK
 
 ifneq (,$(SDK_LIBRARY))
 ifndef NO_DIST_INSTALL
 SDK_LIBRARY_FILES := $(SDK_LIBRARY)
 SDK_LIBRARY_DEST := $(SDK_LIB_DIR)
 SDK_LIBRARY_TARGET := target
 INSTALL_TARGETS += SDK_LIBRARY
@@ -1579,18 +1552,16 @@ endif
 
 FREEZE_VARIABLES = \
   CSRCS \
   CPPSRCS \
   EXPORTS \
   DIRS \
   LIBRARY \
   MODULE \
-  EXTRA_COMPONENTS \
-  EXTRA_PP_COMPONENTS \
   $(NULL)
 
 $(foreach var,$(FREEZE_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
 
 CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
   $(if $(subst $($(var)_FROZEN),,'$($(var))'),$(error Makefile variable '$(var)' changed value after including rules.mk. Was $($(var)_FROZEN), now $($(var)).)))
 
 libs export::
--- a/dom/downloads/moz.build
+++ b/dom/downloads/moz.build
@@ -6,16 +6,16 @@
 
 if CONFIG["MOZ_B2G"]:
     MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
 
 EXTRA_COMPONENTS += [
     'DownloadsAPI.manifest',
 ]
 
-EXTRA_PP_COMPONENTS = [
+EXTRA_PP_COMPONENTS += [
     'DownloadsAPI.js',
 ]
 
 EXTRA_PP_JS_MODULES += [
     'DownloadsAPI.jsm',
     'DownloadsIPC.jsm',
 ]
--- a/python/mozbuild/mozbuild/backend/fastermake.py
+++ b/python/mozbuild/mozbuild/backend/fastermake.py
@@ -10,17 +10,16 @@ from mozbuild.frontend.data import (
     ContextDerived,
     Defines,
     FinalTargetPreprocessedFiles,
     FinalTargetFiles,
     JARManifest,
     JavaScriptModules,
     JsPreferenceFile,
     Resources,
-    VariablePassthru,
     XPIDLFile,
 )
 from mozbuild.jar import JarManifestParser
 from mozbuild.makeutil import Makefile
 from mozbuild.preprocessor import Preprocessor
 from mozbuild.util import OrderedDefaultDict
 from mozpack.manifests import InstallManifest
 import mozpack.path as mozpath
@@ -73,40 +72,16 @@ class FasterMakeBackend(CommonBackend):
             # which is kind of set in stone from the order things are treated
             # in emitter.py.
             assert obj.objdir not in self._seen_directories
 
         elif isinstance(obj, JARManifest) and \
                 obj.install_target.startswith('dist/bin'):
             self._consume_jar_manifest(obj, defines)
 
-        elif isinstance(obj, VariablePassthru) and \
-                obj.install_target.startswith('dist/bin'):
-            for f in obj.variables.get('EXTRA_COMPONENTS', {}):
-                path = mozpath.join(obj.install_target, 'components',
-                                    mozpath.basename(f))
-                self._install_manifests[obj.install_target].add_symlink(
-                    mozpath.join(obj.srcdir, f),
-                    mozpath.join('components', mozpath.basename(f))
-                )
-                if f.endswith('.manifest'):
-                    manifest = mozpath.join(obj.install_target,
-                                            'chrome.manifest')
-                    self._manifest_entries[manifest].append(
-                        'manifest components/%s' % mozpath.basename(f))
-
-            for f in obj.variables.get('EXTRA_PP_COMPONENTS', {}):
-                self._add_preprocess(obj, f, 'components', defines=defines)
-
-                if f.endswith('.manifest'):
-                    manifest = mozpath.join(obj.install_target,
-                                            'chrome.manifest')
-                    self._manifest_entries[manifest].append(
-                        'manifest components/%s' % mozpath.basename(f))
-
         elif isinstance(obj, JavaScriptModules) and \
                 obj.install_target.startswith('dist/bin'):
             for path, strings in obj.modules.walk():
                 base = mozpath.join('modules', path)
                 for f in strings:
                     if obj.flavor == 'extra':
                         self._install_manifests[obj.install_target].add_symlink(
                             mozpath.join(obj.srcdir, f),
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -1373,16 +1373,19 @@ INSTALL_TARGETS += %(prefix)s
 
     def _process_final_target_files(self, obj, files, target):
         if target.startswith('dist/bin'):
             install_manifest = self._install_manifests['dist_bin']
             reltarget = mozpath.relpath(target, 'dist/bin')
         elif target.startswith('dist/xpi-stage'):
             install_manifest = self._install_manifests['dist_xpi-stage']
             reltarget = mozpath.relpath(target, 'dist/xpi-stage')
+        elif target.startswith('_tests'):
+            install_manifest = self._install_manifests['tests']
+            reltarget = mozpath.relpath(target, '_tests')
         else:
             raise Exception("Cannot install to " + target)
 
         for path, strings in files.walk():
             for f in strings:
                 source = mozpath.normpath(os.path.join(obj.srcdir, f))
                 dest = mozpath.join(reltarget, path, mozpath.basename(f))
                 install_manifest.add_symlink(source, dest)
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -996,23 +996,16 @@ VARIABLES = {
         """Disable the wrappers for STL which allow it to work with C++ exceptions
         disabled.
         """, None),
 
     'FINAL_TARGET_PP_FILES': (HierarchicalStringList, list,
         """Like ``FINAL_TARGET_FILES``, with preprocessing.
         """, 'libs'),
 
-    'EXTRA_COMPONENTS': (StrictOrderingOnAppendList, list,
-        """Additional component files to distribute.
-
-       This variable contains a list of files to copy into
-       ``$(FINAL_TARGET)/components/``.
-        """, 'misc'),
-
     'EXTRA_JS_MODULES': (HierarchicalStringList, list,
         """Additional JavaScript files to distribute.
 
         This variable contains a list of files to copy into
         ``$(FINAL_TARGET)/modules.
         """, 'misc'),
 
     'EXTRA_PP_JS_MODULES': (HierarchicalStringList, list,
@@ -1029,23 +1022,16 @@ VARIABLES = {
         with Firefox. This variable defines them.
 
         To install modules in a subdirectory, use properties of this
         variable to control the final destination. e.g.
 
         ``TESTING_JS_MODULES.foo += ['module.jsm']``.
         """, None),
 
-    'EXTRA_PP_COMPONENTS': (StrictOrderingOnAppendList, list,
-        """Javascript XPCOM files.
-
-       This variable contains a list of files to preprocess.  Generated
-       files will be installed in the ``/components`` directory of the distribution.
-        """, 'misc'),
-
     'FINAL_LIBRARY': (unicode, unicode,
         """Library in which the objects of the current directory will be linked.
 
         This variable contains the name of a library, defined elsewhere with
         ``LIBRARY_NAME``, in which the objects of the current directory will be
         linked.
         """, None),
 
@@ -1964,16 +1950,31 @@ SPECIAL_VARIABLES = {
         All the variables defined by the configuration system are available
         through this object. e.g. ``ENABLE_TESTS``, ``CFLAGS``, etc.
 
         Values in this container are read-only. Attempts at changing values
         will result in a run-time error.
 
         Access to an unknown variable will return None.
         """),
+
+    'EXTRA_COMPONENTS': (lambda context: context['FINAL_TARGET_FILES'].components._strings, list,
+        """Additional component files to distribute.
+
+       This variable contains a list of files to copy into
+       ``$(FINAL_TARGET)/components/``.
+        """),
+
+    'EXTRA_PP_COMPONENTS': (lambda context: context['FINAL_TARGET_PP_FILES'].components._strings, list,
+        """Javascript XPCOM files.
+
+       This variable contains a list of files to preprocess.  Generated
+       files will be installed in the ``/components`` directory of the distribution.
+        """),
+
 }
 
 # Deprecation hints.
 DEPRECATION_HINTS = {
     'CPP_UNIT_TESTS': '''
         Please use'
 
             CppUnitTests(['foo', 'bar'])
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -71,17 +71,20 @@ from .data import (
     TestHarnessFiles,
     TestWebIDLFile,
     TestManifest,
     UnifiedSources,
     VariablePassthru,
     WebIDLFile,
     XPIDLFile,
 )
-from mozpack.chrome.manifest import ManifestBinaryComponent
+from mozpack.chrome.manifest import (
+    ManifestBinaryComponent,
+    Manifest,
+)
 
 from .reader import SandboxValidationError
 
 from ..testing import (
     TEST_MANIFESTS,
     REFTEST_FLAVORS,
     WEB_PATFORM_TESTS_FLAVORS,
 )
@@ -549,40 +552,27 @@ class TreeMetadataEmitter(LoggingMixin):
 
         for path in context['CONFIGURE_DEFINE_FILES']:
             yield self._create_substitution(HeaderFileSubstitution, context,
                 path)
 
         for obj in self._process_xpidl(context):
             yield obj
 
-        # Check for manifest declarations in EXTRA_{PP_,}COMPONENTS.
-        extras = context.get('EXTRA_COMPONENTS', []) + context.get('EXTRA_PP_COMPONENTS', [])
-        if any(e.endswith('.js') for e in extras) and \
-                not any(e.endswith('.manifest') for e in extras) and \
-                not context.get('NO_JS_MANIFEST', False):
-            raise SandboxValidationError('A .js component was specified in EXTRA_COMPONENTS '
-                                         'or EXTRA_PP_COMPONENTS without a matching '
-                                         '.manifest file.  See '
-                                         'https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_2.0 .',
-                                         context);
-
         # Proxy some variables as-is until we have richer classes to represent
         # them. We should aim to keep this set small because it violates the
         # desired abstraction of the build definition away from makefiles.
         passthru = VariablePassthru(context)
         varlist = [
             'ALLOW_COMPILER_WARNINGS',
             'ANDROID_APK_NAME',
             'ANDROID_APK_PACKAGE',
             'ANDROID_GENERATED_RESFILES',
             'DISABLE_STL_WRAPPING',
-            'EXTRA_COMPONENTS',
             'EXTRA_DSO_LDOPTS',
-            'EXTRA_PP_COMPONENTS',
             'USE_STATIC_LIBS',
             'PYTHON_UNIT_TESTS',
             'RCFILE',
             'RESFILE',
             'RCINCLUDE',
             'DEFFILE',
             'WIN32_EXE_LDFLAGS',
             'LD_VERSION_SCRIPT',
@@ -681,37 +671,56 @@ class TreeMetadataEmitter(LoggingMixin):
         for local_include in context.get('LOCAL_INCLUDES', []):
             if (not isinstance(local_include, ObjDirPath) and
                     not os.path.exists(local_include.full_path)):
                 raise SandboxValidationError('Path specified in LOCAL_INCLUDES '
                     'does not exist: %s (resolved to %s)' % (local_include,
                     local_include.full_path), context)
             yield LocalInclude(context, local_include)
 
+        components = []
         for var, cls in (
             ('FINAL_TARGET_FILES', FinalTargetFiles),
             ('FINAL_TARGET_PP_FILES', FinalTargetPreprocessedFiles),
         ):
             all_files = context.get(var)
             if not all_files:
                 continue
             if dist_install is False:
                 raise SandboxValidationError(
                     '%s cannot be used with DIST_INSTALL = False' % var,
                     context)
-            for _, files in all_files.walk():
+            for base, files in all_files.walk():
+                if base == 'components':
+                    components.extend(files)
                 for f in files:
                     path = os.path.join(context.srcdir, f)
                     if not os.path.exists(path):
                         raise SandboxValidationError(
                             'File listed in %s does not exist: %s'
                             % (var, f), context)
 
             yield cls(context, all_files, context['FINAL_TARGET'])
 
+        # Check for manifest declarations in EXTRA_{PP_,}COMPONENTS.
+        if any(e.endswith('.js') for e in components) and \
+                not any(e.endswith('.manifest') for e in components) and \
+                not context.get('NO_JS_MANIFEST', False):
+            raise SandboxValidationError('A .js component was specified in EXTRA_COMPONENTS '
+                                         'or EXTRA_PP_COMPONENTS without a matching '
+                                         '.manifest file.  See '
+                                         'https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_2.0 .',
+                                         context);
+
+        for c in components:
+            if c.endswith('.manifest'):
+                yield ChromeManifestEntry(context, 'chrome.manifest',
+                                          Manifest('components',
+                                                   mozpath.basename(c)))
+
         branding_files = context.get('BRANDING_FILES')
         if branding_files:
             yield BrandingFiles(context, branding_files)
 
         for obj in self._handle_libraries(context):
             yield obj
 
         for obj in self._process_test_manifests(context):
--- a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/moz.build
+++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/moz.build
@@ -1,15 +1,12 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # Any copyright is dedicated to the Public Domain.
 # http://creativecommons.org/publicdomain/zero/1.0/
 
-EXTRA_COMPONENTS = ['bar.js', 'dummy.manifest', 'foo.js']
-EXTRA_PP_COMPONENTS = ['bar.pp.js', 'foo.pp.js']
-
 NO_VISIBILITY_FLAGS = True
 
 DELAYLOAD_DLLS = ['foo.dll', 'bar.dll']
 
 RCFILE = 'foo.rc'
 RESFILE = 'bar.res'
 RCINCLUDE = 'bar.rc'
 DEFFILE = 'baz.def'
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -261,25 +261,16 @@ class TestRecursiveMakeBackend(BackendTe
 
         expected = {
             'ALLOW_COMPILER_WARNINGS': [
                 'ALLOW_COMPILER_WARNINGS := 1',
             ],
             'DISABLE_STL_WRAPPING': [
                 'DISABLE_STL_WRAPPING := 1',
             ],
-            'EXTRA_COMPONENTS': [
-                'EXTRA_COMPONENTS += bar.js',
-                'EXTRA_COMPONENTS += dummy.manifest',
-                'EXTRA_COMPONENTS += foo.js',
-            ],
-            'EXTRA_PP_COMPONENTS': [
-                'EXTRA_PP_COMPONENTS += bar.pp.js',
-                'EXTRA_PP_COMPONENTS += foo.pp.js',
-            ],
             'VISIBILITY_FLAGS': [
                 'VISIBILITY_FLAGS :=',
             ],
             'RCFILE': [
                 'RCFILE := foo.rc',
             ],
             'RESFILE': [
                 'RESFILE := bar.res',
--- a/python/mozbuild/mozbuild/test/frontend/data/variable-passthru/moz.build
+++ b/python/mozbuild/mozbuild/test/frontend/data/variable-passthru/moz.build
@@ -1,15 +1,12 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # Any copyright is dedicated to the Public Domain.
 # http://creativecommons.org/publicdomain/zero/1.0/
 
-EXTRA_COMPONENTS = ['dummy.manifest', 'fans.js', 'tans.js']
-EXTRA_PP_COMPONENTS=['fans.pp.js', 'tans.pp.js']
-
 DIST_INSTALL = False
 
 NO_VISIBILITY_FLAGS = True
 
 DELAYLOAD_DLLS = ['foo.dll', 'bar.dll']
 
 RCFILE = 'foo.rc'
 RESFILE = 'bar.res'
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -151,18 +151,16 @@ class TestEmitterBasic(unittest.TestCase
         objs = self.read_topsrcdir(reader)
 
         self.assertEqual(len(objs), 1)
         self.assertIsInstance(objs[0], VariablePassthru)
 
         wanted = {
             'ALLOW_COMPILER_WARNINGS': True,
             'DISABLE_STL_WRAPPING': True,
-            'EXTRA_COMPONENTS': ['dummy.manifest', 'fans.js', 'tans.js'],
-            'EXTRA_PP_COMPONENTS': ['fans.pp.js', 'tans.pp.js'],
             'NO_DIST_INSTALL': True,
             'VISIBILITY_FLAGS': '',
             'RCFILE': 'foo.rc',
             'RESFILE': 'bar.res',
             'RCINCLUDE': 'bar.rc',
             'DEFFILE': 'baz.def',
             'USE_STATIC_LIBS': True,
             'MOZBUILD_CFLAGS': ['-fno-exceptions', '-w'],
--- a/python/mozbuild/mozbuild/test/frontend/test_sandbox.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_sandbox.py
@@ -204,16 +204,17 @@ class TestMozbuildSandbox(unittest.TestC
         self.assertIsNone(sandbox['CONFIG']['MISSING'])
 
         # Should shouldn't be allowed to assign to the config.
         with self.assertRaises(Exception):
             sandbox['CONFIG']['FOO'] = ''
 
     def test_special_variables(self):
         sandbox = self.sandbox()
+        sandbox._context.add_source(sandbox.normalize_path('moz.build'))
 
         for k in SPECIAL_VARIABLES:
             with self.assertRaises(KeyError):
                 sandbox[k] = 0
 
     def test_exec_source_reassign_exported(self):
         template_sandbox = self.sandbox(data_path='templates')