Split examples, test and utils in their own BUILD.gn

The basic change was to copy-paste targets in the new BUILD.gn files and
fixup paths / add includes. There's a couple more changes that had to be
done at the same time:

 - Multiple files need to know if GLFW is supported so the variable was
moved to dawn_features.gni.
 - The gtest_and_gmock target used to abstract between Dawn's copy of
GTest/GMock is only needed by tests and was moved in src/tests/BUILD.gn.
 - A leftover dawn_end2end_tests target is left in the main BUILD.gn
file that is an exact copy of the on in src/tests/BUILD.gn. This is
because the GN path is hardcoded in Chromium's isolate_map.pyl that also
can't support GN groups. The only way to move a target I could figure
out was to duplicate it temporarily.

Bug: chromium:1064305
Change-Id: I96820e9d6510b8c9b9112c3e6cd8df2413f04287
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/19201
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 3b5190b..eb7872d 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -13,397 +13,45 @@
 # limitations under the License.
 
 import("//build_overrides/build.gni")
-import("generator/dawn_generator.gni")
 import("scripts/dawn_features.gni")
 import("scripts/dawn_overrides_with_defaults.gni")
 
+group("all") {
+  testonly = true
+  deps = [
+    "src/fuzzers:dawn_fuzzers",
+    "src/tests:dawn_tests",
+  ]
+  if (dawn_standalone) {
+    deps += [ "examples:dawn_samples" ]
+  }
+}
+
+###############################################################################
+# Temporary Dawn end2end test target
+###############################################################################
+
+# It is not possible to move a target around with a proxy group without
+# breaking swarming tests. This is a temporary target that is a duplicate of
+# //src/tests:dawn_end2end_tests that's used temporarily so that we can land
+# the split of src/tests/BUILD.gn in a Chromium roll and switch which targets
+# the swarmed tests use.
+
 import("//testing/test.gni")
 
