Bug 1407432 - Move stl wrapper generation into moz.build; r=froydnj
authorMike Shal <mshal@mozilla.com>
Wed, 08 Nov 2017 17:42:27 -0500
changeset 444568 ccc34ca6ecfde0b52f0725caeefc03ecf5ec20a5
parent 444567 94f475532485aacdbb8e2c664a8da4a68e0c9e93
child 444569 04b2f4aca51f65ebf35755d79cd76cf5f1d6f8d9
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1407432
milestone58.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 1407432 - Move stl wrapper generation into moz.build; r=froydnj This is fairly straightforward to represent as a GENERATED_FILES, though we have to take some care to construct the outputs tuple correctly. This script needs to run during export, and unfortunately none of the STL headers have proper file extensions, so the 'new' header is special-cased in the recursive make backend to serve as a marker for running it in the correct tier. We can't remove the stl-headers file yet because it is still used for the system header generation. MozReview-Commit-ID: 3tQTOY0LAsQ
config/Makefile.in
config/make-stl-wrappers.py
config/moz.build
config/stl-headers.mozbuild
python/mozbuild/mozbuild/backend/recursivemake.py
python/mozbuild/mozbuild/frontend/sandbox.py
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -50,40 +50,16 @@ export:: $(export-preqs)
 		-DMOZ_SYSTEM_LIBVPX=$(MOZ_SYSTEM_LIBVPX) \
 		-DMOZ_SYSTEM_ICU=$(MOZ_SYSTEM_ICU) \
 		$(srcdir)/system-headers $(srcdir)/stl-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers
 	$(INSTALL) system_wrappers $(DIST)
 
 GARBAGE_DIRS += system_wrappers
 endif
 
