Allow building Dart with Fuchsia SDK enabled buildroots.

The Fuchsia SDK can now be consumed by non-Fuchsia buildroots to produce
Fuchsia artifacts.

The Fuchsia SDK comes with a JSON manifest that describes the various SDK
"parts". GN targets are stamped for each of these parts. The location of these
GN targets can be configured. That location is set to |fuchsia_sdk_root| in
each buildroot. This variable is defined in //build/fuchsia/sdk.gni in each
buildroot. For buildroots that don't care or know about the Fuchsia SDK, that
file may not exist. This is why, the import of that file is guarded behind
the is_fuchsia flag. When the Fuchsia SDK is enabled, that file will define
values for two required variable |using_fuchsia_sdk| and |fuchsia_sdk_root|.

The first flag defines if the SDK is being used. If unset (but defined), the
builds are in-tree. Eventually we want only SDK builds. |fuchsia_sdk_root|
is set to the spot in the buildroot where the GN targets for the SDK parts
are stamped.

Change-Id: I604612c8d6a21efb07b323610e80b596abc1a6dd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101540
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Chinmay Garde <chinmaygarde@google.com>
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 03fddb6..20419e7 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -6,6 +6,10 @@
 import("configs.gni")
 import("runtime_args.gni")
 
+if (is_fuchsia) {
+  import("//build/fuchsia/sdk.gni")
+}
+
 config("dart_public_config") {
   include_dirs = [
     ".",
@@ -143,7 +147,16 @@
   }
 
   if (is_fuchsia) {
-    include_dirs += [ "//zircon/system/ulib/zx/include" ]
+    if (using_fuchsia_sdk) {
+      # TODO(chinmaygarde): Currenty these targets need to be build in the
+      # Fuchsia tree as well as outside it using the SDK. However, not all
+      # Fuchsia features are available in the SDK. As these features are added,
+      # the guards can be removed. Eventually, only SDK builds will be present.
+      # Then, this flag can be removed completely.
+      defines += [ "FUCHSIA_SDK" ]
+    } else {
+      include_dirs += [ "//zircon/system/ulib/zx/include" ]
+    }
   }
 
   if (!is_win) {
@@ -224,10 +237,14 @@
     ":generate_version_cc_file",
   ]
   if (is_fuchsia) {
-    extra_deps += [
-      "//zircon/public/lib/fbl",
-      "//zircon/public/lib/trace-engine",
-    ]
+    if (using_fuchsia_sdk) {
+      extra_deps += [ "$fuchsia_sdk_root/pkg:fdio" ]
+    } else {
+      extra_deps += [
+        "//zircon/public/lib/fbl",
+        "//zircon/public/lib/trace-engine",
+      ]
+    }
   }
   configurable_deps = [
     "platform:libdart_platform",
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 532229e..7c93362 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -14,6 +14,10 @@
 import("io_impl_sources.gni")
 import("io_sources.gni")
 
+if (is_fuchsia) {
+  import("//build/fuchsia/sdk.gni")
+}
+
 config("libdart_builtin_config") {
   if (!is_win) {
     libs = [ "dl" ]
@@ -39,9 +43,15 @@
     public_configs = [ ":libdart_builtin_config" ]
     deps = []
     if (is_fuchsia) {
-      public_deps = [
-        "//zircon/public/lib/fdio",
-      ]
+      if (using_fuchsia_sdk) {
+        public_deps = [
+          "$fuchsia_sdk_root/pkg:fdio",
+        ]
+      } else {
+        public_deps = [
+          "//zircon/public/lib/fdio",
+        ]
+      }
     }
     include_dirs = [ ".." ]
     set_sources_assignment_filter([
@@ -254,10 +264,17 @@
     deps = []
 
     if (is_fuchsia) {
-      deps += [ "//garnet/public/lib/netstack/c" ]
-      public_deps = [
-        "//zircon/public/lib/fdio",
-      ]
+      if (using_fuchsia_sdk) {
+        deps += [ "$fuchsia_sdk_root/pkg/lib/netstack/c" ]
+        public_deps = [
+          "$fuchsia_sdk_root/pkg:fdio",
+        ]
+      } else {
+        deps += [ "//garnet/public/lib/netstack/c" ]
+        public_deps = [
+          "//zircon/public/lib/fdio",
+        ]
+      }
     }
 
     deps += [ "//third_party/zlib" ]
@@ -369,10 +386,17 @@
     deps += [ "//third_party/boringssl" ]
 
     if (is_fuchsia) {
-      deps += [ "//garnet/public/lib/netstack/c" ]
-      public_deps = [
-        "//zircon/public/lib/fdio",
-      ]
+      if (using_fuchsia_sdk) {
+        deps += [ "$fuchsia_sdk_root/pkg/lib/netstack/c" ]
+        public_deps = [
+          "$fuchsia_sdk_root/pkg:fdio",
+        ]
+      } else {
+        deps += [ "//garnet/public/lib/netstack/c" ]
+        public_deps = [
+          "//zircon/public/lib/fdio",
+        ]
+      }
     }
 
     sources = io_impl_sources + cli_impl_sources
@@ -936,7 +960,9 @@
   }
 
   if (is_fuchsia) {
-    deps += [ "//zircon/public/lib/trace" ]
+    if (!using_fuchsia_sdk) {
+      deps += [ "//zircon/public/lib/trace" ]
+    }
   }
 
   # The VM sources are already included in libdart, so we just want to add in
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index f2737c9..599c9a9 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -38,6 +38,10 @@
 import("heap/heap_sources.gni")
 import("vm_sources.gni")
 
+if (is_fuchsia) {
+  import("//build/fuchsia/sdk.gni")
+}
+
 config("libdart_vm_config") {
   if (is_fuchsia) {
     libs = [ "zircon" ]
@@ -62,15 +66,19 @@
   target_type = "source_set"
   extra_deps = [ "//third_party/icu" ]
   if (is_fuchsia) {
-    extra_deps += [
-      # TODO(US-399): Remove time_service specific code when it is no longer
-      # necessary.
-      "//sdk/lib/sys/cpp",
-      "//sdk/fidl/fuchsia.timezone",
+    if (using_fuchsia_sdk) {
+      extra_deps += [ "$fuchsia_sdk_root/pkg/lib/sys/cpp" ]
+    } else {
+      extra_deps += [
+        # TODO(US-399): Remove time_service specific code when it is no longer
+        # necessary.
+        "//sdk/lib/sys/cpp",
+        "//sdk/fidl/fuchsia.timezone",
 
-      "//zircon/public/lib/fbl",
-      "//zircon/public/lib/trace-engine",
-    ]
+        "//zircon/public/lib/fbl",
+        "//zircon/public/lib/trace-engine",
+      ]
+    }
   }
   public_configs = [ ":libdart_vm_config" ]
   set_sources_assignment_filter([
@@ -85,10 +93,12 @@
 library_for_all_configs("libdart_lib") {
   target_type = "source_set"
   if (is_fuchsia) {
-    extra_deps = [
-      "//zircon/public/lib/fbl",
-      "//zircon/public/lib/trace-engine",
-    ]
+    if (!using_fuchsia_sdk) {
+      extra_deps = [
+        "//zircon/public/lib/fbl",
+        "//zircon/public/lib/trace-engine",
+      ]
+    }
   }
   include_dirs = [ ".." ]
   allsources =
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index df94ba9..58acf87 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -8,7 +8,9 @@
 #include "vm/os.h"
 
 #include <errno.h>
+#if !defined(FUCHSIA_SDK)
 #include <fuchsia/timezone/cpp/fidl.h>
+#endif  //  !defined(FUCHSIA_SDK)
 #include <lib/sys/cpp/service_directory.h>
 #include <zircon/process.h>
 #include <zircon/syscalls.h>
@@ -37,6 +39,7 @@
   return static_cast<intptr_t>(getpid());
 }
 
+#if !defined(FUCHSIA_SDK)
 // TODO(FL-98): Change this to talk to fuchsia.dart to get timezone service to
 // directly get timezone.
 //
@@ -44,10 +47,12 @@
 // component:ConnectToEnvironmentServices and this is the only thing that is
 // blocking it and FL-98 will take time.
 static fuchsia::timezone::TimezoneSyncPtr tz;
+#endif  //  !defined(FUCHSIA_SDK)
 
 static zx_status_t GetLocalAndDstOffsetInSeconds(int64_t seconds_since_epoch,
                                                  int32_t* local_offset,
                                                  int32_t* dst_offset) {
+#if !defined(FUCHSIA_SDK)
   zx_status_t status = tz->GetTimezoneOffsetMinutes(seconds_since_epoch * 1000,
                                                     local_offset, dst_offset);
   if (status != ZX_OK) {
@@ -56,9 +61,13 @@
   *local_offset *= 60;
   *dst_offset *= 60;
   return ZX_OK;
+#else
+  return ZX_ERR_NOT_SUPPORTED;
+#endif  //  !defined(FUCHSIA_SDK)
 }
 
 const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
+#if !defined(FUCHSIA_SDK)
   // TODO(abarth): Handle time zone changes.
   static const auto* tz_name = new std::string([] {
     std::string result;
@@ -66,6 +75,9 @@
     return result;
   }());
   return tz_name->c_str();
+#else
+  return "";
+#endif  //  !defined(FUCHSIA_SDK)}
 }
 
 int OS::GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch) {
@@ -252,8 +264,10 @@
 }
 
 void OS::Init() {
+#if !defined(FUCHSIA_SDK)
   auto services = sys::ServiceDirectory::CreateFromNamespace();
   services->Connect(tz.NewRequest());
+#endif  //  !defined(FUCHSIA_SDK)
 }
 
 void OS::Cleanup() {}
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 158c1c3..329f488 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -115,7 +115,7 @@
 
 #if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
       return new TimelineEventSystraceRecorder();
-#elif defined(HOST_OS_FUCHSIA)
+#elif defined(HOST_OS_FUCHSIA) && !defined(FUCHSIA_SDK)
       return new TimelineEventFuchsiaRecorder();
 #else
       OS::PrintErr(
@@ -1108,7 +1108,7 @@
 
 int64_t TimelineEventRecorder::GetNextAsyncId() {
   // TODO(johnmccutchan): Gracefully handle wrap around.
-#if defined(HOST_OS_FUCHSIA)
+#if defined(HOST_OS_FUCHSIA) && !defined(FUCHSIA_SDK)
   return trace_generate_nonce();
 #else
   uint32_t next =
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 37e5af9..3fa4cff 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -14,7 +14,7 @@
 #include "vm/os.h"
 #include "vm/os_thread.h"
 
-#if defined(HOST_OS_FUCHSIA)
+#if defined(HOST_OS_FUCHSIA) && !defined(FUCHSIA_SDK)
 #include <trace-engine/context.h>
 #include <trace-engine/instrumentation.h>
 #endif
@@ -59,7 +59,7 @@
   const char* fuchsia_name() const { return fuchsia_name_; }
 
   bool enabled() {
-#if defined(HOST_OS_FUCHSIA)
+#if defined(HOST_OS_FUCHSIA) && !defined(FUCHSIA_SDK)
     return trace_is_category_enabled(fuchsia_name_);
 #else
     return enabled_ != 0;
@@ -78,7 +78,7 @@
     return OFFSET_OF(TimelineStream, enabled_);
   }
 
-#if defined(HOST_OS_FUCHSIA)
+#if defined(HOST_OS_FUCHSIA) && !defined(FUCHSIA_SDK)
   trace_site_t* trace_site() { return &trace_site_; }
 #endif
 
@@ -90,7 +90,7 @@
   // 0 or 1. If this becomes a BitField, the generated code must be updated.
   uintptr_t enabled_;
 
-#if defined(HOST_OS_FUCHSIA)
+#if defined(HOST_OS_FUCHSIA) && !defined(FUCHSIA_SDK)
   trace_site_t trace_site_ = {};
 #endif
 };
@@ -907,7 +907,7 @@
   void CompleteEvent(TimelineEvent* event);
 };
 
-#if defined(HOST_OS_FUCHSIA)
+#if defined(HOST_OS_FUCHSIA) && !defined(FUCHSIA_SDK)
 // A recorder that sends events to Fuchsia's tracing app. See:
 // https://fuchsia.googlesource.com/garnet/+/master/docs/tracing_usage_guide.md
 class TimelineEventFuchsiaRecorder : public TimelineEventPlatformRecorder {
diff --git a/runtime/vm/timeline_fuchsia.cc b/runtime/vm/timeline_fuchsia.cc
index 0110166..fde26e5 100644
--- a/runtime/vm/timeline_fuchsia.cc
+++ b/runtime/vm/timeline_fuchsia.cc
@@ -3,7 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"
-#if defined(HOST_OS_FUCHSIA) && defined(SUPPORT_TIMELINE)
+#if defined(HOST_OS_FUCHSIA) && defined(SUPPORT_TIMELINE) &&                   \
+    !defined(FUCHSIA_SDK)
 
 #include <trace-engine/context.h>
 #include <trace-engine/instrumentation.h>