-###############################################################################
-# GLFW wrapping target
-###############################################################################
-
-supports_glfw_for_windowing = is_win || (is_linux && !is_chromeos) || is_mac
-
-# GLFW does not support ChromeOS, Android or Fuchsia, so provide a small mock
-# library that can be linked into the Dawn tests on these platforms. Otherwise,
-# use the real library from third_party/.
-if (supports_glfw_for_windowing) {
-  group("dawn_glfw") {
-    public_deps = [
-      "third_party:glfw",
-    ]
-  }
-} else if (is_fuchsia) {
-  # The mock implementation of GLFW on Fuchsia
-  config("dawn_glfw_public_config") {
-    # Allow inclusion of <GLFW/glfw3.h>
-    include_dirs = [ "${dawn_glfw_dir}/include" ]
-
-    # The GLFW/glfw3.h header includes <GL/gl.h> by default, but the latter
-    # does not exist on Fuchsia. Defining GLFW_INCLUDE_NONE helps work around
-    # the issue, but it needs to be defined for any file that includes the
-    # header.
-    defines = [
-      "GLFW_INCLUDE_NONE",
-      "GLFW_INCLUDE_VULKAN",
-    ]
-  }
-
-  static_library("dawn_glfw") {
-    sources = [
-      # NOTE: The header below is required to pass "gn check".
-      "${dawn_glfw_dir}/include/GLFW/glfw3.h",
-      "src/utils/Glfw3Fuchsia.cpp",
-    ]
-    public_configs = [ ":dawn_glfw_public_config" ]
-    deps = [
-      "${dawn_root}/src/common",
-    ]
-  }
-} else {
-  # Just skip GLFW on other systems
-  group("dawn_glfw") {
-  }
-}
-
-###############################################################################
-# Utils for tests and samples
-###############################################################################
-
-static_library("dawn_utils") {
-  configs += [ "${dawn_root}/src/common:dawn_internal" ]
-
-  sources = [
-    "src/utils/ComboRenderBundleEncoderDescriptor.cpp",
-    "src/utils/ComboRenderBundleEncoderDescriptor.h",
-    "src/utils/ComboRenderPipelineDescriptor.cpp",
-    "src/utils/ComboRenderPipelineDescriptor.h",
-    "src/utils/SystemUtils.cpp",
-    "src/utils/SystemUtils.h",
-    "src/utils/TerribleCommandBuffer.cpp",
-    "src/utils/TerribleCommandBuffer.h",
-    "src/utils/TextureFormatUtils.cpp",
-    "src/utils/TextureFormatUtils.h",
-    "src/utils/Timer.h",
-    "src/utils/WGPUHelpers.cpp",
-    "src/utils/WGPUHelpers.h",
-  ]
-  deps = [
-    "${dawn_root}/src/common",
-    "${dawn_root}/src/dawn_native",
-    "${dawn_root}/src/dawn_wire",
-    "${dawn_shaderc_dir}:libshaderc",
-  ]
-  libs = []
-
-  if (is_win) {
-    sources += [ "src/utils/WindowsTimer.cpp" ]
-  } else if (is_mac) {
-    sources += [
-      "src/utils/OSXTimer.cpp",
-      "src/utils/ObjCUtils.h",
-      "src/utils/ObjCUtils.mm",
-    ]
-    libs += [ "QuartzCore.framework" ]
-  } else {
-    sources += [ "src/utils/PosixTimer.cpp" ]
-  }
-
-  if (supports_glfw_for_windowing) {
-    sources += [
-      "src/utils/GLFWUtils.cpp",
-      "src/utils/GLFWUtils.h",
-    ]
-    deps += [ ":dawn_glfw" ]
-
-    if (dawn_enable_metal) {
-      sources += [ "src/utils/GLFWUtils_metal.mm" ]
-      libs += [ "Metal.framework" ]
-    }
-  }
-
-  public_deps = [
-    "${dawn_root}/src/dawn:dawncpp_headers",
-  ]
-}
-
-###############################################################################
-# Dawn test targets
-###############################################################################
-
-dawn_json_generator("mock_webgpu_gen") {
-  target = "mock_webgpu"
-  outputs = [
-    "src/dawn/mock_webgpu.h",
-    "src/dawn/mock_webgpu.cpp",
-  ]
-}
-
-test("dawn_unittests") {
-  configs += [ "${dawn_root}/src/common:dawn_internal" ]
-
-  deps = [
-    ":dawn_utils",
-    ":mock_webgpu_gen",
-    "${dawn_root}/src/common",
-    "${dawn_root}/src/dawn:dawncpp",
-    "${dawn_root}/src/dawn:libdawn_proc",
-    "${dawn_root}/src/dawn_native",
-    "${dawn_root}/src/dawn_native:dawn_native_sources",
-    "${dawn_root}/src/dawn_wire",
-    "third_party:gmock_and_gtest",
-  ]
-
-  # Add internal dawn_native config for internal unittests.
-  configs += [ "${dawn_root}/src/dawn_native:dawn_native_internal" ]
-
-  sources = get_target_outputs(":mock_webgpu_gen")
-  sources += [
-    "src/dawn_wire/client/ClientMemoryTransferService_mock.cpp",
-    "src/dawn_wire/client/ClientMemoryTransferService_mock.h",
-    "src/dawn_wire/server/ServerMemoryTransferService_mock.cpp",
-    "src/dawn_wire/server/ServerMemoryTransferService_mock.h",
-    "src/tests/unittests/BitSetIteratorTests.cpp",
-    "src/tests/unittests/BuddyAllocatorTests.cpp",
-    "src/tests/unittests/BuddyMemoryAllocatorTests.cpp",
-    "src/tests/unittests/CommandAllocatorTests.cpp",
-    "src/tests/unittests/EnumClassBitmasksTests.cpp",
-    "src/tests/unittests/ErrorTests.cpp",
-    "src/tests/unittests/ExtensionTests.cpp",
-    "src/tests/unittests/GetProcAddressTests.cpp",
-    "src/tests/unittests/LinkedListTests.cpp",
-    "src/tests/unittests/MathTests.cpp",
-    "src/tests/unittests/ObjectBaseTests.cpp",
-    "src/tests/unittests/PerStageTests.cpp",
-    "src/tests/unittests/PlacementAllocatedTests.cpp",
-    "src/tests/unittests/RefCountedTests.cpp",
-    "src/tests/unittests/ResultTests.cpp",
-    "src/tests/unittests/RingBufferAllocatorTests.cpp",
-    "src/tests/unittests/SerialMapTests.cpp",
-    "src/tests/unittests/SerialQueueTests.cpp",
-    "src/tests/unittests/SlabAllocatorTests.cpp",
-    "src/tests/unittests/SystemUtilsTests.cpp",
-    "src/tests/unittests/ToBackendTests.cpp",
-    "src/tests/unittests/validation/BindGroupValidationTests.cpp",
-    "src/tests/unittests/validation/BufferValidationTests.cpp",
-    "src/tests/unittests/validation/CommandBufferValidationTests.cpp",
-    "src/tests/unittests/validation/ComputeIndirectValidationTests.cpp",
-    "src/tests/unittests/validation/ComputePassValidationTests.cpp",
-    "src/tests/unittests/validation/ComputeValidationTests.cpp",
-    "src/tests/unittests/validation/CopyCommandsValidationTests.cpp",
-    "src/tests/unittests/validation/DebugMarkerValidationTests.cpp",
-    "src/tests/unittests/validation/DrawIndirectValidationTests.cpp",
-    "src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp",
-    "src/tests/unittests/validation/ErrorScopeValidationTests.cpp",
-    "src/tests/unittests/validation/FenceValidationTests.cpp",
-    "src/tests/unittests/validation/GetBindGroupLayoutValidationTests.cpp",
-    "src/tests/unittests/validation/QueueSubmitValidationTests.cpp",
-    "src/tests/unittests/validation/RenderBundleValidationTests.cpp",
-    "src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp",
-    "src/tests/unittests/validation/RenderPassValidationTests.cpp",
-    "src/tests/unittests/validation/RenderPipelineValidationTests.cpp",
-    "src/tests/unittests/validation/ResourceUsageTrackingTests.cpp",
-    "src/tests/unittests/validation/SamplerValidationTests.cpp",
-    "src/tests/unittests/validation/ShaderModuleValidationTests.cpp",
-    "src/tests/unittests/validation/StorageTextureValidationTests.cpp",
-    "src/tests/unittests/validation/TextureValidationTests.cpp",
-    "src/tests/unittests/validation/TextureViewValidationTests.cpp",
-    "src/tests/unittests/validation/ToggleValidationTests.cpp",
-    "src/tests/unittests/validation/ValidationTest.cpp",
-    "src/tests/unittests/validation/ValidationTest.h",
-    "src/tests/unittests/validation/VertexBufferValidationTests.cpp",
-    "src/tests/unittests/validation/VertexStateValidationTests.cpp",
-    "src/tests/unittests/wire/WireArgumentTests.cpp",
-    "src/tests/unittests/wire/WireBasicTests.cpp",
-    "src/tests/unittests/wire/WireBufferMappingTests.cpp",
-    "src/tests/unittests/wire/WireErrorCallbackTests.cpp",
-    "src/tests/unittests/wire/WireExtensionTests.cpp",
-    "src/tests/unittests/wire/WireFenceTests.cpp",
-    "src/tests/unittests/wire/WireInjectTextureTests.cpp",
-    "src/tests/unittests/wire/WireMemoryTransferServiceTests.cpp",
-    "src/tests/unittests/wire/WireOptionalTests.cpp",
-    "src/tests/unittests/wire/WireTest.cpp",
-    "src/tests/unittests/wire/WireTest.h",
-    "src/tests/unittests/wire/WireWGPUDevicePropertiesTests.cpp",
-  ]
-
-  if (dawn_enable_d3d12) {
-    sources += [ "src/tests/unittests/d3d12/CopySplitTests.cpp" ]
-  }
-
-  # When building inside Chromium, use their gtest main function because it is
-  # needed to run in swarming correctly.
-  if (build_with_chromium) {
-    sources += [ "//gpu/dawn_unittests_main.cc" ]
-  } else {
-    sources += [ "src/tests/UnittestsMain.cpp" ]
-  }
-}
-
-source_set("dawn_end2end_tests_sources") {
-  configs += [ "${dawn_root}/src/common:dawn_internal" ]
-  testonly = true
-
-  deps = [
-    ":dawn_utils",
-    "${dawn_root}/src/common",
-    "${dawn_root}/src/dawn:dawncpp",
-    "${dawn_root}/src/dawn:libdawn_proc",
-    "${dawn_root}/src/dawn_native",
-    "${dawn_root}/src/dawn_wire",
-    "third_party:gmock_and_gtest",
-  ]
-
-  sources = [
-    "src/tests/DawnTest.h",
-    "src/tests/end2end/BasicTests.cpp",
-    "src/tests/end2end/BindGroupTests.cpp",
-    "src/tests/end2end/BufferTests.cpp",
-    "src/tests/end2end/ClipSpaceTests.cpp",
-    "src/tests/end2end/ColorStateTests.cpp",
-    "src/tests/end2end/CompressedTextureFormatTests.cpp",
-    "src/tests/end2end/ComputeCopyStorageBufferTests.cpp",
-    "src/tests/end2end/ComputeIndirectTests.cpp",
-    "src/tests/end2end/ComputeSharedMemoryTests.cpp",
-    "src/tests/end2end/ComputeStorageBufferBarrierTests.cpp",
-    "src/tests/end2end/CopyTests.cpp",
-    "src/tests/end2end/CullingTests.cpp",
-    "src/tests/end2end/DebugMarkerTests.cpp",
-    "src/tests/end2end/DepthStencilStateTests.cpp",
-    "src/tests/end2end/DestroyTests.cpp",
-    "src/tests/end2end/DeviceLostTests.cpp",
-    "src/tests/end2end/DrawIndexedIndirectTests.cpp",
-    "src/tests/end2end/DrawIndexedTests.cpp",
-    "src/tests/end2end/DrawIndirectTests.cpp",
-    "src/tests/end2end/DrawTests.cpp",
-    "src/tests/end2end/DynamicBufferOffsetTests.cpp",
-    "src/tests/end2end/FenceTests.cpp",
-    "src/tests/end2end/GpuMemorySynchronizationTests.cpp",
-    "src/tests/end2end/IndexFormatTests.cpp",
-    "src/tests/end2end/MultisampledRenderingTests.cpp",
-    "src/tests/end2end/NonzeroTextureCreationTests.cpp",
-    "src/tests/end2end/ObjectCachingTests.cpp",
-    "src/tests/end2end/OpArrayLengthTests.cpp",
-    "src/tests/end2end/PrimitiveTopologyTests.cpp",
-    "src/tests/end2end/RenderBundleTests.cpp",
-    "src/tests/end2end/RenderPassLoadOpTests.cpp",
-    "src/tests/end2end/RenderPassTests.cpp",
-    "src/tests/end2end/SamplerTests.cpp",
-    "src/tests/end2end/ScissorTests.cpp",
-    "src/tests/end2end/StorageTextureTests.cpp",
-    "src/tests/end2end/TextureFormatTests.cpp",
-    "src/tests/end2end/TextureViewTests.cpp",
-    "src/tests/end2end/TextureZeroInitTests.cpp",
-    "src/tests/end2end/VertexFormatTests.cpp",
-    "src/tests/end2end/VertexStateTests.cpp",
-    "src/tests/end2end/ViewportOrientationTests.cpp",
-    "src/tests/end2end/ViewportTests.cpp",
-  ]
-
-  # Validation tests that need OS windows live in end2end tests.
-  sources += [
-    "src/tests/unittests/validation/ValidationTest.cpp",
-    "src/tests/unittests/validation/ValidationTest.h",
-  ]
-
-  libs = []
-
-  if (dawn_enable_d3d12) {
-    sources += [ "src/tests/end2end/D3D12ResourceWrappingTests.cpp" ]
-    libs += [
-      "d3d11.lib",
-      "dxgi.lib",
-    ]
-  }
-
-  if (dawn_enable_metal) {
-    sources += [ "src/tests/end2end/IOSurfaceWrappingTests.cpp" ]
-    libs += [ "IOSurface.framework" ]
-  }
-
-  if (dawn_enable_opengl) {
-    assert(supports_glfw_for_windowing)
-  }
-
-  if (supports_glfw_for_windowing) {
-    sources += [
-      "src/tests/end2end/SwapChainTests.cpp",
-      "src/tests/end2end/SwapChainValidationTests.cpp",
-      "src/tests/end2end/WindowSurfaceTests.cpp",
-    ]
-    deps += [ ":dawn_glfw" ]
-  }
-}
-
-source_set("dawn_white_box_tests_sources") {
-  configs += [ "${dawn_root}/src/dawn_native:dawn_native_internal" ]
-  testonly = true
-
-  deps = [
-    ":dawn_utils",
-    "${dawn_root}/src/common",
-    "${dawn_root}/src/dawn:dawncpp",
-    "${dawn_root}/src/dawn:libdawn_proc",
-    "${dawn_root}/src/dawn_native:dawn_native_sources",
-
-    # Static because the tests both link against and have dawn_native
-    # sources. MSVC errors when both importing and exporting symbols.
-    "${dawn_root}/src/dawn_native:dawn_native_static",
-    "${dawn_root}/src/dawn_wire",
-    "third_party:gmock_and_gtest",
-  ]
-
-  sources = [
-    "src/tests/DawnTest.h",
-  ]
-
-  if (dawn_enable_vulkan) {
-    deps += [ "third_party:vulkan_headers" ]
-
-    if (is_chromeos) {
-      sources += [ "src/tests/white_box/VulkanImageWrappingTestsDmaBuf.cpp" ]
-    } else if (is_linux) {
-      sources += [ "src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp" ]
-    }
-
-    if (dawn_enable_error_injection) {
-      sources += [ "src/tests/white_box/VulkanErrorInjectorTests.cpp" ]
-    }
-  }
-
-  if (dawn_enable_d3d12) {
-    sources += [
-      "src/tests/white_box/D3D12DescriptorHeapTests.cpp",
-      "src/tests/white_box/D3D12ResidencyTests.cpp",
-      "src/tests/white_box/D3D12SmallTextureTests.cpp",
-    ]
-  }
-
-  if (dawn_enable_metal) {
-    sources += [ "src/tests/white_box/MetalAutoreleasePoolTests.mm" ]
-  }
-
-  if (dawn_enable_opengl) {
-    deps += [ ":dawn_glfw" ]
-  }
-
-  libs = []
-}
-
 test("dawn_end2end_tests") {
-  configs += [ "${dawn_root}/src/common:dawn_internal" ]
+  configs += [ "src/common:dawn_internal" ]
 
   deps = [
-    ":dawn_end2end_tests_sources",
-    ":dawn_utils",
-    ":dawn_white_box_tests_sources",
-    "${dawn_root}/src/common",
-    "${dawn_root}/src/dawn:dawncpp",
-    "${dawn_root}/src/dawn:libdawn_proc",
-    "${dawn_root}/src/dawn_native",
-    "${dawn_root}/src/dawn_wire",
-    "third_party:gmock_and_gtest",
+    "src/common",
+    "src/dawn:dawncpp",
+    "src/dawn:libdawn_proc",
+    "src/dawn_native",
+    "src/dawn_wire",
+    "src/tests:dawn_end2end_tests_sources",
+    "src/tests:dawn_white_box_tests_sources",
+    "src/tests:gmock_and_gtest",
+    "src/utils:dawn_utils",
   ]
 
   sources = [
@@ -422,7 +70,7 @@
   }
 
   if (dawn_enable_opengl) {
-    deps += [ ":dawn_glfw" ]
+    deps += [ "src/utils:dawn_glfw" ]
   }
 
   if (is_chromeos) {
@@ -430,211 +78,6 @@
   }
 }
 
