Separate `emscripten_install` from `sdk_post_install` (#1733)
The former is used when setting up emscripten from a git checkout.
The later is run when emscripten is installed as part of of an SDK (i.e.
older versions of emsdk releases require this).
Previously these were both called `emscripten_npm_install`.
Co-authored-by: emscripten-bot <179889221+emscripten-bot@users.noreply.github.com>
diff --git a/emsdk.py b/emsdk.py
index 0b80dff..78fc36e 100644
--- a/emsdk.py
+++ b/emsdk.py
@@ -1437,23 +1437,28 @@
return t
-# npm install in Emscripten root directory
-def emscripten_npm_install(tool, directory):
+def get_node_env():
node_tool = find_latest_installed_tool('node')
if not node_tool:
npm_fallback = shutil.which('npm')
if not npm_fallback:
errlog('Failed to find npm command')
- errlog(f'Running "npm ci" in installed Emscripten root directory {tool.installation_path()} is required')
- errlog('Please install node.js first')
- return False
+ errlog('npm is required for Emscripten setup. Please install node.js first')
+ return None, None
node_path = os.path.dirname(npm_fallback)
else:
node_path = os.path.join(node_tool.installation_path(), 'bin')
- npm = os.path.join(node_path, 'npm' + ('.cmd' if WINDOWS else ''))
env = os.environ.copy()
env["PATH"] = node_path + os.pathsep + env["PATH"]
+ return env, node_path
+
+
+def emscripten_npm_setup(directory):
+ env, node_path = get_node_env()
+ if not env:
+ return False
+ npm = os.path.join(node_path, 'npm' + ('.cmd' if WINDOWS else ''))
print('Running post-install step: npm ci ...')
try:
subprocess.check_output(
@@ -1465,8 +1470,27 @@
return False
print('Done running: npm ci')
+ return True
+
+def sdk_post_install():
+ # Older versions of the sdk did not include the node_modules directory
+ # and require `npm ci` to be run post-install
+ emscripten_dir = os.path.join(EMSDK_PATH, 'upstream', 'emscripten')
+ if os.path.exists(os.path.join(emscripten_dir, 'node_modules')):
+ return True
+
+ return emscripten_npm_setup(emscripten_dir)
+
+
+def emscripten_install(tool):
+ # Modern versions of emscripten require bootstrap.py to be run before they
+ # can be used from a git checkout. On older versions we just run `npm ci`
+ directory = tool.installation_path()
if os.path.isfile(os.path.join(directory, 'bootstrap.py')):
+ env = get_node_env()[0]
+ if not env:
+ return False
try:
subprocess.check_output([sys.executable, os.path.join(directory, 'bootstrap.py')],
cwd=directory, stderr=subprocess.STDOUT, env=env,
@@ -1476,6 +1500,9 @@
return False
print('Done running: Emscripten bootstrap')
+ else:
+ return emscripten_npm_setup(directory)
+
return True
@@ -2109,15 +2136,9 @@
print(f"All SDK components already installed: '{self}'.")
return False
- if self.custom_install_script == 'emscripten_npm_install':
- # upstream tools have hardcoded paths that are not stored in emsdk_manifest.json registry
- install_path = 'upstream'
- emscripten_dir = os.path.join(EMSDK_PATH, install_path, 'emscripten')
- # Older versions of the sdk did not include the node_modules directory
- # and require `npm ci` to be run post-install
- if not os.path.exists(os.path.join(emscripten_dir, 'node_modules')):
- if not emscripten_npm_install(self, emscripten_dir):
- exit_with_error('post-install step failed: emscripten_npm_install')
+ if self.custom_install_script == 'sdk_post_install':
+ if not sdk_post_install():
+ exit_with_error('post-install step failed: sdk_post_install')
print(f"Done installing SDK '{self}'.")
return True
@@ -2158,8 +2179,8 @@
exit_with_error("installation failed!")
if self.custom_install_script:
- if self.custom_install_script == 'emscripten_npm_install':
- success = emscripten_npm_install(self, self.installation_path())
+ if self.custom_install_script == 'emscripten_install':
+ success = emscripten_install(self)
elif self.custom_install_script in {'build_llvm', 'build_ninja', 'build_ccache', 'download_node_nightly', 'download_firefox'}:
# 'build_llvm' is a special one that does the download on its
# own, others do the download manually.
diff --git a/emsdk_manifest.json b/emsdk_manifest.json
index ddea07d..fbddb26 100644
--- a/emsdk_manifest.json
+++ b/emsdk_manifest.json
@@ -504,7 +504,7 @@
"activated_cfg": "EMSCRIPTEN_ROOT='%installation_dir%'",
"activated_path": "%installation_dir%",
"activated_env": "EMSCRIPTEN=%installation_dir%",
- "custom_install_script": "emscripten_npm_install"
+ "custom_install_script": "emscripten_install"
},
{
"id": "emscripten",
@@ -516,7 +516,7 @@
"activated_cfg": "EMSCRIPTEN_ROOT='%installation_dir%'",
"activated_path": "%installation_dir%",
"activated_env": "EMSCRIPTEN=%installation_dir%",
- "custom_install_script": "emscripten_npm_install"
+ "custom_install_script": "emscripten_install"
},
{
"id": "emscripten",
@@ -570,7 +570,7 @@
"activated_path": "%installation_dir%",
"activated_env": "EMSCRIPTEN=%installation_dir%",
"cmake_build_type": "Release",
- "custom_install_script": "emscripten_npm_install"
+ "custom_install_script": "emscripten_install"
},
{
"id": "emscripten",
@@ -583,7 +583,7 @@
"activated_path": "%installation_dir%",
"activated_env": "EMSCRIPTEN=%installation_dir%",
"cmake_build_type": "Release",
- "custom_install_script": "emscripten_npm_install"
+ "custom_install_script": "emscripten_install"
},
{
"id": "binaryen",
@@ -677,7 +677,7 @@
"bitness": 64,
"uses": ["node-22.16.0-64bit", "releases-%releases-tag%-64bit"],
"os": "linux",
- "custom_install_script": "emscripten_npm_install"
+ "custom_install_script": "sdk_post_install"
},
{
"version": "releases-%releases-tag%",
@@ -685,7 +685,7 @@
"uses": ["node-22.16.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"],
"os": "macos",
"arch": "x86_64",
- "custom_install_script": "emscripten_npm_install"
+ "custom_install_script": "sdk_post_install"
},
{
"version": "releases-%releases-tag%",
@@ -693,14 +693,14 @@
"uses": ["node-22.16.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"],
"os": "macos",
"arch": "arm64",
- "custom_install_script": "emscripten_npm_install"
+ "custom_install_script": "sdk_post_install"
},
{
"version": "releases-%releases-tag%",
"bitness": 64,
"uses": ["node-22.16.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"],
"os": "win",
- "custom_install_script": "emscripten_npm_install"
+ "custom_install_script": "sdk_post_install"
}
]
}