Skip to content

Commit 263db4c

Browse files
authored
Fix an issue if user passes a relative path to Python (#26799)
Fix an issue if user passes a relative path to Python, and some system cache libraries need rebuilding. Emcc tool would spawn sub-emcc tools to rebuild the cache, with different CWD, resulting in the relative path lookups pointing to the wrong relative directories. To fix the issue, normalize the relative tool paths first. <img width="2380" height="992" alt="image" src="https://github.com/user-attachments/assets/e22b71c0-b73e-411c-9ef5-f51a890f01aa" />
1 parent bcf1551 commit 263db4c

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

test/test_sanity.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,3 +847,26 @@ def test_bootstrap_without_em_config(self):
847847

848848
# Running bootstrap.py should not fail
849849
self.run_process([utils.exe_path_from_root('bootstrap')], env=env)
850+
851+
# Verify that if user specifies a relative path to Python executable, then
852+
# Emscripten is still able to build.
853+
def test_emcc_with_relative_python_path(self):
854+
restore_and_set_up()
855+
# Clear the cache, since rebuilding the cache has been observed to fail
856+
# if Python path is specified as relative.
857+
self.clear_cache()
858+
859+
try:
860+
relative_python = os.path.relpath(os.environ.get('EMSDK_PYTHON'), os.getcwd())
861+
except ValueError:
862+
self.skipTest('Python and Emscripten are located on different drives, cannot run this test.')
863+
864+
relative_python_escaped = relative_python.replace("\\", "\\\\")
865+
add_to_config(f'PYTHON = "{relative_python_escaped}"')
866+
867+
env = os.environ.copy()
868+
env['EMSDK_PYTHON'] = relative_python
869+
870+
output = self.do([EMCC, test_file('hello_world.c')], env=env)
871+
self.assertNotContained('error', output)
872+
self.assertExists('a.out.js')

tools/config.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ def normalize_config_settings():
7474
PORTS = os.path.join(CACHE, 'ports')
7575

7676

77+
def normalize_relative_python_path():
78+
# User may have specified the EMSDK_PYTHON environment variable to point to
79+
# the Python interpreter, e.g.
80+
#
81+
# EMSDK_PYTHON=../../path/to/python emcc test/hello_world.c
82+
#
83+
# As part of its operation, emcc may spawn sub-emcc tasks when building
84+
# libraries to cache. These sub-emcc tasks will run in a different CWD, so
85+
# reinitialize EMSDK_PYTHON here so that sub-tool spawns will use the same
86+
# Python interpreter as the parent.
87+
if os.environ.get('EMSDK_PYTHON'):
88+
os.environ['EMSDK_PYTHON'] = sys.executable
89+
90+
7791
def set_config_from_tool_location(config_key, tool_binary, f):
7892
val = globals()[config_key]
7993
if val is None:
@@ -168,6 +182,7 @@ def read_config():
168182
set_config_from_tool_location('BINARYEN_ROOT', 'wasm-opt', lambda x: os.path.dirname(os.path.dirname(x)))
169183

170184
normalize_config_settings()
185+
normalize_relative_python_path()
171186

172187

173188
def generate_config(path):

0 commit comments

Comments
 (0)