From 757ad7998a036cd3dead11b71defa3d7b9aa6a66 Mon Sep 17 00:00:00 2001
From: kon72 <kinsei0916@gmail.com>
Date: Mon, 15 Jan 2024 18:52:34 +0900
Subject: [PATCH 1/2] [bazel] Use hermetic Python

---
 bazel/deps.bzl                             | 7 +++++++
 bazel/emscripten_deps.bzl                  | 9 +++++++++
 bazel/emscripten_toolchain/BUILD.bazel     | 2 ++
 bazel/emscripten_toolchain/emar.bat        | 2 +-
 bazel/emscripten_toolchain/emar.sh         | 2 +-
 bazel/emscripten_toolchain/emcc.bat        | 2 +-
 bazel/emscripten_toolchain/emcc.sh         | 2 +-
 bazel/emscripten_toolchain/emcc_link.bat   | 2 +-
 bazel/emscripten_toolchain/emcc_link.sh    | 2 +-
 bazel/emscripten_toolchain/env.bat         | 1 +
 bazel/emscripten_toolchain/env.sh          | 1 +
 bazel/emscripten_toolchain/link_wrapper.py | 1 -
 bazel/emscripten_toolchain/toolchain.bzl   | 5 +++++
 13 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/bazel/deps.bzl b/bazel/deps.bzl
index 337f0bafcd..11782e9c3c 100644
--- a/bazel/deps.bzl
+++ b/bazel/deps.bzl
@@ -23,3 +23,10 @@ def deps():
         sha256 = "dcc55f810142b6cf46a44d0180a5a7fb923c04a5061e2e8d8eb05ccccc60864b",
         urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.8.0/rules_nodejs-5.8.0.tar.gz"],
     )
+    maybe(
+        http_archive,
+        name = "rules_python",
+        sha256 = "d70cd72a7a4880f0000a6346253414825c19cdd40a28289bdf67b8e6480edff8",
+        strip_prefix = "rules_python-0.28.0",
+        url = "https://github.com/bazelbuild/rules_python/releases/download/0.28.0/rules_python-0.28.0.tar.gz",
+    )
diff --git a/bazel/emscripten_deps.bzl b/bazel/emscripten_deps.bzl
index 6d369453ca..348fc1dbb3 100644
--- a/bazel/emscripten_deps.bzl
+++ b/bazel/emscripten_deps.bzl
@@ -1,5 +1,6 @@
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories", "npm_install")
+load("@rules_python//python:repositories.bzl", "py_repositories", "python_register_toolchains")
 load(":revisions.bzl", "EMSCRIPTEN_TAGS")
 
 def _parse_version(v):
@@ -206,3 +207,11 @@ def emscripten_deps(emscripten_version = "latest"):
             package_json = "@emscripten_bin_win//:emscripten/package.json",
             package_lock_json = "@emscripten_bin_win//:emscripten/package-lock.json",
         )
+
+    if "python_toolchains" not in excludes:
+        py_repositories()
+        python_register_toolchains(
+            name = "python_3_11",
+            # Available versions are listed in @rules_python//python:versions.bzl.
+            python_version = "3.11",
+        )
diff --git a/bazel/emscripten_toolchain/BUILD.bazel b/bazel/emscripten_toolchain/BUILD.bazel
index fb8a6c1b2e..455e48dcf0 100644
--- a/bazel/emscripten_toolchain/BUILD.bazel
+++ b/bazel/emscripten_toolchain/BUILD.bazel
@@ -1,3 +1,4 @@
+load("@python_3_11//:defs.bzl", "py_binary")
 load(":toolchain.bzl", "emscripten_cc_toolchain_config_rule")
 
 package(default_visibility = ["//visibility:public"])
@@ -9,6 +10,7 @@ filegroup(
         "env.sh",
         "env.bat",
         "@nodejs//:node_files",
+        "@python_3_11//:python3",
     ],
 )
 
