[emscripten] Remove DAWN_EMSCRIPTEN_TOOLCHAIN, simplify conditions

Now that emsdk ships Emscripten with gen_struct_info.py, we don't need
DAWN_EMSCRIPTEN_TOOLCHAIN anymore, and can point directly at the
EMSCRIPTEN_ROOT_PATH set by the toolchain (via emcmake).

Updated docs, including how to set dawn_emscripten_dir in gn.

Also remove ENABLE_EMSCRIPTEN and DAWN_ENABLE_EMSCRIPTEN variables in
favor of the toolchain-builtin EMSCRIPTEN, so there's no risk of them
getting out of sync.

Bug: 371024051
Change-Id: Ibf6d6252046b52643f6e09dadb95e659f4a3665e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/227335
Reviewed-by: Loko Kung <lokokung@google.com>
Auto-Submit: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0e686a5..b46b682 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -60,6 +60,9 @@
 set(DAWN_INCLUDE_DIR "${Dawn_SOURCE_DIR}/include" CACHE PATH "Directory that contains public headers for dawn")
 set(DAWN_TEMPLATE_DIR "${DAWN_GENERATOR_DIR}/templates" CACHE PATH "Directory that contains templates for generators")
 
+# Emscripten.cmake toolchain sets this variable to `0`; otherwise, it's undefined, so set it to 1.
+set_if_not_defined(EMSCRIPTEN 0 "1 if building with Emscripten")
+
 ################################################################################
 # Configuration options
 ################################################################################
@@ -71,7 +74,6 @@
 set(ENABLE_OPENGLES OFF)
 set(ENABLE_DESKTOP_GL OFF)
 set(ENABLE_VULKAN OFF)
-set(ENABLE_EMSCRIPTEN OFF)
 set(ENABLE_SPIRV_VALIDATION OFF)
 set(USE_WAYLAND OFF)
 set(USE_X11 OFF)
@@ -79,10 +81,9 @@
 set(BUILD_SAMPLES OFF)
 set(BUILD_TESTS OFF)
 set(TARGET_MACOS OFF)
-if (CMAKE_SYSTEM_NAME MATCHES "Emscripten")
+if (EMSCRIPTEN)
   # Only the samples are supported for Emscripten at the moment.
   # TODO(crbug.com/42240181): Make dawn_end2end_tests work too.
-  set(ENABLE_EMSCRIPTEN ON)
   set(BUILD_SAMPLES ON)
   set(BUILD_TESTS ON)
   set(ENABLE_NULL OFF)
@@ -117,7 +118,7 @@
 
 # GLFW is not supported in UWP
 set(DAWN_SUPPORTS_GLFW_FOR_WINDOWING OFF)
-if (NOT ENABLE_EMSCRIPTEN AND ((WIN32 AND NOT WINDOWS_STORE) OR (UNIX AND NOT ANDROID)))
+if (NOT EMSCRIPTEN AND ((WIN32 AND NOT WINDOWS_STORE) OR (UNIX AND NOT ANDROID)))
     set(DAWN_SUPPORTS_GLFW_FOR_WINDOWING ON)
 endif()
 
@@ -141,20 +142,13 @@
 option(DAWN_ENABLE_VULKAN "Enable compilation of the Vulkan backend" ${ENABLE_VULKAN})
 option(DAWN_ENABLE_SPIRV_VALIDATION "Enable validation of SPIR-V" ${ENABLE_SPIRV_VALIDATION})
 
-# Optional path to Emscripten toolchain to allow for building WASM.
-option(DAWN_EMSCRIPTEN_TOOLCHAIN "Directory in which to find Emscripten toolchain" "")
-set(DAWN_ENABLE_EMSCRIPTEN OFF)
-if (NOT ${DAWN_EMSCRIPTEN_TOOLCHAIN} STREQUAL "" AND ENABLE_EMSCRIPTEN)
-    set(DAWN_ENABLE_EMSCRIPTEN ON)
-endif()
-
+message(STATUS "Dawn building using Emscripten toolchain: ${EMSCRIPTEN}")
 message(STATUS "Dawn build D3D11 backend: ${DAWN_ENABLE_D3D11}")
 message(STATUS "Dawn build D3D12 backend: ${DAWN_ENABLE_D3D12}")
 message(STATUS "Dawn build Metal backend: ${DAWN_ENABLE_METAL}")
 message(STATUS "Dawn build Vulkan backend: ${DAWN_ENABLE_VULKAN}")
 message(STATUS "Dawn build OpenGL backend: ${DAWN_ENABLE_DESKTOP_GL}")
 message(STATUS "Dawn build OpenGL ES backend: ${DAWN_ENABLE_OPENGLES}")
