BUILD.gn: Add targets to build all command-line tools (#2727)

This adds all the command-line tools from the CMakeLists.txt
file to the BUILD.gn used by Chromium and Fuchsia.

+ Add a convenient "all_spirv_tools" GN target to rebuild
  all command-line tools at once.

+ "gn format" pass to fix a few minor issues in the file.

Tested on Chromium with the following procedure:

 1) Have a clean Chromium checkout

 2) # Update to upstream spirv-headers (otherwise spirv-tools build fails)
    cd $CHROMIUM_SRC/third_party/spirv-headers/src &&
    git remote add upstream https://github.com/KhronosGroup/SPIRV-Headers.git &&
    git fetch upstream &&
    git checkout upstream/master

 3) # Update to upstream spirv-tools (Chromium is tracking older revision)
    cd $CHROMIUM_SRC/third_party/SPIRV-Tools/src &&
    git remote add upstream https://github.com/KhronosGroup/SPIRV-Tools.git &&
    git fetch upstream &&
    git checkout -tb check-patch upstream/master &&
    git cherry-pick <patch>

 3) # Rebuild Chromium and all SPIR-V tools for the host
    cd $CHROMIUM_SRC/src &&
    gn gen out/Linux --args 'use_goma = true' &&
    ninja -C out/Linux -j1000 -l30 gn_all all_spirv_tools

 4) Run the command-line tools, e.g.:

    out/Linux/spirv-link --help
diff --git a/BUILD.gn b/BUILD.gn
index d834ba3..ad71c1d 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -12,8 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("//build_overrides/spirv_tools.gni")
 import("//build_overrides/build.gni")
+import("//build_overrides/spirv_tools.gni")
 if (build_with_chromium) {
   import("//testing/test.gni")
 }
@@ -294,11 +294,11 @@
 
 source_set("spvtools_headers") {
   sources = [
+    "include/spirv-tools/instrument.hpp",
     "include/spirv-tools/libspirv.h",
     "include/spirv-tools/libspirv.hpp",
     "include/spirv-tools/linker.hpp",
     "include/spirv-tools/optimizer.hpp",
-    "include/spirv-tools/instrument.hpp",
   ]
 
   public_configs = [ ":spvtools_public_config" ]
@@ -384,9 +384,7 @@
     configs -= [ "//build/config/compiler:chromium_code" ]
     configs += [ "//build/config/compiler:no_chromium_code" ]
   }
-  configs += [
-    ":spvtools_internal_config",
-  ]
+  configs += [ ":spvtools_internal_config" ]
 }
 
 static_library("spvtools_val") {
@@ -445,9 +443,7 @@
     configs -= [ "//build/config/compiler:chromium_code" ]
     configs += [ "//build/config/compiler:no_chromium_code" ]
   }
-  configs += [
-    ":spvtools_internal_config",
-  ]
+  configs += [ ":spvtools_internal_config" ]
 }
 
 static_library("spvtools_opt") {
@@ -664,15 +660,102 @@
     configs -= [ "//build/config/compiler:chromium_code" ]
     configs += [ "//build/config/compiler:no_chromium_code" ]
   }
