Fuchsia: Use SDK manifest for CC prebuilt and source packages.

Finishes the switch from using hand-rolled SDK target definitions to
using targets automatically generated from SDK metadata files. A
slightly oddball Vulkan copy rule remains intact.

* Remove the old targets from fuchsia_sdk/BUILD.gn
* Switch existing dependents of fuchsia_sdk:* targets to use
  fuchsia_sdk/sdk:* instead.
* Some "gn format" fixups.

[email protected]

Bug: 888753
Change-Id: I3aa9e6aa68cebae343609fc85c9a1c7d0ed1c7aa
Reviewed-on: https://chromium-review.googlesource.com/c/1292570
Reviewed-by: Kevin Marshall <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Wez <[email protected]>
Reviewed-by: David Benjamin <[email protected]>
Reviewed-by: Dirk Pranke <[email protected]>
Commit-Queue: Kevin Marshall <[email protected]>
Cr-Commit-Position: refs/heads/master@{#601799}
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 3affe2c..b8ae809 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1464,15 +1464,15 @@
     # by public //base headers, which requires they be on the include path.
     # TODO(https://crbug.com/841171): Move these back to |deps|.
     public_deps += [
-      "//third_party/fuchsia-sdk:async",
-      "//third_party/fuchsia-sdk:fdio",
-      "//third_party/fuchsia-sdk:zx",
+      "//third_party/fuchsia-sdk/sdk:async",
+      "//third_party/fuchsia-sdk/sdk:fdio",
+      "//third_party/fuchsia-sdk/sdk:zx",
     ]
 
     deps += [
-      "//third_party/fuchsia-sdk:async_default",
-      "//third_party/fuchsia-sdk:fidl",
-      "//third_party/fuchsia-sdk:svc",
+      "//third_party/fuchsia-sdk/sdk:async_default",
+      "//third_party/fuchsia-sdk/sdk:fidl",
+      "//third_party/fuchsia-sdk/sdk:svc",
     ]
   }
 
