[tools][build] Track per-file transitive dependencies.

If target A includes a file that indirectly includes a file from
target B, then add target B to target A's dependency list.

This is required to correctly depend on targets that are transitively
referenced through chains of includes.

Change-Id: I62bd5b079eabbe36acc08fcb545b14dcfe8598f4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/146904
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/api/BUILD.cmake b/src/tint/api/BUILD.cmake
index 1ba680c..b8d0aa9 100644
--- a/src/tint/api/BUILD.cmake
+++ b/src/tint/api/BUILD.cmake
@@ -26,13 +26,35 @@
 )
 
 tint_target_add_dependencies("api"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/hlsl/writer/common"
+  "lang/spirv/reader/common"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
   "lang/wgsl/reader"
+  "lang/wgsl/sem"
   "lang/wgsl/writer"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_GLSL_WRITER)
   tint_target_add_dependencies("api"
     "lang/glsl/writer"
+    "lang/glsl/writer/common"
   )
 endif(TINT_BUILD_GLSL_WRITER)
 
@@ -45,6 +67,7 @@
 if (TINT_BUILD_MSL_WRITER)
   tint_target_add_dependencies("api"
     "lang/msl/writer"
+    "lang/msl/writer/common"
   )
 endif(TINT_BUILD_MSL_WRITER)
 
@@ -57,5 +80,6 @@
 if (TINT_BUILD_SPV_WRITER)
   tint_target_add_dependencies("api"
     "lang/spirv/writer"
+    "lang/spirv/writer/common"
   )
 endif(TINT_BUILD_SPV_WRITER)
