Bug 939074 - Infer LIBXUL_LIBRARY from FINAL_LIBRARY. r=gps
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 19 Nov 2013 11:47:52 +0900
changeset 156207 6d271ac31d9a1a39cc33fafc227bf3b448496188
parent 156206 5c94c8c9989eecfb881589c2fb5d697f3a2c1c8e
child 156208 71cbd5b14aecd782163fbeb0c63b4b73a38ba7a1
push id25670
push usermh@glandium.org
push dateTue, 19 Nov 2013 02:51:47 +0000
treeherdermozilla-central@e4b59fdbc9c2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs939074
milestone28.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 939074 - Infer LIBXUL_LIBRARY from FINAL_LIBRARY. r=gps
config/config.mk
js/src/config/config.mk
python/mozbuild/mozbuild/frontend/data.py
python/mozbuild/mozbuild/frontend/emitter.py
--- a/config/config.mk
+++ b/config/config.mk
@@ -39,16 +39,17 @@ endif
   CMSRCS \
   CMMSRCS \
   CPP_UNIT_TESTS \
   DIRS \
   EXTRA_PP_COMPONENTS \
   EXTRA_PP_JS_MODULES \
   FORCE_SHARED_LIB \
   FORCE_STATIC_LIB \
+  FINAL_LIBRARY \
   GTEST_CMMSRCS \
   GTEST_CPPSRCS \
   GTEST_CSRCS \
   HOST_CSRCS \
   HOST_CMMSRCS \
   HOST_LIBRARY_NAME \
   HOST_PROGRAM \
   HOST_SIMPLE_PROGRAMS \
@@ -328,16 +329,23 @@ endif
 #
 # Build using PIC by default
 #
 _ENABLE_PIC=1
 
 # Determine if module being compiled is destined
 # to be merged into libxul
 
+ifeq ($(FINAL_LIBRARY),xul)
+  ifdef LIBXUL_LIBRARY
+    $(error FINAL_LIBRARY is "xul", LIBXUL_LIBRARY is implied)
+  endif
+  LIBXUL_LIBRARY := 1
+endif
+
 ifdef LIBXUL_LIBRARY
 ifdef IS_COMPONENT
 $(error IS_COMPONENT is set, but is not compatible with LIBXUL_LIBRARY)
 endif
 ifdef MODULE_NAME
 $(error MODULE_NAME is $(MODULE_NAME) but MODULE_NAME and LIBXUL_LIBRARY are not compatible)
 endif
 FORCE_STATIC_LIB=1
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -39,16 +39,17 @@ endif
   CMSRCS \
   CMMSRCS \
   CPP_UNIT_TESTS \
   DIRS \
   EXTRA_PP_COMPONENTS \
   EXTRA_PP_JS_MODULES \
   FORCE_SHARED_LIB \
   FORCE_STATIC_LIB \
+  FINAL_LIBRARY \
   GTEST_CMMSRCS \
   GTEST_CPPSRCS \
   GTEST_CSRCS \
   HOST_CSRCS \
   HOST_CMMSRCS \
   HOST_LIBRARY_NAME \
   HOST_PROGRAM \
   HOST_SIMPLE_PROGRAMS \
@@ -328,16 +329,23 @@ endif
 #
 # Build using PIC by default
 #
 _ENABLE_PIC=1
 
 # Determine if module being compiled is destined
 # to be merged into libxul
 
+ifeq ($(FINAL_LIBRARY),xul)
+  ifdef LIBXUL_LIBRARY
+    $(error FINAL_LIBRARY is "xul", LIBXUL_LIBRARY is implied)
+  endif
+  LIBXUL_LIBRARY := 1
+endif
+
 ifdef LIBXUL_LIBRARY
 ifdef IS_COMPONENT
 $(error IS_COMPONENT is set, but is not compatible with LIBXUL_LIBRARY)
 endif
 ifdef MODULE_NAME
 $(error MODULE_NAME is $(MODULE_NAME) but MODULE_NAME and LIBXUL_LIBRARY are not compatible)
 endif
 FORCE_STATIC_LIB=1
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -330,22 +330,24 @@ class LibraryDefinition(SandboxDerived):
 
     The static_libraries member tracks the list of relative directory and
     library names of static libraries that are meant to be linked into
     the library defined by an instance of this class.
     """
     __slots__ = (
         'basename',
         'static_libraries',
+        'refcount',
     )
 
     def __init__(self, sandbox, basename):
         SandboxDerived.__init__(self, sandbox)
 
         self.basename = basename
+        self.refcount = 0
         self.static_libraries = []
 
     def link_static_lib(self, reldir, basename):
         self.static_libraries.append((reldir, basename))
 
 
 class TestManifest(SandboxDerived):
     """Represents a manifest file containing information about tests."""
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -77,19 +77,23 @@ class TreeMetadataEmitter(LoggingMixin):
     def emit(self, output):
         """Convert the BuildReader output into data structures.
 
         The return value from BuildReader.read_topsrcdir() (a generator) is
         typically fed into this function.
         """
         file_count = 0
         execution_time = 0.0
+        sandboxes = {}
 
         for out in output:
             if isinstance(out, MozbuildSandbox):
+                # Keep all sandboxes around, we will need them later.
+                sandboxes[out['RELATIVEDIR']] = out
+
                 for o in self.emit_from_sandbox(out):
                     yield o
                     if not o._ack:
                         raise Exception('Unhandled object of type %s' % type(o))
 
                 # Update the stats.
                 file_count += len(out.all_paths)
                 execution_time += out.execution_time
@@ -102,19 +106,39 @@ class TreeMetadataEmitter(LoggingMixin):
                 raise Exception('FINAL_LIBRARY in %s (%s) does not match any '
                                 'LIBRARY_NAME' % (reldir, final_lib))
             libs = self._libs[final_lib]
             if len(libs) > 1:
                 raise Exception('FINAL_LIBRARY in %s (%s) matches a '
                                 'LIBRARY_NAME defined in multiple places (%s)' %
                                 (reldir, final_lib, ', '.join(libs.keys())))
             libs.values()[0].link_static_lib(reldir, libname)
+            self._libs[libname][reldir].refcount += 1
+            # The refcount can't go above 1 right now. It might in the future,
+            # but that will have to be specifically handled. At which point the
+            # refcount might have to be a list of referencees, for better error
+            # reporting.
+            assert self._libs[libname][reldir].refcount <= 1
+
+        def recurse_libs(path, name):
+            for p, n in self._libs[name][path].static_libraries:
+                yield p
+                for q in recurse_libs(p, n):
+                    yield q
 
         for basename, libs in self._libs.items():
-            for libdef in libs.values():
+            for path, libdef in libs.items():
+                # For all root libraries (i.e. libraries that don't have a
+                # FINAL_LIBRARY), record, for each static library it links
+                # (recursively), that its FINAL_LIBRARY is that root library.
+                if not libdef.refcount:
+                    for p in recurse_libs(path, basename):
+                        passthru = VariablePassthru(sandboxes[p])
+                        passthru.variables['FINAL_LIBRARY'] = basename
+                        yield passthru
                 yield libdef
 
         yield ReaderSummary(file_count, execution_time)
 
     def emit_from_sandbox(self, sandbox):
         """Convert a MozbuildSandbox to tree metadata objects.
 
         This is a generator of mozbuild.frontend.data.SandboxDerived instances.