@@ -2730,9 +2730,9 @@
 
     deps += [
       ":testfidl",
-      "//third_party/fuchsia-sdk:async",
-      "//third_party/fuchsia-sdk:async_default",
-      "//third_party/fuchsia-sdk:fdio",
+      "//third_party/fuchsia-sdk/sdk:async",
+      "//third_party/fuchsia-sdk/sdk:async_default",
+      "//third_party/fuchsia-sdk/sdk:fdio",
     ]
   }
 
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn
index 83914f2..6b71dd9e 100644
--- a/base/test/BUILD.gn
+++ b/base/test/BUILD.gn
@@ -203,7 +203,7 @@
   }
 
   if (is_fuchsia) {
-    deps += [ "//third_party/fuchsia-sdk:zx" ]
+    deps += [ "//third_party/fuchsia-sdk/sdk:zx" ]
   }
 
   if (is_linux) {
diff --git a/build/config/fuchsia/fidl_library.gni b/build/config/fuchsia/fidl_library.gni
index 5ec90a49..13d2a3d 100644
--- a/build/config/fuchsia/fidl_library.gni
+++ b/build/config/fuchsia/fidl_library.gni
@@ -21,7 +21,11 @@
 # files.
 
 template("fidl_library") {
-  forward_variables_from(invoker, [ "namespace", "languages" ])
+  forward_variables_from(invoker,
+                         [
+                           "languages",
+                           "namespace",
+                         ])
 
   _library_basename = target_name
   if (defined(invoker.library_name)) {
@@ -235,8 +239,8 @@
     if (!defined(public_deps)) {
       public_deps = []
     }
-    public_deps += [ "//third_party/fuchsia-sdk:fidl" ]
-    public_deps += [ "//third_party/fuchsia-sdk:fidl_cpp" ]
+    public_deps += [ "//third_party/fuchsia-sdk/sdk:fidl" ]
+    public_deps += [ "//third_party/fuchsia-sdk/sdk:fidl_cpp" ]
 
     public_configs = [ ":${invoker.target_name}_config" ]
   }
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 854924d..88626f8 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -464,7 +464,7 @@
     ]
 
     deps += [
-      "//third_party/fuchsia-sdk:fdio",
+      "//third_party/fuchsia-sdk/sdk:fdio",
       "//third_party/fuchsia-sdk/sdk:fonts",
       "//third_party/fuchsia-sdk/sdk:scenic",
     ]
diff --git a/mojo/core/BUILD.gn b/mojo/core/BUILD.gn
index 49a537b..ce271ed7 100644
--- a/mojo/core/BUILD.gn
+++ b/mojo/core/BUILD.gn
@@ -108,7 +108,7 @@
     if (is_fuchsia) {
       sources += [ "channel_fuchsia.cc" ]
 
-      public_deps += [ "//third_party/fuchsia-sdk:fdio" ]
+      public_deps += [ "//third_party/fuchsia-sdk/sdk:fdio" ]
     }
 
     if (is_posix) {
diff --git a/mojo/public/cpp/platform/BUILD.gn b/mojo/public/cpp/platform/BUILD.gn
index b0aa90ef..b2504c5 100644
--- a/mojo/public/cpp/platform/BUILD.gn
+++ b/mojo/public/cpp/platform/BUILD.gn
@@ -41,8 +41,8 @@
   if (is_fuchsia) {
     sources += [ "named_platform_channel_fuchsia.cc" ]
     public_deps += [
-      "//third_party/fuchsia-sdk:fdio",
-      "//third_party/fuchsia-sdk:zx",
+      "//third_party/fuchsia-sdk/sdk:fdio",
+      "//third_party/fuchsia-sdk/sdk:zx",
     ]
   }
 
diff --git a/net/BUILD.gn b/net/BUILD.gn
index d88b362..99041ad 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -5396,7 +5396,7 @@
   if (is_fuchsia) {
     use_test_server = true
     deps += [
-      "//third_party/fuchsia-sdk:fidl_cpp",
+      "//third_party/fuchsia-sdk/sdk:fidl_cpp",
       "//third_party/fuchsia-sdk/sdk:netstack",
     ]
     sources += [ "base/network_change_notifier_fuchsia_unittest.cc" ]
diff --git a/third_party/crashpad/crashpad/third_party/fuchsia/BUILD.gn b/third_party/crashpad/crashpad/third_party/fuchsia/BUILD.gn
index 6c2339b..ca41617 100644
--- a/third_party/crashpad/crashpad/third_party/fuchsia/BUILD.gn
+++ b/third_party/crashpad/crashpad/third_party/fuchsia/BUILD.gn
@@ -23,7 +23,7 @@
 } else if (crashpad_is_in_chromium) {
   group("zx") {
     public_deps = [
-      "//third_party/fuchsia-sdk:zx",
+      "//third_party/fuchsia-sdk/sdk:zx",
     ]
   }
 } else {
diff --git a/third_party/fuchsia-sdk/BUILD.gn b/third_party/fuchsia-sdk/BUILD.gn
index 8fad6c5a..064078a 100644
--- a/third_party/fuchsia-sdk/BUILD.gn
+++ b/third_party/fuchsia-sdk/BUILD.gn
@@ -11,199 +11,6 @@
   lib_dirs = [ "sdk/arch/${target_cpu}/lib" ]
 }
 
-fuchsia_sdk_pkg("async") {
-  sources = [
-    "include/lib/async/dispatcher.h",
-    "include/lib/async/receiver.h",
-    "include/lib/async/task.h",
-    "include/lib/async/time.h",
-    "include/lib/async/trap.h",
-    "include/lib/async/wait.h",
-    "ops.c",
-  ]
-}
-
-# async-default keep a per-thread dispatcher for async.
-fuchsia_sdk_pkg("async_default") {
-  package_name = "async-default"
-  sources = [
-    "include/lib/async/default.h",
-  ]
-
-  libs = [ "async-default" ]
-}
-
-fuchsia_sdk_pkg("fdio") {
-  sources = [
-    "include/lib/fdio/debug.h",
-    "include/lib/fdio/io.h",
-    "include/lib/fdio/limits.h",
-    "include/lib/fdio/module.modulemap",
-    "include/lib/fdio/namespace.h",
-    "include/lib/fdio/remoteio.h",
-    "include/lib/fdio/spawn.h",
-    "include/lib/fdio/unsafe.h",
-    "include/lib/fdio/util.h",
-    "include/lib/fdio/vfs.h",
-    "include/lib/fdio/watcher.h",
-  ]
-
-  libs = [ "fdio" ]
-}
-
-fuchsia_sdk_pkg("fidl") {
-  # FIDL headers include async headers. These dependencies needs to be public
-  # to ensure that dependent targets get correct include paths.
-  public_deps = [
-    ":async",
-    ":async_default",
-  ]
-
-  sources = [
-    "builder.cpp",
-    "decoding.cpp",
-    "encoding.cpp",
-    "formatting.cpp",
-    "include/lib/fidl/coding.h",
-    "include/lib/fidl/cpp/builder.h",
-    "include/lib/fidl/cpp/message.h",
-    "include/lib/fidl/cpp/message_buffer.h",
-    "include/lib/fidl/cpp/message_builder.h",
-    "include/lib/fidl/cpp/message_part.h",
-    "include/lib/fidl/cpp/string_view.h",
-    "include/lib/fidl/cpp/vector_view.h",
-    "include/lib/fidl/internal.h",
-    "message.cpp",
-    "message_buffer.cpp",
-    "message_builder.cpp",
-    "validating.cpp",
-  ]
-}
-
-fuchsia_sdk_pkg("fidl_cpp") {
-  public_deps = [
-    ":fidl",
-    ":fidl_cpp_sync",
-    ":fit",
-    ":zx",
-  ]
-  sources = [
-    "clone.cc",
-    "include/lib/fidl/cpp/binding.h",
-    "include/lib/fidl/cpp/binding_set.h",
-    "include/lib/fidl/cpp/clone.h",
-    "include/lib/fidl/cpp/interface_ptr.h",
-    "include/lib/fidl/cpp/interface_ptr_set.h",
-    "include/lib/fidl/cpp/internal/header.h",
-    "include/lib/fidl/cpp/internal/implementation.h",
-    "include/lib/fidl/cpp/internal/message_handler.h",
-    "include/lib/fidl/cpp/internal/message_reader.h",
-    "include/lib/fidl/cpp/internal/pending_response.h",
-    "include/lib/fidl/cpp/internal/proxy.h",
-    "include/lib/fidl/cpp/internal/proxy_controller.h",
-    "include/lib/fidl/cpp/internal/stub.h",
-    "include/lib/fidl/cpp/internal/stub_controller.h",
-    "include/lib/fidl/cpp/internal/weak_stub_controller.h",
-    "include/lib/fidl/cpp/optional.h",
-    "include/lib/fidl/cpp/string.h",
-    "include/lib/fidl/cpp/thread_safe_binding_set.h",
-    "internal/message_handler.cc",
-    "internal/message_reader.cc",
-    "internal/pending_response.cc",
-    "internal/proxy.cc",
-    "internal/proxy_controller.cc",
-    "internal/stub.cc",
-    "internal/stub_controller.cc",
-    "internal/weak_stub_controller.cc",
-    "string.cc",
-  ]
-}
-
-fuchsia_sdk_pkg("fidl_cpp_sync") {
-  public_deps = [
-    ":fidl",
-    ":fit",
-    ":zx",
-  ]
-  sources = [
-    "coding_traits.cc",
-    "decoder.cc",
-    "encoder.cc",
-    "include/lib/fidl/cpp/array.h",
-    "include/lib/fidl/cpp/coding_traits.h",
-    "include/lib/fidl/cpp/comparison.h",
-    "include/lib/fidl/cpp/decoder.h",
-    "include/lib/fidl/cpp/encoder.h",
-    "include/lib/fidl/cpp/interface_handle.h",
-    "include/lib/fidl/cpp/interface_request.h",
-    "include/lib/fidl/cpp/internal/logging.h",
-    "include/lib/fidl/cpp/internal/synchronous_proxy.h",
-    "include/lib/fidl/cpp/synchronous_interface_ptr.h",
-    "include/lib/fidl/cpp/traits.h",
-    "include/lib/fidl/cpp/vector.h",
-    "internal/logging.cc",
-    "internal/synchronous_proxy.cc",
-  ]
-}
-
-fuchsia_sdk_pkg("fit") {
-  sources = [
-    "include/lib/fit/function.h",
-  ]
-}
-
-fuchsia_sdk_pkg("svc") {
-  sources = [
-    "include/lib/svc/dir.h",
-  ]
-
-  libs = [ "svc" ]
-}
-
-fuchsia_sdk_pkg("zx") {
-  sources = [
-    "channel.cpp",
-    "event.cpp",
-    "eventpair.cpp",
-    "fifo.cpp",
-    "guest.cpp",
-    "include/lib/zx/bti.h",
-    "include/lib/zx/channel.h",
-    "include/lib/zx/event.h",
-    "include/lib/zx/eventpair.h",
-    "include/lib/zx/fifo.h",
-    "include/lib/zx/guest.h",
-    "include/lib/zx/handle.h",
-    "include/lib/zx/interrupt.h",
-    "include/lib/zx/job.h",
-    "include/lib/zx/log.h",
-    "include/lib/zx/object.h",
-    "include/lib/zx/object_traits.h",
-    "include/lib/zx/pmt.h",
-    "include/lib/zx/port.h",
-    "include/lib/zx/process.h",
-    "include/lib/zx/resource.h",
-    "include/lib/zx/socket.h",
-    "include/lib/zx/task.h",
-    "include/lib/zx/thread.h",
-    "include/lib/zx/time.h",
-    "include/lib/zx/timer.h",
-    "include/lib/zx/vmar.h",
-    "include/lib/zx/vmo.h",
-    "interrupt.cpp",
-    "job.cpp",
-    "log.cpp",
-    "port.cpp",
-    "process.cpp",
-    "resource.cpp",
-    "socket.cpp",
-    "thread.cpp",
-    "timer.cpp",
-    "vmar.cpp",
-    "vmo.cpp",
-  ]
-}
-
 copy("vulkan_layers") {
   sources = [
     "sdk/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_core_validation.json",
diff --git a/third_party/fuchsia-sdk/fuchsia_sdk_pkg.gni b/third_party/fuchsia-sdk/fuchsia_sdk_pkg.gni
index 042fa12..371e622e 100644
--- a/third_party/fuchsia-sdk/fuchsia_sdk_pkg.gni
+++ b/third_party/fuchsia-sdk/fuchsia_sdk_pkg.gni
@@ -50,14 +50,9 @@
 #   deps         - List of dependencies.
 #   libs         - List of precompiled libraries.
 template("fuchsia_sdk_pkg") {
-  _package_name = target_name
-  if (defined(invoker.package_name)) {
-    _package_name = invoker.package_name
-  }
-
   config("${target_name}_config") {
+    forward_variables_from(invoker, [ "include_dirs" ])
     visibility = [ ":${invoker.target_name}" ]
-    include_dirs = [ "sdk/pkg/${_package_name}/include" ]
   }
 
   static_library(target_name) {
@@ -65,23 +60,17 @@
                            [
                              "data",
                              "deps",
+                             "libs",
                              "public_deps",
+                             "sources",
                              "testonly",
                              "visibility",
                            ])
 
-    sources = []
-    if (defined(invoker.sources)) {
-      foreach(src, invoker.sources) {
-        sources += [ "sdk/pkg/${_package_name}/${src}" ]
-      }
-    }
-
     public_configs = [ ":${invoker.target_name}_config" ]
 
-    if (defined(invoker.libs)) {
-      configs += [ ":sdk_lib_dirs_config" ]
-      libs = invoker.libs
+    if (defined(libs)) {
+      configs += [ "//third_party/fuchsia-sdk:sdk_lib_dirs_config" ]
     }
   }
 }
diff --git a/third_party/fuchsia-sdk/gen_build_defs.py b/third_party/fuchsia-sdk/gen_build_defs.py
index e2ab7f2d..ba6c922 100755
--- a/third_party/fuchsia-sdk/gen_build_defs.py
+++ b/third_party/fuchsia-sdk/gen_build_defs.py
@@ -25,48 +25,128 @@
 def SerializeListOfStrings(strings):
   """Outputs a list of strings in GN-friendly, double-quoted format."""
 
-  return '[\n' + ''.join(['    "{}",\n'.format(s) for s in strings]) + '  ]'
+  return '[' + ','.join(['"{}"'.format(s) for s in strings]) + ']'
 
+def ConvertCommonFields(json):
+  """Extracts fields from JSON manifest data which are used across all
+  target types."""
+
+  output = {}
+
+  output['target_name'] = json['name'].replace('-', '_')
+
+  output['public_deps'] = []
+  for package_dep in json['deps']:
+    # If the dep has a namespace prefix, then remove it, and replace any
+    # hyphens with underscores for compatibility with the GN identifier
+    # character set.
+    dep_reformatted = ':' + package_dep.split('.')[-1].replace('-','_')
+    output['public_deps'].extend([dep_reformatted])
+
+  return output
+
+def FormatGNTarget(fields):
+  """Returns a GN target definition as a string.
+
+  |fields|: The GN fields to include in the target body.
+            'target_name' and 'type' are mandatory."""
+
+  output = '%s("%s") {\n' % (fields['type'], fields['target_name'])
+  del fields['target_name']
+  del fields['type']
+
+  for key, val in fields.iteritems():
+    if isinstance(val, str) or isinstance(val, unicode):
+      val_serialized = '\"%s\"' % val
+    elif isinstance(val, list):
+      # Serialize a list of strings in the prettiest possible manner.
+      if len(val) == 0:
+        val_serialized = '[]'
+      elif len(val) == 1:
+        val_serialized = '[ \"%s\" ]' % val[0]
+      else:
+        val_serialized = '[\n    ' + ',\n    '.join(
+            ['\"%s\"' % x for x in val]) + '\n  ]'
+    else:
+      raise Exception('Could not serialize %r' % val)
+
+    output += '  %s = %s\n' % (key, val_serialized)
+  output += '}'
+
+  return output
 
 def ConvertFidlLibrary(json):
-  """Massages the manifest data to match the format required by the GN build
-  and outputs a GN target for the FIDL library
+  """Converts a fidl_library manifest entry to a GN target.
 
   Arguments:
     json: The parsed manifest JSON.
   Returns:
     The GN target definition, represented as a string."""
 
-  json['deps'] = SerializeListOfStrings(
-      [':' + dep.split('.')[-1] for dep in json['deps']])
-  json['sources'] = SerializeListOfStrings(json['sources'])
+  converted = ConvertCommonFields(json)
+  converted['type'] = 'fuchsia_sdk_fidl_pkg'
+  converted['sources'] = json['sources']
 
-  name_tokenized = json['name'].split('.')
-  json['shortname'] = name_tokenized[-1]
-  json['namespace'] = '.'.join(name_tokenized[:-1])
+  # Split "name" into "namespace" and "name" pair.
+  name_parts = converted['target_name'].split('.')
+  converted['target_name'] = name_parts[-1]
+  converted['namespace'] = '.'.join(name_parts[:-1])
 
-  return """fuchsia_sdk_fidl_pkg("{shortname}") {{
-  namespace = "{namespace}"
-  public_deps = {deps}
-  sources = {sources}
-}}\n\n""".format(**json)
+  return converted
 
+def ConvertCcPrebuiltLibrary(json):
+  """Converts a cc_prebuilt_library manifest entry to a GN target.
+
+  Arguments:
+    json: The parsed manifest JSON.
+  Returns:
+    The GN target definition, represented as a string."""
+
+  converted = ConvertCommonFields(json)
+  converted['type'] = 'fuchsia_sdk_pkg'
+  converted['sources'] = json['headers']
+  converted['libs'] = [json['name']]
+  converted['include_dirs'] = [json['root'] + '/include']
+
+  return converted
+
+def ConvertCcSourceLibrary(json):
+  """Converts a cc_source_library manifest entry to a GN target.
+
+  Arguments:
+    json: The parsed manifest JSON.
+  Returns:
+    The GN target definition, represented as a string."""
+
+  converted = ConvertCommonFields(json)
+  converted['type'] = 'fuchsia_sdk_pkg'
+
+  # Headers and source file paths can be scattered across "sources", "headers",
+  # and "files". Merge them together into one source list.
+  converted['sources'] = json['sources']
+  if 'headers' in json:
+    converted['sources'] += json['headers']
+  if 'files' in json:
+    converted['sources'] += json['files']
+  converted['sources'] = list(set(converted['sources']))
+
+  converted['include_dirs'] = [json['root'] + '/include']
+
+  return converted
 
 def ConvertNoOp(json):
   """Null implementation of a conversion function. No output is generated."""
 
-  return ""
+  return None
 
 
-"""Maps manifest type strings to relevant conversion functions."""
+"""Maps manifest types to conversion functions."""
 _CONVERSION_FUNCTION_MAP = {
   'fidl_library': ConvertFidlLibrary,
+  'cc_source_library': ConvertCcSourceLibrary,
+  'cc_prebuilt_library': ConvertCcPrebuiltLibrary,
 
-  # TODO(888753): Add conversion routines for these manifest types and migrate
-  # existing dependents of //third_party/fuchsia_sdk/BUILD.gn to use the
-  # generated targets instead. The migration can be executed incrementally.
-  'cc_source_library': ConvertNoOp,
-  'cc_prebuilt_library': ConvertNoOp,
+  # No need to build targets for these types yet.
   'host_tool': ConvertNoOp,
   'image': ConvertNoOp,
   'loadable_module': ConvertNoOp,
@@ -92,7 +172,10 @@
       if convert_function is None:
         raise Exception('Unexpected SDK artifact type %s in %s.' %
                         (parsed['type'], next_part))
-      buildfile.write(convert_function(parsed))
+
+      converted = convert_function(parsed)
+      if converted:
+        buildfile.write(FormatGNTarget(converted) + '\n\n')
 
 
 if __name__ == '__main__':
diff --git a/third_party/googletest/BUILD.gn b/third_party/googletest/BUILD.gn
index 34c1118..9d0c8b2 100644
--- a/third_party/googletest/BUILD.gn
+++ b/third_party/googletest/BUILD.gn
@@ -129,9 +129,7 @@
   }
 
   if (is_fuchsia) {
-    deps += [
-      "//third_party/fuchsia-sdk:fdio",
-    ]
+    deps += [ "//third_party/fuchsia-sdk/sdk:fdio" ]
   }
 }
 
@@ -176,11 +174,11 @@
     "src/googlemock/src/gmock.cc",
   ]
 
-  public_deps = [ ":gtest" ]
-
-  public_configs = [
-    ":gmock_config",
+  public_deps = [
+    ":gtest",
   ]
+
+  public_configs = [ ":gmock_config" ]
 }
 
 # Do NOT depend on this directly. Use //testing/gmock:gmock_main instead.
diff --git a/tools/fuchsia/fidlgen_js/BUILD.gn b/tools/fuchsia/fidlgen_js/BUILD.gn
index daaec940..4b2bb640 100644
--- a/tools/fuchsia/fidlgen_js/BUILD.gn
+++ b/tools/fuchsia/fidlgen_js/BUILD.gn
@@ -44,8 +44,8 @@
   deps = [
     "//base",
     "//gin",
-    "//third_party/fuchsia-sdk:async",
-    "//third_party/fuchsia-sdk:async_default",
+    "//third_party/fuchsia-sdk/sdk:async",
+    "//third_party/fuchsia-sdk/sdk:async_default",
     "//v8",
   ]
 }