Bug 1231314 - Turn mozilla-config.h and js-confdefs.h into CONFIGURE_DEFINE_FILES. r=gps
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 04 Dec 2015 10:51:12 +0900
changeset 276417 3033ec8d8b3aadcef610dbdf6f5d5110dd9027c0
parent 276416 8ebce8df55cd8b53e3a0a15fffba10bed869d610
child 276418 75e62a17dbba803107221515cbe3fab7f540fcdf
push id16648
push usercbook@mozilla.com
push dateTue, 15 Dec 2015 13:54:56 +0000
treeherderfx-team@8d24d95b8a13 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs1231314
milestone45.0a1
Bug 1231314 - Turn mozilla-config.h and js-confdefs.h into CONFIGURE_DEFINE_FILES. r=gps Both these files, are, after all, define files, like other CONFIGURE_DEFINE_FILES. They only happen to have a special requirement for an expansion for all defines, which doesn't need to happen through traditional preprocessing. This change adds consistency in how configure-related headers are being handled.
js/src/js-confdefs.h.in
js/src/moz.build
moz.build
mozilla-config.h.in
python/mozbuild/mozbuild/backend/common.py
python/mozbuild/mozbuild/backend/configenvironment.py
python/mozbuild/mozbuild/test/backend/test_configenvironment.py
--- a/js/src/js-confdefs.h.in
+++ b/js/src/js-confdefs.h.in
@@ -1,13 +1,14 @@
 /* List of defines generated by configure. Included with preprocessor flag,
  * -include, to avoid long list of -D defines on the compile command-line.
  * Do not edit.
  */
 
 #ifndef js_confdefs_h
 #define js_confdefs_h
 
-@ALLDEFINES@
+// Expands to all the defines from configure.
+#undef ALLDEFINES
 
 #include "js/RequiredDefines.h"
 
 #endif /* js_confdefs_h */
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -56,20 +56,22 @@ if CONFIG['JS_BUNDLED_EDITLINE']:
 # editline needs to get built before the shell
 if not CONFIG['JS_DISABLE_SHELL']:
     DIRS += ['shell']
 
 TEST_DIRS += ['jsapi-tests', 'tests', 'gdb']
 
 CONFIGURE_SUBST_FILES += [
     'devtools/rootAnalysis/Makefile',
-    'js-confdefs.h',
     'js-config',
     'js.pc',
 ]