-message(STATUS "Dawn build Emscripten: ${DAWN_ENABLE_EMSCRIPTEN}")
 message(STATUS "Dawn build Null backend: ${DAWN_ENABLE_NULL}")
 message(STATUS "")
 message(STATUS "Dawn enable SPIR-V validation: ${DAWN_ENABLE_SPIRV_VALIDATION}")
@@ -220,7 +214,7 @@
 option(TINT_BUILD_CMD_TOOLS "Build the Tint command line tools" ON)
 
 if (DAWN_BUILD_SAMPLES)
-  if (NOT DAWN_USE_GLFW AND NOT DAWN_ENABLE_EMSCRIPTEN)
+  if (NOT DAWN_USE_GLFW AND NOT EMSCRIPTEN)
     message(SEND_ERROR "Dawn samples require GLFW or Emscripten")
   endif()
 endif()
@@ -248,7 +242,7 @@
 option(TINT_BUILD_TESTS "Build tests" ON)
 option(TINT_BUILD_AS_OTHER_OS "Override OS detection to force building of *_other.cc files" OFF)
 
-if (DAWN_ENABLE_EMSCRIPTEN)
+if (EMSCRIPTEN)
   # Skip tint tests in emscripten build
   set(TINT_BUILD_TESTS OFF)
   # Skip GLSL validation in Emscripten
@@ -339,16 +333,6 @@
 message(STATUS "Dawn build monolithic library: ${DAWN_BUILD_MONOLITHIC_LIBRARY}")
 message(STATUS "")
 
-# Optional path to Emscripten toolchain to allow for building WASM.
-set_if_not_defined(DAWN_EMSCRIPTEN_TOOLCHAIN "" "Directory in which to find Emscripten toolchain")
-set(DAWN_ENABLE_EMSCRIPTEN OFF)
-if (NOT ${DAWN_EMSCRIPTEN_TOOLCHAIN} STREQUAL "" AND ENABLE_EMSCRIPTEN)
-    set(DAWN_ENABLE_EMSCRIPTEN ON)
-endif()
-
-message(STATUS "Dawn Emscripten toolchain: ${DAWN_EMSCRIPTEN_TOOLCHAIN}")
-message(STATUS "")
-
 # Much of the backend code is shared among desktop OpenGL and OpenGL ES
 if (${DAWN_ENABLE_DESKTOP_GL} OR ${DAWN_ENABLE_OPENGLES})
     set(DAWN_ENABLE_OPENGL ON)
@@ -476,7 +460,7 @@
 
 set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_SAVED})
 
-if (DAWN_ENABLE_D3D11 OR DAWN_ENABLE_D3D12 OR DAWN_ENABLE_METAL OR DAWN_ENABLE_NULL OR DAWN_ENABLE_DESKTOP_GL OR DAWN_ENABLE_OPENGLES OR DAWN_ENABLE_VULKAN OR DAWN_ENABLE_EMSCRIPTEN)
+if (DAWN_ENABLE_D3D11 OR DAWN_ENABLE_D3D12 OR DAWN_ENABLE_METAL OR DAWN_ENABLE_NULL OR DAWN_ENABLE_DESKTOP_GL OR DAWN_ENABLE_OPENGLES OR DAWN_ENABLE_VULKAN OR EMSCRIPTEN)
     add_subdirectory(generator)
     # Note that we must add Emscripten directory first to ensure the correct
     # headers will be exported upwards.
diff --git a/src/cmake/DawnLibrary.cmake b/src/cmake/DawnLibrary.cmake
index 6793d19..2e7b63b 100644
--- a/src/cmake/DawnLibrary.cmake
+++ b/src/cmake/DawnLibrary.cmake
@@ -75,7 +75,7 @@
   endif ()
 
   # Skip targets that shouldn't be built with Emscripten.
