Bug 1319228 - Build dependentlibs.list in the tup backend, create a group for shared libraries to be used as its input. draft
authorChris Manchester <cmanchester@mozilla.com>
Wed, 13 Jun 2018 22:33:23 -0700
changeset 807317 43641ab7be8d20f8181045f116dd2729f39e48d2
parent 807316 25ceeb4da18d2835e5b7761f14b94751385113dd
push id113083
push userbmo:cmanchester@mozilla.com
push dateThu, 14 Jun 2018 06:09:19 +0000
bugs1319228
milestone62.0a1
Bug 1319228 - Build dependentlibs.list in the tup backend, create a group for shared libraries to be used as its input. MozReview-Commit-ID: 5nDZpTcqVfv
python/mozbuild/mozbuild/backend/tup.py
toolkit/library/dependentlibs.py
--- a/python/mozbuild/mozbuild/backend/tup.py
+++ b/python/mozbuild/mozbuild/backend/tup.py
@@ -254,16 +254,18 @@ class TupBackend(CommonBackend):
         # The preprocessor including source-repo.h and buildid.h creates
         # dependencies that aren't specified by moz.build and cause errors
         # in Tup. Express these as a group dependency.
         self._early_generated_files = '$(MOZ_OBJ_ROOT)/<early-generated-files>'
 
         self._built_in_addons = set()
         self._built_in_addons_file = 'dist/bin/browser/chrome/browser/content/browser/built_in_addons.json'
 
+        self._shlibs = '$(MOZ_OBJ_ROOT)/<shlibs>'
+
     def _get_mozconfig_env(self, config):
         env = {}
         loader = MozconfigLoader(config.topsrcdir)
         mozconfig = loader.read_mozconfig(config.substs['MOZCONFIG'])
         make_extra = mozconfig['make_extra'] or []
         env = {}
         for line in make_extra:
             if line.startswith('export '):
@@ -378,35 +380,40 @@ class TupBackend(CommonBackend):
             [backend_file.environment.substs['OS_LIBS']] +
             os_libs
         )
         backend_file.rule(
             cmd=cmd,
             inputs=inputs,
             extra_inputs=extra_inputs,
             outputs=[shlib.lib_name],
+            extra_outputs=[self._shlibs],
             display='LINK %o'
         )
         backend_file.symlink_rule(mozpath.join(backend_file.objdir,
                                                shlib.lib_name),
                                   output=mozpath.join(self.environment.topobjdir,
                                                       shlib.install_target,
-                                                      shlib.lib_name))
+                                                      shlib.lib_name),
+                                  output_group=self._shlibs)
 
     def _gen_programs(self, backend_file):
         for p in backend_file.programs:
             self._gen_program(backend_file, p)
 
     def _gen_program(self, backend_file, prog):
         cc_or_cxx = 'CXX' if prog.cxx_link else 'CC'
         objs, _, shared_libs, os_libs, static_libs = self._expand_libs(prog)
         static_libs = self._lib_paths(backend_file.objdir, static_libs)
         shared_libs = self._lib_paths(backend_file.objdir, shared_libs)
 