+CONFIGURE_DEFINE_FILES += [
+    'js-confdefs.h',
+]
 
 if not CONFIG['JS_STANDALONE']:
     CONFIGURE_SUBST_FILES += [
         '../../config/autoconf-js.mk',
         '../../config/emptyvars-js.mk',
     ]
 
 CONFIGURE_DEFINE_FILES += [
--- a/moz.build
+++ b/moz.build
@@ -18,18 +18,20 @@ if CONFIG['ENABLE_CLANG_PLUGIN']:
 
 DIRS += [
     'config',
     'python',
 ]
 
 if not CONFIG['JS_STANDALONE']:
     CONFIGURE_SUBST_FILES += [
+        'tools/update-packaging/Makefile',
+    ]
+    CONFIGURE_DEFINE_FILES += [
         'mozilla-config.h',
-        'tools/update-packaging/Makefile',
     ]
 
     DIRS += [
         'build',
         'probes',
     ]
 
 DIRS += [
--- a/mozilla-config.h.in
+++ b/mozilla-config.h.in
@@ -8,17 +8,18 @@
 
 #if defined(__clang__)
 #pragma clang diagnostic push
 #if __has_warning("-Wreserved-id-macro")
 #pragma clang diagnostic ignored "-Wreserved-id-macro"
 #endif
 #endif
 
-@ALLDEFINES@
+// Expands to all the defines from configure.
+#undef ALLDEFINES
 
 /*
  * The c99 defining the limit macros (UINT32_MAX for example), says:
  *
  *   C++ implementations should define these macros only when
  *   __STDC_LIMIT_MACROS is defined before <stdint.h> is included.
  *
  * The same also occurs with __STDC_CONSTANT_MACROS for the constant macros
--- a/python/mozbuild/mozbuild/backend/common.py
+++ b/python/mozbuild/mozbuild/backend/common.py
@@ -377,28 +377,42 @@ class CommonBackend(BuildBackend):
         '''Creates the given config header. A config header is generated by
         taking the corresponding source file and replacing some #define/#undef
         occurences:
             "#undef NAME" is turned into "#define NAME VALUE"
             "#define NAME" is unchanged
             "#define NAME ORIGINAL_VALUE" is turned into "#define NAME VALUE"
             "#undef UNKNOWN_NAME" is turned into "/* #undef UNKNOWN_NAME */"
             Whitespaces are preserved.
+
+        As a special rule, "#undef ALLDEFINES" is turned into "#define NAME
+        VALUE" for all the defined variables.
         '''
         with self._write_file(obj.output_path) as fh, \
              open(obj.input_path, 'rU') as input:
             r = re.compile('^\s*#\s*(?P<cmd>[a-z]+)(?:\s+(?P<name>\S+)(?:\s+(?P<value>\S+))?)?', re.U)
             for l in input:
                 m = r.match(l)
                 if m:
                     cmd = m.group('cmd')
                     name = m.group('name')
                     value = m.group('value')
                     if name:
-                        if name in obj.config.defines:
+                        if name == 'ALLDEFINES':
+                            if cmd == 'define':
+                                raise Exception(
+                                    '`#define ALLDEFINES` is not allowed in a '
+                                    'CONFIGURE_DEFINE_FILE')
+                            defines = '\n'.join(sorted(
+                                '#define %s %s' % (name, val)
+                                for name, val in obj.config.defines.iteritems()
+                                if name not in obj.config.non_global_defines))
+                            l = l[:m.start('cmd') - 1] \
+                                + defines + l[m.end('name'):]
+                        elif name in obj.config.defines:
                             if cmd == 'define' and value:
                                 l = l[:m.start('value')] \
                                     + str(obj.config.defines[name]) \
                                     + l[m.end('value'):]
                             elif cmd == 'undef':
                                 l = l[:m.start('cmd')] \
                                     + 'define' \
                                     + l[m.end('cmd'):m.end('name')] \
--- a/python/mozbuild/mozbuild/backend/configenvironment.py
+++ b/python/mozbuild/mozbuild/backend/configenvironment.py
@@ -76,34 +76,30 @@ class ConfigEnvironment(object):
     each treated through a different member function.
 
     Creating a ConfigEnvironment requires a few arguments:
       - topsrcdir and topobjdir are, respectively, the top source and
         the top object directory.
       - defines is a list of (name, value) tuples. In autoconf, these are
         set with AC_DEFINE and AC_DEFINE_UNQUOTED
       - non_global_defines are a list of names appearing in defines above
-        that are not meant to be exported in ACDEFINES and ALLDEFINES (see
-        below)
+        that are not meant to be exported in ACDEFINES (see below)
       - substs is a list of (name, value) tuples. In autoconf, these are
         set with AC_SUBST.
 
-    ConfigEnvironment automatically defines two additional substs variables
+    ConfigEnvironment automatically defines one additional substs variable
     from all the defines not appearing in non_global_defines:
       - ACDEFINES contains the defines in the form -DNAME=VALUE, for use on
         preprocessor command lines. The order in which defines were given
         when creating the ConfigEnvironment is preserved.
-      - ALLDEFINES contains the defines in the form #define NAME VALUE, in
-        sorted order, for use in config files, for an automatic listing of
-        defines.
     and two other additional subst variables from all the other substs:
       - ALLSUBSTS contains the substs in the form NAME = VALUE, in sorted
-        order, for use in autoconf.mk. It includes ACDEFINES, but doesn't
-        include ALLDEFINES. Only substs with a VALUE are included, such that
-        the resulting file doesn't change when new empty substs are added.
+        order, for use in autoconf.mk. It includes ACDEFINES
+        Only substs with a VALUE are included, such that the resulting file
+        doesn't change when new empty substs are added.
         This results in less invalidation of build dependencies in the case
         of autoconf.mk..
       - ALLEMPTYSUBSTS contains the substs with an empty value, in the form
         NAME =.
 
     ConfigEnvironment expects a "top_srcdir" subst to be set with the top
     source directory, in msys format on windows. It is used to derive a
     "srcdir" subst when treating config files. It can either be an absolute
@@ -112,16 +108,17 @@ class ConfigEnvironment(object):
 
     def __init__(self, topsrcdir, topobjdir, defines=[], non_global_defines=[],
         substs=[], source=None):
 
         if not source:
             source = mozpath.join(topobjdir, 'config.status')
         self.source = source
         self.defines = ReadOnlyDict(defines)
+        self.non_global_defines = non_global_defines
         self.substs = dict(substs)
         self.topsrcdir = mozpath.abspath(topsrcdir)
         self.topobjdir = mozpath.abspath(topobjdir)
         self.lib_prefix = self.substs.get('LIB_PREFIX', '')
         if 'LIB_SUFFIX' in self.substs:
             self.lib_suffix = '.%s' % self.substs['LIB_SUFFIX']
         self.dll_prefix = self.substs.get('DLL_PREFIX', '')
         self.dll_suffix = self.substs.get('DLL_SUFFIX', '')
@@ -141,18 +138,16 @@ class ConfigEnvironment(object):
                 return obj
             if isinstance(obj, Iterable):
                 return ' '.join(obj)
             raise Exception('Unhandled type %s', type(obj))
         self.substs['ALLSUBSTS'] = '\n'.join(sorted(['%s = %s' % (name,
             serialize(self.substs[name])) for name in self.substs if self.substs[name]]))
         self.substs['ALLEMPTYSUBSTS'] = '\n'.join(sorted(['%s =' % name
             for name in self.substs if not self.substs[name]]))
-        self.substs['ALLDEFINES'] = '\n'.join(sorted(['#define %s %s' % (name,
-            self.defines[name]) for name in global_defines]))
 
         self.substs = ReadOnlyDict(self.substs)
 
         self.external_source_dir = None
         external = self.substs.get('EXTERNAL_SOURCE_DIR', '')
         if external:
             external = mozpath.normpath(external)
             if not os.path.isabs(external):
--- a/python/mozbuild/mozbuild/test/backend/test_configenvironment.py
+++ b/python/mozbuild/mozbuild/test/backend/test_configenvironment.py
@@ -30,36 +30,30 @@ class ConfigEnvironment(ConfigStatus.Con
 
             d = dict(self.substs_unicode)
             d[u'top_srcdir'] = top_srcdir.decode('utf-8')
             self.substs_unicode = ReadOnlyDict(d)
 
 
 class TestEnvironment(unittest.TestCase):
     def test_auto_substs(self):
-        '''Test the automatically set values of ACDEFINES, ALLDEFINES,
-        ALLSUBSTS and ALLEMPTYSUBSTS.
+        '''Test the automatically set values of ACDEFINES, ALLSUBSTS
+        and ALLEMPTYSUBSTS.
         '''
         env = ConfigEnvironment('.', '.',
                   defines = [ ('foo', 'bar'), ('baz', 'qux 42'),
                               ('abc', "d'e'f"), ('extra', 'foobar') ],
                   non_global_defines = ['extra', 'ignore'],
                   substs = [ ('FOO', 'bar'), ('FOOBAR', ''), ('ABC', 'def'),
                              ('bar', 'baz qux'), ('zzz', '"abc def"'),
                              ('qux', '') ])
-        # non_global_defines should be filtered out in ACDEFINES and
-        # ALLDEFINES.
+        # non_global_defines should be filtered out in ACDEFINES.
         # Original order of the defines need to be respected in ACDEFINES
         self.assertEqual(env.substs['ACDEFINES'], """-Dfoo=bar -Dbaz='qux 42' -Dabc='d'\\''e'\\''f'""")
-        # ALLDEFINES, on the other hand, needs to be sorted
-        self.assertEqual(env.substs['ALLDEFINES'], '''#define abc d'e'f
-#define baz qux 42
-#define foo bar''')
-        # Likewise for ALLSUBSTS, which also mustn't contain ALLDEFINES
-        # but contain ACDEFINES
+        # Likewise for ALLSUBSTS, which also must contain ACDEFINES
         self.assertEqual(env.substs['ALLSUBSTS'], '''ABC = def
 ACDEFINES = -Dfoo=bar -Dbaz='qux 42' -Dabc='d'\\''e'\\''f'
 FOO = bar
 bar = baz qux
 zzz = "abc def"''')
         # ALLEMPTYSUBSTS contains all substs with no value.
         self.assertEqual(env.substs['ALLEMPTYSUBSTS'], '''FOOBAR =
 qux =''')