-ifdef WRAP_STL_INCLUDES
-ifdef GNU_CXX
-stl_compiler = gcc
-else
-ifdef _MSC_VER
-stl_compiler = msvc
-endif
-endif
-endif
-
-ifdef stl_compiler
-STL_WRAPPERS_SENTINEL = $(DIST)/stl_wrappers/sentinel
-
-$(STL_WRAPPERS_SENTINEL): $(srcdir)/make-stl-wrappers.py $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers $(GLOBAL_DEPS)
-	$(PYTHON) $(srcdir)/make-stl-wrappers.py stl_wrappers $(stl_compiler) $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers
-	$(PYTHON) $(srcdir)/nsinstall.py -t stl_wrappers $(DIST)
-	touch $(STL_WRAPPERS_SENTINEL)
-
-export:: $(STL_WRAPPERS_SENTINEL)
-
-GARBAGE += $(STL_WRAPPERS_SENTINEL)
-GARBAGE_DIRS += stl_wrappers
-endif
-
 GARBAGE += \
   $(FINAL_LINK_COMPS) $(FINAL_LINK_LIBS) $(FINAL_LINK_COMP_NAMES) $(srcdir)/*.pyc *.pyc
 
 FORCE:
 
 ifndef JS_STANDALONE
 check-preqs += check-jar-mn
 endif
--- a/config/make-stl-wrappers.py
+++ b/config/make-stl-wrappers.py
@@ -17,36 +17,18 @@ def header_path(header, compiler):
         # we use include_next on gcc
         return header
     elif compiler == 'msvc':
         return find_in_path(header, os.environ.get('INCLUDE', ''))
     else:
         # hope someone notices this ...
         raise NotImplementedError(compiler)
 
-def is_comment(line):
-    return re.match(r'\s*#.*', line)
-
-def main(outdir, compiler, template_file, header_list_file):
-    if not os.path.isdir(outdir):
-        os.mkdir(outdir)
-
+# The 'unused' arg is the output file from the file_generate action. We actually
+# generate all the files in header_list
+def gen_wrappers(unused, outdir, compiler, template_file, *header_list):
     template = open(template_file, 'r').read()
 
-    for header in open(header_list_file, 'r'):
-        header = header.rstrip()
-        if 0 == len(header) or is_comment(header):
-            continue
-
+    for header in header_list:
         path = header_path(header, compiler)
         with FileAvoidWrite(os.path.join(outdir, header)) as f:
             f.write(string.Template(template).substitute(HEADER=header,
                                                          HEADER_PATH=path))
-
-
-if __name__ == '__main__':
-    if 5 != len(sys.argv):
-        print("""Usage:
-  python {0} OUT_DIR ('msvc'|'gcc') TEMPLATE_FILE HEADER_LIST_FILE
-""".format(sys.argv[0]), file=sys.stderr)
-        sys.exit(1)
-
-    main(*sys.argv[1:])
--- a/config/moz.build
+++ b/config/moz.build
@@ -37,8 +37,29 @@ PYTHON_UNITTEST_MANIFESTS += [
 
 if CONFIG['GNU_CC'] and CONFIG['MOZ_OPTIMIZE']:
     CFLAGS += ['-O3']
 
 HOST_DEFINES = {
     'UNICODE': True,
     '_UNICODE': True,
 }
+
+include('stl-headers.mozbuild')
+if CONFIG['WRAP_STL_INCLUDES']:
+    stl_compiler = None
+    if CONFIG['GNU_CXX']:
+        stl_compiler = 'gcc'
+    elif CONFIG['_MSC_VER']:
+        stl_compiler = 'msvc'
+
+    if stl_compiler:
+        template_file = SRCDIR + '/%s-stl-wrapper.template.h' % stl_compiler
+        output_dir = '../dist/stl_wrappers'
+        # We have to use a sentinel file as the first file because the
+        # file_generate action will create it for us, but we want to create all
+        # the files in gen_wrappers()
+        outputs = tuple(['stl.sentinel'] + ['%s/%s' % (output_dir, h) for h in stl_headers])
+        GENERATED_FILES += [outputs]
+        stl = GENERATED_FILES[outputs]
+        stl.script = 'make-stl-wrappers.py:gen_wrappers'
+        stl.flags = [output_dir, stl_compiler, template_file]
+        stl.flags.extend(stl_headers)
new file mode 100644
--- /dev/null
+++ b/config/stl-headers.mozbuild
@@ -0,0 +1,57 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This list contains the of STL headers that have been reviewed for exception
+# safety and approved. See
+#
+#   https://bugzilla.mozilla.org/show_bug.cgi?id=551254
+#
+# At build time, each header listed here is converted into a "wrapper
+# header" that is installed into dist/stl_includes.
+#
+# If you would like to request a new STL header <foo> be added, please
+# file a Core:XPCOM bug with a title like "STL: Review exception
+# safety of <foo> for gcc and MSVC".
+stl_headers = [
+    'new',
+
+    # FIXME: these headers haven't been reviewed yet, but we use them
+    # unsafely in Gecko, so we might as well prevent them from
+    # throwing exceptions
+    'algorithm',
+    'atomic',
+    'deque',
+    'functional',
+    'ios',
+    'iosfwd',
+    'iostream',
+    'istream',
+    'iterator',
+    'limits',
+    'list',
+    'map',
+    'memory',
+    'ostream',
+    'set',
+    'stack',
+    'string',
+    'thread',
+    'type_traits',
+    'unordered_map',
+    'unordered_set',
+    'utility',
+    'vector',
+    'cassert',
+    'climits',
+    'cmath',
+    'cstdarg',
+    'cstdio',
+    'cstdlib',
+    'cstring',
+    'cwchar',
+    'tuple',
+    'xutility',
+]
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -520,16 +520,17 @@ class RecursiveMakeBackend(CommonBackend
         elif isinstance(obj, GeneratedFile):
             export_suffixes = (
                 '.c',
                 '.cpp',
                 '.h',
                 '.inc',
                 '.py',
                 '.rs',
+                'new', # 'new' is an output from make-stl-wrappers.py
             )
             tier = 'export' if any(f.endswith(export_suffixes) for f in obj.outputs) else 'misc'
             self._no_skip[tier].add(backend_file.relobjdir)
             first_output = obj.outputs[0]
             dep_file = "%s.pp" % first_output
 
             # If we're doing this during export that means we need it during
             # compile, but if we have an artifact build we don't run compile,
--- a/python/mozbuild/mozbuild/frontend/sandbox.py
+++ b/python/mozbuild/mozbuild/frontend/sandbox.py
@@ -106,16 +106,17 @@ class Sandbox(dict):
     BUILTINS = ReadOnlyDict({
         # Only real Python built-ins should go here.
         'None': None,
         'False': False,
         'True': True,
         'sorted': alphabetical_sorted,
         'int': int,
         'set': set,
+        'tuple': tuple,
     })
 
     def __init__(self, context, finder=default_finder):
         """Initialize a Sandbox ready for execution.
         """
         self._builtins = self.BUILTINS
         dict.__setitem__(self, '__builtins__', self._builtins)