| # 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/. |
| |
| ###################################################################### |
| # DO NOT UPDATE THIS FILE WITHOUT SIGN-OFF FROM A BUILD MODULE PEER. # |
| ###################################################################### |
| |
| r"""This module contains the data structure (context) holding the configuration |
| from a moz.build. The data emitted by the frontend derives from those contexts. |
| |
| It also defines the set of variables and functions available in moz.build. |
| If you are looking for the absolute authority on what moz.build files can |
| contain, you've come to the right place. |
| """ |
| |
| from __future__ import absolute_import, unicode_literals |
| |
| import os |
| |
| from collections import ( |
| Counter, |
| OrderedDict, |
| ) |
| from mozbuild.util import ( |
| HierarchicalStringList, |
| KeyedDefaultDict, |
| List, |
| memoize, |
| memoized_property, |
| ReadOnlyKeyedDefaultDict, |
| StrictOrderingOnAppendList, |
| StrictOrderingOnAppendListWithFlagsFactory, |
| TypedList, |
| TypedNamedTuple, |
| ) |
| |
| from ..testing import all_test_flavors |
| import mozpack.path as mozpath |
| from types import FunctionType |
| |
| import itertools |
| |
| |
| class ContextDerivedValue(object): |
| """Classes deriving from this one receive a special treatment in a |
| Context. See Context documentation. |
| """ |
| __slots__ = () |
| |
| |
| class Context(KeyedDefaultDict): |
| """Represents a moz.build configuration context. |
| |
| Instances of this class are filled by the execution of sandboxes. |
| At the core, a Context is a dict, with a defined set of possible keys we'll |
| call variables. Each variable is associated with a type. |
| |
| When reading a value for a given key, we first try to read the existing |
| value. If a value is not found and it is defined in the allowed variables |
| set, we return a new instance of the class for that variable. We don't |
| assign default instances until they are accessed because this makes |
| debugging the end-result much simpler. Instead of a data structure with |
| lots of empty/default values, you have a data structure with only the |
| values that were read or touched. |
| |
| Instances of variables classes are created by invoking ``class_name()``, |
| except when class_name derives from ``ContextDerivedValue`` or |
| ``SubContext``, in which case ``class_name(instance_of_the_context)`` or |
| ``class_name(self)`` is invoked. A value is added to those calls when |
| instances are created during assignment (setitem). |
| |
| allowed_variables is a dict of the variables that can be set and read in |
| this context instance. Keys in this dict are the strings representing keys |
| in this context which are valid. Values are tuples of stored type, |
| assigned type, default value, a docstring describing the purpose of the |
| variable, and a tier indicator (see comment above the VARIABLES declaration |
| in this module). |
| |
| config is the ConfigEnvironment for this context. |
| """ |
| def __init__(self, allowed_variables={}, config=None): |
| self._allowed_variables = allowed_variables |
| self.main_path = None |
| self.current_path = None |
| # There aren't going to be enough paths for the performance of scanning |
| # a list to be a problem. |
| self._all_paths = [] |
| self.config = config |
| self._sandbox = None |
| KeyedDefaultDict.__init__(self, self._factory) |
| |
| def push_source(self, path): |
| """Adds the given path as source of the data from this context and make |
| it the current path for the context.""" |
| assert os.path.isabs(path) |
| if not self.main_path: |
| self.main_path = path |
| else: |
| # Callers shouldn't push after main_path has been popped. |
| assert self.current_path |
| self.current_path = path |
| # The same file can be pushed twice, so don't remove any previous |
| # occurrence. |
| self._all_paths.append(path) |
| |
| def pop_source(self): |
| """Get back to the previous current path for the context.""" |
| assert self.main_path |
| assert self.current_path |
| last = self._all_paths.pop() |
| # Keep the popped path in the list of all paths, but before the main |
| # path so that it's not popped again. |
| self._all_paths.insert(0, last) |
| if last == self.main_path: |
| self.current_path = None |
| else: |
| self.current_path = self._all_paths[-1] |
| return last |
| |
| def add_source(self, path): |
| """Adds the given path as source of the data from this context.""" |
| assert os.path.isabs(path) |
| if not self.main_path: |
| self.main_path = self.current_path = path |
| # Insert at the beginning of the list so that it's always before the |
| # main path. |
| if path not in self._all_paths: |
| self._all_paths.insert(0, path) |
| |
| @property |
| def all_paths(self): |
| """Returns all paths ever added to the context.""" |
| return set(self._all_paths) |
| |
| @property |
| def source_stack(self): |
| """Returns the current stack of pushed sources.""" |
| if not self.current_path: |
| return [] |
| return self._all_paths[self._all_paths.index(self.main_path):] |
| |
| @memoized_property |
| def objdir(self): |
| return mozpath.join(self.config.topobjdir, self.relobjdir).rstrip('/') |
| |
| @memoize |
| def _srcdir(self, path): |
| return mozpath.join(self.config.topsrcdir, |
| self._relsrcdir(path)).rstrip('/') |
| |
| @property |
| def srcdir(self): |
| return self._srcdir(self.current_path or self.main_path) |
| |
| @memoize |
| def _relsrcdir(self, path): |
| return mozpath.relpath(mozpath.dirname(path), self.config.topsrcdir) |
| |
| @property |
| def relsrcdir(self): |
| assert self.main_path |
| return self._relsrcdir(self.current_path or self.main_path) |
| |
| @memoized_property |
| def relobjdir(self): |
| assert self.main_path |
| return mozpath.relpath(mozpath.dirname(self.main_path), |
| self.config.topsrcdir) |
| |
| def _factory(self, key): |
| """Function called when requesting a missing key.""" |
| defaults = self._allowed_variables.get(key) |
| if not defaults: |
| raise KeyError('global_ns', 'get_unknown', key) |
| |
| # If the default is specifically a lambda (or, rather, any function |
| # --but not a class that can be called), then it is actually a rule to |
| # generate the default that should be used. |
| default = defaults[0] |
| if issubclass(default, ContextDerivedValue): |
| return default(self) |
| else: |
| return default() |
| |
| def _validate(self, key, value, is_template=False): |
| """Validates whether the key is allowed and if the value's type |
| matches. |
| """ |
| stored_type, input_type, docs, tier = \ |
| self._allowed_variables.get(key, (None, None, None, None)) |
| |
| if stored_type is None or not is_template and key in TEMPLATE_VARIABLES: |
| raise KeyError('global_ns', 'set_unknown', key, value) |
| |
| # If the incoming value is not the type we store, we try to convert |
| # it to that type. This relies on proper coercion rules existing. This |
| # is the responsibility of whoever defined the symbols: a type should |
| # not be in the allowed set if the constructor function for the stored |
| # type does not accept an instance of that type. |
| if not isinstance(value, (stored_type, input_type)): |
| raise ValueError('global_ns', 'set_type', key, value, input_type) |
| |
| return stored_type |
| |
| def __setitem__(self, key, value): |
| stored_type = self._validate(key, value) |
| |
| if not isinstance(value, stored_type): |
| if issubclass(stored_type, ContextDerivedValue): |
| value = stored_type(self, value) |
| else: |
| value = stored_type(value) |
| |
| return KeyedDefaultDict.__setitem__(self, key, value) |
| |
| def update(self, iterable={}, **kwargs): |
| """Like dict.update(), but using the context's setitem. |
| |
| This function is transactional: if setitem fails for one of the values, |
| the context is not updated at all.""" |
| if isinstance(iterable, dict): |
| iterable = iterable.items() |
| |
| update = {} |
| for key, value in itertools.chain(iterable, kwargs.items()): |
| stored_type = self._validate(key, value) |
| # Don't create an instance of stored_type if coercion is needed, |
| # until all values are validated. |
| update[key] = (value, stored_type) |
| for key, (value, stored_type) in update.items(): |
| if not isinstance(value, stored_type): |
| update[key] = stored_type(value) |
| else: |
| update[key] = value |
| KeyedDefaultDict.update(self, update) |
| |
| def get_affected_tiers(self): |
| """Returns the list of tiers affected by the variables set in the |
| context. |
| """ |
| tiers = (VARIABLES[key][3] for key in self if key in VARIABLES) |
| return set(tier for tier in tiers if tier) |
| |
| |
| class TemplateContext(Context): |
| def __init__(self, template=None, allowed_variables={}, config=None): |
| self.template = template |
| super(TemplateContext, self).__init__(allowed_variables, config) |
| |
| def _validate(self, key, value): |
| return Context._validate(self, key, value, True) |
| |
| |
| class SubContext(Context, ContextDerivedValue): |
| """A Context derived from another Context. |
| |
| Sub-contexts are intended to be used as context managers. |
| |
| Sub-contexts inherit paths and other relevant state from the parent |
| context. |
| """ |
| def __init__(self, parent): |
| assert isinstance(parent, Context) |
| |
| Context.__init__(self, allowed_variables=self.VARIABLES, |
| config=parent.config) |
| |
| # Copy state from parent. |
| for p in parent.source_stack: |
| self.push_source(p) |
| self._sandbox = parent._sandbox |
| |
| def __enter__(self): |
| if not self._sandbox or self._sandbox() is None: |
| raise Exception('a sandbox is required') |
| |
| self._sandbox().push_subcontext(self) |
| |
| def __exit__(self, exc_type, exc_value, traceback): |
| self._sandbox().pop_subcontext(self) |
| |
| |
| class FinalTargetValue(ContextDerivedValue, unicode): |
| def __new__(cls, context, value=""): |
| if not value: |
| value = 'dist/' |
| if context['XPI_NAME']: |
| value += 'xpi-stage/' + context['XPI_NAME'] |
| else: |
| value += 'bin' |
| if context['DIST_SUBDIR']: |
| value += '/' + context['DIST_SUBDIR'] |
| return unicode.__new__(cls, value) |
| |
| |
| def Enum(*values): |
| assert len(values) |
| default = values[0] |
| |
| class EnumClass(object): |
| def __new__(cls, value=None): |
| if value is None: |
| return default |
| if value in values: |
| return value |
| raise ValueError('Invalid value. Allowed values are: %s' |
| % ', '.join(repr(v) for v in values)) |
| return EnumClass |
| |
| |
| class PathMeta(type): |
| """Meta class for the Path family of classes. |
| |
| It handles calling __new__ and __init__ with the right arguments |
| in cases where a Path is instantiated with another instance of |
| Path instead of having received a context. |
| |
| It also makes Path(context, value) instantiate one of the |
| subclasses depending on the value, allowing callers to do |
| standard type checking (isinstance(path, ObjDirPath)) instead |
| of checking the value itself (path.startswith('!')). |
| """ |
| def __call__(cls, context, value=None): |
| if isinstance(context, Path): |
| assert value is None |
| value = context |
| context = context.context |
| else: |
| assert isinstance(context, Context) |
| if isinstance(value, Path): |
| context = value.context |
| if not issubclass(cls, (SourcePath, ObjDirPath, AbsolutePath)): |
| if value.startswith('!'): |
| cls = ObjDirPath |
| elif value.startswith('%'): |
| cls = AbsolutePath |
| else: |
| cls = SourcePath |
| return super(PathMeta, cls).__call__(context, value) |
| |
| class Path(ContextDerivedValue, unicode): |
| """Stores and resolves a source path relative to a given context |
| |
| This class is used as a backing type for some of the sandbox variables. |
| It expresses paths relative to a context. Supported paths are: |
| - '/topsrcdir/relative/paths' |
| - 'srcdir/relative/paths' |
| - '!/topobjdir/relative/paths' |
| - '!objdir/relative/paths' |
| - '%/filesystem/absolute/paths' |
| """ |
| __metaclass__ = PathMeta |
| |
| def __new__(cls, context, value=None): |
| return super(Path, cls).__new__(cls, value) |
| |
| def __init__(self, context, value=None): |
| # Only subclasses should be instantiated. |
| assert self.__class__ != Path |
| self.context = context |
| self.srcdir = context.srcdir |
| |
| def join(self, *p): |
| """ContextDerived equivalent of mozpath.join(self, *p), returning a |
| new Path instance. |
| """ |
| return Path(self.context, mozpath.join(self, *p)) |
| |
| def __cmp__(self, other): |
| if isinstance(other, Path) and self.srcdir != other.srcdir: |
| return cmp(self.full_path, other.full_path) |
| return cmp(unicode(self), other) |
| |
| # __cmp__ is not enough because unicode has __eq__, __ne__, etc. defined |
| # and __cmp__ is only used for those when they don't exist. |
| def __eq__(self, other): |
| return self.__cmp__(other) == 0 |
| |
| def __ne__(self, other): |
| return self.__cmp__(other) != 0 |
| |
| def __lt__(self, other): |
| return self.__cmp__(other) < 0 |
| |
| def __gt__(self, other): |
| return self.__cmp__(other) > 0 |
| |
| def __le__(self, other): |
| return self.__cmp__(other) <= 0 |
| |
| def __ge__(self, other): |
| return self.__cmp__(other) >= 0 |
| |
| def __repr__(self): |
| return '<%s (%s)%s>' % (self.__class__.__name__, self.srcdir, self) |
| |
| def __hash__(self): |
| return hash(self.full_path) |
| |
| |
| class SourcePath(Path): |
| """Like Path, but limited to paths in the source directory.""" |
| def __init__(self, context, value): |
| if value.startswith('!'): |
| raise ValueError('Object directory paths are not allowed') |
| if value.startswith('%'): |
| raise ValueError('Filesystem absolute paths are not allowed') |
| super(SourcePath, self).__init__(context, value) |
| |
| if value.startswith('/'): |
| path = None |
| # If the path starts with a '/' and is actually relative to an |
| # external source dir, use that as base instead of topsrcdir. |
| if context.config.external_source_dir: |
| path = mozpath.join(context.config.external_source_dir, |
| value[1:]) |
| if not path or not os.path.exists(path): |
| path = mozpath.join(context.config.topsrcdir, |
| value[1:]) |
| else: |
| path = mozpath.join(self.srcdir, value) |
| self.full_path = mozpath.normpath(path) |
| |
| @memoized_property |
| def translated(self): |
| """Returns the corresponding path in the objdir. |
| |
| Ideally, we wouldn't need this function, but the fact that both source |
| path under topsrcdir and the external source dir end up mixed in the |
| objdir (aka pseudo-rework), this is needed. |
| """ |
| return ObjDirPath(self.context, '!%s' % self).full_path |
| |
| |
| class ObjDirPath(Path): |
| """Like Path, but limited to paths in the object directory.""" |
| def __init__(self, context, value=None): |
| if not value.startswith('!'): |
| raise ValueError('Object directory paths must start with ! prefix') |
| super(ObjDirPath, self).__init__(context, value) |
| |
| if value.startswith('!/'): |
| path = mozpath.join(context.config.topobjdir,value[2:]) |
| else: |
| path = mozpath.join(context.objdir, value[1:]) |
| self.full_path = mozpath.normpath(path) |
| |
| |
| class AbsolutePath(Path): |
| """Like Path, but allows arbitrary paths outside the source and object directories.""" |
| def __init__(self, context, value=None): |
| if not value.startswith('%'): |
| raise ValueError('Absolute paths must start with % prefix') |
| if not os.path.isabs(value[1:]): |
| raise ValueError('Path \'%s\' is not absolute' % value[1:]) |
| super(AbsolutePath, self).__init__(context, value) |
| |
| self.full_path = mozpath.normpath(value[1:]) |
| |
| |
| @memoize |
| def ContextDerivedTypedList(klass, base_class=List): |
| """Specialized TypedList for use with ContextDerivedValue types. |
| """ |
| assert issubclass(klass, ContextDerivedValue) |
| class _TypedList(ContextDerivedValue, TypedList(klass, base_class)): |
| def __init__(self, context, iterable=[]): |
| self.context = context |
| super(_TypedList, self).__init__(iterable) |
| |
| def normalize(self, e): |
| if not isinstance(e, klass): |
| e = klass(self.context, e) |
| return e |
| |
| return _TypedList |
| |
| @memoize |
| def ContextDerivedTypedListWithItems(type, base_class=List): |
| """Specialized TypedList for use with ContextDerivedValue types. |
| """ |
| class _TypedListWithItems(ContextDerivedTypedList(type, base_class)): |
| def __getitem__(self, name): |
| name = self.normalize(name) |
| return super(_TypedListWithItems, self).__getitem__(name) |
| |
| return _TypedListWithItems |
| |
| |
| @memoize |
| def ContextDerivedTypedRecord(*fields): |
| """Factory for objects with certain properties and dynamic |
| type checks. |
| |
| This API is extremely similar to the TypedNamedTuple API, |
| except that properties may be mutated. This supports syntax like: |
| |
| VARIABLE_NAME.property += [ |
| 'item1', |
| 'item2', |
| ] |
| """ |
| |
| class _TypedRecord(ContextDerivedValue): |
| __slots__ = tuple([name for name, _ in fields]) |
| |
| def __init__(self, context): |
| for fname, ftype in self._fields.items(): |
| if issubclass(ftype, ContextDerivedValue): |
| setattr(self, fname, self._fields[fname](context)) |
| else: |
| setattr(self, fname, self._fields[fname]()) |
| |
| def __setattr__(self, name, value): |
| if name in self._fields and not isinstance(value, self._fields[name]): |
| value = self._fields[name](value) |
| object.__setattr__(self, name, value) |
| |
| _TypedRecord._fields = dict(fields) |
| return _TypedRecord |
| |
| |
| @memoize |
| def ContextDerivedTypedHierarchicalStringList(type): |
| """Specialized HierarchicalStringList for use with ContextDerivedValue |
| types.""" |
| class _TypedListWithItems(ContextDerivedValue, HierarchicalStringList): |
| __slots__ = ('_strings', '_children', '_context') |
| |
| def __init__(self, context): |
| self._strings = ContextDerivedTypedList( |
| type, StrictOrderingOnAppendList)(context) |
| self._children = {} |
| self._context = context |
| |
| def _get_exportvariable(self, name): |
| child = self._children.get(name) |
| if not child: |
| child = self._children[name] = _TypedListWithItems( |
| self._context) |
| return child |
| |
| return _TypedListWithItems |
| |
| |
| BugzillaComponent = TypedNamedTuple('BugzillaComponent', |
| [('product', unicode), ('component', unicode)]) |
| |
| WebPlatformTestManifest = TypedNamedTuple("WebPlatformTestManifest", |
| [("manifest_path", unicode), |
| ("test_root", unicode)]) |
| |
| OrderedSourceList = ContextDerivedTypedList(SourcePath, StrictOrderingOnAppendList) |
| OrderedTestFlavorList = TypedList(Enum(*all_test_flavors()), |
| StrictOrderingOnAppendList) |
| OrderedStringList = TypedList(unicode, StrictOrderingOnAppendList) |
| DependentTestsEntry = ContextDerivedTypedRecord(('files', OrderedSourceList), |
| ('tags', OrderedStringList), |
| ('flavors', OrderedTestFlavorList)) |
| |
| class Files(SubContext): |
| """Metadata attached to files. |
| |
| It is common to want to annotate files with metadata, such as which |
| Bugzilla component tracks issues with certain files. This sub-context is |
| where we stick that metadata. |
| |
| The argument to this sub-context is a file matching pattern that is applied |
| against the host file's directory. If the pattern matches a file whose info |
| is currently being sought, the metadata attached to this instance will be |
| applied to that file. |
| |
| Patterns are collections of filename characters with ``/`` used as the |
| directory separate (UNIX-style paths) and ``*`` and ``**`` used to denote |
| wildcard matching. |
| |
| Patterns without the ``*`` character are literal matches and will match at |
| most one entity. |
| |
| Patterns with ``*`` or ``**`` are wildcard matches. ``*`` matches files |
| at least within a single directory. ``**`` matches files across several |
| directories. |
| |
| ``foo.html`` |
| Will match only the ``foo.html`` file in the current directory. |
| ``*.jsm`` |
| Will match all ``.jsm`` files in the current directory. |
| ``**/*.cpp`` |
| Will match all ``.cpp`` files in this and all child directories. |
| ``foo/*.css`` |
| Will match all ``.css`` files in the ``foo/`` directory. |
| ``bar/*`` |
| Will match all files in the ``bar/`` directory and all of its |
| children directories. |
| ``bar/**`` |
| This is equivalent to ``bar/*`` above. |
| ``bar/**/foo`` |
| Will match all ``foo`` files in the ``bar/`` directory and all of its |
| children directories. |
| |
| The difference in behavior between ``*`` and ``**`` is only evident if |
| a pattern follows the ``*`` or ``**``. A pattern ending with ``*`` is |
| greedy. ``**`` is needed when you need an additional pattern after the |
| wildcard. e.g. ``**/foo``. |
| """ |
| |
| VARIABLES = { |
| 'BUG_COMPONENT': (BugzillaComponent, tuple, |
| """The bug component that tracks changes to these files. |
| |
| Values are a 2-tuple of unicode describing the Bugzilla product and |
| component. e.g. ``('Core', 'Build Config')``. |
| """, None), |
| |
| 'FINAL': (bool, bool, |
| """Mark variable assignments as finalized. |
| |
| During normal processing, values from newer Files contexts |
| overwrite previously set values. Last write wins. This behavior is |
| not always desired. ``FINAL`` provides a mechanism to prevent |
| further updates to a variable. |
| |
| When ``FINAL`` is set, the value of all variables defined in this |
| context are marked as frozen and all subsequent writes to them |
| are ignored during metadata reading. |
| |
| See :ref:`mozbuild_files_metadata_finalizing` for more info. |
| """, None), |
| 'IMPACTED_TESTS': (DependentTestsEntry, list, |
| """File patterns, tags, and flavors for tests relevant to these files. |
| |
| Maps source files to the tests potentially impacted by those files. |
| Tests can be specified by file pattern, tag, or flavor. |
| |
| For example: |
| |
| with Files('runtests.py'): |
| IMPACTED_TESTS.files += [ |
| '**', |
| ] |
| |
| in testing/mochitest/moz.build will suggest that any of the tests |
| under testing/mochitest may be impacted by a change to runtests.py. |
| |
| File patterns may be made relative to the topsrcdir with a leading |
| '/', so |
| |
| with Files('httpd.js'): |
| IMPACTED_TESTS.files += [ |
| '/testing/mochitest/tests/Harness_sanity/**', |
| ] |
| |
| in netwerk/test/httpserver/moz.build will suggest that any change to httpd.js |
| will be relevant to the mochitest sanity tests. |
| |
| Tags and flavors are sorted string lists (flavors are limited to valid |
| values). |
| |
| For example: |
| |
| with Files('toolkit/devtools/*'): |
| IMPACTED_TESTS.tags += [ |
| 'devtools', |
| ] |
| |
| in the root moz.build would suggest that any test tagged 'devtools' would |
| potentially be impacted by a change to a file under toolkit/devtools, and |
| |
| with Files('dom/base/nsGlobalWindow.cpp'): |
| IMPACTED_TESTS.flavors += [ |
| 'mochitest', |
| ] |
| |
| Would suggest that nsGlobalWindow.cpp is potentially relevant to |
| any plain mochitest. |
| """, None), |
| } |
| |
| def __init__(self, parent, pattern=None): |
| super(Files, self).__init__(parent) |
| self.pattern = pattern |
| self.finalized = set() |
| self.test_files = set() |
| self.test_tags = set() |
| self.test_flavors = set() |
| |
| def __iadd__(self, other): |
| assert isinstance(other, Files) |
| |
| self.test_files |= other.test_files |
| self.test_tags |= other.test_tags |
| self.test_flavors |= other.test_flavors |
| |
| for k, v in other.items(): |
| if k == 'IMPACTED_TESTS': |
| self.test_files |= set(mozpath.relpath(e.full_path, e.context.config.topsrcdir) |
| for e in v.files) |
| self.test_tags |= set(v.tags) |
| self.test_flavors |= set(v.flavors) |
| continue |
| |
| # Ignore updates to finalized flags. |
| if k in self.finalized: |
| continue |
| |
| # Only finalize variables defined in this instance. |
| if k == 'FINAL': |
| self.finalized |= set(other) - {'FINAL'} |
| continue |
| |
| self[k] = v |
| |
| return self |
| |
| def asdict(self): |
| """Return this instance as a dict with built-in data structures. |
| |
| Call this to obtain an object suitable for serializing. |
| """ |
| d = {} |
| if 'BUG_COMPONENT' in self: |
| bc = self['BUG_COMPONENT'] |
| d['bug_component'] = (bc.product, bc.component) |
| |
| return d |
| |
| @staticmethod |
| def aggregate(files): |
| """Given a mapping of path to Files, obtain aggregate results. |
| |
| Consumers may want to extract useful information from a collection of |
| Files describing paths. e.g. given the files info data for N paths, |
| recommend a single bug component based on the most frequent one. This |
| function provides logic for deriving aggregate knowledge from a |
| collection of path File metadata. |
| |
| Note: the intent of this function is to operate on the result of |
| :py:func:`mozbuild.frontend.reader.BuildReader.files_info`. The |
| :py:func:`mozbuild.frontend.context.Files` instances passed in are |
| thus the "collapsed" (``__iadd__``ed) results of all ``Files`` from all |
| moz.build files relevant to a specific path, not individual ``Files`` |
| instances from a single moz.build file. |
| """ |
| d = {} |
| |
| bug_components = Counter() |
| |
| for f in files.values(): |
| bug_component = f.get('BUG_COMPONENT') |
| if bug_component: |
| bug_components[bug_component] += 1 |
| |
| d['bug_component_counts'] = [] |
| for c, count in bug_components.most_common(): |
| component = (c.product, c.component) |
| d['bug_component_counts'].append((c, count)) |
| |
| if 'recommended_bug_component' not in d: |
| d['recommended_bug_component'] = component |
| recommended_count = count |
| elif count == recommended_count: |
| # Don't recommend a component if it doesn't have a clear lead. |
| d['recommended_bug_component'] = None |
| |
| # In case no bug components. |
| d.setdefault('recommended_bug_component', None) |
| |
| return d |
| |
| |
| # This defines functions that create sub-contexts. |
| # |
| # Values are classes that are SubContexts. The class name will be turned into |
| # a function that when called emits an instance of that class. |
| # |
| # Arbitrary arguments can be passed to the class constructor. The first |
| # argument is always the parent context. It is up to each class to perform |
| # argument validation. |
| SUBCONTEXTS = [ |
| Files, |
| ] |
| |
| for cls in SUBCONTEXTS: |
| if not issubclass(cls, SubContext): |
| raise ValueError('SUBCONTEXTS entry not a SubContext class: %s' % cls) |
| |
| if not hasattr(cls, 'VARIABLES'): |
| raise ValueError('SUBCONTEXTS entry does not have VARIABLES: %s' % cls) |
| |
| SUBCONTEXTS = {cls.__name__: cls for cls in SUBCONTEXTS} |
| |
| |
| # This defines the set of mutable global variables. |
| # |
| # Each variable is a tuple of: |
| # |
| # (storage_type, input_types, docs, tier) |
| # |
| # Tier says for which specific tier the variable has an effect. |
| # Valid tiers are: |
| # - 'export' |
| # - 'libs': everything that is not built from C/C++/ObjC source and that has |
| # traditionally been in the libs tier. |
| # - 'misc': like libs, but with parallel build. Eventually, everything that |
| # currently is in libs should move here. |
| # A value of None means the variable has no direct effect on any tier. |
| |
| VARIABLES = { |
| 'ALLOW_COMPILER_WARNINGS': (bool, bool, |
| """Whether to allow compiler warnings (i.e. *not* treat them as |
| errors). |
| |
| This is commonplace (almost mandatory, in fact) in directories |
| containing third-party code that we regularly update from upstream and |
| thus do not control, but is otherwise discouraged. |
| """, None), |
| |
| # Variables controlling reading of other frontend files. |
| 'ANDROID_GENERATED_RESFILES': (StrictOrderingOnAppendList, list, |
| """Android resource files generated as part of the build. |
| |
| This variable contains a list of files that are expected to be |
| generated (often by preprocessing) into a 'res' directory as |
| part of the build process, and subsequently merged into an APK |
| file. |
| """, 'export'), |
| |
| 'ANDROID_APK_NAME': (unicode, unicode, |
| """The name of an Android APK file to generate. |
| """, 'export'), |
| |
| 'ANDROID_APK_PACKAGE': (unicode, unicode, |
| """The name of the Android package to generate R.java for, like org.mozilla.gecko. |
| """, 'export'), |
| |
| 'ANDROID_EXTRA_PACKAGES': (StrictOrderingOnAppendList, list, |
| """The name of extra Android packages to generate R.java for, like ['org.mozilla.other']. |
| """, 'export'), |
| |
| 'ANDROID_EXTRA_RES_DIRS': (ContextDerivedTypedListWithItems(Path, List), list, |
| """Android extra package resource directories. |
| |
| This variable contains a list of directories containing static files |
| to package into a 'res' directory and merge into an APK file. These |
| directories are packaged into the APK but are assumed to be static |
| unchecked dependencies that should not be otherwise re-distributed. |
| """, 'export'), |
| |
| 'ANDROID_RES_DIRS': (ContextDerivedTypedListWithItems(Path, List), list, |
| """Android resource directories. |
| |
| This variable contains a list of directories containing static |
| files to package into a 'res' directory and merge into an APK |
| file. |
| """, 'export'), |
| |
| 'ANDROID_ASSETS_DIRS': (ContextDerivedTypedListWithItems(Path, List), list, |
| """Android assets directories. |
| |
| This variable contains a list of directories containing static |
| files to package into an 'assets' directory and merge into an |
| APK file. |
| """, 'export'), |
| |
| 'ANDROID_ECLIPSE_PROJECT_TARGETS': (dict, dict, |
| """Defines Android Eclipse project targets. |
| |
| This variable should not be populated directly. Instead, it should |
| populated by calling add_android_eclipse{_library}_project(). |
| """, 'export'), |
| |
| 'SOURCES': (ContextDerivedTypedListWithItems(Path, StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool, 'flags': List})), list, |
| """Source code files. |
| |
| This variable contains a list of source code files to compile. |
| Accepts assembler, C, C++, Objective C/C++. |
| """, None), |
| |
| 'FILES_PER_UNIFIED_FILE': (int, int, |
| """The number of source files to compile into each unified source file. |
| |
| """, 'None'), |
| |
| 'UNIFIED_SOURCES': (ContextDerivedTypedList(SourcePath, StrictOrderingOnAppendList), list, |
| """Source code files that can be compiled together. |
| |
| This variable contains a list of source code files to compile, |
| that can be concatenated all together and built as a single source |
| file. This can help make the build faster and reduce the debug info |
| size. |
| """, None), |
| |
| 'GENERATED_FILES': (StrictOrderingOnAppendListWithFlagsFactory({ |
| 'script': unicode, |
| 'inputs': list }), list, |
| """Generic generated files. |
| |
| This variable contains a list of files for the build system to |
| generate at export time. The generation method may be declared |
| with optional ``script`` and ``inputs`` flags on individual entries. |
| If the optional ``script`` flag is not present on an entry, it |
| is assumed that rules for generating the file are present in |
| the associated Makefile.in. |
| |
| Example:: |
| |
| GENERATED_FILES += ['bar.c', 'baz.c', 'foo.c'] |
| bar = GENERATED_FILES['bar.c'] |
| bar.script = 'generate.py' |
| bar.inputs = ['datafile-for-bar'] |
| foo = GENERATED_FILES['foo.c'] |
| foo.script = 'generate.py' |
| foo.inputs = ['datafile-for-foo'] |
| |
| This definition will generate bar.c by calling the main method of |
| generate.py with a open (for writing) file object for bar.c, and |
| the string ``datafile-for-bar``. In a similar fashion, the main |
| method of generate.py will also be called with an open |
| (for writing) file object for foo.c and the string |
| ``datafile-for-foo``. Please note that only string arguments are |
| supported for passing to scripts, and that all arguments provided |
| to the script should be filenames relative to the directory in which |
| the moz.build file is located. |
| |
| To enable using the same script for generating multiple files with |
| slightly different non-filename parameters, alternative entry points |
| into ``script`` can be specified:: |
| |
| GENERATED_FILES += ['bar.c'] |
| bar = GENERATED_FILES['bar.c'] |
| bar.script = 'generate.py:make_bar' |
| |
| The chosen script entry point may optionally return a set of strings, |
| indicating extra files the output depends on. |
| """, 'export'), |
| |
| 'DEFINES': (OrderedDict, dict, |
| """Dictionary of compiler defines to declare. |
| |
| These are passed in to the compiler as ``-Dkey='value'`` for string |
| values, ``-Dkey=value`` for numeric values, or ``-Dkey`` if the |
| value is True. Note that for string values, the outer-level of |
| single-quotes will be consumed by the shell. If you want to have |
| a string-literal in the program, the value needs to have |
| double-quotes. |
| |
| Example:: |
| |
| DEFINES['NS_NO_XPCOM'] = True |
| DEFINES['MOZ_EXTENSIONS_DB_SCHEMA'] = 15 |
| DEFINES['DLL_SUFFIX'] = '".so"' |
| |
| This will result in the compiler flags ``-DNS_NO_XPCOM``, |
| ``-DMOZ_EXTENSIONS_DB_SCHEMA=15``, and ``-DDLL_SUFFIX='".so"'``, |
| respectively. These could also be combined into a single |
| update:: |
| |
| DEFINES.update({ |
| 'NS_NO_XPCOM': True, |
| 'MOZ_EXTENSIONS_DB_SCHEMA': 15, |
| 'DLL_SUFFIX': '".so"', |
| }) |
| """, None), |
| |
| 'DELAYLOAD_DLLS': (List, list, |
| """Delay-loaded DLLs. |
| |
| This variable contains a list of DLL files which the module being linked |
| should load lazily. This only has an effect when building with MSVC. |
| """, None), |
| |
| 'DIRS': (ContextDerivedTypedList(SourcePath), list, |
| """Child directories to descend into looking for build frontend files. |
| |
| This works similarly to the ``DIRS`` variable in make files. Each str |
| value in the list is the name of a child directory. When this file is |
| done parsing, the build reader will descend into each listed directory |
| and read the frontend file there. If there is no frontend file, an error |
| is raised. |
| |
| Values are relative paths. They can be multiple directory levels |
| above or below. Use ``..`` for parent directories and ``/`` for path |
| delimiters. |
| """, None), |
| |
| 'HAS_MISC_RULE': (bool, bool, |
| """Whether this directory should be traversed in the ``misc`` tier. |
| |
| Many ``libs`` rules still exist in Makefile.in files. We highly prefer |
| that these rules exist in the ``misc`` tier/target so that they can be |
| executed concurrently during tier traversal (the ``misc`` tier is |
| fully concurrent). |
| |
| Presence of this variable indicates that this directory should be |
| traversed by the ``misc`` tier. |
| |
| Please note that converting ``libs`` rules to the ``misc`` tier must |
| be done with care, as there are many implicit dependencies that can |
| break the build in subtle ways. |
| """, 'misc'), |
| |
| 'FINAL_TARGET_FILES': (ContextDerivedTypedHierarchicalStringList(Path), list, |
| """List of files to be installed into the application directory. |
| |
| ``FINAL_TARGET_FILES`` will copy (or symlink, if the platform supports it) |
| the contents of its files to the directory specified by |
| ``FINAL_TARGET`` (typically ``dist/bin``). Files that are destined for a |
| subdirectory can be specified by accessing a field, or as a dict access. |
| For example, to export ``foo.png`` to the top-level directory and |
| ``bar.svg`` to the directory ``images/do-not-use``, append to |
| ``FINAL_TARGET_FILES`` like so:: |
| |
| FINAL_TARGET_FILES += ['foo.png'] |
| FINAL_TARGET_FILES.images['do-not-use'] += ['bar.svg'] |
| """, None), |
| |
| 'DISABLE_STL_WRAPPING': (bool, bool, |
| """Disable the wrappers for STL which allow it to work with C++ exceptions |
| disabled. |
| """, None), |
| |
| 'FINAL_TARGET_PP_FILES': (ContextDerivedTypedHierarchicalStringList(Path), list, |
| """Like ``FINAL_TARGET_FILES``, with preprocessing. |
| """, 'libs'), |
| |
| 'TESTING_FILES': (ContextDerivedTypedHierarchicalStringList(Path), list, |
| """List of files to be installed in the _tests directory. |
| |
| This works similarly to FINAL_TARGET_FILES. |
| """, None), |
| |
| '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), |
| |
| 'CPP_UNIT_TESTS': (StrictOrderingOnAppendList, list, |
| """Compile a list of C++ unit test names. |
| |
| Each name in this variable corresponds to an executable built from the |
| corresponding source file with the same base name. |
| |
| If the configuration token ``BIN_SUFFIX`` is set, its value will be |
| automatically appended to each name. If a name already ends with |
| ``BIN_SUFFIX``, the name will remain unchanged. |
| """, None), |
| |
| 'FORCE_SHARED_LIB': (bool, bool, |
| """Whether the library in this directory is a shared library. |
| """, None), |
| |
| 'FORCE_STATIC_LIB': (bool, bool, |
| """Whether the library in this directory is a static library. |
| """, None), |
| |
| 'USE_STATIC_LIBS': (bool, bool, |
| """Whether the code in this directory is a built against the static |
| runtime library. |
| |
| This variable only has an effect when building with MSVC. |
| """, None), |
| |
| 'HOST_SOURCES': (ContextDerivedTypedList(SourcePath, StrictOrderingOnAppendList), list, |
| """Source code files to compile with the host compiler. |
| |
| This variable contains a list of source code files to compile. |
| with the host compiler. |
| """, None), |
| |
| 'IS_COMPONENT': (bool, bool, |
| """Whether the library contains a binary XPCOM component manifest. |
| |
| Implies FORCE_SHARED_LIB. |
| """, None), |
| |
| 'PYTHON_UNIT_TESTS': (StrictOrderingOnAppendList, list, |
| """A list of python unit tests. |
| """, None), |
| |
| 'HOST_LIBRARY_NAME': (unicode, unicode, |
| """Name of target library generated when cross compiling. |
| """, None), |
| |
| 'JAVA_JAR_TARGETS': (dict, dict, |
| """Defines Java JAR targets to be built. |
| |
| This variable should not be populated directly. Instead, it should |
| populated by calling add_java_jar(). |
| """, 'libs'), |
| |
| 'LIBRARY_DEFINES': (OrderedDict, dict, |
| """Dictionary of compiler defines to declare for the entire library. |
| |
| This variable works like DEFINES, except that declarations apply to all |
| libraries that link into this library via FINAL_LIBRARY. |
| """, None), |
| |
| 'LIBRARY_NAME': (unicode, unicode, |
| """The code name of the library generated for a directory. |
| |
| By default STATIC_LIBRARY_NAME and SHARED_LIBRARY_NAME take this name. |
| In ``example/components/moz.build``,:: |
| |
| LIBRARY_NAME = 'xpcomsample' |
| |
| would generate ``example/components/libxpcomsample.so`` on Linux, or |
| ``example/components/xpcomsample.lib`` on Windows. |
| """, None), |
| |
| 'SHARED_LIBRARY_NAME': (unicode, unicode, |
| """The name of the static library generated for a directory, if it needs to |
| differ from the library code name. |
| |
| Implies FORCE_SHARED_LIB. |
| """, None), |
| |
| 'IS_FRAMEWORK': (bool, bool, |
| """Whether the library to build should be built as a framework on OSX. |
| |
| This implies the name of the library won't be prefixed nor suffixed. |
| Implies FORCE_SHARED_LIB. |
| """, None), |
| |
| 'STATIC_LIBRARY_NAME': (unicode, unicode, |
| """The name of the static library generated for a directory, if it needs to |
| differ from the library code name. |
| |
| Implies FORCE_STATIC_LIB. |
| """, None), |
| |
| 'USE_LIBS': (StrictOrderingOnAppendList, list, |
| """List of libraries to link to programs and libraries. |
| """, None), |
| |
| 'HOST_USE_LIBS': (StrictOrderingOnAppendList, list, |
| """List of libraries to link to host programs and libraries. |
| """, None), |
| |
| 'HOST_OS_LIBS': (List, list, |
| """List of system libraries for host programs and libraries. |
| """, None), |
| |
| 'LOCAL_INCLUDES': (ContextDerivedTypedList(Path, StrictOrderingOnAppendList), list, |
| """Additional directories to be searched for include files by the compiler. |
| """, None), |
| |
| 'NO_PGO': (bool, bool, |
| """Whether profile-guided optimization is disable in this directory. |
| """, None), |
| |
| 'NO_VISIBILITY_FLAGS': (bool, bool, |
| """Build sources listed in this file without VISIBILITY_FLAGS. |
| """, None), |
| |
| 'OS_LIBS': (List, list, |
| """System link libraries. |
| |
| This variable contains a list of system libaries to link against. |
| """, None), |
| 'RCFILE': (unicode, unicode, |
| """The program .rc file. |
| |
| This variable can only be used on Windows. |
| """, None), |
| |
| 'RESFILE': (unicode, unicode, |
| """The program .res file. |
| |
| This variable can only be used on Windows. |
| """, None), |
| |
| 'RCINCLUDE': (unicode, unicode, |
| """The resource script file to be included in the default .res file. |
| |
| This variable can only be used on Windows. |
| """, None), |
| |
| 'DEFFILE': (unicode, unicode, |
| """The program .def (module definition) file. |
| |
| This variable can only be used on Windows. |
| """, None), |
| |
| 'LD_VERSION_SCRIPT': (unicode, unicode, |
| """The linker version script for shared libraries. |
| |
| This variable can only be used on Linux. |
| """, None), |
| |
| 'BRANDING_FILES': (HierarchicalStringList, list, |
| """List of files to be installed into the branding directory. |
| |
| ``BRANDING_FILES`` will copy (or symlink, if the platform supports it) |
| the contents of its files to the ``dist/branding`` directory. Files that |
| are destined for a subdirectory can be specified by accessing a field. |
| For example, to export ``foo.png`` to the top-level directory and |
| ``bar.png`` to the directory ``images/subdir``, append to |
| ``BRANDING_FILES`` like so:: |
| |
| BRANDING_FILES += ['foo.png'] |
| BRANDING_FILES.images.subdir += ['bar.png'] |
| """, None), |
| |
| 'SDK_LIBRARY': (bool, bool, |
| """Whether the library built in the directory is part of the SDK. |
| |
| The library will be copied into ``SDK_LIB_DIR`` (``$DIST/sdk/lib``). |
| """, None), |
| |
| 'SIMPLE_PROGRAMS': (StrictOrderingOnAppendList, list, |
| """Compile a list of executable names. |
| |
| Each name in this variable corresponds to an executable built from the |
| corresponding source file with the same base name. |
| |
| If the configuration token ``BIN_SUFFIX`` is set, its value will be |
| automatically appended to each name. If a name already ends with |
| ``BIN_SUFFIX``, the name will remain unchanged. |
| """, None), |
| |
| 'SONAME': (unicode, unicode, |
| """The soname of the shared object currently being linked |
| |
| soname is the "logical name" of a shared object, often used to provide |
| version backwards compatibility. This variable makes sense only for |
| shared objects, and is supported only on some unix platforms. |
| """, None), |
| |
| 'HOST_SIMPLE_PROGRAMS': (StrictOrderingOnAppendList, list, |
| """Compile a list of host executable names. |
| |
| Each name in this variable corresponds to a hosst executable built |
| from the corresponding source file with the same base name. |
| |
| If the configuration token ``HOST_BIN_SUFFIX`` is set, its value will |
| be automatically appended to each name. If a name already ends with |
| ``HOST_BIN_SUFFIX``, the name will remain unchanged. |
| """, None), |
| |
| 'TEST_DIRS': (ContextDerivedTypedList(SourcePath), list, |
| """Like DIRS but only for directories that contain test-only code. |
| |
| If tests are not enabled, this variable will be ignored. |
| |
| This variable may go away once the transition away from Makefiles is |
| complete. |
| """, None), |
| |
| 'CONFIGURE_SUBST_FILES': (ContextDerivedTypedList(SourcePath, StrictOrderingOnAppendList), list, |
| """Output files that will be generated using configure-like substitution. |
| |
| This is a substitute for ``AC_OUTPUT`` in autoconf. For each path in this |
| list, we will search for a file in the srcdir having the name |
| ``{path}.in``. The contents of this file will be read and variable |
| patterns like ``@foo@`` will be substituted with the values of the |
| ``AC_SUBST`` variables declared during configure. |
| """, None), |
| |
| 'CONFIGURE_DEFINE_FILES': (ContextDerivedTypedList(SourcePath, StrictOrderingOnAppendList), list, |
| """Output files generated from configure/config.status. |
| |
| This is a substitute for ``AC_CONFIG_HEADER`` in autoconf. This is very |
| similar to ``CONFIGURE_SUBST_FILES`` except the generation logic takes |
| into account the values of ``AC_DEFINE`` instead of ``AC_SUBST``. |
| """, None), |
| |
| 'EXPORTS': (ContextDerivedTypedHierarchicalStringList(Path), list, |
| """List of files to be exported, and in which subdirectories. |
| |
| ``EXPORTS`` is generally used to list the include files to be exported to |
| ``dist/include``, but it can be used for other files as well. This variable |
| behaves as a list when appending filenames for export in the top-level |
| directory. Files can also be appended to a field to indicate which |
| subdirectory they should be exported to. For example, to export |
| ``foo.h`` to the top-level directory, and ``bar.h`` to ``mozilla/dom/``, |
| append to ``EXPORTS`` like so:: |
| |
| EXPORTS += ['foo.h'] |
| EXPORTS.mozilla.dom += ['bar.h'] |
| |
| Entries in ``EXPORTS`` are paths, so objdir paths may be used, but |
| any files listed from the objdir must also be listed in |
| ``GENERATED_FILES``. |
| """, None), |
| |
| 'PROGRAM' : (unicode, unicode, |
| """Compiled executable name. |
| |
| If the configuration token ``BIN_SUFFIX`` is set, its value will be |
| automatically appended to ``PROGRAM``. If ``PROGRAM`` already ends with |
| ``BIN_SUFFIX``, ``PROGRAM`` will remain unchanged. |
| """, None), |
| |
| 'HOST_PROGRAM' : (unicode, unicode, |
| """Compiled host executable name. |
| |
| If the configuration token ``HOST_BIN_SUFFIX`` is set, its value will be |
| automatically appended to ``HOST_PROGRAM``. If ``HOST_PROGRAM`` already |
| ends with ``HOST_BIN_SUFFIX``, ``HOST_PROGRAM`` will remain unchanged. |
| """, None), |
| |
| 'DIST_INSTALL': (Enum(None, False, True), bool, |
| """Whether to install certain files into the dist directory. |
| |
| By default, some files types are installed in the dist directory, and |
| some aren't. Set this variable to True to force the installation of |
| some files that wouldn't be installed by default. Set this variable to |
| False to force to not install some files that would be installed by |
| default. |
| |
| This is confusing for historical reasons, but eventually, the behavior |
| will be made explicit. |
| """, None), |
| |
| 'JAR_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """JAR manifest files that should be processed as part of the build. |
| |
| JAR manifests are files in the tree that define how to package files |
| into JARs and how chrome registration is performed. For more info, |
| see :ref:`jar_manifests`. |
| """, 'libs'), |
| |
| # IDL Generation. |
| 'XPIDL_SOURCES': (StrictOrderingOnAppendList, list, |
| """XPCOM Interface Definition Files (xpidl). |
| |
| This is a list of files that define XPCOM interface definitions. |
| Entries must be files that exist. Entries are almost certainly ``.idl`` |
| files. |
| """, 'export'), |
| |
| 'XPIDL_MODULE': (unicode, unicode, |
| """XPCOM Interface Definition Module Name. |
| |
| This is the name of the ``.xpt`` file that is created by linking |
| ``XPIDL_SOURCES`` together. If unspecified, it defaults to be the same |
| as ``MODULE``. |
| """, None), |
| |
| 'XPIDL_NO_MANIFEST': (bool, bool, |
| """Indicate that the XPIDL module should not be added to a manifest. |
| |
| This flag exists primarily to prevent test-only XPIDL modules from being |
| added to the application's chrome manifest. Most XPIDL modules should |
| not use this flag. |
| """, None), |
| |
| 'IPDL_SOURCES': (StrictOrderingOnAppendList, list, |
| """IPDL source files. |
| |
| These are ``.ipdl`` files that will be parsed and converted to |
| ``.cpp`` files. |
| """, 'export'), |
| |
| 'WEBIDL_FILES': (StrictOrderingOnAppendList, list, |
| """WebIDL source files. |
| |
| These will be parsed and converted to ``.cpp`` and ``.h`` files. |
| """, 'export'), |
| |
| 'GENERATED_EVENTS_WEBIDL_FILES': (StrictOrderingOnAppendList, list, |
| """WebIDL source files for generated events. |
| |
| These will be parsed and converted to ``.cpp`` and ``.h`` files. |
| """, 'export'), |
| |
| 'TEST_WEBIDL_FILES': (StrictOrderingOnAppendList, list, |
| """Test WebIDL source files. |
| |
| These will be parsed and converted to ``.cpp`` and ``.h`` files |
| if tests are enabled. |
| """, 'export'), |
| |
| 'GENERATED_WEBIDL_FILES': (StrictOrderingOnAppendList, list, |
| """Generated WebIDL source files. |
| |
| These will be generated from some other files. |
| """, 'export'), |
| |
| 'PREPROCESSED_TEST_WEBIDL_FILES': (StrictOrderingOnAppendList, list, |
| """Preprocessed test WebIDL source files. |
| |
| These will be preprocessed, then parsed and converted to .cpp |
| and ``.h`` files if tests are enabled. |
| """, 'export'), |
| |
| 'PREPROCESSED_WEBIDL_FILES': (StrictOrderingOnAppendList, list, |
| """Preprocessed WebIDL source files. |
| |
| These will be preprocessed before being parsed and converted. |
| """, 'export'), |
| |
| 'WEBIDL_EXAMPLE_INTERFACES': (StrictOrderingOnAppendList, list, |
| """Names of example WebIDL interfaces to build as part of the build. |
| |
| Names in this list correspond to WebIDL interface names defined in |
| WebIDL files included in the build from one of the \*WEBIDL_FILES |
| variables. |
| """, 'export'), |
| |
| # Test declaration. |
| 'A11Y_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining a11y tests. |
| """, None), |
| |
| 'BROWSER_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining browser chrome tests. |
| """, None), |
| |
| 'JETPACK_PACKAGE_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining jetpack package tests. |
| """, None), |
| |
| 'JETPACK_ADDON_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining jetpack addon tests. |
| """, None), |
| |
| 'CRASHTEST_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining crashtests. |
| |
| These are commonly named crashtests.list. |
| """, None), |
| |
| 'ANDROID_INSTRUMENTATION_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining Android instrumentation tests. |
| """, None), |
| |
| 'METRO_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining metro browser chrome tests. |
| """, None), |
| |
| 'MOCHITEST_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining mochitest chrome tests. |
| """, None), |
| |
| 'MOCHITEST_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining mochitest tests. |
| """, None), |
| |
| 'MOCHITEST_WEBAPPRT_CONTENT_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining webapprt mochitest content tests. |
| """, None), |
| |
| 'MOCHITEST_WEBAPPRT_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining webapprt mochitest chrome tests. |
| """, None), |
| |
| 'REFTEST_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining reftests. |
| |
| These are commonly named reftest.list. |
| """, None), |
| |
| 'WEB_PLATFORM_TESTS_MANIFESTS': (TypedList(WebPlatformTestManifest), list, |
| """List of (manifest_path, test_path) defining web-platform-tests. |
| """, None), |
| |
| 'WEBRTC_SIGNALLING_TEST_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining WebRTC signalling tests. |
| """, None), |
| |
| 'XPCSHELL_TESTS_MANIFESTS': (StrictOrderingOnAppendList, list, |
| """List of manifest files defining xpcshell tests. |
| """, None), |
| |
| # The following variables are used to control the target of installed files. |
| 'XPI_NAME': (unicode, unicode, |
| """The name of an extension XPI to generate. |
| |
| When this variable is present, the results of this directory will end up |
| being packaged into an extension instead of the main dist/bin results. |
| """, 'libs'), |
| |
| 'DIST_SUBDIR': (unicode, unicode, |
| """The name of an alternate directory to install files to. |
| |
| When this variable is present, the results of this directory will end up |
| being placed in the $(DIST_SUBDIR) subdirectory of where it would |
| otherwise be placed. |
| """, None), |
| |
| 'FINAL_TARGET': (FinalTargetValue, unicode, |
| """The name of the directory to install targets to. |
| |
| The directory is relative to the top of the object directory. The |
| default value is dependent on the values of XPI_NAME and DIST_SUBDIR. If |
| neither are present, the result is dist/bin. If XPI_NAME is present, the |
| result is dist/xpi-stage/$(XPI_NAME). If DIST_SUBDIR is present, then |
| the $(DIST_SUBDIR) directory of the otherwise default value is used. |
| """, None), |
| |
| 'USE_EXTENSION_MANIFEST': (bool, bool, |
| """Controls the name of the manifest for JAR files. |
| |
| By default, the name of the manifest is ${JAR_MANIFEST}.manifest. |
| Setting this variable to ``True`` changes the name of the manifest to |
| chrome.manifest. |
| """, None), |
| |
| 'NO_JS_MANIFEST': (bool, bool, |
| """Explicitly disclaims responsibility for manifest listing in EXTRA_COMPONENTS. |
| |
| Normally, if you have .js files listed in ``EXTRA_COMPONENTS`` or |
| ``EXTRA_PP_COMPONENTS``, you are expected to have a corresponding |
| .manifest file to go with those .js files. Setting ``NO_JS_MANIFEST`` |
| indicates that the relevant .manifest file and entries for those .js |
| files are elsehwere (jar.mn, for instance) and this state of affairs |
| is OK. |
| """, None), |
| |
| 'GYP_DIRS': (StrictOrderingOnAppendListWithFlagsFactory({ |
| 'variables': dict, |
| 'input': unicode, |
| 'sandbox_vars': dict, |
| 'non_unified_sources': StrictOrderingOnAppendList, |
| }), list, |
| """Defines a list of object directories handled by gyp configurations. |
| |
| Elements of this list give the relative object directory. For each |
| element of the list, GYP_DIRS may be accessed as a dictionary |
| (GYP_DIRS[foo]). The object this returns has attributes that need to be |
| set to further specify gyp processing: |
| - input, gives the path to the root gyp configuration file for that |
| object directory. |
| - variables, a dictionary containing variables and values to pass |
| to the gyp processor. |
| - sandbox_vars, a dictionary containing variables and values to |
| pass to the mozbuild processor on top of those derived from gyp |
| configuration. |
| - non_unified_sources, a list containing sources files, relative to |
| the current moz.build, that should be excluded from source file |
| unification. |
| |
| Typical use looks like: |
| GYP_DIRS += ['foo', 'bar'] |
| GYP_DIRS['foo'].input = 'foo/foo.gyp' |
| GYP_DIRS['foo'].variables = { |
| 'foo': 'bar', |
| (...) |
| } |
| (...) |
| """, None), |
| |
| 'SPHINX_TREES': (dict, dict, |
| """Describes what the Sphinx documentation tree will look like. |
| |
| Keys are relative directories inside the final Sphinx documentation |
| tree to install files into. Values are directories (relative to this |
| file) whose content to copy into the Sphinx documentation tree. |
| """, None), |
| |
| 'SPHINX_PYTHON_PACKAGE_DIRS': (StrictOrderingOnAppendList, list, |
| """Directories containing Python packages that Sphinx documents. |
| """, None), |
| |
| 'CFLAGS': (List, list, |
| """Flags passed to the C compiler for all of the C source files |
| declared in this directory. |
| |
| Note that the ordering of flags matters here, these flags will be |
| added to the compiler's command line in the same order as they |
| appear in the moz.build file. |
| """, None), |
| |
| 'CXXFLAGS': (List, list, |
| """Flags passed to the C++ compiler for all of the C++ source files |
| declared in this directory. |
| |
| Note that the ordering of flags matters here; these flags will be |
| added to the compiler's command line in the same order as they |
| appear in the moz.build file. |
| """, None), |
| |
| 'HOST_DEFINES': (OrderedDict, dict, |
| """Dictionary of compiler defines to declare for host compilation. |
| See ``DEFINES`` for specifics. |
| """, None), |
| |
| 'CMFLAGS': (List, list, |
| """Flags passed to the Objective-C compiler for all of the Objective-C |
| source files declared in this directory. |
| |
| Note that the ordering of flags matters here; these flags will be |
| added to the compiler's command line in the same order as they |
| appear in the moz.build file. |
| """, None), |
| |
| 'CMMFLAGS': (List, list, |
| """Flags passed to the Objective-C++ compiler for all of the |
| Objective-C++ source files declared in this directory. |
| |
| Note that the ordering of flags matters here; these flags will be |
| added to the compiler's command line in the same order as they |
| appear in the moz.build file. |
| """, None), |
| |
| 'ASFLAGS': (List, list, |
| """Flags passed to the assembler for all of the assembly source files |
| declared in this directory. |
| |
| Note that the ordering of flags matters here; these flags will be |
| added to the assembler's command line in the same order as they |
| appear in the moz.build file. |
| """, None), |
| |
| 'HOST_CFLAGS': (List, list, |
| """Flags passed to the host C compiler for all of the C source files |
| declared in this directory. |
| |
| Note that the ordering of flags matters here, these flags will be |
| added to the compiler's command line in the same order as they |
| appear in the moz.build file. |
| """, None), |
| |
| 'HOST_CXXFLAGS': (List, list, |
| """Flags passed to the host C++ compiler for all of the C++ source files |
| declared in this directory. |
| |
| Note that the ordering of flags matters here; these flags will be |
| added to the compiler's command line in the same order as they |
| appear in the moz.build file. |
| """, None), |
| |
| 'LDFLAGS': (List, list, |
| """Flags passed to the linker when linking all of the libraries and |
| executables declared in this directory. |
| |
| Note that the ordering of flags matters here; these flags will be |
| added to the linker's command line in the same order as they |
| appear in the moz.build file. |
| """, None), |
| |
| 'EXTRA_DSO_LDOPTS': (List, list, |
| """Flags passed to the linker when linking a shared library. |
| |
| Note that the ordering of flags matter here, these flags will be |
| added to the linker's command line in the same order as they |
| appear in the moz.build file. |
| """, None), |
| |
| 'WIN32_EXE_LDFLAGS': (List, list, |
| """Flags passed to the linker when linking a Windows .exe executable |
| declared in this directory. |
| |
| Note that the ordering of flags matter here, these flags will be |
| added to the linker's command line in the same order as they |
| appear in the moz.build file. |
| |
| This variable only has an effect on Windows. |
| """, None), |
| |
| 'TEST_HARNESS_FILES': (HierarchicalStringList, list, |
| """List of files to be installed for test harnesses. |
| |
| ``TEST_HARNESS_FILES`` can be used to install files to any directory |
| under $objdir/_tests. Files can be appended to a field to indicate |
| which subdirectory they should be exported to. For example, |
| to export ``foo.py`` to ``_tests/foo``, append to |
| ``TEST_HARNESS_FILES`` like so:: |
| TEST_HARNESS_FILES.foo += ['foo.py'] |
| |
| Files from topsrcdir and the objdir can also be installed by prefixing |
| the path(s) with a '/' character and a '!' character, respectively:: |
| TEST_HARNESS_FILES.path += ['/build/bar.py', '!quux.py'] |
| """, 'libs'), |
| |
| 'NO_EXPAND_LIBS': (bool, bool, |
| """Forces to build a real static library, and no corresponding fake |
| library. |
| """, None), |
| |
| 'NO_COMPONENTS_MANIFEST': (bool, bool, |
| """Do not create a binary-component manifest entry for the |
| corresponding XPCOMBinaryComponent. |
| """, None), |
| } |
| |
| # Sanity check: we don't want any variable above to have a list as storage type. |
| for name, (storage_type, input_types, docs, tier) in VARIABLES.items(): |
| if storage_type == list: |
| raise RuntimeError('%s has a "list" storage type. Use "List" instead.' |
| % name) |
| |
| # Set of variables that are only allowed in templates: |
| TEMPLATE_VARIABLES = { |
| 'CPP_UNIT_TESTS', |
| 'FORCE_SHARED_LIB', |
| 'HOST_PROGRAM', |
| 'HOST_LIBRARY_NAME', |
| 'HOST_SIMPLE_PROGRAMS', |
| 'IS_COMPONENT', |
| 'IS_FRAMEWORK', |
| 'LIBRARY_NAME', |
| 'PROGRAM', |
| 'SIMPLE_PROGRAMS', |
| } |
| |
| # Add a note to template variable documentation. |
| for name in TEMPLATE_VARIABLES: |
| if name not in VARIABLES: |
| raise RuntimeError('%s is in TEMPLATE_VARIABLES but not in VARIABLES.' |
| % name) |
| storage_type, input_types, docs, tier = VARIABLES[name] |
| docs += 'This variable is only available in templates.\n' |
| VARIABLES[name] = (storage_type, input_types, docs, tier) |
| |
| |
| # The set of functions exposed to the sandbox. |
| # |
| # Each entry is a tuple of: |
| # |
| # (function returning the corresponding function from a given sandbox, |
| # (argument types), docs) |
| # |
| # The first element is an attribute on Sandbox that should be a function type. |
| # |
| FUNCTIONS = { |
| 'include': (lambda self: self._include, (SourcePath,), |
| """Include another mozbuild file in the context of this one. |
| |
| This is similar to a ``#include`` in C languages. The filename passed to |
| the function will be read and its contents will be evaluated within the |
| context of the calling file. |
| |
| If a relative path is given, it is evaluated as relative to the file |
| currently being processed. If there is a chain of multiple include(), |
| the relative path computation is from the most recent/active file. |
| |
| If an absolute path is given, it is evaluated from ``TOPSRCDIR``. In |
| other words, ``include('/foo')`` references the path |
| ``TOPSRCDIR + '/foo'``. |
| |
| Example usage |
| ^^^^^^^^^^^^^ |
| |
| Include ``sibling.build`` from the current directory.:: |
| |
| include('sibling.build') |
| |
| Include ``foo.build`` from a path within the top source directory:: |
| |
| include('/elsewhere/foo.build') |
| """), |
| |
| 'add_java_jar': (lambda self: self._add_java_jar, (str,), |
| """Declare a Java JAR target to be built. |
| |
| This is the supported way to populate the JAVA_JAR_TARGETS |
| variable. |
| |
| The parameters are: |
| * dest - target name, without the trailing .jar. (required) |
| |
| This returns a rich Java JAR type, described at |
| :py:class:`mozbuild.frontend.data.JavaJarData`. |
| """), |
| |
| 'add_android_eclipse_project': ( |
| lambda self: self._add_android_eclipse_project, (str, str), |
| """Declare an Android Eclipse project. |
| |
| This is one of the supported ways to populate the |
| ANDROID_ECLIPSE_PROJECT_TARGETS variable. |
| |
| The parameters are: |
| * name - project name. |
| * manifest - path to AndroidManifest.xml. |
| |
| This returns a rich Android Eclipse project type, described at |
| :py:class:`mozbuild.frontend.data.AndroidEclipseProjectData`. |
| """), |
| |
| 'add_android_eclipse_library_project': ( |
| lambda self: self._add_android_eclipse_library_project, (str,), |
| """Declare an Android Eclipse library project. |
| |
| This is one of the supported ways to populate the |
| ANDROID_ECLIPSE_PROJECT_TARGETS variable. |
| |
| The parameters are: |
| * name - project name. |
| |
| This returns a rich Android Eclipse project type, described at |
| :py:class:`mozbuild.frontend.data.AndroidEclipseProjectData`. |
| """), |
| |
| 'export': (lambda self: self._export, (str,), |
| """Make the specified variable available to all child directories. |
| |
| The variable specified by the argument string is added to the |
| environment of all directories specified in the DIRS and TEST_DIRS |
| variables. If those directories themselves have child directories, |
| the variable will be exported to all of them. |
| |
| The value used for the variable is the final value at the end of the |
| moz.build file, so it is possible (but not recommended style) to place |
| the export before the definition of the variable. |
| |
| This function is limited to the upper-case variables that have special |
| meaning in moz.build files. |
| |
| NOTE: Please consult with a build peer before adding a new use of this |
| function. |
| |
| Example usage |
| ^^^^^^^^^^^^^ |
| |
| To make all children directories install as the given extension:: |
| |
| XPI_NAME = 'cool-extension' |
| export('XPI_NAME') |
| """), |
| |
| 'warning': (lambda self: self._warning, (str,), |
| """Issue a warning. |
| |
| Warnings are string messages that are printed during execution. |
| |
| Warnings are ignored during execution. |
| """), |
| |
| 'error': (lambda self: self._error, (str,), |
| """Issue a fatal error. |
| |
| If this function is called, processing is aborted immediately. |
| """), |
| |
| 'template': (lambda self: self._template_decorator, (FunctionType,), |
| """Decorator for template declarations. |
| |
| Templates are a special kind of functions that can be declared in |
| mozbuild files. Uppercase variables assigned in the function scope |
| are considered to be the result of the template. |
| |
| Contrary to traditional python functions: |
| - return values from template functions are ignored, |
| - template functions don't have access to the global scope. |
| |
| Example template |
| ^^^^^^^^^^^^^^^^ |
| |
| The following ``Program`` template sets two variables ``PROGRAM`` and |
| ``USE_LIBS``. ``PROGRAM`` is set to the argument given on the template |
| invocation, and ``USE_LIBS`` to contain "mozglue":: |
| |
| @template |
| def Program(name): |
| PROGRAM = name |
| USE_LIBS += ['mozglue'] |
| |
| Template invocation |
| ^^^^^^^^^^^^^^^^^^^ |
| |
| A template is invoked in the form of a function call:: |
| |
| Program('myprog') |
| |
| The result of the template, being all the uppercase variable it sets |
| is mixed to the existing set of variables defined in the mozbuild file |
| invoking the template:: |
| |
| FINAL_TARGET = 'dist/other' |
| USE_LIBS += ['mylib'] |
| Program('myprog') |
| USE_LIBS += ['otherlib'] |
| |
| The above mozbuild results in the following variables set: |
| |
| - ``FINAL_TARGET`` is 'dist/other' |
| - ``USE_LIBS`` is ['mylib', 'mozglue', 'otherlib'] |
| - ``PROGRAM`` is 'myprog' |
| |
| """), |
| } |
| |
| # Special variables. These complement VARIABLES. |
| # |
| # Each entry is a tuple of: |
| # |
| # (function returning the corresponding value from a given context, type, docs) |
| # |
| SPECIAL_VARIABLES = { |
| 'TOPSRCDIR': (lambda context: context.config.topsrcdir, str, |
| """Constant defining the top source directory. |
| |
| The top source directory is the parent directory containing the source |
| code and all build files. It is typically the root directory of a |
| cloned repository. |
| """), |
| |
| 'TOPOBJDIR': (lambda context: context.config.topobjdir, str, |
| """Constant defining the top object directory. |
| |
| The top object directory is the parent directory which will contain |
| the output of the build. This is commonly referred to as "the object |
| directory." |
| """), |
| |
| 'RELATIVEDIR': (lambda context: context.relsrcdir, str, |
| """Constant defining the relative path of this file. |
| |
| The relative path is from ``TOPSRCDIR``. This is defined as relative |
| to the main file being executed, regardless of whether additional |
| files have been included using ``include()``. |
| """), |
| |
| 'SRCDIR': (lambda context: context.srcdir, str, |
| """Constant defining the source directory of this file. |
| |
| This is the path inside ``TOPSRCDIR`` where this file is located. It |
| is the same as ``TOPSRCDIR + RELATIVEDIR``. |
| """), |
| |
| 'OBJDIR': (lambda context: context.objdir, str, |
| """The path to the object directory for this file. |
| |
| Is is the same as ``TOPOBJDIR + RELATIVEDIR``. |
| """), |
| |
| 'CONFIG': (lambda context: ReadOnlyKeyedDefaultDict( |
| lambda key: context.config.substs_unicode.get(key)), dict, |
| """Dictionary containing the current configuration 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. |
| """), |
| |
| 'JS_PREFERENCE_FILES': (lambda context: context['FINAL_TARGET_FILES'].defaults.pref._strings, list, |
| """Exported javascript files. |
| |
| A list of files copied into the dist directory for packaging and installation. |
| Path will be defined for gre or application prefs dir based on what is building. |
| """), |
| |
| 'JS_PREFERENCE_PP_FILES': (lambda context: context['FINAL_TARGET_PP_FILES'].defaults.pref._strings, list, |
| """Like JS_PREFERENCE_FILES, preprocessed.. |
| """), |
| |
| 'RESOURCE_FILES': (lambda context: context['FINAL_TARGET_FILES'].res, list, |
| """List of resources to be exported, and in which subdirectories. |
| |
| ``RESOURCE_FILES`` is used to list the resource files to be exported to |
| ``dist/bin/res``, but it can be used for other files as well. This variable |
| behaves as a list when appending filenames for resources in the top-level |
| directory. Files can also be appended to a field to indicate which |
| subdirectory they should be exported to. For example, to export |
| ``foo.res`` to the top-level directory, and ``bar.res`` to ``fonts/``, |
| append to ``RESOURCE_FILES`` like so:: |
| |
| RESOURCE_FILES += ['foo.res'] |
| RESOURCE_FILES.fonts += ['bar.res'] |
| """), |
| |
| 'EXTRA_JS_MODULES': (lambda context: context['FINAL_TARGET_FILES'].modules, list, |
| """Additional JavaScript files to distribute. |
| |
| This variable contains a list of files to copy into |
| ``$(FINAL_TARGET)/modules. |
| """), |
| |
| 'EXTRA_PP_JS_MODULES': (lambda context: context['FINAL_TARGET_PP_FILES'].modules, list, |
| """Additional JavaScript files to distribute. |
| |
| This variable contains a list of files to copy into |
| ``$(FINAL_TARGET)/modules``, after preprocessing. |
| """), |
| |
| 'TESTING_JS_MODULES': (lambda context: context['TESTING_FILES'].modules, list, |
| """JavaScript modules to install in the test-only destination. |
| |
| Some JavaScript modules (JSMs) are test-only and not distributed |
| 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']``. |
| """), |
| |
| } |
| |
| # Deprecation hints. |
| DEPRECATION_HINTS = { |
| 'CPP_UNIT_TESTS': ''' |
| Please use' |
| |
| CppUnitTests(['foo', 'bar']) |
| |
| instead of |
| |
| CPP_UNIT_TESTS += ['foo', 'bar'] |
| ''', |
| |
| 'HOST_PROGRAM': ''' |
| Please use |
| |
| HostProgram('foo') |
| |
| instead of |
| |
| HOST_PROGRAM = 'foo' |
| ''', |
| |
| 'HOST_LIBRARY_NAME': ''' |
| Please use |
| |
| HostLibrary('foo') |
| |
| instead of |
| |
| HOST_LIBRARY_NAME = 'foo' |
| ''', |
| |
| 'HOST_SIMPLE_PROGRAMS': ''' |
| Please use |
| |
| HostSimplePrograms(['foo', 'bar']) |
| |
| instead of |
| |
| HOST_SIMPLE_PROGRAMS += ['foo', 'bar']" |
| ''', |
| |
| 'LIBRARY_NAME': ''' |
| Please use |
| |
| Library('foo') |
| |
| instead of |
| |
| LIBRARY_NAME = 'foo' |
| ''', |
| |
| 'PROGRAM': ''' |
| Please use |
| |
| Program('foo') |
| |
| instead of |
| |
| PROGRAM = 'foo'" |
| ''', |
| |
| 'SIMPLE_PROGRAMS': ''' |
| Please use |
| |
| SimplePrograms(['foo', 'bar']) |
| |
| instead of |
| |
| SIMPLE_PROGRAMS += ['foo', 'bar']" |
| ''', |
| |
| 'FORCE_SHARED_LIB': ''' |
| Please use |
| |
| SharedLibrary('foo') |
| |
| instead of |
| |
| Library('foo') [ or LIBRARY_NAME = 'foo' ] |
| FORCE_SHARED_LIB = True |
| ''', |
| |
| 'IS_COMPONENT': ''' |
| Please use |
| |
| XPCOMBinaryComponent('foo') |
| |
| instead of |
| |
| Library('foo') [ or LIBRARY_NAME = 'foo' ] |
| IS_COMPONENT = True |
| ''', |
| |
| 'IS_FRAMEWORK': ''' |
| Please use |
| |
| Framework('foo') |
| |
| instead of |
| |
| Library('foo') [ or LIBRARY_NAME = 'foo' ] |
| IS_FRAMEWORK = True |
| ''', |
| |
| 'TOOL_DIRS': 'Please use the DIRS variable instead.', |
| |
| 'TEST_TOOL_DIRS': 'Please use the TEST_DIRS variable instead.', |
| |
| 'PARALLEL_DIRS': 'Please use the DIRS variable instead.', |
| |
| 'NO_DIST_INSTALL': ''' |
| Please use |
| |
| DIST_INSTALL = False |
| |
| instead of |
| |
| NO_DIST_INSTALL = True |
| ''', |
| |
| 'GENERATED_SOURCES': ''' |
| Please use |
| |
| SOURCES += [ '!foo.cpp' ] |
| |
| instead of |
| |
| GENERATED_SOURCES += [ 'foo.cpp'] |
| ''', |
| |
| 'GENERATED_INCLUDES': ''' |
| Please use |
| |
| LOCAL_INCLUDES += [ '!foo' ] |
| |
| instead of |
| |
| GENERATED_INCLUDES += [ 'foo' ] |
| ''', |
| |
| 'DIST_FILES': ''' |
| Please use |
| |
| FINAL_TARGET_PP_FILES += [ 'foo' ] |
| |
| instead of |
| |
| DIST_FILES += [ 'foo' ] |
| ''', |
| } |
| |
| # Make sure that all template variables have a deprecation hint. |
| for name in TEMPLATE_VARIABLES: |
| if name not in DEPRECATION_HINTS: |
| raise RuntimeError('Missing deprecation hint for %s' % name) |