-test("dawn_perf_tests") {
-  configs += [ "${dawn_root}/src/common:dawn_internal" ]
-
-  deps = [
-    ":dawn_utils",
-    "${dawn_root}/src/common",
-    "${dawn_root}/src/dawn:dawncpp",
-    "${dawn_root}/src/dawn:libdawn_proc",
-    "${dawn_root}/src/dawn_native",
-    "${dawn_root}/src/dawn_platform",
-    "${dawn_root}/src/dawn_wire",
-    "third_party:gmock_and_gtest",
-  ]
-
-  sources = [
-    "src/tests/DawnTest.cpp",
-    "src/tests/DawnTest.h",
-    "src/tests/ParamGenerator.h",
-    "src/tests/perf_tests/BufferUploadPerf.cpp",
-    "src/tests/perf_tests/DawnPerfTest.cpp",
-    "src/tests/perf_tests/DawnPerfTest.h",
-    "src/tests/perf_tests/DawnPerfTestPlatform.cpp",
-    "src/tests/perf_tests/DawnPerfTestPlatform.h",
-    "src/tests/perf_tests/DrawCallPerf.cpp",
-  ]
-
-  libs = []
-
-  # When building inside Chromium, use their gtest main function because it is
-  # needed to run in swarming correctly.
-  if (build_with_chromium) {
-    sources += [ "//gpu/dawn_perf_tests_main.cc" ]
-  } else {
-    sources += [ "src/tests/PerfTestsMain.cpp" ]
-  }
-
-  if (dawn_enable_metal) {
-    libs += [ "IOSurface.framework" ]
-  }
-
-  if (dawn_enable_opengl) {
-    deps += [ ":dawn_glfw" ]
-  }
-}
-
-###############################################################################
-# Dawn samples, only in standalone builds
-###############################################################################
-
-if (dawn_standalone) {
-  # Library to handle the interaction of Dawn with GLFW windows in samples
-  static_library("dawn_bindings") {
-    configs += [ "${dawn_root}/src/common:dawn_internal" ]
-
-    sources = [
-      "src/utils/BackendBinding.cpp",
-      "src/utils/BackendBinding.h",
-    ]
-
-    public_deps = [
-      "${dawn_root}/src/dawn:dawn_headers",
-    ]
-
-    deps = [
-      ":dawn_glfw",
-      "${dawn_root}/src/common",
-      "${dawn_root}/src/dawn_native",
-    ]
-    libs = []
-
-    if (dawn_enable_d3d12) {
-      sources += [ "src/utils/D3D12Binding.cpp" ]
-    }
-
-    if (dawn_enable_metal) {
-      sources += [ "src/utils/MetalBinding.mm" ]
-      libs += [
-        "Metal.framework",
-        "QuartzCore.framework",
-      ]
-
-      # Suppress warnings that Metal isn't in the deployment target of Chrome
-      if (is_mac) {
-        cflags_objcc = [ "-Wno-unguarded-availability" ]
-      }
-    }
-
-    if (dawn_enable_null) {
-      sources += [ "src/utils/NullBinding.cpp" ]
-    }
-
-    if (dawn_enable_opengl) {
-      sources += [ "src/utils/OpenGLBinding.cpp" ]
-    }
-
-    if (dawn_enable_vulkan) {
-      sources += [ "src/utils/VulkanBinding.cpp" ]
-    }
-  }
-
-  # Static library to contain code and dependencies common to all samples
-  static_library("dawn_sample_utils") {
-    sources = [
-      "examples/SampleUtils.cpp",
-      "examples/SampleUtils.h",
-    ]
-
-    # Export all of these as public deps so that `gn check` allows includes
-    public_deps = [
-      ":dawn_bindings",
-      ":dawn_glfw",
-      ":dawn_utils",
-      "${dawn_root}/src/common",
-      "${dawn_root}/src/dawn:dawncpp",
-      "${dawn_root}/src/dawn:libdawn_proc",
-      "${dawn_root}/src/dawn_native",
-      "${dawn_root}/src/dawn_wire",
-    ]
-    public_configs = [ "${dawn_root}/src/common:dawn_internal" ]
-  }
-
-  # Template for samples to avoid listing dawn_sample_utils as a dep every time
-  template("dawn_sample") {
-    executable(target_name) {
-      deps = [
-        ":dawn_sample_utils",
-      ]
-      forward_variables_from(invoker, "*", [ "deps" ])
-
-      if (defined(invoker.deps)) {
-        deps += invoker.deps
-      }
-    }
-  }
-
-  dawn_sample("CppHelloTriangle") {
-    sources = [
-      "examples/CppHelloTriangle.cpp",
-    ]
-  }
-
-  dawn_sample("CHelloTriangle") {
-    sources = [
-      "examples/CHelloTriangle.cpp",
-    ]
-  }
-
-  dawn_sample("ComputeBoids") {
-    sources = [
-      "examples/ComputeBoids.cpp",
-    ]
-    deps = [
-      "third_party:glm",
-    ]
-  }
-
-  dawn_sample("Animometer") {
-    sources = [
-      "examples/Animometer.cpp",
-    ]
-  }
-
-  dawn_sample("CubeReflection") {
-    sources = [
-      "examples/CubeReflection.cpp",
-    ]
-    deps = [
-      "third_party:glm",
-    ]
-  }
-
-  dawn_sample("ManualSwapChainTest") {
-    sources = [
-      "examples/ManualSwapChainTest.cpp",
-    ]
-  }
-
-  group("dawn_samples") {
-    deps = [
-      ":Animometer",
-      ":CHelloTriangle",
-      ":ComputeBoids",
-      ":CppHelloTriangle",
-      ":CubeReflection",
-    ]
-  }
-}
-
-###############################################################################
-# Fuzzers
-###############################################################################
-
-group("dawn_fuzzers") {
-  testonly = true
-  deps = [
-    "src/fuzzers:dawn_spirv_cross_glsl_fast_fuzzer",
-    "src/fuzzers:dawn_spirv_cross_hlsl_fast_fuzzer",
-    "src/fuzzers:dawn_spirv_cross_msl_fast_fuzzer",
-    "src/fuzzers:dawn_spvc_glsl_fast_fuzzer",
-    "src/fuzzers:dawn_spvc_hlsl_fast_fuzzer",
-    "src/fuzzers:dawn_spvc_msl_fast_fuzzer",
-    "src/fuzzers:dawn_wire_server_and_frontend_fuzzer",
-  ]
-}
-
 ###############################################################################
 # Temporary groups
 ###############################################################################