-  configs += [
-    ":spvtools_internal_config",
+  configs += [ ":spvtools_internal_config" ]
+}
+
+static_library("spvtools_link") {
+  sources = [
+    "source/link/linker.cpp",
   ]
+  deps = [
+    ":spvtools",
+    ":spvtools_val",
+  ]
+  public_deps = [
+    ":spvtools_headers",
+  ]
+  if (build_with_chromium) {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
+  configs += [ ":spvtools_internal_config" ]
+}
+
+static_library("spvtools_reduce") {
+  sources = [
+    "source/reduce/change_operand_reduction_opportunity.cpp",
+    "source/reduce/change_operand_reduction_opportunity.h",
+    "source/reduce/change_operand_to_undef_reduction_opportunity.cpp",
+    "source/reduce/change_operand_to_undef_reduction_opportunity.h",
+    "source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.cpp",
+    "source/reduce/conditional_branch_to_simple_conditional_branch_opportunity_finder.h",
+    "source/reduce/conditional_branch_to_simple_conditional_branch_reduction_opportunity.cpp",
+    "source/reduce/conditional_branch_to_simple_conditional_branch_reduction_opportunity.h",
+    "source/reduce/merge_blocks_reduction_opportunity.cpp",
+    "source/reduce/merge_blocks_reduction_opportunity.h",
+    "source/reduce/merge_blocks_reduction_opportunity_finder.cpp",
+    "source/reduce/merge_blocks_reduction_opportunity_finder.h",
+    "source/reduce/operand_to_const_reduction_opportunity_finder.cpp",
+    "source/reduce/operand_to_const_reduction_opportunity_finder.h",
+    "source/reduce/operand_to_dominating_id_reduction_opportunity_finder.cpp",
+    "source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h",
+    "source/reduce/operand_to_undef_reduction_opportunity_finder.cpp",
+    "source/reduce/operand_to_undef_reduction_opportunity_finder.h",
+    "source/reduce/reducer.cpp",
+    "source/reduce/reducer.h",
+    "source/reduce/reduction_opportunity.cpp",
+    "source/reduce/reduction_opportunity.h",
+    "source/reduce/reduction_pass.cpp",
+    "source/reduce/reduction_pass.h",
+    "source/reduce/reduction_util.cpp",
+    "source/reduce/reduction_util.h",
+    "source/reduce/remove_block_reduction_opportunity.cpp",
+    "source/reduce/remove_block_reduction_opportunity.h",
+    "source/reduce/remove_block_reduction_opportunity_finder.cpp",
+    "source/reduce/remove_block_reduction_opportunity_finder.h",
+    "source/reduce/remove_function_reduction_opportunity.cpp",
+    "source/reduce/remove_function_reduction_opportunity.h",
+    "source/reduce/remove_function_reduction_opportunity_finder.cpp",
+    "source/reduce/remove_function_reduction_opportunity_finder.h",
+    "source/reduce/remove_instruction_reduction_opportunity.cpp",
+    "source/reduce/remove_instruction_reduction_opportunity.h",
+    "source/reduce/remove_opname_instruction_reduction_opportunity_finder.cpp",
+    "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h",
+    "source/reduce/remove_selection_reduction_opportunity.cpp",
+    "source/reduce/remove_selection_reduction_opportunity.h",
+    "source/reduce/remove_selection_reduction_opportunity_finder.cpp",
+    "source/reduce/remove_selection_reduction_opportunity_finder.h",
+    "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.cpp",
+    "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h",
+    "source/reduce/simple_conditional_branch_to_branch_opportunity_finder.cpp",
+    "source/reduce/simple_conditional_branch_to_branch_opportunity_finder.h",
+    "source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.cpp",
+    "source/reduce/simple_conditional_branch_to_branch_reduction_opportunity.h",
+    "source/reduce/structured_loop_to_selection_reduction_opportunity.cpp",
+    "source/reduce/structured_loop_to_selection_reduction_opportunity.h",
+    "source/reduce/structured_loop_to_selection_reduction_opportunity_finder.cpp",
+    "source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h",
+  ]
+  deps = [
+    ":spvtools",
+    ":spvtools_opt",
+  ]
+  public_deps = [
+    ":spvtools_headers",
+  ]
+  if (build_with_chromium) {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
+  configs += [ ":spvtools_internal_config" ]
 }
 
 group("SPIRV-Tools") {
   deps = [
     ":spvtools",
+    ":spvtools_link",
     ":spvtools_opt",
+    ":spvtools_reduce",
     ":spvtools_val",
   ]
 }
@@ -742,12 +825,12 @@
     ]
 
     deps = [
-      "//testing/gmock",
-      "//testing/gtest",
-      "//testing/gtest:gtest_main",
       ":spvtools",
       ":spvtools_language_header_unified1",
       ":spvtools_val",
+      "//testing/gmock",
+      "//testing/gtest",
+      "//testing/gtest:gtest_main",
     ]
 
     if (is_clang) {
@@ -767,30 +850,129 @@
   }
 }
 