diff --git a/bazel/emscripten_toolchain/emar.bat b/bazel/emscripten_toolchain/emar.bat
index b8e9125862..844c378370 100644
--- a/bazel/emscripten_toolchain/emar.bat
+++ b/bazel/emscripten_toolchain/emar.bat
@@ -2,4 +2,4 @@
 
 call external\emsdk\emscripten_toolchain\env.bat
 
-py -3 %EMSCRIPTEN%\emar.py %*
+%EMSDK_PYTHON% %EMSCRIPTEN%\emar.py %*
diff --git a/bazel/emscripten_toolchain/emar.sh b/bazel/emscripten_toolchain/emar.sh
index b4ead6ef9b..7748cc7021 100755
--- a/bazel/emscripten_toolchain/emar.sh
+++ b/bazel/emscripten_toolchain/emar.sh
@@ -2,4 +2,4 @@
 
 source $(dirname $0)/env.sh
 
-exec python3 $EMSCRIPTEN/emar.py "$@"
+exec $EMSDK_PYTHON $EMSCRIPTEN/emar.py "$@"
diff --git a/bazel/emscripten_toolchain/emcc.bat b/bazel/emscripten_toolchain/emcc.bat
index aba66f45d2..b302736180 100644
--- a/bazel/emscripten_toolchain/emcc.bat
+++ b/bazel/emscripten_toolchain/emcc.bat
@@ -2,4 +2,4 @@
 
 call external\emsdk\emscripten_toolchain\env.bat
 
-py -3 %EMSCRIPTEN%\emcc.py %*
+%EMSDK_PYTHON% %EMSCRIPTEN%\emcc.py %*
diff --git a/bazel/emscripten_toolchain/emcc.sh b/bazel/emscripten_toolchain/emcc.sh
index 5fdaf9c295..3fd72da55b 100755
--- a/bazel/emscripten_toolchain/emcc.sh
+++ b/bazel/emscripten_toolchain/emcc.sh
@@ -2,4 +2,4 @@
 
 source $(dirname $0)/env.sh
 
-exec python3 $EMSCRIPTEN/emcc.py "$@"
+exec $EMSDK_PYTHON $EMSCRIPTEN/emcc.py "$@"
diff --git a/bazel/emscripten_toolchain/emcc_link.bat b/bazel/emscripten_toolchain/emcc_link.bat
index 8e5a6eb1a9..fef6501ef9 100644
--- a/bazel/emscripten_toolchain/emcc_link.bat
+++ b/bazel/emscripten_toolchain/emcc_link.bat
@@ -2,4 +2,4 @@
 
 call external\emsdk\emscripten_toolchain\env.bat
 
-py -3 external\emsdk\emscripten_toolchain\link_wrapper.py %*
+%EMSDK_PYTHON% external\emsdk\emscripten_toolchain\link_wrapper.py %*
diff --git a/bazel/emscripten_toolchain/emcc_link.sh b/bazel/emscripten_toolchain/emcc_link.sh
index 44f32353ba..e538915bcd 100755
--- a/bazel/emscripten_toolchain/emcc_link.sh
+++ b/bazel/emscripten_toolchain/emcc_link.sh
@@ -2,4 +2,4 @@
 
 source $(dirname $0)/env.sh
 
-exec python3 $(dirname $0)/link_wrapper.py "$@"
+exec $EMSDK_PYTHON $(dirname $0)/link_wrapper.py "$@"
diff --git a/bazel/emscripten_toolchain/env.bat b/bazel/emscripten_toolchain/env.bat
index 644519ebf0..a13d66afcc 100644
--- a/bazel/emscripten_toolchain/env.bat
+++ b/bazel/emscripten_toolchain/env.bat
@@ -3,3 +3,4 @@
 set ROOT_DIR=%CD%
 set EMSCRIPTEN=%ROOT_DIR%\%EM_BIN_PATH%\emscripten
 set EM_CONFIG=%ROOT_DIR%\%EM_CONFIG_PATH%