@@ -643,7 +86,7 @@
 group("dawn_unittests_temp_group") {
   testonly = true
   public_deps = [
-    ":dawn_unittests",
+    "src/tests:dawn_unittests",
   ]
 }
 
@@ -657,9 +100,9 @@
 group("dawn_perf_tests_temp_group") {
   testonly = true
   public_deps = [
-    ":dawn_perf_tests",
+    "src/tests:dawn_perf_tests",
   ]
   data_deps = [
-    ":dawn_perf_tests",
+    "src/tests:dawn_perf_tests",
   ]
 }
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
new file mode 100644
index 0000000..f14be6e
--- /dev/null
+++ b/examples/BUILD.gn
@@ -0,0 +1,103 @@
+# Copyright 2020 The Dawn Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../scripts/dawn_overrides_with_defaults.gni")
+
+group("dawn_samples") {
+  deps = [
+    ":Animometer",
+    ":CHelloTriangle",
+    ":ComputeBoids",
+    ":CppHelloTriangle",
+    ":CubeReflection",
+    ":ManualSwapChainTest",
+  ]
+}
+
+# Static library to contain code and dependencies common to all samples
+static_library("dawn_sample_utils") {
+  sources = [
+    "SampleUtils.cpp",
+    "SampleUtils.h",
+  ]
+
+  # Export all of these as public deps so that `gn check` allows includes
+  public_deps = [
+    "${dawn_root}/src/common",
+    "${dawn_root}/src/dawn:dawncpp",
+    "${dawn_root}/src/dawn:libdawn_proc",
+    "${dawn_root}/src/dawn_native",
+    "${dawn_root}/src/dawn_wire",
+    "${dawn_root}/src/utils:dawn_bindings",
+    "${dawn_root}/src/utils:dawn_glfw",
+    "${dawn_root}/src/utils:dawn_utils",
+  ]
+  public_configs = [ "${dawn_root}/src/common:dawn_internal" ]
+}
+
+# Template for samples to avoid listing dawn_sample_utils as a dep every time
+template("dawn_sample") {
+  executable(target_name) {
+    deps = [
+      ":dawn_sample_utils",
+    ]
+    forward_variables_from(invoker, "*", [ "deps" ])
+
+    if (defined(invoker.deps)) {
+      deps += invoker.deps
+    }
+  }
+}
+
+dawn_sample("CppHelloTriangle") {
+  sources = [
+    "CppHelloTriangle.cpp",
+  ]
+}
+
+dawn_sample("CHelloTriangle") {
+  sources = [
+    "CHelloTriangle.cpp",
+  ]
+}
+
+dawn_sample("ComputeBoids") {
+  sources = [
+    "ComputeBoids.cpp",
+  ]
+  deps = [
+    "${dawn_root}/third_party:glm",
+  ]
+}
+
+dawn_sample("Animometer") {
+  sources = [
+    "Animometer.cpp",
+  ]
+}
+
+dawn_sample("CubeReflection") {
+  sources = [
+    "CubeReflection.cpp",
+  ]
+  deps = [
+    "${dawn_root}/third_party:glm",
+  ]
+}
+
+dawn_sample("ManualSwapChainTest") {
+  sources = [
+    "ManualSwapChainTest.cpp",
+  ]
+}
diff --git a/scripts/dawn_features.gni b/scripts/dawn_features.gni
index 37a32a0..9f4da33 100644
--- a/scripts/dawn_features.gni
+++ b/scripts/dawn_features.gni
@@ -78,3 +78,6 @@
   dawn_enable_vulkan_validation_layers =
       dawn_enable_vulkan && ((is_linux && !is_chromeos) || is_win)
 }