diff --git a/src/tint/cmd/bench/BUILD.cmake b/src/tint/cmd/bench/BUILD.cmake
index 433ce29..cb70516 100644
--- a/src/tint/cmd/bench/BUILD.cmake
+++ b/src/tint/cmd/bench/BUILD.cmake
@@ -26,8 +26,24 @@
 )
 
 tint_target_add_dependencies("cmd/bench"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("cmd/bench:bench"
@@ -36,13 +52,32 @@
 
 tint_target_add_dependencies("cmd/bench:bench"
   "cmd/bench"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/core:bench"
+  "lang/spirv/reader/common"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
   "lang/wgsl/reader"
   "lang/wgsl/reader:bench"
+  "lang/wgsl/sem"
   "lang/wgsl/writer"
   "lang/wgsl/writer:bench"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
   "utils/rtti:bench"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_GLSL_WRITER)
diff --git a/src/tint/cmd/common/BUILD.cmake b/src/tint/cmd/common/BUILD.cmake
index 6f59465..6d210d2 100644
--- a/src/tint/cmd/common/BUILD.cmake
+++ b/src/tint/cmd/common/BUILD.cmake
@@ -28,6 +28,8 @@
 )
 
 tint_target_add_dependencies("cmd/common"
+  "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/spirv/reader/common"
   "lang/wgsl/ast"
@@ -36,8 +38,19 @@
   "lang/wgsl/reader"
   "lang/wgsl/sem"
   "lang/wgsl/writer"
+  "utils/containers"
   "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_SPV_READER)
@@ -58,6 +71,23 @@
 
 tint_target_add_dependencies("cmd/common:test"
   "cmd/common"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/cmd/info/BUILD.cmake b/src/tint/cmd/info/BUILD.cmake
index 6fa735c..ba03eca 100644
--- a/src/tint/cmd/info/BUILD.cmake
+++ b/src/tint/cmd/info/BUILD.cmake
@@ -26,12 +26,27 @@
 
 tint_target_add_dependencies("cmd/info:cmd"
   "cmd/common"
+  "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "lang/spirv/reader/common"
   "lang/wgsl/ast"
   "lang/wgsl/inspector"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
   "utils/command"
   "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_SPV_READER  OR  TINT_BUILD_SPV_WRITER)
diff --git a/src/tint/cmd/loopy/BUILD.cmake b/src/tint/cmd/loopy/BUILD.cmake
index 6e4ec49..a881479 100644
--- a/src/tint/cmd/loopy/BUILD.cmake
+++ b/src/tint/cmd/loopy/BUILD.cmake
@@ -27,14 +27,37 @@
 tint_target_add_dependencies("cmd/loopy:cmd"
   "api"
   "cmd/common"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/hlsl/writer/common"
+  "lang/spirv/reader/common"
+  "lang/wgsl/ast"
   "lang/wgsl/helpers"
+  "lang/wgsl/inspector"
+  "lang/wgsl/program"
   "lang/wgsl/reader"
+  "lang/wgsl/sem"
   "lang/wgsl/writer"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_GLSL_WRITER)
   tint_target_add_dependencies("cmd/loopy:cmd"
     "lang/glsl/writer"
+    "lang/glsl/writer/common"
   )
 endif(TINT_BUILD_GLSL_WRITER)
 
@@ -54,6 +77,7 @@
 if (TINT_BUILD_MSL_WRITER)
   tint_target_add_dependencies("cmd/loopy:cmd"
     "lang/msl/writer"
+    "lang/msl/writer/common"
   )
 endif(TINT_BUILD_MSL_WRITER)
 
@@ -66,5 +90,6 @@
 if (TINT_BUILD_SPV_WRITER)
   tint_target_add_dependencies("cmd/loopy:cmd"
     "lang/spirv/writer"
+    "lang/spirv/writer/common"
   )
 endif(TINT_BUILD_SPV_WRITER)
diff --git a/src/tint/cmd/test/BUILD.cmake b/src/tint/cmd/test/BUILD.cmake
index 1e5441f..a3a9833 100644
--- a/src/tint/cmd/test/BUILD.cmake
+++ b/src/tint/cmd/test/BUILD.cmake
@@ -48,6 +48,7 @@
   "utils/file:test"
   "utils/ice"
   "utils/ice:test"
+  "utils/macros"
   "utils/macros:test"
   "utils/math:test"
   "utils/memory:test"
diff --git a/src/tint/cmd/tint/BUILD.cmake b/src/tint/cmd/tint/BUILD.cmake
index 2847068..34ec55d 100644
--- a/src/tint/cmd/tint/BUILD.cmake
+++ b/src/tint/cmd/tint/BUILD.cmake
@@ -27,22 +27,41 @@
 tint_target_add_dependencies("cmd/tint:cmd"
   "api"
   "cmd/common"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/hlsl/writer/common"
+  "lang/spirv/reader/common"
   "lang/wgsl/ast"
   "lang/wgsl/ast/transform"
   "lang/wgsl/helpers"
+  "lang/wgsl/inspector"
+  "lang/wgsl/program"
   "lang/wgsl/reader"
+  "lang/wgsl/sem"
   "lang/wgsl/writer"
   "utils/cli"
   "utils/command"
   "utils/containers"
   "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/strconv"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_GLSL_WRITER)
   tint_target_add_dependencies("cmd/tint:cmd"
     "lang/glsl/writer"
+    "lang/glsl/writer/common"
   )
   tint_target_add_external_dependencies("cmd/tint:cmd"
     "glslang"
@@ -68,6 +87,7 @@
   tint_target_add_dependencies("cmd/tint:cmd"
     "lang/msl/validate"
     "lang/msl/writer"
+    "lang/msl/writer/common"
   )
 endif(TINT_BUILD_MSL_WRITER)
 
@@ -86,5 +106,6 @@
 if (TINT_BUILD_SPV_WRITER)
   tint_target_add_dependencies("cmd/tint:cmd"
     "lang/spirv/writer"
+    "lang/spirv/writer/common"
   )
 endif(TINT_BUILD_SPV_WRITER)
diff --git a/src/tint/lang/core/BUILD.cmake b/src/tint/lang/core/BUILD.cmake
index 2f87bf2..e6015c1 100644
--- a/src/tint/lang/core/BUILD.cmake
+++ b/src/tint/lang/core/BUILD.cmake
@@ -68,8 +68,10 @@
   "utils/diagnostic"
   "utils/ice"
   "utils/macros"
+  "utils/math"
   "utils/memory"
   "utils/result"
+  "utils/rtti"
   "utils/text"
   "utils/traits"
 )
@@ -91,9 +93,23 @@
 
 tint_target_add_dependencies("lang/core:test"
   "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/core:bench"
@@ -112,4 +128,13 @@
 
 tint_target_add_dependencies("lang/core:bench"
   "lang/core"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/rtti"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/core/constant/BUILD.cmake b/src/tint/lang/core/constant/BUILD.cmake
index 08da524..fc1e8e2 100644
--- a/src/tint/lang/core/constant/BUILD.cmake
+++ b/src/tint/lang/core/constant/BUILD.cmake
@@ -43,12 +43,16 @@
   "lang/core/type"
   "utils/containers"
   "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
   "utils/memory"
   "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/core/constant:test"
@@ -73,13 +77,25 @@
 tint_target_add_dependencies("lang/core/constant:test"
   "lang/core"
   "lang/core/constant"
+  "lang/core/intrinsic"
   "lang/core/type"
   "lang/core/type:test"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/reader"
+  "lang/wgsl/resolver"
   "lang/wgsl/resolver:test"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
   "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/core/intrinsic/BUILD.cmake b/src/tint/lang/core/intrinsic/BUILD.cmake
index 876dd98..aef5e03 100644
--- a/src/tint/lang/core/intrinsic/BUILD.cmake
+++ b/src/tint/lang/core/intrinsic/BUILD.cmake
@@ -36,10 +36,16 @@
   "lang/core/type"
   "utils/containers"
   "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/core/intrinsic:test"
@@ -47,10 +53,27 @@
 )
 
 tint_target_add_dependencies("lang/core/intrinsic:test"
+  "lang/core"
+  "lang/core/constant"
   "lang/core/intrinsic"
   "lang/core/intrinsic/data"
   "lang/core/type"
   "lang/core/type:test"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
+  "lang/wgsl/resolver"
   "lang/wgsl/resolver:test"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/core/intrinsic/data/BUILD.cmake b/src/tint/lang/core/intrinsic/data/BUILD.cmake
index 05abcb6..562c72c 100644
--- a/src/tint/lang/core/intrinsic/data/BUILD.cmake
+++ b/src/tint/lang/core/intrinsic/data/BUILD.cmake
@@ -28,7 +28,18 @@
 
 tint_target_add_dependencies("lang/core/intrinsic/data"
   "lang/core"
+  "lang/core/constant"
   "lang/core/intrinsic"
   "lang/core/type"
+  "utils/containers"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/core/ir/BUILD.cmake b/src/tint/lang/core/ir/BUILD.cmake
index 0903315..59467b6 100644
--- a/src/tint/lang/core/ir/BUILD.cmake
+++ b/src/tint/lang/core/ir/BUILD.cmake
@@ -132,11 +132,13 @@
   "utils/ice"
   "utils/id"
   "utils/macros"
+  "utils/math"
   "utils/memory"
   "utils/result"
   "utils/rtti"
   "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 endif(TINT_BUILD_IR)
@@ -186,8 +188,20 @@
 
 tint_target_add_dependencies("lang/core/ir:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
diff --git a/src/tint/lang/core/ir/transform/BUILD.cmake b/src/tint/lang/core/ir/transform/BUILD.cmake
index ea3abf5..3224ab5 100644
--- a/src/tint/lang/core/ir/transform/BUILD.cmake
+++ b/src/tint/lang/core/ir/transform/BUILD.cmake
@@ -43,10 +43,21 @@
 )
 
 tint_target_add_dependencies("lang/core/ir/transform"
+  "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "utils/containers"
+  "utils/diagnostic"
   "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
   "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
@@ -70,7 +81,21 @@
 )
 
 tint_target_add_dependencies("lang/core/ir/transform:test"
+  "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
diff --git a/src/tint/lang/core/type/BUILD.cmake b/src/tint/lang/core/type/BUILD.cmake
index a5af5d4..1132fa0 100644
--- a/src/tint/lang/core/type/BUILD.cmake
+++ b/src/tint/lang/core/type/BUILD.cmake
@@ -97,8 +97,11 @@
   "utils/containers"
   "utils/diagnostic"
   "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
   "utils/symbol"
   "utils/text"
@@ -134,10 +137,22 @@
 
 tint_target_add_dependencies("lang/core/type:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
   "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
   "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/glsl/writer/BUILD.cmake b/src/tint/lang/glsl/writer/BUILD.cmake
index 25bd799..dfe82ef 100644
--- a/src/tint/lang/glsl/writer/BUILD.cmake
+++ b/src/tint/lang/glsl/writer/BUILD.cmake
@@ -32,9 +32,26 @@
 )
 
 tint_target_add_dependencies("lang/glsl/writer"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/ast/transform"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
   "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_GLSL_WRITER)
@@ -52,12 +69,30 @@
 
 tint_target_add_dependencies("lang/glsl/writer:bench"
   "cmd/bench"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/wgsl/ast"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_GLSL_WRITER)
   tint_target_add_dependencies("lang/glsl/writer:bench"
     "lang/glsl/writer"
+    "lang/glsl/writer/common"
   )
 endif(TINT_BUILD_GLSL_WRITER)
 
diff --git a/src/tint/lang/glsl/writer/ast_printer/BUILD.cmake b/src/tint/lang/glsl/writer/ast_printer/BUILD.cmake
index 117ceb4..e06b488 100644
--- a/src/tint/lang/glsl/writer/ast_printer/BUILD.cmake
+++ b/src/tint/lang/glsl/writer/ast_printer/BUILD.cmake
@@ -36,13 +36,19 @@
   "lang/wgsl/program"
   "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
   "utils/generator"
   "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
   "utils/strconv"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_GLSL_WRITER)
@@ -90,13 +96,27 @@
 
 tint_target_add_dependencies("lang/glsl/writer/ast_printer:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/ast/transform"
   "lang/wgsl/ast:test"
+  "lang/wgsl/program"
   "lang/wgsl/resolver"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_GLSL_WRITER)
diff --git a/src/tint/lang/glsl/writer/common/BUILD.cmake b/src/tint/lang/glsl/writer/common/BUILD.cmake
index 7f0c883..d171b15 100644
--- a/src/tint/lang/glsl/writer/common/BUILD.cmake
+++ b/src/tint/lang/glsl/writer/common/BUILD.cmake
@@ -30,6 +30,8 @@
 tint_target_add_dependencies("lang/glsl/writer/common"
   "lang/core"
   "lang/wgsl/sem"
+  "utils/text"
+  "utils/traits"
 )
 
 endif(TINT_BUILD_GLSL_WRITER)
\ No newline at end of file
diff --git a/src/tint/lang/hlsl/validate/BUILD.cmake b/src/tint/lang/hlsl/validate/BUILD.cmake
index 4c1258d..27a02ea 100644
--- a/src/tint/lang/hlsl/validate/BUILD.cmake
+++ b/src/tint/lang/hlsl/validate/BUILD.cmake
@@ -29,8 +29,15 @@
 tint_target_add_dependencies("lang/hlsl/validate"
   "lang/wgsl/ast"
   "utils/command"
+  "utils/containers"
   "utils/file"
+  "utils/ice"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/rtti"
   "utils/text"
+  "utils/traits"
 )
 
 endif(TINT_BUILD_HLSL_WRITER)
\ No newline at end of file
diff --git a/src/tint/lang/hlsl/writer/BUILD.cmake b/src/tint/lang/hlsl/writer/BUILD.cmake
index 11d0990..1254bfc 100644
--- a/src/tint/lang/hlsl/writer/BUILD.cmake
+++ b/src/tint/lang/hlsl/writer/BUILD.cmake
@@ -32,9 +32,28 @@
 )
 
 tint_target_add_dependencies("lang/hlsl/writer"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/hlsl/writer/common"
   "lang/wgsl/ast"
+  "lang/wgsl/ast/transform"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
   "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_HLSL_WRITER)
@@ -51,6 +70,26 @@
 
 tint_target_add_dependencies("lang/hlsl/writer:bench"
   "cmd/bench"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/hlsl/writer/common"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_HLSL_WRITER)
diff --git a/src/tint/lang/hlsl/writer/ast_printer/BUILD.cmake b/src/tint/lang/hlsl/writer/ast_printer/BUILD.cmake
index 45d0357..57fb681 100644
--- a/src/tint/lang/hlsl/writer/ast_printer/BUILD.cmake
+++ b/src/tint/lang/hlsl/writer/ast_printer/BUILD.cmake
@@ -37,13 +37,20 @@
   "lang/wgsl/program"
   "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
   "utils/generator"
   "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
   "utils/rtti"
   "utils/strconv"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 endif(TINT_BUILD_HLSL_WRITER)
@@ -84,14 +91,29 @@
 
 tint_target_add_dependencies("lang/hlsl/writer/ast_printer:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/hlsl/writer/common"
   "lang/wgsl/ast"
   "lang/wgsl/ast/transform"
   "lang/wgsl/ast:test"
+  "lang/wgsl/program"
   "lang/wgsl/resolver"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_HLSL_WRITER)
diff --git a/src/tint/lang/hlsl/writer/common/BUILD.cmake b/src/tint/lang/hlsl/writer/common/BUILD.cmake
index cc78336..4833152 100644
--- a/src/tint/lang/hlsl/writer/common/BUILD.cmake
+++ b/src/tint/lang/hlsl/writer/common/BUILD.cmake
@@ -26,5 +26,6 @@
 )
 
 tint_target_add_dependencies("lang/hlsl/writer/common"
+  "utils/macros"
   "utils/reflection"
 )
diff --git a/src/tint/lang/msl/validate/BUILD.cmake b/src/tint/lang/msl/validate/BUILD.cmake
index 1bb754a..82ca27a 100644
--- a/src/tint/lang/msl/validate/BUILD.cmake
+++ b/src/tint/lang/msl/validate/BUILD.cmake
@@ -27,10 +27,26 @@
 )
 
 tint_target_add_dependencies("lang/msl/validate"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/program"
+  "lang/wgsl/sem"
   "utils/command"
+  "utils/containers"
+  "utils/diagnostic"
   "utils/file"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 endif(TINT_BUILD_MSL_WRITER)
\ No newline at end of file
diff --git a/src/tint/lang/msl/writer/BUILD.cmake b/src/tint/lang/msl/writer/BUILD.cmake
index 24c87ee..87c3673 100644
--- a/src/tint/lang/msl/writer/BUILD.cmake
+++ b/src/tint/lang/msl/writer/BUILD.cmake
@@ -34,12 +34,32 @@
 )
 
 tint_target_add_dependencies("lang/msl/writer"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/msl/writer/raise"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
   "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
   tint_target_add_dependencies("lang/msl/writer"
+    "lang/core/ir"
     "lang/wgsl/reader/program_to_ir"
   )
 endif(TINT_BUILD_IR)
@@ -65,13 +85,31 @@
 
 tint_target_add_dependencies("lang/msl/writer:bench"
   "cmd/bench"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/wgsl/ast"
+  "lang/wgsl/program"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_MSL_WRITER)
   tint_target_add_dependencies("lang/msl/writer:bench"
     "lang/msl/writer"
+    "lang/msl/writer/common"
   )
 endif(TINT_BUILD_MSL_WRITER)
 
diff --git a/src/tint/lang/msl/writer/ast_printer/BUILD.cmake b/src/tint/lang/msl/writer/ast_printer/BUILD.cmake
index e78f3f4..b0dbf53 100644
--- a/src/tint/lang/msl/writer/ast_printer/BUILD.cmake
+++ b/src/tint/lang/msl/writer/ast_printer/BUILD.cmake
@@ -36,10 +36,19 @@
   "lang/wgsl/program"
   "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
   "utils/generator"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_MSL_WRITER)
@@ -85,19 +94,34 @@
 
 tint_target_add_dependencies("lang/msl/writer/ast_printer:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/ast:test"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_MSL_WRITER)
   tint_target_add_dependencies("lang/msl/writer/ast_printer:test"
     "lang/msl/writer"
     "lang/msl/writer/ast_printer"
+    "lang/msl/writer/common"
   )
 endif(TINT_BUILD_MSL_WRITER)
 
diff --git a/src/tint/lang/msl/writer/common/BUILD.cmake b/src/tint/lang/msl/writer/common/BUILD.cmake
index 524f5f6..b946bdd 100644
--- a/src/tint/lang/msl/writer/common/BUILD.cmake
+++ b/src/tint/lang/msl/writer/common/BUILD.cmake
@@ -31,11 +31,18 @@
 tint_target_add_dependencies("lang/msl/writer/common"
   "lang/core"
   "lang/core/type"
+  "utils/containers"
   "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
   "utils/reflection"
   "utils/rtti"
   "utils/strconv"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 endif(TINT_BUILD_MSL_WRITER)
@@ -44,6 +51,19 @@
   lang/msl/writer/common/printer_support_test.cc
 )
 
+tint_target_add_dependencies("lang/msl/writer/common:test"
+  "lang/core"
+  "lang/core/type"
+  "utils/containers"
+  "utils/ice"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/rtti"
+  "utils/text"
+  "utils/traits"
+)
+
 if (TINT_BUILD_MSL_WRITER)
   tint_target_add_dependencies("lang/msl/writer/common:test"
     "lang/msl/writer/common"
diff --git a/src/tint/lang/msl/writer/printer/BUILD.cmake b/src/tint/lang/msl/writer/printer/BUILD.cmake
index cdb6736..0bf4c58 100644
--- a/src/tint/lang/msl/writer/printer/BUILD.cmake
+++ b/src/tint/lang/msl/writer/printer/BUILD.cmake
@@ -33,9 +33,16 @@
   "utils/containers"
   "utils/diagnostic"
   "utils/generator"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
@@ -66,9 +73,22 @@
 
 tint_target_add_dependencies("lang/msl/writer/printer:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/msl/writer/raise"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
diff --git a/src/tint/lang/msl/writer/raise/BUILD.cmake b/src/tint/lang/msl/writer/raise/BUILD.cmake
index d9d2aa2..b2de6d5 100644
--- a/src/tint/lang/msl/writer/raise/BUILD.cmake
+++ b/src/tint/lang/msl/writer/raise/BUILD.cmake
@@ -26,5 +26,9 @@
 )
 
 tint_target_add_dependencies("lang/msl/writer/raise"
+  "utils/ice"
+  "utils/macros"
   "utils/result"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/spirv/reader/BUILD.cmake b/src/tint/lang/spirv/reader/BUILD.cmake
index 76044d5..4d9a48c 100644
--- a/src/tint/lang/spirv/reader/BUILD.cmake
+++ b/src/tint/lang/spirv/reader/BUILD.cmake
@@ -30,8 +30,25 @@
 )
 
 tint_target_add_dependencies("lang/spirv/reader"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/spirv/reader/common"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_SPV_READER)
diff --git a/src/tint/lang/spirv/reader/ast_parser/BUILD.cmake b/src/tint/lang/spirv/reader/ast_parser/BUILD.cmake
index 2459346..998dcab 100644
--- a/src/tint/lang/spirv/reader/ast_parser/BUILD.cmake
+++ b/src/tint/lang/spirv/reader/ast_parser/BUILD.cmake
@@ -46,17 +46,22 @@
 
 tint_target_add_dependencies("lang/spirv/reader/ast_parser"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/spirv/reader/common"
   "lang/wgsl/ast"
   "lang/wgsl/ast/transform"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
+  "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
   "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
   "utils/memory"
+  "utils/result"
   "utils/rtti"
   "utils/symbol"
   "utils/text"
@@ -111,13 +116,26 @@
 
 tint_target_add_dependencies("lang/spirv/reader/ast_parser:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "lang/spirv/reader/common"
   "lang/wgsl/ast"
+  "lang/wgsl/program"
   "lang/wgsl/sem"
   "lang/wgsl/writer/ast_printer"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_SPV_READER)
@@ -128,6 +146,7 @@
 
 if (TINT_BUILD_SPV_READER  OR  TINT_BUILD_SPV_WRITER)
   tint_target_add_external_dependencies("lang/spirv/reader/ast_parser:test"
+    "spirv-headers"
     "spirv-opt-internal"
     "spirv-tools"
   )
diff --git a/src/tint/lang/spirv/writer/BUILD.cmake b/src/tint/lang/spirv/writer/BUILD.cmake
index 76e34ba..d5da3e6 100644
--- a/src/tint/lang/spirv/writer/BUILD.cmake
+++ b/src/tint/lang/spirv/writer/BUILD.cmake
@@ -33,11 +33,30 @@
 )
 
 tint_target_add_dependencies("lang/spirv/writer"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
   "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
   tint_target_add_dependencies("lang/spirv/writer"
+    "lang/core/ir"
     "lang/core/ir/transform"
     "lang/wgsl/reader/program_to_ir"
   )
@@ -70,7 +89,21 @@
 
 tint_target_add_dependencies("lang/spirv/writer:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
@@ -101,12 +134,27 @@
   )
 endif(TINT_BUILD_IR)
 
+if (TINT_BUILD_SPV_READER  OR  TINT_BUILD_SPV_WRITER)
+  tint_target_add_external_dependencies("lang/spirv/writer:test"
+    "spirv-headers"
+    "spirv-tools"
+  )
+endif(TINT_BUILD_SPV_READER  OR  TINT_BUILD_SPV_WRITER)
+
 if (TINT_BUILD_SPV_WRITER)
   tint_target_add_dependencies("lang/spirv/writer:test"
+    "lang/spirv/writer/common"
     "lang/spirv/writer/common:test"
   )
 endif(TINT_BUILD_SPV_WRITER)
 
+if (TINT_BUILD_SPV_WRITER  AND  TINT_BUILD_IR)
+  tint_target_add_dependencies("lang/spirv/writer:test"
+    "lang/spirv/writer/printer"
+    "lang/spirv/writer/raise"
+  )
+endif(TINT_BUILD_SPV_WRITER  AND  TINT_BUILD_IR)
+
 endif(TINT_BUILD_SPV_WRITER)
 if(TINT_BUILD_SPV_WRITER)
 tint_add_target("lang/spirv/writer:bench"
@@ -114,6 +162,25 @@
 
 tint_target_add_dependencies("lang/spirv/writer:bench"
   "cmd/bench"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
@@ -125,6 +192,7 @@
 if (TINT_BUILD_SPV_WRITER)
   tint_target_add_dependencies("lang/spirv/writer:bench"
     "lang/spirv/writer"
+    "lang/spirv/writer/common"
   )
 endif(TINT_BUILD_SPV_WRITER)
 
diff --git a/src/tint/lang/spirv/writer/ast_printer/BUILD.cmake b/src/tint/lang/spirv/writer/ast_printer/BUILD.cmake
index 74ef39f..46a304b 100644
--- a/src/tint/lang/spirv/writer/ast_printer/BUILD.cmake
+++ b/src/tint/lang/spirv/writer/ast_printer/BUILD.cmake
@@ -39,9 +39,18 @@
   "lang/wgsl/program"
   "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_SPV_READER  OR  TINT_BUILD_SPV_WRITER)
@@ -91,16 +100,31 @@
 
 tint_target_add_dependencies("lang/spirv/writer/ast_printer:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/ast:test"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_SPV_READER  OR  TINT_BUILD_SPV_WRITER)
   tint_target_add_external_dependencies("lang/spirv/writer/ast_printer:test"
+    "spirv-headers"
     "spirv-tools"
   )
 endif(TINT_BUILD_SPV_READER  OR  TINT_BUILD_SPV_WRITER)
diff --git a/src/tint/lang/spirv/writer/common/BUILD.cmake b/src/tint/lang/spirv/writer/common/BUILD.cmake
index 2674bf8..1292eeb 100644
--- a/src/tint/lang/spirv/writer/common/BUILD.cmake
+++ b/src/tint/lang/spirv/writer/common/BUILD.cmake
@@ -36,6 +36,7 @@
 )
 
 tint_target_add_dependencies("lang/spirv/writer/common"
+  "utils/macros"
   "utils/math"
   "utils/reflection"
 )
@@ -58,7 +59,22 @@
 )
 
 tint_target_add_dependencies("lang/spirv/writer/common:test"
+  "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
diff --git a/src/tint/lang/spirv/writer/printer/BUILD.cmake b/src/tint/lang/spirv/writer/printer/BUILD.cmake
index 065d957..aa0fd15 100644
--- a/src/tint/lang/spirv/writer/printer/BUILD.cmake
+++ b/src/tint/lang/spirv/writer/printer/BUILD.cmake
@@ -30,12 +30,22 @@
   "lang/core"
   "lang/core/constant"
   "lang/core/type"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
   "utils/containers"
   "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
   "utils/result"
   "utils/rtti"
   "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
diff --git a/src/tint/lang/spirv/writer/raise/BUILD.cmake b/src/tint/lang/spirv/writer/raise/BUILD.cmake
index 96c3fe1..b41a2a7 100644
--- a/src/tint/lang/spirv/writer/raise/BUILD.cmake
+++ b/src/tint/lang/spirv/writer/raise/BUILD.cmake
@@ -40,11 +40,21 @@
 
 tint_target_add_dependencies("lang/spirv/writer/raise"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "utils/containers"
+  "utils/diagnostic"
   "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
   "utils/result"
   "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
@@ -78,11 +88,26 @@
 )
 
 tint_target_add_dependencies("lang/spirv/writer/raise:test"
+  "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
   tint_target_add_dependencies("lang/spirv/writer/raise:test"
+    "lang/core/ir"
     "lang/core/ir/transform:test"
   )
 endif(TINT_BUILD_IR)
diff --git a/src/tint/lang/wgsl/BUILD.cmake b/src/tint/lang/wgsl/BUILD.cmake
index 3756cc5..0f9000d 100644
--- a/src/tint/lang/wgsl/BUILD.cmake
+++ b/src/tint/lang/wgsl/BUILD.cmake
@@ -33,14 +33,34 @@
 )
 
 tint_target_add_dependencies("lang/wgsl:test"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/helpers:test"
+  "lang/wgsl/program"
   "lang/wgsl/reader"
+  "lang/wgsl/resolver"
+  "lang/wgsl/sem"
   "lang/wgsl/writer"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
   tint_target_add_dependencies("lang/wgsl:test"
+    "lang/core/ir"
     "lang/wgsl/reader/program_to_ir"
     "lang/wgsl/writer/ir_to_program"
   )
diff --git a/src/tint/lang/wgsl/ast/BUILD.cmake b/src/tint/lang/wgsl/ast/BUILD.cmake
index b63991b..f9f1d2e 100644
--- a/src/tint/lang/wgsl/ast/BUILD.cmake
+++ b/src/tint/lang/wgsl/ast/BUILD.cmake
@@ -190,6 +190,9 @@
   "utils/ice"
   "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
   "utils/symbol"
   "utils/text"
@@ -264,12 +267,26 @@
 
 tint_target_add_dependencies("lang/wgsl/ast:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/ast/transform"
   "lang/wgsl/program"
   "lang/wgsl/reader"
   "lang/wgsl/resolver"
+  "lang/wgsl/sem"
   "lang/wgsl/writer"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/ast/transform/BUILD.cmake b/src/tint/lang/wgsl/ast/transform/BUILD.cmake
index d48ebf7..3927bcc 100644
--- a/src/tint/lang/wgsl/ast/transform/BUILD.cmake
+++ b/src/tint/lang/wgsl/ast/transform/BUILD.cmake
@@ -133,6 +133,7 @@
 
 tint_target_add_dependencies("lang/wgsl/ast/transform"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/program"
@@ -141,12 +142,16 @@
   "utils/containers"
   "utils/diagnostic"
   "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
   "utils/memory"
   "utils/reflection"
+  "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/wgsl/ast/transform:test"
@@ -211,6 +216,7 @@
 
 tint_target_add_dependencies("lang/wgsl/ast/transform:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/ast/transform"
@@ -221,6 +227,17 @@
   "lang/wgsl/resolver"
   "lang/wgsl/sem"
   "lang/wgsl/writer"
+  "utils/containers"
+  "utils/diagnostic"
   "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/helpers/BUILD.cmake b/src/tint/lang/wgsl/helpers/BUILD.cmake
index 6f06ae7..8194543 100644
--- a/src/tint/lang/wgsl/helpers/BUILD.cmake
+++ b/src/tint/lang/wgsl/helpers/BUILD.cmake
@@ -31,6 +31,8 @@
 
 tint_target_add_dependencies("lang/wgsl/helpers"
   "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/ast/transform"
   "lang/wgsl/inspector"
@@ -38,8 +40,16 @@
   "lang/wgsl/sem"
   "utils/containers"
   "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/wgsl/helpers:test"
@@ -51,14 +61,28 @@
 
 tint_target_add_dependencies("lang/wgsl/helpers:test"
   "lang/core"
+  "lang/core/constant"
+  "lang/core/intrinsic"
   "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/ast:test"
   "lang/wgsl/helpers"
   "lang/wgsl/program"
   "lang/wgsl/reader"
   "lang/wgsl/resolver"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
diff --git a/src/tint/lang/wgsl/inspector/BUILD.cmake b/src/tint/lang/wgsl/inspector/BUILD.cmake
index 90990cd..a51c743 100644
--- a/src/tint/lang/wgsl/inspector/BUILD.cmake
+++ b/src/tint/lang/wgsl/inspector/BUILD.cmake
@@ -33,14 +33,23 @@
 
 tint_target_add_dependencies("lang/wgsl/inspector"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/wgsl/inspector:test"
@@ -53,6 +62,7 @@
 
 tint_target_add_dependencies("lang/wgsl/inspector:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/inspector"
@@ -60,5 +70,16 @@
   "lang/wgsl/reader"
   "lang/wgsl/resolver"
   "lang/wgsl/sem"
+  "utils/containers"
   "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/program/BUILD.cmake b/src/tint/lang/wgsl/program/BUILD.cmake
index 26b412c..87c3057 100644
--- a/src/tint/lang/wgsl/program/BUILD.cmake
+++ b/src/tint/lang/wgsl/program/BUILD.cmake
@@ -36,12 +36,17 @@
   "lang/wgsl/ast"
   "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
   "utils/ice"
   "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
   "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/wgsl/program:test"
@@ -51,8 +56,24 @@
 )
 
 tint_target_add_dependencies("lang/wgsl/program:test"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/ast:test"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/reader/BUILD.cmake b/src/tint/lang/wgsl/reader/BUILD.cmake
index 4728364..c1bbfd7 100644
--- a/src/tint/lang/wgsl/reader/BUILD.cmake
+++ b/src/tint/lang/wgsl/reader/BUILD.cmake
@@ -29,9 +29,26 @@
 )
 
 tint_target_add_dependencies("lang/wgsl/reader"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/reader/parser"
   "lang/wgsl/resolver"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/wgsl/reader:bench"
@@ -40,5 +57,23 @@
 
 tint_target_add_dependencies("lang/wgsl/reader:bench"
   "cmd/bench"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
   "lang/wgsl/reader"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/reader/parser/BUILD.cmake b/src/tint/lang/wgsl/reader/parser/BUILD.cmake
index 29981dd..c071041 100644
--- a/src/tint/lang/wgsl/reader/parser/BUILD.cmake
+++ b/src/tint/lang/wgsl/reader/parser/BUILD.cmake
@@ -34,16 +34,25 @@
 
 tint_target_add_dependencies("lang/wgsl/reader/parser"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
+  "lang/wgsl/sem"
   "utils/containers"
   "utils/diagnostic"
   "utils/ice"
+  "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
   "utils/strconv"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/wgsl/reader/parser:test"
@@ -118,10 +127,24 @@
 
 tint_target_add_dependencies("lang/wgsl/reader/parser:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/ast:test"
+  "lang/wgsl/program"
   "lang/wgsl/reader/parser"
+  "lang/wgsl/resolver"
+  "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/BUILD.cmake b/src/tint/lang/wgsl/reader/program_to_ir/BUILD.cmake
index 6f617c9..9678f65 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/BUILD.cmake
+++ b/src/tint/lang/wgsl/reader/program_to_ir/BUILD.cmake
@@ -28,14 +28,23 @@
 
 tint_target_add_dependencies("lang/wgsl/reader/program_to_ir"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
+  "utils/math"
+  "utils/memory"
   "utils/result"
   "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
@@ -65,13 +74,31 @@
 tint_target_add_dependencies("lang/wgsl/reader/program_to_ir:test"
   "lang/core"
   "lang/core/constant"
+  "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/helpers:test"
+  "lang/wgsl/program"
+  "lang/wgsl/reader"
+  "lang/wgsl/resolver"
+  "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
   tint_target_add_dependencies("lang/wgsl/reader/program_to_ir:test"
     "lang/core/ir"
+    "lang/wgsl/reader/program_to_ir"
   )
 endif(TINT_BUILD_IR)
 
diff --git a/src/tint/lang/wgsl/resolver/BUILD.cmake b/src/tint/lang/wgsl/resolver/BUILD.cmake
index e11cd82..a108d45 100644
--- a/src/tint/lang/wgsl/resolver/BUILD.cmake
+++ b/src/tint/lang/wgsl/resolver/BUILD.cmake
@@ -46,11 +46,16 @@
   "lang/wgsl/sem"
   "utils/containers"
   "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
   "utils/memory"
+  "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/wgsl/resolver:test"
@@ -114,6 +119,8 @@
 
 tint_target_add_dependencies("lang/wgsl/resolver:test"
   "lang/core"
+  "lang/core/constant"
+  "lang/core/intrinsic"
   "lang/core/type"
   "lang/core/type:test"
   "lang/wgsl/ast"
@@ -125,7 +132,15 @@
   "lang/wgsl/sem"
   "lang/wgsl/sem:test"
   "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
   "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/sem/BUILD.cmake b/src/tint/lang/wgsl/sem/BUILD.cmake
index cf4d742..4871cb0 100644
--- a/src/tint/lang/wgsl/sem/BUILD.cmake
+++ b/src/tint/lang/wgsl/sem/BUILD.cmake
@@ -94,8 +94,13 @@
   "lang/core/type"
   "lang/wgsl/ast"
   "utils/containers"
+  "utils/diagnostic"
   "utils/ice"
+  "utils/id"
+  "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
   "utils/symbol"
   "utils/text"
@@ -112,8 +117,22 @@
 
 tint_target_add_dependencies("lang/wgsl/sem:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/writer/BUILD.cmake b/src/tint/lang/wgsl/writer/BUILD.cmake
index bcab9fd..fa82fe3 100644
--- a/src/tint/lang/wgsl/writer/BUILD.cmake
+++ b/src/tint/lang/wgsl/writer/BUILD.cmake
@@ -34,11 +34,28 @@
 )
 
 tint_target_add_dependencies("lang/wgsl/writer"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
+  "lang/wgsl/sem"
   "lang/wgsl/writer/ast_printer"
   "lang/wgsl/writer/syntax_tree_printer"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
   "utils/reflection"
   "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/wgsl/writer:bench"
@@ -47,5 +64,24 @@
 
 tint_target_add_dependencies("lang/wgsl/writer:bench"
   "cmd/bench"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
   "lang/wgsl/writer"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake b/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake
index 6f54463..63ef359 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake
+++ b/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake
@@ -27,15 +27,25 @@
 
 tint_target_add_dependencies("lang/wgsl/writer/ast_printer"
   "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
   "utils/generator"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
   "utils/strconv"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("lang/wgsl/writer/ast_printer:test"
@@ -74,11 +84,24 @@
 
 tint_target_add_dependencies("lang/wgsl/writer/ast_printer:test"
   "lang/core"
+  "lang/core/constant"
   "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
   "lang/wgsl/sem"
   "lang/wgsl/writer/ast_printer"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/generator"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/BUILD.cmake b/src/tint/lang/wgsl/writer/ir_to_program/BUILD.cmake
index 59dc028..fadedb6 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/BUILD.cmake
+++ b/src/tint/lang/wgsl/writer/ir_to_program/BUILD.cmake
@@ -32,14 +32,22 @@
   "lang/core"
   "lang/core/constant"
   "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/resolver"
+  "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
+  "utils/memory"
   "utils/result"
   "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
@@ -58,9 +66,26 @@
 )
 
 tint_target_add_dependencies("lang/wgsl/writer/ir_to_program:test"
+  "lang/core"
+  "lang/core/constant"
   "lang/core/type"
+  "lang/wgsl/ast"
+  "lang/wgsl/program"
+  "lang/wgsl/sem"
   "lang/wgsl/writer"
+  "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/reflection"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
 
 if (TINT_BUILD_IR)
diff --git a/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.cmake b/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.cmake
index 83f72e1..929d8ac 100644
--- a/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.cmake
+++ b/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.cmake
@@ -27,13 +27,23 @@
 
 tint_target_add_dependencies("lang/wgsl/writer/syntax_tree_printer"
   "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
   "lang/wgsl/ast"
   "lang/wgsl/program"
   "lang/wgsl/sem"
+  "utils/containers"
+  "utils/diagnostic"
   "utils/generator"
+  "utils/ice"
+  "utils/id"
   "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/result"
   "utils/rtti"
   "utils/strconv"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/utils/cli/BUILD.cmake b/src/tint/utils/cli/BUILD.cmake
index 2b0e0a2..e0f286f 100644
--- a/src/tint/utils/cli/BUILD.cmake
+++ b/src/tint/utils/cli/BUILD.cmake
@@ -27,11 +27,15 @@
 
 tint_target_add_dependencies("utils/cli"
   "utils/containers"
+  "utils/ice"
   "utils/macros"
+  "utils/math"
   "utils/memory"
   "utils/result"
+  "utils/rtti"
   "utils/strconv"
   "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("utils/cli:test"
@@ -41,5 +45,13 @@
 tint_target_add_dependencies("utils/cli:test"
   "utils/cli"
   "utils/containers"
+  "utils/ice"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/strconv"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/utils/containers/BUILD.cmake b/src/tint/utils/containers/BUILD.cmake
index ad003cf..3712f41 100644
--- a/src/tint/utils/containers/BUILD.cmake
+++ b/src/tint/utils/containers/BUILD.cmake
@@ -64,8 +64,22 @@
 )
 
 tint_target_add_dependencies("utils/containers:test"
+  "lang/core"
+  "lang/core/constant"
+  "lang/core/type"
+  "lang/wgsl/ast"
   "lang/wgsl/program"
+  "lang/wgsl/sem"
   "utils/containers"
+  "utils/diagnostic"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
   "utils/memory"
+  "utils/result"
+  "utils/rtti"
+  "utils/symbol"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/utils/diagnostic/BUILD.cmake b/src/tint/utils/diagnostic/BUILD.cmake
index a302b7d..b7e5658 100644
--- a/src/tint/utils/diagnostic/BUILD.cmake
+++ b/src/tint/utils/diagnostic/BUILD.cmake
@@ -63,4 +63,6 @@
 
 tint_target_add_dependencies("utils/diagnostic:test"
   "utils/diagnostic"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/utils/file/BUILD.cmake b/src/tint/utils/file/BUILD.cmake
index 6aaceac..9bebfae 100644
--- a/src/tint/utils/file/BUILD.cmake
+++ b/src/tint/utils/file/BUILD.cmake
@@ -26,6 +26,7 @@
 
 tint_target_add_dependencies("utils/file"
   "utils/ice"
+  "utils/macros"
   "utils/text"
 )
 
@@ -53,4 +54,5 @@
 
 tint_target_add_dependencies("utils/file:test"
   "utils/file"
+  "utils/text"
 )
diff --git a/src/tint/utils/generator/BUILD.cmake b/src/tint/utils/generator/BUILD.cmake
index 4b6a3ad..1a25efd 100644
--- a/src/tint/utils/generator/BUILD.cmake
+++ b/src/tint/utils/generator/BUILD.cmake
@@ -29,5 +29,7 @@
   "utils/containers"
   "utils/diagnostic"
   "utils/ice"
+  "utils/macros"
   "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/utils/ice/BUILD.cmake b/src/tint/utils/ice/BUILD.cmake
index 9fdf8ef..58cd8db 100644
--- a/src/tint/utils/ice/BUILD.cmake
+++ b/src/tint/utils/ice/BUILD.cmake
@@ -36,4 +36,5 @@
 
 tint_target_add_dependencies("utils/ice:test"
   "utils/ice"
+  "utils/macros"
 )
diff --git a/src/tint/utils/id/BUILD.cmake b/src/tint/utils/id/BUILD.cmake
index d56067c..4453639 100644
--- a/src/tint/utils/id/BUILD.cmake
+++ b/src/tint/utils/id/BUILD.cmake
@@ -27,6 +27,7 @@
 
 tint_target_add_dependencies("utils/id"
   "utils/ice"
+  "utils/macros"
   "utils/text"
   "utils/traits"
 )
diff --git a/src/tint/utils/math/BUILD.cmake b/src/tint/utils/math/BUILD.cmake
index 477e285..d95c8d3 100644
--- a/src/tint/utils/math/BUILD.cmake
+++ b/src/tint/utils/math/BUILD.cmake
@@ -35,5 +35,10 @@
 
 tint_target_add_dependencies("utils/math:test"
   "utils/containers"
+  "utils/ice"
+  "utils/macros"
   "utils/math"
+  "utils/memory"
+  "utils/rtti"
+  "utils/traits"
 )
diff --git a/src/tint/utils/memory/BUILD.cmake b/src/tint/utils/memory/BUILD.cmake
index c8f8be7..82e78e0 100644
--- a/src/tint/utils/memory/BUILD.cmake
+++ b/src/tint/utils/memory/BUILD.cmake
@@ -38,5 +38,6 @@
 )
 
 tint_target_add_dependencies("utils/memory:test"
+  "utils/math"
   "utils/memory"
 )
diff --git a/src/tint/utils/reflection/BUILD.cmake b/src/tint/utils/reflection/BUILD.cmake
index 1645878..61d90d9 100644
--- a/src/tint/utils/reflection/BUILD.cmake
+++ b/src/tint/utils/reflection/BUILD.cmake
@@ -34,5 +34,6 @@
 )
 
 tint_target_add_dependencies("utils/reflection:test"
+  "utils/macros"
   "utils/reflection"
 )
diff --git a/src/tint/utils/result/BUILD.cmake b/src/tint/utils/result/BUILD.cmake
index ae6db4e..f1673b1 100644
--- a/src/tint/utils/result/BUILD.cmake
+++ b/src/tint/utils/result/BUILD.cmake
@@ -27,6 +27,7 @@
 
 tint_target_add_dependencies("utils/result"
   "utils/ice"
+  "utils/macros"
   "utils/text"
   "utils/traits"
 )
@@ -36,5 +37,9 @@
 )
 
 tint_target_add_dependencies("utils/result:test"
+  "utils/ice"
+  "utils/macros"
   "utils/result"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/utils/rtti/BUILD.cmake b/src/tint/utils/rtti/BUILD.cmake
index df557b9..64802b0 100644
--- a/src/tint/utils/rtti/BUILD.cmake
+++ b/src/tint/utils/rtti/BUILD.cmake
@@ -39,7 +39,11 @@
 )
 
 tint_target_add_dependencies("utils/rtti:test"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
   "utils/rtti"
+  "utils/traits"
 )
 
 tint_add_target("utils/rtti:bench"
@@ -47,5 +51,9 @@
 )
 
 tint_target_add_dependencies("utils/rtti:bench"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
   "utils/rtti"
+  "utils/traits"
 )
diff --git a/src/tint/utils/strconv/BUILD.cmake b/src/tint/utils/strconv/BUILD.cmake
index 85ed5cd..254ae22 100644
--- a/src/tint/utils/strconv/BUILD.cmake
+++ b/src/tint/utils/strconv/BUILD.cmake
@@ -32,6 +32,7 @@
   "utils/macros"
   "utils/result"
   "utils/text"
+  "utils/traits"
 )
 
 tint_target_add_external_dependencies("utils/strconv"
diff --git a/src/tint/utils/symbol/BUILD.cmake b/src/tint/utils/symbol/BUILD.cmake
index 2d7bc46..8a53a24 100644
--- a/src/tint/utils/symbol/BUILD.cmake
+++ b/src/tint/utils/symbol/BUILD.cmake
@@ -31,7 +31,12 @@
   "utils/containers"
   "utils/ice"
   "utils/id"
+  "utils/macros"
+  "utils/math"
   "utils/memory"
+  "utils/rtti"
+  "utils/text"
+  "utils/traits"
 )
 
 tint_add_target("utils/symbol:test"
@@ -40,5 +45,14 @@
 )
 
 tint_target_add_dependencies("utils/symbol:test"
+  "utils/containers"
+  "utils/ice"
+  "utils/id"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/rtti"
   "utils/symbol"
+  "utils/text"
+  "utils/traits"
 )
diff --git a/src/tint/utils/text/BUILD.cmake b/src/tint/utils/text/BUILD.cmake
index a441546..f5843a1 100644
--- a/src/tint/utils/text/BUILD.cmake
+++ b/src/tint/utils/text/BUILD.cmake
@@ -31,6 +31,12 @@
 
 tint_target_add_dependencies("utils/text"
   "utils/containers"
+  "utils/ice"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/rtti"
+  "utils/traits"
 )
 
 tint_add_target("utils/text:test"
@@ -41,6 +47,11 @@
 
 tint_target_add_dependencies("utils/text:test"
   "utils/containers"
+  "utils/ice"
+  "utils/macros"
+  "utils/math"
+  "utils/memory"
+  "utils/rtti"
   "utils/text"
   "utils/traits"
 )
diff --git a/tools/src/cmd/gen/build/BUILD.cmake.tmpl b/tools/src/cmd/gen/build/BUILD.cmake.tmpl
index a75ce8c..918e482 100644
--- a/tools/src/cmd/gen/build/BUILD.cmake.tmpl
+++ b/tools/src/cmd/gen/build/BUILD.cmake.tmpl
@@ -51,8 +51,8 @@
 {{-   end}}
 )
 
-{{- /* Emit unconditional dependencies */}}
-{{-   $UnconditionalDeps    := $.UnconditionalDependencies }}
+{{- /* Emit unconditional internal dependencies */}}
+{{-   $UnconditionalDeps    := $.Dependencies.UnconditionalInternal }}
 {{-   if $UnconditionalDeps}}
 {{/*   newline */}}
 tint_target_add_dependencies("{{$.Name}}"
@@ -63,7 +63,7 @@
 {{-   end}}
 
 {{- /* Emit unconditional external dependencies */}}
-{{-   $UnconditionalExtDeps := $.UnconditionalExternalDependencies }}
+{{-   $UnconditionalExtDeps := $.Dependencies.UnconditionalExternal }}
 {{-   if $UnconditionalExtDeps}}
 {{/*   newline */}}
 tint_target_add_external_dependencies("{{$.Name}}"
diff --git a/tools/src/cmd/gen/build/build.go b/tools/src/cmd/gen/build/build.go
index cb64847..c308194 100644
--- a/tools/src/cmd/gen/build/build.go
+++ b/tools/src/cmd/gen/build/build.go
@@ -78,6 +78,7 @@
 		{"populating source files", populateSourceFiles},
 		{"scanning source files", scanSourceFiles},
 		{"loading directory configs", applyDirectoryConfigs},
+		{"building dependencies", buildDependencies},
 		{"checking for cycles", checkForCycles},
 		{"emitting build files", emitBuildFiles},
 	} {
@@ -124,10 +125,11 @@
 		if err != nil {
 			return fmt.Errorf("'externals.json' matcher error: %w", err)
 		}
-		p.externals = append(p.externals, projectExternalDependency{
-			name:                ExternalDependencyName(name),
+		name := ExternalDependencyName(name)
+		p.externals.Add(name, ExternalDependency{
+			Name:                name,
+			Condition:           external.Condition,
 			includePatternMatch: match,
-			condition:           external.Condition,
 		})
 	}
 
@@ -172,12 +174,6 @@
 // * #includes to build a dependencies between targets
 // * 'GEN_BUILD:' directives
 func scanSourceFiles(p *Project) error {
-	// Include describes a #include in a source file
-	type Include struct {
-		path string
-		line int
-	}
-
 	// ParsedFile describes all the includes and conditions found in a source file
 	type ParsedFile struct {
 		conditions []string
@@ -228,37 +224,7 @@
 					}
 				}
 
-				// Resolve includes, and add dependencies to the targets
-				for _, include := range parsed.includes {
-					if strings.HasPrefix(include.path, srcTint) {
-						// #include "src/tint/..."
-						include.path = include.path[len(srcTint)+1:] // Strip 'src/tint/'
-
-						includeFile := p.File(include.path)
-						if includeFile == nil {
-							return fmt.Errorf(`%v:%v includes non-existent file '%v'`, file.Path(), include.line, include.path)
-						}
-
-						dependencyKind := targetKindFromFilename(include.path)
-						if dependencyKind == targetInvalid {
-							return fmt.Errorf(`%v:%v unknown target type for include '%v'`, file.Path(), include.line, includeFile.Path())
-						}
-						if target.Kind == targetLib && dependencyKind == targetTest {
-							return fmt.Errorf(`%v:%v lib target must not include test code '%v'`, file.Path(), include.line, includeFile.Path())
-						}
-
-						if dependency := p.Target(includeFile.Directory, dependencyKind); dependency != nil {
-							target.AddDependency(dependency)
-						}
-					} else {
-						// Check for external includes
-						for _, external := range p.externals {
-							if external.includePatternMatch(include.path) {
-								target.AddExternalDependency(external.name, external.condition)
-							}
-						}
-					}
-				}
+				file.Includes = append(file.Includes, parsed.includes...)
 			}
 		}
 	}
@@ -332,7 +298,9 @@
 				}
 				target := p.AddTarget(dir, tc.kind)
 				for _, dep := range additionalDeps {
-					target.AddDependency(dep)
+					if dep != target {
+						target.Dependencies.AddInternal(dep)
+					}
 				}
 			}
 		}
@@ -341,6 +309,104 @@
 	return nil
 }
 
+// buildDependencies walks all the #includes in all files, building the dependency information for
+// all targets and files in the project. Errors if any cyclic includes are found.
+func buildDependencies(p *Project) error {
+	type state int
+	const (
+		unvisited state = iota
+		visiting
+		checked
+	)
+
+	cache := container.NewMap[string, state]()
+
+	type FileInclude struct {
+		file string
+		inc  Include
+	}
+
+	var walk func(file *File, route []FileInclude) error
+	walk = func(file *File, route []FileInclude) error {
+		// Adds the dependency to the file and target's list of internal dependencies
+		addInternalDependency := func(dep *Target) {
+			file.TransitiveDependencies.AddInternal(dep)
+			if file.Target != dep {
+				file.Target.Dependencies.AddInternal(dep)
+			}
+		}
+		// Adds the dependency to the file and target's list of external dependencies
+		addExternalDependency := func(dep ExternalDependency) {
+			file.TransitiveDependencies.AddExternal(dep)
+			file.Target.Dependencies.AddExternal(dep)
+		}
+
+		filePath := file.Path()
+		switch cache[filePath] {
+		case unvisited:
+			cache[filePath] = visiting
+
+			for _, include := range file.Includes {
+				if strings.HasPrefix(include.Path, srcTint) {
+					// #include "src/tint/..."
+					path := include.Path[len(srcTint)+1:] // Strip 'src/tint/'
+
+					includeFile := p.File(path)
+					if includeFile == nil {
+						return fmt.Errorf(`%v:%v includes non-existent file '%v'`, file.Path(), include.Line, path)
+					}
+
+					if file.Target.Kind == targetLib && includeFile.Target.Kind != targetLib {
+						return fmt.Errorf(`%v:%v lib target must not include %v target`, file.Path(), include.Line, includeFile.Target.Kind)
+					}
+
+					addInternalDependency(includeFile.Target)
+
+					// Gather the dependencies for the included file
+					if err := walk(includeFile, append(route, FileInclude{file: file.Path(), inc: include})); err != nil {
+						return err
+					}
+
+					for _, dependency := range includeFile.TransitiveDependencies.Internal() {
+						addInternalDependency(dependency)
+					}
+					for _, dependency := range includeFile.TransitiveDependencies.External() {
+						addExternalDependency(dependency)
+					}
+
+				} else {
+					// Check for external includes
+					for _, external := range p.externals.Values() {
+						if external.includePatternMatch(include.Path) {
+							addExternalDependency(external)
+						}
+					}
+				}
+
+			}
+
+			cache[filePath] = checked
+
+		case visiting:
+			err := strings.Builder{}
+			fmt.Fprintln(&err, "cyclic include found:")
+			for _, include := range route {
+				fmt.Fprintf(&err, "  %v:%v includes '%v'\n", include.file, include.inc.Line, include.inc.Path)
+			}
+			return fmt.Errorf(err.String())
+		}
+		return nil
+	}
+
+	for _, file := range p.Files.Values() {
+		if err := walk(file, []FileInclude{}); err != nil {
+			return err
+		}
+	}
+	return nil
+
+}
+
 // checkForCycles ensures that the graph of target dependencies are acyclic (a DAG)
 func checkForCycles(p *Project) error {
 	type state int
@@ -357,7 +423,7 @@
 		switch cache[t.Name] {
 		case unvisited:
 			cache[t.Name] = visiting
-			for _, dep := range t.Dependencies() {
+			for _, dep := range t.Dependencies.Internal() {
 				if err := walk(dep, append(path, dep.Name)); err != nil {
 					return err
 				}
@@ -518,8 +584,8 @@
 		nodes.Add(target.Name, g.AddNode(string(target.Name)))
 	}
 	for _, target := range targets {
-		for _, dep := range target.DependencyNames.List() {
-			g.AddEdge(nodes[target.Name], nodes[dep], "")
+		for _, dep := range target.Dependencies.Internal() {
+			g.AddEdge(nodes[target.Name], nodes[dep.Name], "")
 		}
 	}
 
diff --git a/tools/src/cmd/gen/build/dependencies.go b/tools/src/cmd/gen/build/dependencies.go
new file mode 100644
index 0000000..0578966
--- /dev/null
+++ b/tools/src/cmd/gen/build/dependencies.go
@@ -0,0 +1,89 @@
+// Copyright 2023 The Tint 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.
+
+package build
+
+import (
+	"dawn.googlesource.com/dawn/tools/src/container"
+	"dawn.googlesource.com/dawn/tools/src/transform"
+)
+
+// Dependencies describes the dependencies of a target
+type Dependencies struct {
+	// The project
+	project *Project
+	// Target names of all dependencies of this target
+	internal container.Set[TargetName]
+	// All external dependencies used by this target
+	external container.Set[ExternalDependencyName]
+}
+
+// NewDependencies returns a new Dependencies
+func NewDependencies(p *Project) *Dependencies {
+	return &Dependencies{
+		project:  p,
+		internal: container.NewSet[TargetName](),
+		external: container.NewSet[ExternalDependencyName](),
+	}
+}
+
+// AddInternal adds dep to the list of internal dependencies
+func (d *Dependencies) AddInternal(dep *Target) {
+	d.internal.Add(dep.Name)
+}
+
+// AddExternal adds dep to the list of external dependencies
+func (d *Dependencies) AddExternal(dep ExternalDependency) {
+	d.external.Add(dep.Name)
+}
+
+// Internal returns the sorted list of dependencies of this target
+func (d *Dependencies) Internal() []*Target {
+	out := make([]*Target, len(d.internal))
+	for i, name := range d.internal.List() {
+		out[i] = d.project.Targets[name]
+	}
+	return out
+}
+
+// UnconditionalInternal returns the sorted list of dependencies that have no build condition.
+func (d *Dependencies) UnconditionalInternal() []*Target {
+	return transform.Filter(d.Internal(), func(d *Target) bool { return d.Condition == "" })
+}
+
+// External returns the sorted list of external dependencies.
+func (d *Dependencies) External() []ExternalDependency {
+	out := make([]ExternalDependency, 0, len(d.external))
+	for _, name := range d.external.List() {
+		out = append(out, d.project.externals[name])
+	}
+	return out
+}
+
+// ConditionalExternalDependencies returns the sorted list of external dependencies that have a
+// build condition.
+func (d *Dependencies) ConditionalExternal() []ExternalDependency {
+	return transform.Filter(d.External(), func(e ExternalDependency) bool { return e.Condition != "" })
+}
+
+// ConditionalExternalDependencies returns the sorted list of external dependencies that have no
+// build condition.
+func (d *Dependencies) UnconditionalExternal() []ExternalDependency {
+	return transform.Filter(d.External(), func(e ExternalDependency) bool { return e.Condition == "" })
+}
+
+// ContainsExternal returns true if the external dependencies contains name
+func (d *Dependencies) ContainsExternal(name ExternalDependencyName) bool {
+	return d.external.Contains(name)
+}
diff --git a/tools/src/cmd/gen/build/external_dependency.go b/tools/src/cmd/gen/build/external_dependency.go
index fb8937c..a411d34 100644
--- a/tools/src/cmd/gen/build/external_dependency.go
+++ b/tools/src/cmd/gen/build/external_dependency.go
@@ -14,6 +14,8 @@
 
 package build
 
+import "dawn.googlesource.com/dawn/tools/src/match"
+
 // ExternalDependency describes a dependency on an external library
 type ExternalDependency struct {
 	// Name of the library.
@@ -21,6 +23,8 @@
 	Name ExternalDependencyName
 	// The optional condition for using this dependency
 	Condition string
+	// Include file pattern matcher
+	includePatternMatch match.Test
 }
 
 // Name of an external dependency
diff --git a/tools/src/cmd/gen/build/file.go b/tools/src/cmd/gen/build/file.go
index 6c558ab..a9d9cac 100644
--- a/tools/src/cmd/gen/build/file.go
+++ b/tools/src/cmd/gen/build/file.go
@@ -16,14 +16,26 @@
 
 import "path"
 
+// Include describes a single #include in a file
+type Include struct {
+	Path string
+	Line int
+}
+
 // File holds information about a source file
 type File struct {
 	// The directory that holds this source file
 	Directory *Directory
+	// The target that this source file belongs to
+	Target *Target
 	// The name of the file
 	Name string
 	// An optional condition used to build this source file
 	Condition string
+	// All the #include made by this file
+	Includes []Include
+	// All the transitive dependencies of this file
+	TransitiveDependencies *Dependencies
 }
 
 // Path returns the project-relative path of the file
diff --git a/tools/src/cmd/gen/build/project.go b/tools/src/cmd/gen/build/project.go
index a879e31..309b738 100644
--- a/tools/src/cmd/gen/build/project.go
+++ b/tools/src/cmd/gen/build/project.go
@@ -22,7 +22,6 @@
 
 	"dawn.googlesource.com/dawn/tools/src/cmd/gen/common"
 	"dawn.googlesource.com/dawn/tools/src/container"
-	"dawn.googlesource.com/dawn/tools/src/match"
 )
 
 // Project holds information about all the directories, targets and source files
@@ -39,17 +38,7 @@
 	// A map of target name to target.
 	Targets container.Map[TargetName, *Target]
 	// A list of external project dependencies used by the project
-	externals []projectExternalDependency
-}
-
-// projectExternalDependency describes an external dependency of a Project
-type projectExternalDependency struct {
-	// name of the external dependency
-	name ExternalDependencyName
-	// include matcher
-	includePatternMatch match.Test
-	// condition of the dependency
-	condition string
+	externals container.Map[ExternalDependencyName, ExternalDependency]
 }
 
 // NewProject returns a newly initialized Project
@@ -60,6 +49,7 @@
 		Files:       container.NewMap[string, *File](),
 		Directories: container.NewMap[string, *Directory](),
 		Targets:     container.NewMap[TargetName, *Target](),
+		externals:   container.NewMap[ExternalDependencyName, ExternalDependency](),
 	}
 }
 
@@ -68,8 +58,9 @@
 	return p.Files.GetOrCreate(file, func() *File {
 		dir, name := path.Split(file)
 		return &File{
-			Directory: p.Directory(dir),
-			Name:      name,
+			Directory:              p.Directory(dir),
+			Name:                   name,
+			TransitiveDependencies: NewDependencies(p),
 		}
 	})
 }
@@ -84,12 +75,11 @@
 	name := p.TargetName(dir, kind)
 	return p.Targets.GetOrCreate(name, func() *Target {
 		t := &Target{
-			Name:                  name,
-			Directory:             dir,
-			Kind:                  kind,
-			SourceFileSet:         container.NewSet[string](),
-			DependencyNames:       container.NewSet[TargetName](),
-			ExternalDependencyMap: container.NewMap[ExternalDependencyName, ExternalDependency](),
+			Name:          name,
+			Directory:     dir,
+			Kind:          kind,
+			SourceFileSet: container.NewSet[string](),
+			Dependencies:  NewDependencies(p),
 		}
 		dir.TargetNames.Add(name)
 		p.Targets.Add(name, t)
diff --git a/tools/src/cmd/gen/build/target.go b/tools/src/cmd/gen/build/target.go
index d60231a..06a01a2 100644
--- a/tools/src/cmd/gen/build/target.go
+++ b/tools/src/cmd/gen/build/target.go
@@ -31,10 +31,8 @@
 	Directory *Directory
 	// All project-relative paths of source files that are part of this target
 	SourceFileSet container.Set[string]
-	// Target names of all dependencies of this target
-	DependencyNames container.Set[TargetName]
-	// All external dependencies used by this target
-	ExternalDependencyMap container.Map[ExternalDependencyName, ExternalDependency]
+	// Dependencies of this target
+	Dependencies *Dependencies
 	// An optional condition for building this target
 	Condition string
 }
@@ -42,6 +40,7 @@
 // AddSourceFile adds the File to the target's source set
 func (t *Target) AddSourceFile(f *File) {
 	t.SourceFileSet.Add(f.Path())
+	f.Target = t
 }
 
 // SourceFiles returns the sorted list of the target's source files
@@ -58,57 +57,6 @@
 	return transform.Filter(t.SourceFiles(), func(t *File) bool { return t.Condition == "" })
 }
 
-// AddDependency adds dep to this target's list of dependencies
-func (t *Target) AddDependency(dep *Target) {
-	if dep != t {
-		t.DependencyNames.Add(dep.Name)
-	}
-}
-
-// AddExternalDependency adds the external dependency with the given name to this target's list of
-// external dependencies with the given condition
-func (t *Target) AddExternalDependency(name ExternalDependencyName, condition string) {
-	if existing, ok := t.ExternalDependencyMap[name]; ok && existing.Condition != condition {
-		panic("external dependency added twice with different conditions")
-	}
-	t.ExternalDependencyMap.Add(name, ExternalDependency{Name: name, Condition: condition})
-}
-
-// Dependencies returns the sorted list of dependencies of this target
-func (t *Target) Dependencies() []*Target {
-	out := make([]*Target, len(t.DependencyNames))
-	for i, name := range t.DependencyNames.List() {
-		out[i] = t.Directory.Project.Targets[name]
-	}
-	return out
-}
-
-// UnconditionalDependencies returns the sorted list of dependencies that have no build condition.
-func (t *Target) UnconditionalDependencies() []*Target {
-	return transform.Filter(t.Dependencies(), func(t *Target) bool { return t.Condition == "" })
-}
-
-// ExternalDependencies returns the sorted list of external dependencies.
-func (t *Target) ExternalDependencies() []ExternalDependency {
-	out := make([]ExternalDependency, 0, len(t.ExternalDependencyMap))
-	for _, name := range t.ExternalDependencyMap.Keys() {
-		out = append(out, t.ExternalDependencyMap[name])
-	}
-	return out
-}
-
-// ConditionalExternalDependencies returns the sorted list of external dependencies that have a
-// build condition.
-func (t *Target) ConditionalExternalDependencies() []ExternalDependency {
-	return transform.Filter(t.ExternalDependencies(), func(t ExternalDependency) bool { return t.Condition != "" })
-}
-
-// ConditionalExternalDependencies returns the sorted list of external dependencies that have no
-// build condition.
-func (t *Target) UnconditionalExternalDependencies() []ExternalDependency {
-	return transform.Filter(t.ExternalDependencies(), func(t ExternalDependency) bool { return t.Condition == "" })
-}
-
 // A collection of source files and dependencies sharing the same condition
 type TargetConditional struct {
 	Condition            string
@@ -129,7 +77,7 @@
 			c.SourceFiles = append(c.SourceFiles, file)
 		}
 	}
-	for name := range t.DependencyNames {
+	for name := range t.Dependencies.internal {
 		dep := t.Directory.Project.Targets[name]
 		if dep.Condition != "" {
 			c := m.GetOrCreate(dep.Condition, func() *TargetConditional {
@@ -138,7 +86,8 @@
 			c.InternalDependencies = append(c.InternalDependencies, dep)
 		}
 	}
-	for _, dep := range t.ExternalDependencyMap {
+	for name := range t.Dependencies.external {
+		dep := t.Directory.Project.externals[name]
 		if dep.Condition != "" {
 			c := m.GetOrCreate(dep.Condition, func() *TargetConditional {
 				return &TargetConditional{Condition: dep.Condition}