# HG changeset patch
# User Nathan Froyd <froydnj@mozilla.com>
# Date 1591734209 0
# Node ID c1628d8da86fff9d408cb53d1a3c886c57099101
# Parent  a9239d02662726ebc80e3c0b02213b32795feaf4
Bug 1642032 - part 2 - install non-wildcard absolute FINAL_TARGET_FILES during misc; r=nalexander

Such files are, at least as of this writing, only libraries, and we can
get by with installing them later.  This change will also avoid having
them added to the dependent libraries list.

Differential Revision: https://phabricator.services.mozilla.com/D78618

diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -1451,42 +1451,64 @@ class RecursiveMakeBackend(CommonBackend
 
         manifest = path.replace('/', '_')
         install_manifest = self._install_manifests[manifest]
         reltarget = mozpath.relpath(target, path)
 
         for path, files in files.walk():
             target_var = (mozpath.join(target, path)
                           if path else target).replace('/', '_')
+            # We don't necessarily want to combine these, because non-wildcard
+            # absolute files tend to be libraries, and we don't want to mix
+            # those in with objdir headers that will be installed during export.
+            # (See bug 1642882 for details.)
             objdir_files = []
-
+            absolute_files = []
+ 
             for f in files:
                 assert not isinstance(f, RenamedSourcePath)
                 dest = mozpath.join(reltarget, path, f.target_basename)
                 if not isinstance(f, ObjDirPath):
                     if '*' in f:
                         if f.startswith('/') or isinstance(f, AbsolutePath):
                             basepath, wild = os.path.split(f.full_path)
                             if '*' in basepath:
                                 raise Exception("Wildcards are only supported in the filename part of "
                                                 "srcdir-relative or absolute paths.")
 
                             install_manifest.add_pattern_link(basepath, wild, path)
                         else:
                             install_manifest.add_pattern_link(f.srcdir, f, path)
+                    elif isinstance(f, AbsolutePath):
+                        if not f.full_path.lower().endswith(('.dll', '.pdb', '.so')):
+                            raise Exception("Absolute paths installed to FINAL_TARGET_FILES must"
+                                            " only be shared libraries or associated debug"
+                                            " information.")
+                        install_manifest.add_optional_exists(dest)
+                        absolute_files.append(f.full_path)
                     else:
                         install_manifest.add_link(f.full_path, dest)
                 else:
                     install_manifest.add_optional_exists(dest)
                     objdir_files.append(self._pretty_path(f, backend_file))
+            install_location = '$(DEPTH)/%s' % mozpath.join(target, path)
             if objdir_files:
                 tier = 'export' if obj.install_target == 'dist/include' else 'misc'
                 self._add_install_target(backend_file, target_var, tier,
-                                         '$(DEPTH)/%s' % mozpath.join(target, path),
-                                         objdir_files)
+                                         install_location, objdir_files)
+            if absolute_files:
+                # Unfortunately, we can't use _add_install_target because on
+                # Windows, the absolute file paths that we want to install
+                # from often have spaces.  So we write our own rule.
+                self._no_skip['misc'].add(backend_file.relobjdir)
+                backend_file.write('misc::\n%s\n' %
+                                   '\n'.join(
+                                       '\t$(INSTALL) %s %s' % (
+                                           make_quote(shell_quote(f)), install_location)
+                                       for f in absolute_files))
 
     def _process_final_target_pp_files(self, obj, files, backend_file, name):
         # Bug 1177710 - We'd like to install these via manifests as
         # preprocessed files. But they currently depend on non-standard flags
         # being added via some Makefiles, so for now we just pass them through
         # to the underlying Makefile.in.
         #
         # Note that if this becomes a manifest, OBJDIR_PP_FILES will likely