+
+dawn_supports_glfw_for_windowing =
+    is_win || (is_linux && !is_chromeos) || is_mac
diff --git a/src/fuzzers/BUILD.gn b/src/fuzzers/BUILD.gn
index 65164b9..83c6da4 100644
--- a/src/fuzzers/BUILD.gn
+++ b/src/fuzzers/BUILD.gn
@@ -182,3 +182,17 @@
 
   additional_configs = [ "${dawn_root}/src/common:dawn_internal" ]
 }
+
+# A group target to build all the fuzzers
+group("dawn_fuzzers") {
+  testonly = true
+  deps = [
+    ":dawn_spirv_cross_glsl_fast_fuzzer",
+    ":dawn_spirv_cross_hlsl_fast_fuzzer",
+    ":dawn_spirv_cross_msl_fast_fuzzer",
+    ":dawn_spvc_glsl_fast_fuzzer",
+    ":dawn_spvc_hlsl_fast_fuzzer",
+    ":dawn_spvc_msl_fast_fuzzer",
+    ":dawn_wire_server_and_frontend_fuzzer",
+  ]
+}
diff --git a/src/tests/BUILD.gn b/src/tests/BUILD.gn
new file mode 100644
index 0000000..793981e
--- /dev/null
+++ b/src/tests/BUILD.gn
@@ -0,0 +1,449 @@
+# Copyright 2012 The Dawn Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../scripts/dawn_overrides_with_defaults.gni")
+
+import("//testing/test.gni")
+import("${dawn_root}/generator/dawn_generator.gni")
+import("${dawn_root}/scripts/dawn_features.gni")
+
+group("dawn_tests") {
+  testonly = true
+  deps = [
+    ":dawn_end2end_tests_tmp",
+    ":dawn_perf_tests",
+    ":dawn_unittests",
+  ]
+}
+
+###############################################################################
+# Gtest Gmock - Handle building inside and outside of Chromium.
+###############################################################################
+
+# When building outside of Chromium we need to define our own targets for GTest
+# and GMock. However when compiling inside of Chromium we need to reuse the
+# existing targets, both because Chromium has a special harness for swarming
+# and because otherwise the "gn check" fails.
+
+if (!build_with_chromium) {
+  # When we aren't in Chromium we define out own targets based on the location
+  # of the googletest repo.
+  googletest_dir = dawn_googletest_dir
+
+  config("gtest_config") {
+    include_dirs = [
+      "${googletest_dir}/googletest",
+      "${googletest_dir}/googletest/include",
+    ]
+  }
+
+  static_library("gtest") {
+    testonly = true
+    sources = [
+      "${googletest_dir}/googletest/src/gtest-all.cc",
+    ]
+    public_configs = [ ":gtest_config" ]
+  }
+
+  config("gmock_config") {
+    include_dirs = [
+      "${googletest_dir}/googlemock",
+      "${googletest_dir}/googlemock/include",
+      "${googletest_dir}/googletest/include",
+    ]
+  }
+
+  static_library("gmock") {
+    testonly = true
+    sources = [
+      "${googletest_dir}/googlemock/src/gmock-all.cc",
+    ]
+    public_configs = [ ":gmock_config" ]
+  }
+
+  group("gmock_and_gtest") {
+    testonly = true
+    public_deps = [
+      ":gmock",
+      ":gtest",
+    ]
+  }
+} else {
+  # When we are in Chromium we reuse its targets, and also add some deps that
+  # are needed to launch the test in swarming mode.
+  group("gmock_and_gtest") {
+    testonly = true
+    public_deps = [
+      "//base",
+      "//base/test:test_support",
+      "//testing/gmock",
+      "//testing/gtest",
+    ]
+  }
+}
+
+###############################################################################
+# Dawn unittests
+###############################################################################
+
+dawn_json_generator("mock_webgpu_gen") {
+  target = "mock_webgpu"
+  outputs = [
+    "src/dawn/mock_webgpu.h",
+    "src/dawn/mock_webgpu.cpp",
+  ]
+}
+
+test("dawn_unittests") {
+  configs += [ "${dawn_root}/src/common:dawn_internal" ]
+
+  deps = [
+    ":gmock_and_gtest",
+    ":mock_webgpu_gen",
+    "${dawn_root}/src/common",
+    "${dawn_root}/src/dawn:dawncpp",
+    "${dawn_root}/src/dawn:libdawn_proc",
+    "${dawn_root}/src/dawn_native",
+    "${dawn_root}/src/dawn_native:dawn_native_sources",
+    "${dawn_root}/src/dawn_wire",
+    "${dawn_root}/src/utils:dawn_utils",
+  ]
+
+  # Add internal dawn_native config for internal unittests.
+  configs += [ "${dawn_root}/src/dawn_native:dawn_native_internal" ]
+
+  sources = get_target_outputs(":mock_webgpu_gen")
+  sources += [
+    "${dawn_root}/src/dawn_wire/client/ClientMemoryTransferService_mock.cpp",
+    "${dawn_root}/src/dawn_wire/client/ClientMemoryTransferService_mock.h",
+    "${dawn_root}/src/dawn_wire/server/ServerMemoryTransferService_mock.cpp",
+    "${dawn_root}/src/dawn_wire/server/ServerMemoryTransferService_mock.h",
+    "unittests/BitSetIteratorTests.cpp",
+    "unittests/BuddyAllocatorTests.cpp",
+    "unittests/BuddyMemoryAllocatorTests.cpp",
+    "unittests/CommandAllocatorTests.cpp",
+    "unittests/EnumClassBitmasksTests.cpp",
+    "unittests/ErrorTests.cpp",
+    "unittests/ExtensionTests.cpp",
+    "unittests/GetProcAddressTests.cpp",
+    "unittests/LinkedListTests.cpp",
+    "unittests/MathTests.cpp",
+    "unittests/ObjectBaseTests.cpp",
+    "unittests/PerStageTests.cpp",
+    "unittests/PlacementAllocatedTests.cpp",
+    "unittests/RefCountedTests.cpp",
+    "unittests/ResultTests.cpp",
+    "unittests/RingBufferAllocatorTests.cpp",
+    "unittests/SerialMapTests.cpp",
+    "unittests/SerialQueueTests.cpp",
+    "unittests/SlabAllocatorTests.cpp",
+    "unittests/SystemUtilsTests.cpp",
+    "unittests/ToBackendTests.cpp",
+    "unittests/validation/BindGroupValidationTests.cpp",
+    "unittests/validation/BufferValidationTests.cpp",
+    "unittests/validation/CommandBufferValidationTests.cpp",
+    "unittests/validation/ComputeIndirectValidationTests.cpp",
+    "unittests/validation/ComputePassValidationTests.cpp",
+    "unittests/validation/ComputeValidationTests.cpp",
+    "unittests/validation/CopyCommandsValidationTests.cpp",
+    "unittests/validation/DebugMarkerValidationTests.cpp",
+    "unittests/validation/DrawIndirectValidationTests.cpp",
+    "unittests/validation/DynamicStateCommandValidationTests.cpp",
+    "unittests/validation/ErrorScopeValidationTests.cpp",
+    "unittests/validation/FenceValidationTests.cpp",
+    "unittests/validation/GetBindGroupLayoutValidationTests.cpp",
+    "unittests/validation/QueueSubmitValidationTests.cpp",
+    "unittests/validation/RenderBundleValidationTests.cpp",
+    "unittests/validation/RenderPassDescriptorValidationTests.cpp",
+    "unittests/validation/RenderPassValidationTests.cpp",
+    "unittests/validation/RenderPipelineValidationTests.cpp",
+    "unittests/validation/ResourceUsageTrackingTests.cpp",
+    "unittests/validation/SamplerValidationTests.cpp",
+    "unittests/validation/ShaderModuleValidationTests.cpp",
+    "unittests/validation/StorageTextureValidationTests.cpp",
+    "unittests/validation/TextureValidationTests.cpp",
+    "unittests/validation/TextureViewValidationTests.cpp",
+    "unittests/validation/ToggleValidationTests.cpp",
+    "unittests/validation/ValidationTest.cpp",
+    "unittests/validation/ValidationTest.h",
+    "unittests/validation/VertexBufferValidationTests.cpp",
+    "unittests/validation/VertexStateValidationTests.cpp",
+    "unittests/wire/WireArgumentTests.cpp",
+    "unittests/wire/WireBasicTests.cpp",
+    "unittests/wire/WireBufferMappingTests.cpp",
+    "unittests/wire/WireErrorCallbackTests.cpp",
+    "unittests/wire/WireExtensionTests.cpp",
+    "unittests/wire/WireFenceTests.cpp",
+    "unittests/wire/WireInjectTextureTests.cpp",
+    "unittests/wire/WireMemoryTransferServiceTests.cpp",
+    "unittests/wire/WireOptionalTests.cpp",
+    "unittests/wire/WireTest.cpp",
+    "unittests/wire/WireTest.h",
+    "unittests/wire/WireWGPUDevicePropertiesTests.cpp",
+  ]
+
+  if (dawn_enable_d3d12) {
+    sources += [ "unittests/d3d12/CopySplitTests.cpp" ]
+  }
+
+  # When building inside Chromium, use their gtest main function because it is
+  # needed to run in swarming correctly.
+  if (build_with_chromium) {
+    sources += [ "//gpu/dawn_unittests_main.cc" ]
+  } else {
+    sources += [ "UnittestsMain.cpp" ]
+  }
+}
+
+###############################################################################
+# Dawn end2end tests targets
+###############################################################################
+
+source_set("dawn_end2end_tests_sources") {
+  configs += [ "${dawn_root}/src/common:dawn_internal" ]
+  testonly = true
+
+  deps = [
+    ":gmock_and_gtest",
+    "${dawn_root}/src/common",
+    "${dawn_root}/src/dawn:dawncpp",
+    "${dawn_root}/src/dawn:libdawn_proc",
+    "${dawn_root}/src/dawn_native",
+    "${dawn_root}/src/dawn_wire",
+    "${dawn_root}/src/utils:dawn_utils",
+  ]
+
+  sources = [
+    "DawnTest.h",
+    "end2end/BasicTests.cpp",
+    "end2end/BindGroupTests.cpp",
+    "end2end/BufferTests.cpp",
+    "end2end/ClipSpaceTests.cpp",
+    "end2end/ColorStateTests.cpp",
+    "end2end/CompressedTextureFormatTests.cpp",
+    "end2end/ComputeCopyStorageBufferTests.cpp",
+    "end2end/ComputeIndirectTests.cpp",
+    "end2end/ComputeSharedMemoryTests.cpp",
+    "end2end/ComputeStorageBufferBarrierTests.cpp",
+    "end2end/CopyTests.cpp",
+    "end2end/CullingTests.cpp",
+    "end2end/DebugMarkerTests.cpp",
+    "end2end/DepthStencilStateTests.cpp",
+    "end2end/DestroyTests.cpp",
+    "end2end/DeviceLostTests.cpp",
+    "end2end/DrawIndexedIndirectTests.cpp",
+    "end2end/DrawIndexedTests.cpp",
+    "end2end/DrawIndirectTests.cpp",
+    "end2end/DrawTests.cpp",
+    "end2end/DynamicBufferOffsetTests.cpp",
+    "end2end/FenceTests.cpp",
+    "end2end/GpuMemorySynchronizationTests.cpp",
+    "end2end/IndexFormatTests.cpp",
+    "end2end/MultisampledRenderingTests.cpp",
+    "end2end/NonzeroTextureCreationTests.cpp",
+    "end2end/ObjectCachingTests.cpp",
+    "end2end/OpArrayLengthTests.cpp",
+    "end2end/PrimitiveTopologyTests.cpp",
+    "end2end/RenderBundleTests.cpp",
+    "end2end/RenderPassLoadOpTests.cpp",
+    "end2end/RenderPassTests.cpp",
+    "end2end/SamplerTests.cpp",
+    "end2end/ScissorTests.cpp",
+    "end2end/StorageTextureTests.cpp",
+    "end2end/TextureFormatTests.cpp",
+    "end2end/TextureViewTests.cpp",
+    "end2end/TextureZeroInitTests.cpp",
+    "end2end/VertexFormatTests.cpp",
+    "end2end/VertexStateTests.cpp",
+    "end2end/ViewportOrientationTests.cpp",
+    "end2end/ViewportTests.cpp",
+  ]
+
+  # Validation tests that need OS windows live in end2end tests.
+  sources += [
+    "unittests/validation/ValidationTest.cpp",
+    "unittests/validation/ValidationTest.h",
+  ]
+
+  libs = []
+
+  if (dawn_enable_d3d12) {
+    sources += [ "end2end/D3D12ResourceWrappingTests.cpp" ]
+    libs += [
+      "d3d11.lib",
+      "dxgi.lib",
+    ]
+  }
+
+  if (dawn_enable_metal) {
+    sources += [ "end2end/IOSurfaceWrappingTests.cpp" ]
+    libs += [ "IOSurface.framework" ]
+  }
+
+  if (dawn_enable_opengl) {
+    assert(dawn_supports_glfw_for_windowing)
+  }
+
+  if (dawn_supports_glfw_for_windowing) {
+    sources += [
+      "end2end/SwapChainTests.cpp",
+      "end2end/SwapChainValidationTests.cpp",
+      "end2end/WindowSurfaceTests.cpp",
+    ]
+    deps += [ "${dawn_root}/src/utils:dawn_glfw" ]
+  }
+}
+
+source_set("dawn_white_box_tests_sources") {
+  configs += [ "${dawn_root}/src/dawn_native:dawn_native_internal" ]
+  testonly = true
+
+  deps = [
+    ":gmock_and_gtest",
+    "${dawn_root}/src/common",
+    "${dawn_root}/src/dawn:dawncpp",
+    "${dawn_root}/src/dawn:libdawn_proc",
+    "${dawn_root}/src/dawn_native:dawn_native_sources",
+    "${dawn_root}/src/dawn_wire",
+    "${dawn_root}/src/utils:dawn_utils",
+
+    # Static because the tests both link against and have dawn_native
+    # sources. MSVC errors when both importing and exporting symbols.
+    "${dawn_root}/src/dawn_native:dawn_native_static",
+  ]
+
+  sources = [
+    "DawnTest.h",
+  ]
+
+  if (dawn_enable_vulkan) {
+    deps += [ "${dawn_root}/third_party:vulkan_headers" ]
+
+    if (is_chromeos) {
+      sources += [ "white_box/VulkanImageWrappingTestsDmaBuf.cpp" ]
+    } else if (is_linux) {
+      sources += [ "white_box/VulkanImageWrappingTestsOpaqueFD.cpp" ]
+    }
+
+    if (dawn_enable_error_injection) {
+      sources += [ "white_box/VulkanErrorInjectorTests.cpp" ]
+    }
+  }
+
+  if (dawn_enable_d3d12) {
+    sources += [
+      "white_box/D3D12DescriptorHeapTests.cpp",
+      "white_box/D3D12ResidencyTests.cpp",
+      "white_box/D3D12SmallTextureTests.cpp",
+    ]
+  }
+
+  if (dawn_enable_metal) {
+    sources += [ "white_box/MetalAutoreleasePoolTests.mm" ]
+  }
+
+  if (dawn_enable_opengl) {
+    deps += [ "${dawn_root}/src/utils:dawn_glfw" ]
+  }
+
+  libs = []
+}
+
+test("dawn_end2end_tests_tmp") {
+  configs += [ "${dawn_root}/src/common:dawn_internal" ]
+
+  deps = [
+    ":dawn_end2end_tests_sources",
+    ":dawn_white_box_tests_sources",
+    ":gmock_and_gtest",
+    "${dawn_root}/src/common",
+    "${dawn_root}/src/dawn:dawncpp",
+    "${dawn_root}/src/dawn:libdawn_proc",
+    "${dawn_root}/src/dawn_native",
+    "${dawn_root}/src/dawn_wire",
+    "${dawn_root}/src/utils:dawn_utils",
+  ]
+
+  sources = [
+    "DawnTest.cpp",
+    "DawnTest.h",
+  ]
+
+  libs = []
+
+  # When building inside Chromium, use their gtest main function because it is
+  # needed to run in swarming correctly.
+  if (build_with_chromium) {
+    sources += [ "//gpu/dawn_end2end_tests_main.cc" ]
+  } else {
+    sources += [ "End2EndTestsMain.cpp" ]
+  }
+
+  if (dawn_enable_opengl) {
+    deps += [ "${dawn_root}/src/utils:dawn_glfw" ]
+  }
+
+  if (is_chromeos) {
+    libs += [ "gbm" ]
+  }
+}
+
+###############################################################################
+# Dawn perf tests
+###############################################################################
+
+test("dawn_perf_tests") {
+  configs += [ "${dawn_root}/src/common:dawn_internal" ]
+
+  deps = [
+    ":gmock_and_gtest",
+    "${dawn_root}/src/common",
+    "${dawn_root}/src/dawn:dawncpp",
+    "${dawn_root}/src/dawn:libdawn_proc",
+    "${dawn_root}/src/dawn_native",
+    "${dawn_root}/src/dawn_platform",
+    "${dawn_root}/src/dawn_wire",
+    "${dawn_root}/src/utils:dawn_utils",
+  ]
+
+  sources = [
+    "DawnTest.cpp",
+    "DawnTest.h",
+    "ParamGenerator.h",
+    "perf_tests/BufferUploadPerf.cpp",
+    "perf_tests/DawnPerfTest.cpp",
+    "perf_tests/DawnPerfTest.h",
+    "perf_tests/DawnPerfTestPlatform.cpp",
+    "perf_tests/DawnPerfTestPlatform.h",
+    "perf_tests/DrawCallPerf.cpp",
+  ]
+
+  libs = []
+
+  # When building inside Chromium, use their gtest main function because it is
+  # needed to run in swarming correctly.
+  if (build_with_chromium) {
+    sources += [ "//gpu/dawn_perf_tests_main.cc" ]
+  } else {
+    sources += [ "PerfTestsMain.cpp" ]
+  }
+
+  if (dawn_enable_metal) {
+    libs += [ "IOSurface.framework" ]
+  }
+
+  if (dawn_enable_opengl) {
+    deps += [ "${dawn_root}/src/utils:dawn_glfw" ]
+  }
+}
diff --git a/src/utils/BUILD.gn b/src/utils/BUILD.gn
new file mode 100644
index 0000000..90ccf91
--- /dev/null
+++ b/src/utils/BUILD.gn
@@ -0,0 +1,180 @@
+# Copyright 2020 The Dawn Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../scripts/dawn_overrides_with_defaults.gni")
+
+import("${dawn_root}/scripts/dawn_features.gni")
+
+###############################################################################
+# GLFW wrapping target
+###############################################################################
+
+# GLFW does not support ChromeOS, Android or Fuchsia, so provide a small mock
+# library that can be linked into the Dawn tests on these platforms. Otherwise,
+# use the real library from third_party/.
+if (dawn_supports_glfw_for_windowing) {
+  group("dawn_glfw") {
+    public_deps = [
+      "${dawn_root}/third_party:glfw",
+    ]
+  }
+} else if (is_fuchsia) {
+  # The mock implementation of GLFW on Fuchsia
+  config("dawn_glfw_public_config") {
+    # Allow inclusion of <GLFW/glfw3.h>
+    include_dirs = [ "${dawn_glfw_dir}/include" ]
+
+    # The GLFW/glfw3.h header includes <GL/gl.h> by default, but the latter
+    # does not exist on Fuchsia. Defining GLFW_INCLUDE_NONE helps work around
+    # the issue, but it needs to be defined for any file that includes the
+    # header.
+    defines = [
+      "GLFW_INCLUDE_NONE",
+      "GLFW_INCLUDE_VULKAN",
+    ]
+  }
+
+  static_library("dawn_glfw") {
+    sources = [
+      # NOTE: The header below is required to pass "gn check".
+      "${dawn_glfw_dir}/include/GLFW/glfw3.h",
+      "Glfw3Fuchsia.cpp",
+    ]
+    public_configs = [ ":dawn_glfw_public_config" ]
+    deps = [
+      "${dawn_root}/src/common",
+    ]
+  }
+} else {
+  # Just skip GLFW on other systems
+  group("dawn_glfw") {
+  }
+}
+
+###############################################################################
+# Utils for tests and samples
+###############################################################################
+
+static_library("dawn_utils") {
+  configs += [ "${dawn_root}/src/common:dawn_internal" ]
+
+  sources = [
+    "ComboRenderBundleEncoderDescriptor.cpp",
+    "ComboRenderBundleEncoderDescriptor.h",
+    "ComboRenderPipelineDescriptor.cpp",
+    "ComboRenderPipelineDescriptor.h",
+    "SystemUtils.cpp",
+    "SystemUtils.h",
+    "TerribleCommandBuffer.cpp",
+    "TerribleCommandBuffer.h",
+    "TextureFormatUtils.cpp",
+    "TextureFormatUtils.h",
+    "Timer.h",
+    "WGPUHelpers.cpp",
+    "WGPUHelpers.h",
+  ]
+  deps = [
+    "${dawn_root}/src/common",
+    "${dawn_root}/src/dawn_native",
+    "${dawn_root}/src/dawn_wire",
+    "${dawn_shaderc_dir}:libshaderc",
+  ]
+  libs = []
+
+  if (is_win) {
+    sources += [ "WindowsTimer.cpp" ]
+  } else if (is_mac) {
+    sources += [
+      "OSXTimer.cpp",
+      "ObjCUtils.h",
+      "ObjCUtils.mm",
+    ]
+    libs += [ "QuartzCore.framework" ]
+  } else {
+    sources += [ "PosixTimer.cpp" ]
+  }
+
+  if (dawn_supports_glfw_for_windowing) {
+    sources += [
+      "GLFWUtils.cpp",
+      "GLFWUtils.h",
+    ]
+    deps += [ ":dawn_glfw" ]
+
+    if (dawn_enable_metal) {
+      sources += [ "GLFWUtils_metal.mm" ]
+      libs += [ "Metal.framework" ]
+    }
+  }
+
+  public_deps = [
+    "${dawn_root}/src/dawn:dawncpp_headers",
+  ]
+}
+
+###############################################################################
+# Dawn samples, only in standalone builds
+###############################################################################
+
+if (dawn_standalone) {
+  # Library to handle the interaction of Dawn with GLFW windows in samples
+  static_library("dawn_bindings") {
+    configs += [ "${dawn_root}/src/common:dawn_internal" ]
+
+    sources = [
+      "BackendBinding.cpp",
+      "BackendBinding.h",
+    ]
+
+    public_deps = [
+      "${dawn_root}/src/dawn:dawn_headers",
+    ]
+
+    deps = [
+      ":dawn_glfw",
+      "${dawn_root}/src/common",
+      "${dawn_root}/src/dawn_native",
+    ]
+    libs = []
+
+    if (dawn_enable_d3d12) {
+      sources += [ "D3D12Binding.cpp" ]
+    }
+
+    if (dawn_enable_metal) {
+      sources += [ "MetalBinding.mm" ]
+      libs += [
+        "Metal.framework",
+        "QuartzCore.framework",
+      ]
+
+      # Suppress warnings that Metal isn't in the deployment target of Chrome
+      if (is_mac) {
+        cflags_objcc = [ "-Wno-unguarded-availability" ]
+      }
+    }
+
+    if (dawn_enable_null) {
+      sources += [ "NullBinding.cpp" ]
+    }
+
+    if (dawn_enable_opengl) {
+      sources += [ "OpenGLBinding.cpp" ]
+    }
+
+    if (dawn_enable_vulkan) {
+      sources += [ "VulkanBinding.cpp" ]
+    }
+  }
+}
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
index c18b088..468db4e 100644
--- a/third_party/BUILD.gn
+++ b/third_party/BUILD.gn
@@ -47,80 +47,20 @@
 }
 
 source_set("khronos_platform") {
-  sources = [ "khronos/KHR/khrplatform.h" ]
+  sources = [
+    "khronos/KHR/khrplatform.h",
+  ]
 
   public_configs = [ ":khronos_headers_public" ]
 }
 
 ###############################################################################
