Import vscode tools from Dawn.

Dawn has more advanced tools for generating GN / CMake projects. Bring these across.

Change-Id: I569f706fc28d5e182abb81420bce808d9e7f753a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/104700
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index f584277..d003b81 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -10,46 +10,42 @@
     // ${cwd}: the current working directory of the spawned process
     "version": "2.0.0",
     "tasks": [
+        // Invokes ninja in the 'out/active' directory, which is created with
+        // the 'gn gen' task (see below).
         {
-            "label": "make",
+            "label": "build",
             "group": {
                 "kind": "build",
                 "isDefault": true
             },
             "type": "shell",
-            "osx": {
-                "command": "sh",
-                "args": [
-                    "-c",
-                    "cmake --build . && echo Done"
-                ],
-                "options": {
-                    "cwd": "${workspaceRoot}/build",
-                },
-            },
             "linux": {
                 "command": "sh",
                 "args": [
                     "-c",
-                    "cmake --build . && echo Done"
-                ],
-                "options": {
-                    "cwd": "${workspaceRoot}/build",
-                },
-            },
-            "windows": {
-                // Invokes ninja in the 'out/active' directory, which is created
-                // with the 'generate' task (see below).
-                "command": "/C",
-                "args": [
                     "ninja && echo Done"
                 ],
+            },
+            "osx": {
+                "command": "sh",
+                "args": [
+                    "-c",
+                    "ninja && echo Done"
+                ],
+            },
+            "windows": {
+                "command": "/C",
+                "args": [
+                    "ninja && echo Done",
+                ],
                 "options": {
-                    "cwd": "${workspaceRoot}/out/active",
                     "shell": {
                         "executable": "cmd"
-                    }
-                },
+                    },
+                }
+            },
+            "options": {
+                "cwd": "${workspaceRoot}/out/active",
             },
             "presentation": {
                 "echo": false,
@@ -72,36 +68,28 @@
                 }
             }
         },
+        // Generates a GN build directory at 'out/<build-type>' with the
+        // is_debug argument set to to true iff the build-type is Debug.
+        // A symbolic link to this build directory is created at 'out/active'
+        // which is used to track the active build directory.
         {
-            "label": "configure",
+            "label": "gn gen",
             "type": "shell",
-            "osx": {
-                "command": "cmake",
-                "args": [
-                    "..",
-                    "-GNinja",
-                    "-DCMAKE_BUILD_TYPE=${input:buildType}",
-                ],
-                "options": {
-                    "cwd": "${workspaceRoot}/build"
-                },
-            },
             "linux": {
-                "command": "cmake",
+                "command": "./tools/setup-build",
                 "args": [
-                    "..",
-                    "-GNinja",
-                    "-DCMAKE_BUILD_TYPE=${input:buildType}",
+                    "gn",
+                    "${input:buildType}",
                 ],
-                "options": {
-                    "cwd": "${workspaceRoot}/build"
-                },
+            },
+            "osx": {
+                "command": "./tools/setup-build",
+                "args": [
+                    "gn",
+                    "${input:buildType}",
+                ],
             },
             "windows": {
-                // Generates a GN build directory at 'out/<build-type>' with the
-                // is_debug argument set to true iff the build-type is Debug.
-                // A symbolic link to this build directory is created at 'out/active'
-                // which is used to track the active build directory.
                 "command": "/C",
                 "args": [
                     "(IF \"${input:buildType}\" == \"Debug\" ( gn gen \"out\\${input:buildType}\" --args=is_debug=true ) ELSE ( gn gen \"out\\${input:buildType}\" --args=is_debug=false )) && (IF EXIST \"out\\active\" rmdir \"out\\active\" /q /s) && (mklink /j \"out\\active\" \"out\\${input:buildType}\")",
@@ -109,13 +97,85 @@
                 "options": {
                     "shell": {
                         "executable": "cmd"
-                    }
-                },
+                    },
+                }
+            },
+            "options": {
+                "cwd": "${workspaceRoot}"
             },
             "problemMatcher": [],
         },
         {
-            "label": "Push branch for review",
+            "label": "cmake gen",
+            "type": "shell",
+            "linux": {
+                "command": "./tools/setup-build",
+                "args": [
+                    "cmake",
+                    "${input:buildType}",
+                ],
+            },
+            "osx": {
+                "command": "./tools/setup-build",
+                "args": [
+                    "cmake",
+                    "${input:buildType}",
+                ],
+            },
+            "windows": {
+                "command": "/C",
+                "args": [
+                    "echo TODO",
+                ],
+                "options": {
+                    "shell": {
+                        "executable": "cmd"
+                    },
+                }
+            },
+            "options": {
+                "cwd": "${workspaceRoot}"
+            },
+            "problemMatcher": [],
+        },
+        // Rebases the current branch on to origin/main and then calls
+        // `gclient sync`.
+        {
+            "label": "sync",
+            "type": "shell",
+            "linux": {
+                "command": "sh",
+                "args": [
+                    "-c",
+                    "git fetch origin && git rebase origin/main && gclient sync && echo Done"
+                ],
+            },
+            "osx": {
+                "command": "sh",
+                "args": [
+                    "-c",
+                    "git fetch origin && git rebase origin/main && gclient sync && echo Done"
+                ],
+            },
+            "windows": {
+                "command": "/C",
+                "args": [
+                    "git fetch origin && git rebase origin/main && gclient sync && echo Done",
+                ],
+                "options": {
+                    "shell": {
+                        "executable": "cmd"
+                    },
+                }
+            },
+            "options": {
+                "cwd": "${workspaceRoot}"
+            },
+            "problemMatcher": [],
+        },
+        // Pushes the changes at HEAD to gerrit for review
+        {
+            "label": "push",
             "type": "shell",
             "command": "git",
             "args": [
@@ -136,11 +196,9 @@
             "options": [
                 "Debug",
                 "Release",
-                "MinSizeRel",
-                "RelWithDebInfo",
             ],
             "default": "Debug",
             "description": "The type of build",
         },
     ]