-  if (NOT arg_ENABLE_EMSCRIPTEN AND ${DAWN_ENABLE_EMSCRIPTEN})
+  if (EMSCRIPTEN AND NOT arg_ENABLE_EMSCRIPTEN)
     return()
   endif ()
 
diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt
index 38ec75e..316414a 100644
--- a/src/dawn/CMakeLists.txt
+++ b/src/dawn/CMakeLists.txt
@@ -46,7 +46,7 @@
         dawn_public_config
 )
 
-if (${DAWN_ENABLE_EMSCRIPTEN})
+if (EMSCRIPTEN)
   add_library(webgpu_c ALIAS emdawnwebgpu_c)
 else()
   add_library(webgpu_c ALIAS dawn_headers)
@@ -73,7 +73,7 @@
         dawn::dawn_headers
 )
 
-if (${DAWN_ENABLE_EMSCRIPTEN})
+if (EMSCRIPTEN)
   add_library(webgpu_cpp ALIAS emdawnwebgpu_cpp)
 else()
   add_library(dawncpp ALIAS dawncpp_headers)
@@ -88,7 +88,7 @@
 add_subdirectory(common)
 add_subdirectory(utils)
 # Only build the rest of Dawn when Emscripten is not the target environment.
-if (NOT ${DAWN_ENABLE_EMSCRIPTEN})
+if (NOT EMSCRIPTEN)
   add_subdirectory(platform)
   add_subdirectory(wire)
   add_subdirectory(native)
@@ -112,7 +112,7 @@
 #   Only built when not building for Emscripten
 ###############################################################################
 
-if (NOT ${DAWN_ENABLE_EMSCRIPTEN})
+if (NOT EMSCRIPTEN)
   DawnJSONGenerator(
       TARGET "proc"
       PRINT_NAME "Dawn C++ wrapper"
diff --git a/src/dawn/samples/CMakeLists.txt b/src/dawn/samples/CMakeLists.txt
index ff4d9d9..41c4ef5 100644
--- a/src/dawn/samples/CMakeLists.txt
+++ b/src/dawn/samples/CMakeLists.txt
@@ -35,7 +35,7 @@
     dawn::dawn_system_utils
     dawn::dawn_wgpu_utils
 )
-if (NOT ${DAWN_ENABLE_EMSCRIPTEN})
+if (NOT EMSCRIPTEN)
     list(APPEND sample_util_depends
         dawn::dawn_test_utils
         dawn::dawn_proc
@@ -70,12 +70,12 @@
     )
 
     # Skip targets that shouldn't be built with Emscripten.
-    if (NOT arg_ENABLE_EMSCRIPTEN AND ${DAWN_ENABLE_EMSCRIPTEN})
+    if (EMSCRIPTEN AND NOT arg_ENABLE_EMSCRIPTEN)
         return()
     endif ()
 
     add_executable(${arg_NAME} ${arg_SOURCES})
-    if (${DAWN_ENABLE_EMSCRIPTEN})
+    if (EMSCRIPTEN)
         set_target_properties(${arg_NAME} PROPERTIES
             SUFFIX ".html")
         target_link_options(${arg_NAME} PUBLIC
@@ -113,4 +113,4 @@
 Sample(
     NAME ManualSurfaceTest
     SOURCES "ManualSurfaceTest.cpp"
-)
\ No newline at end of file
+)
diff --git a/src/emdawnwebgpu/CMakeLists.txt b/src/emdawnwebgpu/CMakeLists.txt
index 7912947..0168d56 100644
--- a/src/emdawnwebgpu/CMakeLists.txt
+++ b/src/emdawnwebgpu/CMakeLists.txt
@@ -61,7 +61,7 @@
 # - library_webgpu_enum_tables.js
 # - library_webgpu_generated_sig_info.js
 #   which we generate directly instead of using "gen_sig_info.py"