-executable("spirv-as") {
+source_set("spvtools_util_cli_consumer") {
+  sources = [
+    "tools/util/cli_consumer.cpp",
+    "tools/util/cli_consumer.h",
+  ]
+  configs += [ ":spvtools_internal_config" ]
+}
+
+source_set("spvtools_software_version") {
   sources = [
     "source/software_version.cpp",
+  ]
+  deps = [
+    ":spvtools_build_version",
+  ]
+  configs += [ ":spvtools_internal_config" ]
+}
+
+executable("spirv-as") {
+  sources = [
     "tools/as/as.cpp",
   ]
   deps = [
     ":spvtools",
-    ":spvtools_build_version",
+    ":spvtools_software_version",
+  ]
+  configs += [ ":spvtools_internal_config" ]
+}
+
+executable("spirv-dis") {
+  sources = [
+    "tools/dis/dis.cpp",
+  ]
+  deps = [
+    ":spvtools",
+    ":spvtools_software_version",
+  ]
+  configs += [ ":spvtools_internal_config" ]
+}
+
+executable("spirv-val") {
+  sources = [
+    "tools/val/val.cpp",
+  ]
+  deps = [
+    ":spvtools",
+    ":spvtools_software_version",
+    ":spvtools_util_cli_consumer",
+    ":spvtools_val",
+  ]
+  configs += [ ":spvtools_internal_config" ]
+}
+
+executable("spirv-cfg") {
+  sources = [
+    "tools/cfg/bin_to_dot.cpp",
+    "tools/cfg/bin_to_dot.h",
+    "tools/cfg/cfg.cpp",
+  ]
+  deps = [
+    ":spvtools",
+    ":spvtools_software_version",
   ]
   configs += [ ":spvtools_internal_config" ]
 }
 
 executable("spirv-opt") {
   sources = [
-    "source/software_version.cpp",
     "tools/opt/opt.cpp",
-    "tools/util/cli_consumer.cpp",
-    "tools/util/cli_consumer.h",
   ]
   deps = [
     ":spvtools",
     ":spvtools_opt",
+    ":spvtools_software_version",
+    ":spvtools_util_cli_consumer",
     ":spvtools_val",
-    ":spvtools_build_version",
   ]
   configs += [ ":spvtools_internal_config" ]
 }
+
+executable("spirv-link") {
+  sources = [
+    "tools/link/linker.cpp",
+  ]
+  deps = [
+    ":spvtools",
+    ":spvtools_link",
+    ":spvtools_opt",
+    ":spvtools_software_version",
+    ":spvtools_val",
+  ]
+  configs += [ ":spvtools_internal_config" ]
+}
+
+if (!is_ios) {
+  # iOS does not allow std::system calls which spirv-reduce requires
+  executable("spirv-reduce") {
+    sources = [
+      "source/spirv_reducer_options.cpp",
+      "source/spirv_reducer_options.h",
+      "tools/reduce/reduce.cpp",
+    ]
+    deps = [
+      ":spvtools",
+      ":spvtools_reduce",
+      ":spvtools_software_version",
+      ":spvtools_util_cli_consumer",
+      ":spvtools_val",
+    ]
+    configs += [ ":spvtools_internal_config" ]
+  }
+}
+
+group("all_spirv_tools") {
+  deps = [
+    ":spirv-as",
+    ":spirv-cfg",
+    ":spirv-dis",
+    ":spirv-link",
+    ":spirv-opt",
+    ":spirv-val",
+  ]
+  if (!is_ios) {
+    deps += [ ":spirv-reduce" ]
+  }
+}