-        inputs = objs + static_libs + shared_libs
+        # Linking some programs will access libraries installed to dist/bin,
+        # so depend on the installed libraries here. This can be made more
+        # accurate once we start building libraries in their final locations.
+        inputs = objs + static_libs + shared_libs + [self._shlibs]
 
         list_file_name = '%s.list' % prog.name.replace('.', '_')
         list_file = self._make_list_file(backend_file.objdir, objs, list_file_name)
 
         if isinstance(prog, SimpleProgram):
             outputs = [prog.name]
         else:
             outputs = [mozpath.relpath(prog.output_path.full_path,
@@ -842,29 +849,35 @@ class TupBackend(CommonBackend):
 
             if any(f.endswith(('automation.py', 'source-repo.h', 'buildid.h'))
                    for f in obj.outputs):
                 extra_outputs = [self._early_generated_files]
             else:
                 extra_outputs = [self._installed_files] if obj.required_for_compile else []
                 full_inputs += [self._early_generated_files]
 
+            extra_inputs = []
+            if any(f in obj.outputs for f in ('dependentlibs.list',
+                                              'dependendentlibs.list.gtest')):
+                extra_inputs += [self._shlibs]
+
             if len(outputs) > 3:
                 display_outputs = ', '.join(outputs[0:3]) + ', ...'
             else:
                 display_outputs = ', '.join(outputs)
             display = 'python {script}:{method} -> [{display_outputs}]'.format(
                 script=obj.script,
                 method=obj.method,
                 display_outputs=display_outputs
             )
             backend_file.rule(
                 display=display,
                 cmd=cmd,
                 inputs=full_inputs,
+                extra_inputs=extra_inputs,
                 outputs=outputs,
                 extra_outputs=extra_outputs,
                 check_unchanged=True,
             )
 
     def _process_defines(self, backend_file, obj, host=False):
         defines = list(obj.get_defines())
         if defines:
@@ -942,28 +955,24 @@ class TupBackend(CommonBackend):
                         backend_file.symlink_rule(f.full_path, output=f.target_basename, output_group=output_group)
                 else:
                     if (self.environment.is_artifact_build and
                         any(mozpath.match(f.target_basename, p) for p in self._compile_env_gen_files)):
                         # If we have an artifact build we never would have generated this file,
                         # so do not attempt to install it.
                         continue
 
-                    # We're not generating files in these directories yet, so
-                    # don't attempt to install files generated from them.
-                    if f.context.relobjdir not in ('toolkit/library',
-                                                   'js/src/shell'):
-                        output = mozpath.join('$(MOZ_OBJ_ROOT)', target, path,
-                                              f.target_basename)
-                        gen_backend_file = self._get_backend_file(f.context.relobjdir)
-                        if gen_backend_file.requires_delay([f]):
-                            gen_backend_file.delayed_installed_files.append((f.full_path, output, output_group))
-                        else:
-                            gen_backend_file.symlink_rule(f.full_path, output=output,
-                                                          output_group=output_group)
+                    output = mozpath.join('$(MOZ_OBJ_ROOT)', target, path,
+                                          f.target_basename)
+                    gen_backend_file = self._get_backend_file(f.context.relobjdir)
+                    if gen_backend_file.requires_delay([f]):
+                        gen_backend_file.delayed_installed_files.append((f.full_path, output, output_group))
+                    else:
+                        gen_backend_file.symlink_rule(f.full_path, output=output,
+                                                      output_group=output_group)
 
 
     def _process_final_target_pp_files(self, obj, backend_file):
         for i, (path, files) in enumerate(obj.files.walk()):
             self._add_features(obj.install_target, path)
             for f in files:
                 self._preprocess(backend_file, f.full_path,
                                  destdir=mozpath.join(self.environment.topobjdir, obj.install_target, path),
--- a/toolkit/library/dependentlibs.py
+++ b/toolkit/library/dependentlibs.py
@@ -123,17 +123,18 @@ def gen_list(output, lib):
     elif binary_type == MACHO:
         func = dependentlibs_otool
     else:
         ext = os.path.splitext(lib)[1]
         assert(ext == '.dll')
         func = dependentlibs_dumpbin
 
     deps = dependentlibs(lib, libpaths, func)
-    deps[lib] = mozpath.join(libpaths[0], lib)
+    base_lib = mozpath.basename(lib)
+    deps[base_lib] = mozpath.join(libpaths[0], base_lib)
     output.write('\n'.join(deps.keys()) + '\n')
 
     with open(output.name + ".gtest", 'w') as gtest_out:
         libs = deps.keys()
         libs[-1] = 'gtest/' + libs[-1]
         gtest_out.write('\n'.join(libs) + '\n')
 
     return set(deps.values())