-if (${DAWN_ENABLE_EMSCRIPTEN})
+if (EMSCRIPTEN)
     set(EM_SRC_DIR "${DAWN_SRC_DIR}/emdawnwebgpu")
     set(EM_BUILD_GEN_DIR "${DAWN_BUILD_GEN_DIR}/src/emdawnwebgpu")
 
@@ -81,7 +81,7 @@
         # at tools/maint/gen_struct_info.py).
         set(ARGS
             ${Python3_EXECUTABLE}
-            "${DAWN_EMSCRIPTEN_TOOLCHAIN}/tools/gen_struct_info.py"
+            "${EMSCRIPTEN_ROOT_PATH}/tools/gen_struct_info.py"
             -q
             "${EM_BUILD_GEN_DIR}/struct_info_webgpu.json"
             "-I=${EM_BUILD_GEN_DIR}/include"
@@ -203,7 +203,7 @@
         "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_generated_struct_info.js"
         "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_generated_sig_info.js"
         "--js-library=${DAWN_EMDAWNWEBGPU_DIR}/library_webgpu.js"
-        "--closure-args=--externs=${DAWN_EMSCRIPTEN_TOOLCHAIN}/src/closure-externs/webgpu-externs.js"
+        "--closure-args=--externs=${EMSCRIPTEN_ROOT_PATH}/src/closure-externs/webgpu-externs.js"
     )
     # Relink when library_webgpu.js file changes.
     set_target_properties(emdawnwebgpu_config PROPERTIES
diff --git a/src/emdawnwebgpu/README.md b/src/emdawnwebgpu/README.md
index efd6491..fe7dcb4 100644
--- a/src/emdawnwebgpu/README.md
+++ b/src/emdawnwebgpu/README.md
@@ -1,66 +1,71 @@
-# Dawn Emscripten Fork
+# "emdawnwebgpu" (Dawn's fork of Emscripten's WebGPU bindings)
 
-Dawn temporarily maintains a fork of the Emscripten WebGPU bindings
+"emdawnwebgpu" is Dawn's fork of the Emscripten WebGPU bindings
 (`library_webgpu.js` and friends). The forked files live in
 [`//third_party/emdawnwebgpu`](../third_party/emdawnwebgpu/)
 and the build targets in this directory produce the other files needed to build
 an Emscripten-based project using these bindings.
 
-This allows the the webgpu.h interface to be kept roughly in sync\* between the
-two implementations in a single place (the Dawn repository) instead of two,
-while also avoiding constantly breaking the version of webgpu.h that is
-currently in Emscripten. (\* Note we don't guarantee it will always be in sync,
-though - we don't have any automated testing for this, so we'll periodically fix
-it up as needed for import into other projects that use these bindings.)
+We keep the `webgpu.h` interface roughly in sync between Dawn and emdawnwebgpu,
+however we don't guarantee it will always be in sync - we don't have any
+automated testing for this, so we'll periodically fix
+it up as needed for import into other projects that use these bindings.
 
-Changes to this code in the Dawn repository will be synced back out to the
-upstream Emscripten repository after webgpu.h becomes stable, in what should
-theoretically be one big final breaking update. Between then and now, projects
-can use Dawn's fork of the bindings.
+Projects should use this fork (by compiling Dawn as instructed below) if they
+want the latest version, which is mostly compatible with the same version of Dawn
+Native. For the future of this fork, please see <https://crbug.com/371024051>.
 
 ## Setting up Emscripten
 
-- Get an emsdk toolchain:
+- Get an emsdk toolchain (at least Emscripten 4.0.3, which includes the necessary tools in the
+  package release). There are two options to do this:
+  - Set the `dawn_wasm` gclient variable (use
+    [`standalone-with-wasm.gclient`](../../scripts/standalone-with-wasm.gclient)
+    as your `.gclient`), and `gclient sync`. This installs emsdk in `//third_party/emsdk`.
+
+  - Install it manually following the official
   [instructions](https://emscripten.org/docs/getting_started/downloads.html#installation-instructions-using-the-emsdk-recommended).
 
-- Get a separate source checkout of [Emscripten](https://github.com/emscripten-core/emscripten)
-  and set it up to point at the toolchain from emsdk by creating a file at `emscripten/.emscripten`:
+## Building the bindings
 
-  ```
-  LLVM_ROOT = '/path/to/emsdk/upstream/bin'
-  BINARYEN_ROOT = '/path/to/emsdk/upstream'
-  NODE_JS = '/path/to/emsdk/node/18.20.3_64bit/bin/node'
-  ```
+First, get the Dawn code and its dependencies.
+See [building.md](../../docs/building.md).
 
-  Note this must be a source checkout of Emscripten,
-  not emsdk's `upstream/emscripten` release, which excludes necessary tools.
+You can either build the bindings "standalone" and link them manually,
+or if your project uses CMake you can link to it as a CMake subproject.
 
+### Using Dawn as a CMake subproject (bindings only)
 
-- Make sure you run the `./bootstrap` in the `emscripten` folder to make sure node is setup.
+TODO(crbug.com/371024051): Provide a sample!
 
-## Building Dawn Emscripten bindings with GN
+### Using pre-built emdawnwebgpu bindings via CMake (bindings only)
 
-- Set up a Dawn GN build, with `dawn_emscripten_dir` in the GN args set to point to
-  your Emscripten source checkout.
+TODO(crbug.com/371024051): Make pre-built bindings and provide a sample!
 
-- Build the `emdawnwebgpu` GN build target.
+### Standalone with CMake (bindings and samples)
 
-- Configure the Emscripten build with all of the linker flags listed in `emdawnwebgpu_config`
-  (and without `-sUSE_WEBGPU`, because we don't want the built-in bindings).
-
-## Building Dawn Emscripten bindings and samples with CMake
-
-Set up the build directory using emcmake
+Set up the build directory using emcmake:
 
 ```
 mkdir out/cmake-wasm
 cd out/cmake-wasm
 
-# Make sure the path is to the source checkout of Emscripten, not emsdk's release.
-emcmake cmake -GNinja -DDAWN_EMSCRIPTEN_TOOLCHAIN="path/to/emscripten" ../..
+path/to/emsdk/upstream/emscripten/emcmake cmake ../..
 
-ninja
-
-# The resulting html files can then be served and viewed in a compatible Browser.
-
+make -j8
 ```
+
+(To use Ninja instead of Make, for better parallelism, add `-GNinja` to the
+`cmake` invocation, and build using `ninja`.)
+
+The resulting html files can then be served and viewed in a compatible browser.
+
+### Standalone with GN (bindings only)
+
+- Set up a Dawn GN build, with `dawn_emscripten_dir` in the GN args set to point to
+  `emsdk/upstream/emscripten`.
+
+- Build the `emdawnwebgpu` GN build target.
+
+- Configure the Emscripten build with all of the linker flags listed in `emdawnwebgpu_config`
+  (and without Emscripten's `-sUSE_WEBGPU` setting, because we don't want the built-in bindings).
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index 1ffa3d8..cdfde38 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -72,7 +72,7 @@
 
 if ((DAWN_BUILD_TESTS OR TINT_BUILD_TESTS) AND NOT TARGET gmock)
     set(gtest_force_shared_crt ON CACHE BOOL "Controls whether a shared run-time library should be used even when Google Test is built as static library" FORCE)
-    if (${DAWN_ENABLE_EMSCRIPTEN})
+    if (EMSCRIPTEN)
         # For Emscripten builds, we need to disable pthreads.
         set(gtest_disable_pthreads ON)
     endif()
@@ -89,7 +89,7 @@
 ################################################################################
 # End of Emscripten enabled third party directories
 ################################################################################
-if (${DAWN_ENABLE_EMSCRIPTEN})
+if (EMSCRIPTEN)
     return()
 endif()
 
diff --git a/third_party/emdawnwebgpu/README.md b/third_party/emdawnwebgpu/README.md
index ad23eaa..2b8dc23 100644
--- a/third_party/emdawnwebgpu/README.md
+++ b/third_party/emdawnwebgpu/README.md
@@ -1,4 +1,3 @@
-The source files in this directory are copied out of Emscripten, and will be
-contributed back upstream after webgpu.h becomes stable.
+The source files in this directory were originally developed in Emscripten.
 See [`//src/emdawnwebgpu/README.md`](../../src/emdawnwebgpu/README.md)
 for details.