-}
\ No newline at end of file
+}
diff --git a/tools/setup-build b/tools/setup-build
new file mode 100755
index 0000000..76ec76c
--- /dev/null
+++ b/tools/setup-build
@@ -0,0 +1,82 @@
+#!/usr/bin/env bash
+# Copyright 2022 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.
+
+set -e # Fail on any error.
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )"
+ROOT_DIR="$( cd "${SCRIPT_DIR}/.." >/dev/null 2>&1 && pwd )"
+BUILD_SYSTEM=$(echo "$1" | tr '[:upper:]' '[:lower:]') # lowercase
+BUILD_TYPE=$(echo "$2" | tr '[:upper:]' '[:lower:]') # lowercase
+BUILD_DIR="${BUILD_SYSTEM}-${BUILD_TYPE}"
+
+function show_usage() {
+  echo "setup-build [gn|cmake] [debug|release]"
+  echo
+  echo "creates a build directory in <dawn>/out using either GN or CMake, then"
+  echo "updates the '<dawn>/out/active' symlink to point to the build directory"
+  exit 1
+}
+
+function generate() {
+  CMD=$1
+  pushd "$ROOT_DIR" > /dev/null
+    mkdir -p "out/$BUILD_DIR"
+    rm -fr "out/active" || true
+    ln -s "$BUILD_DIR" "out/active"
+    ${CMD}
+  popd > /dev/null
+}
+
+case $BUILD_SYSTEM in
+  "gn")
+    case $BUILD_TYPE in
+      "debug")
+        generate "gn gen out/active --args=is_debug=true"
+      ;;
+      "release")
+        generate "gn gen out/active --args=is_debug=false"
+      ;;
+      *)
+        echo "invalid build type '${BUILD_TYPE}'"
+        show_usage
+      ;;
+    esac
+  ;;
+  "cmake")
+    CMAKE_FLAGS=""
+    if [[ -x $(command -v ccache) ]]; then
+      CMAKE_FLAGS+="-DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
+    fi
+    case $BUILD_TYPE in
+      "debug")
+        generate "cmake -S . -B out/active -GNinja -DCMAKE_BUILD_TYPE=Debug ${CMAKE_FLAGS}"
+      ;;
+      "release")
+        generate "cmake -S . -B out/active -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo ${CMAKE_FLAGS}"
+      ;;
+      *)
+        echo "invalid build type '${BUILD_TYPE}'"
+        show_usage
+      ;;
+    esac
+  ;;
+  "--help" | "-help" | "-h")
+    show_usage
+  ;;
+  *)
+    echo "invalid build system '${BUILD_SYSTEM}'"
+    show_usage
+  ;;
+esac