[Fuchsia] Place built libraries in ${root_out_dir}/lib

Fuchsia has a platform requirement that libraries be placed in in the
/lib directory in order to be located by the loader. We used to have a
shlib_subdir variable to satisfy such a requirement.  Bring this variable
back and set it to "/lib" on Fuchsia.

This allows us to reduce special handling of libraries during the
packaging phase. Ideally all package artifacts would be placed correctly
by the build system so that the packager doesn't have to rearrange.

Don't use abspath() in the script, either. Using absolute paths in the
build can be harmful (leaks data, causes cache misses) and is rarely
necessary.

BUG=925040
[email protected]

Change-Id: Idb2d8d4a0fa493904000244332ed242790698b8b

Reviewed-on: https://chromium-review.googlesource.com/c/1434221
Reviewed-by: Michael Spang <[email protected]>
Reviewed-by: Scott Graham <[email protected]>
Reviewed-by: Kevin Marshall <[email protected]>
Reviewed-by: Wez <[email protected]>
Commit-Queue: Michael Spang <[email protected]>
Cr-Commit-Position: refs/heads/master@{#626877}
diff --git a/build/config/fuchsia/build_manifest.py b/build/config/fuchsia/build_manifest.py
index 1268455..ee13568 100644
--- a/build/config/fuchsia/build_manifest.py
+++ b/build/config/fuchsia/build_manifest.py
@@ -17,11 +17,9 @@
   """Computes a path for |file_path| that is relative to one of the directory
   paths in |roots|.
 
-  file_path: The absolute file path to relativize.
-  roots: A list of absolute directory paths which may serve as a relative root
-         for |file_path|. At least one path must contain |file_path|.
-         Overlapping roots are permitted; the deepest matching root will be
-         chosen.
+  file_path: The file path to relativize.
+  roots: A list of directory paths which may serve as a relative root
+         for |file_path|.
 
   Examples:
 
@@ -46,28 +44,17 @@
     if file_path.startswith(next_root):
       relative_path = file_path[len(next_root):]
 
-      # Move all dynamic libraries (ending in .so or .so.<number>) to lib/.
-      if re.search('.*\.so(\.\d+)?$', file_path):
-        relative_path = 'lib/' + os.path.basename(relative_path)
-
       return relative_path
 
-  raise Exception('Error: no matching root paths found for \'%s\'.' % file_path)
+  return file_path
 
 
 def _GetStrippedPath(bin_path):
   """Finds the stripped version of the binary |bin_path| in the build
   output directory."""
 
-  # Skip the resolution step for binaries that don't have stripped counterparts,
-  # like system libraries or other libraries built outside the Chromium build.
-  if not '.unstripped' in bin_path:
-    return bin_path
-
-  return os.path.normpath(os.path.join(bin_path,
-                                       os.path.pardir,
-                                       os.path.pardir,
-                                       os.path.basename(bin_path)))
+  return bin_path.replace('lib.unstripped/', 'lib/').replace(
+      'exe.unstripped/', '')
 
 
 def _IsBinary(path):
@@ -83,9 +70,9 @@
   with open(args.output_path, 'w') as manifest, \
        open(args.depfile_path, 'w') as depfile:
     # Process the runtime deps file for file paths, recursively walking
-    # directories as needed. File paths are stored in absolute form,
-    # so that MakePackagePath() may relativize to either the source root or
-    # output directory.
+    # directories as needed.
+    # MakePackagePath() may relativize to either the source root or output
+    # directory.
     # runtime_deps may contain duplicate paths, so use a set for
     # de-duplication.
     expanded_files = set()
@@ -96,21 +83,20 @@
           for current_file in files:
             if current_file.startswith('.'):
               continue
-            expanded_files.add(os.path.abspath(
-                os.path.join(root, current_file)))
+            expanded_files.add(
+                os.path.join(root, current_file))
       else:
-        expanded_files.add(os.path.abspath(next_path))
+        expanded_files.add(next_path)
 
     # Format and write out the manifest contents.
-    gen_dir = os.path.join(args.out_dir, "gen")
+    gen_dir = os.path.normpath(os.path.join(args.out_dir, "gen"))
     app_found = False
     excluded_files_set = set(args.exclude_file)
     for current_file in expanded_files:
       if _IsBinary(current_file):
         current_file = _GetStrippedPath(current_file)
 
-      absolute_file_path = os.path.join(args.out_dir, current_file)
-      in_package_path = MakePackagePath(absolute_file_path,
+      in_package_path = MakePackagePath(current_file,
                                         [gen_dir, args.root_dir, args.out_dir])
       if in_package_path == args.app_filename:
         app_found = True
@@ -119,11 +105,7 @@
         excluded_files_set.remove(in_package_path)
         continue
 
-      # The source path is relativized so that it can be used on multiple
-      # environments with differing parent directory structures,
-      # e.g. builder bots and swarming clients.
-      manifest.write('%s=%s\n' % (in_package_path,
-                                  os.path.relpath(current_file, args.out_dir)))
+      manifest.write('%s=%s\n' % (in_package_path, current_file))
 
     if len(excluded_files_set) > 0:
       raise Exception('Some files were excluded with --exclude-file, but '
diff --git a/build/config/fuchsia/config.gni b/build/config/fuchsia/config.gni
index 165153b..cdf684e2 100644
--- a/build/config/fuchsia/config.gni
+++ b/build/config/fuchsia/config.gni
@@ -11,9 +11,9 @@
 
 # Compute the arch-specific path to packages' dynamic library dependencies.
 if (current_cpu == "arm64") {
-  dist_libroot = fuchsia_sdk + "/arch/arm64/dist/"
+  dist_libroot = fuchsia_sdk + "/arch/arm64/dist"
 } else if (current_cpu == "x64") {
-  dist_libroot = fuchsia_sdk + "/arch/x64/dist/"
+  dist_libroot = fuchsia_sdk + "/arch/x64/dist"
 } else {
   assert(false, "No libraries available for architecture: $current_cpu")
 }
diff --git a/build/config/fuchsia/package.gni b/build/config/fuchsia/package.gni
index 9dd3dbef..924eb0a 100644
--- a/build/config/fuchsia/package.gni
+++ b/build/config/fuchsia/package.gni
@@ -85,21 +85,21 @@
 
     args = [
       "--root-dir",
-      rebase_path("//"),
+      rebase_path("//", root_build_dir),
       "--out-dir",
-      rebase_path(root_out_dir),
+      rebase_path(root_out_dir, root_build_dir),
       "--app-name",
       pkg.package_name,
       "--app-filename",
       get_label_info(pkg.binary, "name"),
       "--sandbox-policy-path",
-      rebase_path(pkg.sandbox_policy),
+      rebase_path(pkg.sandbox_policy, root_build_dir),
       "--runtime-deps-file",
-      rebase_path(_runtime_deps_file),
+      rebase_path(_runtime_deps_file, root_build_dir),
       "--depfile-path",
-      rebase_path(_depfile),
+      rebase_path(_depfile, root_build_dir),
       "--output-path",
-      rebase_path(_archive_manifest),
+      rebase_path(_archive_manifest, root_build_dir),
     ]
 
     if (defined(pkg.excluded_files)) {
diff --git a/build/toolchain/fuchsia/BUILD.gn b/build/toolchain/fuchsia/BUILD.gn
index 7ab3a2d0..654073b 100644
--- a/build/toolchain/fuchsia/BUILD.gn
+++ b/build/toolchain/fuchsia/BUILD.gn
@@ -2,8 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/toolchain/gcc_toolchain.gni")
 import("//build/config/fuchsia/config.gni")
+import("//build/toolchain/gcc_toolchain.gni")
 
 # Fuchsia builds using the Clang toolchain, with most parameters common across
 # the different target architectures.
@@ -21,6 +21,8 @@
       use_unstripped_as_runtime_outputs = true
     }
 
+    default_shlib_subdir = "/lib"
+
     toolchain_args = invoker.toolchain_args
     toolchain_args.current_os = "fuchsia"
   }
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni
index d3bf0ae0..42686fb 100644
--- a/build/toolchain/gcc_toolchain.gni
+++ b/build/toolchain/gcc_toolchain.gni
@@ -241,6 +241,12 @@
       default_shlib_extension = shlib_extension
     }
 
+    if (defined(invoker.default_shlib_subdir)) {
+      default_shlib_subdir = invoker.default_shlib_subdir
+    } else {
+      default_shlib_subdir = ""
+    }
+
     if (defined(invoker.executable_extension)) {
       default_executable_extension = invoker.executable_extension
     } else {
@@ -434,7 +440,7 @@
       # specifies).
       default_output_extension = default_shlib_extension
 
-      default_output_dir = "{{root_out_dir}}"
+      default_output_dir = "{{root_out_dir}}${default_shlib_subdir}"
 
       output_prefix = "lib"
 
@@ -494,7 +500,7 @@
         default_output_extension = default_shlib_extension
       }
 
-      default_output_dir = "{{root_out_dir}}"
+      default_output_dir = "{{root_out_dir}}${default_shlib_subdir}"
 
       output_prefix = "lib"
 
@@ -622,6 +628,7 @@
                            [
                              "strip",
                              "is_clang_analysis_supported",
+                             "default_shlib_subdir",
                              "enable_linker_map",
                              "use_unstripped_as_runtime_outputs",
                            ])
diff --git a/build/toolchain/toolchain.gni b/build/toolchain/toolchain.gni
index c0e1dbe..f9fb7e7 100644
--- a/build/toolchain/toolchain.gni
+++ b/build/toolchain/toolchain.gni
@@ -78,6 +78,13 @@
   shlib_prefix = ""
 }
 
+# Directory for shared library files.
+if (is_fuchsia) {
+  shlib_subdir = "/lib"
+} else {
+  shlib_subdir = ""
+}
+
 # While other "tool"s in a toolchain are specific to the target of that
 # toolchain, the "stamp" and "copy" tools are really generic to the host;
 # but each toolchain must define them separately.  GN doesn't allow a
diff --git a/components/cronet/BUILD.gn b/components/cronet/BUILD.gn
index 794bad1..df22474f 100644
--- a/components/cronet/BUILD.gn
+++ b/components/cronet/BUILD.gn
@@ -217,7 +217,7 @@
   # Copy boiler-plate files into the package.
   copy("cronet_package_copy") {
     sources = [
-      "$root_out_dir/$_cronet_shared_lib_file_name",
+      "${root_out_dir}${shlib_subdir}/${_cronet_shared_lib_file_name}",
       "//AUTHORS",
       "//chrome/VERSION",
     ]
diff --git a/third_party/fuchsia-sdk/BUILD.gn b/third_party/fuchsia-sdk/BUILD.gn
index c9117db..9a6dfad 100644
--- a/third_party/fuchsia-sdk/BUILD.gn
+++ b/third_party/fuchsia-sdk/BUILD.gn
@@ -4,6 +4,7 @@
 
 assert(is_fuchsia)
 
+import("//build/toolchain/toolchain.gni")
 import("fuchsia_sdk_pkg.gni")
 
 config("sdk_lib_dirs_config") {
@@ -18,7 +19,7 @@
   ]
 
   outputs = [
-    "${root_out_dir}/{{source_file_part}}",
+    "${root_out_dir}${shlib_subdir}/{{source_file_part}}",
   ]
 }
 
@@ -29,7 +30,7 @@
     ":sysroot_dist_libs",
 
     # This is used directly from //build/config/fuchsia:compiler and thus
-    # needs to be included by default.
+    # also needs to be included by default.
     "sdk:fdio_dist_libs",
   ]
 }
@@ -50,7 +51,7 @@
   ]
 
   outputs = [
-    "${root_out_dir}/{{source_file_part}}",
+    "${root_out_dir}${shlib_subdir}/{{source_file_part}}",
   ]
 }
 
@@ -87,7 +88,7 @@
   ]
 
   outputs = [
-    "${root_out_dir}/{{source_file_part}}",
+    "${root_out_dir}${shlib_subdir}/{{source_file_part}}",
   ]
 }
 
diff --git a/third_party/fuchsia-sdk/fuchsia_sdk_pkg.gni b/third_party/fuchsia-sdk/fuchsia_sdk_pkg.gni
index 6fe133e3..32c8c89 100644
--- a/third_party/fuchsia-sdk/fuchsia_sdk_pkg.gni
+++ b/third_party/fuchsia-sdk/fuchsia_sdk_pkg.gni
@@ -71,7 +71,7 @@
       }
 
       outputs = [
-        "${root_out_dir}/{{source_file_part}}",
+        "${root_out_dir}${shlib_subdir}/{{source_file_part}}",
       ]
     }
   }