+set EMSDK_PYTHON=%ROOT_DIR%\%EM_PYTHON_PATH%
diff --git a/bazel/emscripten_toolchain/env.sh b/bazel/emscripten_toolchain/env.sh
index b2a6bd60b0..ccdfe45a4a 100755
--- a/bazel/emscripten_toolchain/env.sh
+++ b/bazel/emscripten_toolchain/env.sh
@@ -3,3 +3,4 @@
 export ROOT_DIR=${EXT_BUILD_ROOT:-$(pwd -P)}
 export EMSCRIPTEN=$ROOT_DIR/$EM_BIN_PATH/emscripten
 export EM_CONFIG=$ROOT_DIR/$EM_CONFIG_PATH
+export EMSDK_PYTHON=$ROOT_DIR/$EM_PYTHON_PATH
diff --git a/bazel/emscripten_toolchain/link_wrapper.py b/bazel/emscripten_toolchain/link_wrapper.py
index ca6ca48fd8..78bc08ab01 100644
--- a/bazel/emscripten_toolchain/link_wrapper.py
+++ b/bazel/emscripten_toolchain/link_wrapper.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 """wrapper around emcc link step.
 
 This wrapper currently serves the following purposes.
diff --git a/bazel/emscripten_toolchain/toolchain.bzl b/bazel/emscripten_toolchain/toolchain.bzl
index e92a61257f..3ffaf6e53c 100644
--- a/bazel/emscripten_toolchain/toolchain.bzl
+++ b/bazel/emscripten_toolchain/toolchain.bzl
@@ -1040,6 +1040,10 @@ def _impl(ctx):
                     key = "EM_CONFIG_PATH",
                     value = ctx.file.em_config.path,
                 ),
+                env_entry(
+                    key = "EM_PYTHON_PATH",
+                    value = ctx.file._python_interpreter.path,
+                ),
             ],
         ),
         # Use llvm backend.  Off by default, enabled via --features=llvm_backend
@@ -1115,6 +1119,7 @@ emscripten_cc_toolchain_config_rule = rule(
         "em_config": attr.label(mandatory = True, allow_single_file = True),
         "emscripten_binaries": attr.label(mandatory = True, cfg = "exec"),
         "script_extension": attr.string(mandatory = True, values = ["sh", "bat"]),
+        "_python_interpreter": attr.label(allow_single_file = True, cfg = "exec", default = Label("@python_3_11//:python3")),
     },
     provides = [CcToolchainConfigInfo],
 )

From 2699e9157dc78f4386e49692ab4dbe23a58c7984 Mon Sep 17 00:00:00 2001
From: kon72 <kinsei0916@gmail.com>
Date: Sun, 21 Jan 2024 14:17:11 +0900
Subject: [PATCH 2/2] Set EMSDK_PYTHON directly

---
 bazel/emscripten_toolchain/BUILD.bazel   |  6 +++---
 bazel/emscripten_toolchain/env.bat       |  1 -
 bazel/emscripten_toolchain/env.sh        |  1 -
 bazel/emscripten_toolchain/toolchain.bzl | 18 ++++++++++++------
 4 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/bazel/emscripten_toolchain/BUILD.bazel b/bazel/emscripten_toolchain/BUILD.bazel
index 455e48dcf0..772c91825d 100644
--- a/bazel/emscripten_toolchain/BUILD.bazel
+++ b/bazel/emscripten_toolchain/BUILD.bazel
@@ -64,9 +64,9 @@ emscripten_cc_toolchain_config_rule(
     cpu = "wasm",
     em_config = "emscripten_config",
     emscripten_binaries = "@emsdk//:compiler_files",
-    script_extension = select({
-        "@bazel_tools//src/conditions:host_windows": "bat",
-        "//conditions:default": "sh",
+    is_windows = select({
+        "@bazel_tools//src/conditions:host_windows": True,
+        "//conditions:default": False,
     }),
 )
 
diff --git a/bazel/emscripten_toolchain/env.bat b/bazel/emscripten_toolchain/env.bat
index a13d66afcc..644519ebf0 100644
--- a/bazel/emscripten_toolchain/env.bat
+++ b/bazel/emscripten_toolchain/env.bat
@@ -3,4 +3,3 @@
 set ROOT_DIR=%CD%
 set EMSCRIPTEN=%ROOT_DIR%\%EM_BIN_PATH%\emscripten
 set EM_CONFIG=%ROOT_DIR%\%EM_CONFIG_PATH%
-set EMSDK_PYTHON=%ROOT_DIR%\%EM_PYTHON_PATH%
diff --git a/bazel/emscripten_toolchain/env.sh b/bazel/emscripten_toolchain/env.sh
index ccdfe45a4a..b2a6bd60b0 100755
--- a/bazel/emscripten_toolchain/env.sh
+++ b/bazel/emscripten_toolchain/env.sh
@@ -3,4 +3,3 @@
 export ROOT_DIR=${EXT_BUILD_ROOT:-$(pwd -P)}
 export EMSCRIPTEN=$ROOT_DIR/$EM_BIN_PATH/emscripten
 export EM_CONFIG=$ROOT_DIR/$EM_CONFIG_PATH
-export EMSDK_PYTHON=$ROOT_DIR/$EM_PYTHON_PATH
diff --git a/bazel/emscripten_toolchain/toolchain.bzl b/bazel/emscripten_toolchain/toolchain.bzl
index 3ffaf6e53c..5b03f301d1 100644
--- a/bazel/emscripten_toolchain/toolchain.bzl
+++ b/bazel/emscripten_toolchain/toolchain.bzl
@@ -54,6 +54,11 @@ CROSSTOOL_DEFAULT_WARNINGS = [
     "-Wall",
 ]
 
+def _os_path(ctx, path):
+    if ctx.attr.is_windows:
+        path = path.replace("/", "\\")
+    return path
+
 def _impl(ctx):
     target_cpu = ctx.attr.cpu
     toolchain_identifier = "emscripten-" + target_cpu
@@ -74,9 +79,10 @@ def _impl(ctx):
 
     builtin_sysroot = emscripten_dir + "/emscripten/cache/sysroot"
 
-    emcc_script = "emcc.%s" % ctx.attr.script_extension
-    emcc_link_script = "emcc_link.%s" % ctx.attr.script_extension
-    emar_script = "emar.%s" % ctx.attr.script_extension
+    script_extension = "bat" if ctx.attr.is_windows else "sh"
+    emcc_script = "emcc.%s" % script_extension
+    emcc_link_script = "emcc_link.%s" % script_extension
+    emar_script = "emar.%s" % script_extension
 
     ################################################################
     # Tools
@@ -1041,8 +1047,8 @@ def _impl(ctx):
                     value = ctx.file.em_config.path,
                 ),
                 env_entry(
-                    key = "EM_PYTHON_PATH",
-                    value = ctx.file._python_interpreter.path,
+                    key = "EMSDK_PYTHON",
+                    value = _os_path(ctx, ctx.file._python_interpreter.path),
                 ),
             ],
         ),
@@ -1118,7 +1124,7 @@ emscripten_cc_toolchain_config_rule = rule(
         "cpu": attr.string(mandatory = True, values = ["asmjs", "wasm"]),
         "em_config": attr.label(mandatory = True, allow_single_file = True),
         "emscripten_binaries": attr.label(mandatory = True, cfg = "exec"),
-        "script_extension": attr.string(mandatory = True, values = ["sh", "bat"]),
+        "is_windows": attr.bool(mandatory = True),
         "_python_interpreter": attr.label(allow_single_file = True, cfg = "exec", default = Label("@python_3_11//:python3")),
     },
     provides = [CcToolchainConfigInfo],