-# Gtest Gmock - Handle building inside and outside of Chromium.
-###############################################################################
-
-# When building outside of Chromium we need to define our own targets for GTest
-# and GMock. However when compiling inside of Chromium we need to reuse the
-# existing targets, both because Chromium has a special harness for swarming
-# and because otherwise the "gn check" fails.
-
-if (!build_with_chromium) {
-  # When we aren't in Chromium we define out own targets based on the location
-  # of the googletest repo.
-  googletest_dir = dawn_googletest_dir
-
-  config("gtest_config") {
-    include_dirs = [
-      "${googletest_dir}/googletest",
-      "${googletest_dir}/googletest/include",
-    ]
-  }
-
-  static_library("gtest") {
-    testonly = true
-    sources = [ "${googletest_dir}/googletest/src/gtest-all.cc" ]
-    public_configs = [ ":gtest_config" ]
-  }
-
-  config("gmock_config") {
-    include_dirs = [
-      "${googletest_dir}/googlemock",
-      "${googletest_dir}/googlemock/include",
-      "${googletest_dir}/googletest/include",
-    ]
-  }
-
-  static_library("gmock") {
-    testonly = true
-    sources = [ "${googletest_dir}/googlemock/src/gmock-all.cc" ]
-    public_configs = [ ":gmock_config" ]
-  }
-
-  group("gmock_and_gtest") {
-    testonly = true
-    public_deps = [
-      ":gmock",
-      ":gtest",
-    ]
-  }
-} else {
-  # When we are in Chromium we reuse its targets, and also add some deps that
-  # are needed to launch the test in swarming mode.
-  group("gmock_and_gtest") {
-    testonly = true
-    public_deps = [
-      "//base",
-      "//base/test:test_support",
-      "//testing/gmock",
-      "//testing/gtest",
-    ]
-  }
-}
-
-###############################################################################
 # GLFW - good enough build targets
 ###############################################################################
 
 # Only expose GLFW targets on platforms where GLFW is supported: otherwise they
 # might get discovered by GN when another target in this file is referenced,
-# and GLFW will bbe built as part of "all" builds, causing compilation failures.
+# and GLFW will be built as part of "all" builds, causing compilation failures.
 if (is_win || (is_linux && !is_chromeos) || is_mac) {
   glfw_dir = dawn_glfw_dir