Normalize case for key config pathnames on Windows - #27626
Merged
Conversation
On Windows, file systems are case-insensitive. When tools like VS Code CMake Tools invoke the compiler through an all-lowercased path (e.g. via its `platformNormalizePath` helper), the caller-specified casing affects the value of `__file__` in Python which then propagates all the way to `LLVM_ROOT` and the `sanity.txt` file (at least in the emsdk case): `__file__` -> `__rootpath__` -> `EM_CONFIG` -> `CFGDIR` -> `LLVM_ROOT` -> `sanity.txt`. Address this in two places: 1. In `tools/utils.py`, normalize `__file__` using `normcase` when initializing `__rootpath__`. This prevents caller-specified casing from polluting paths derived from the script location (default `EM_CONFIG`, `$CFGDIR`, and default `CACHE`). 2. In `tools/shared.py`, normalize `config.LLVM_ROOT` using `normcase` in `generate_sanity()`. This ensures that even if `LLVM_ROOT` was configured explicitly (e.g. via `EM_LLVM_ROOT` or an absolute path in `.emscripten`), the string written to `sanity.txt` is always canonical on Windows. See: emscripten-core#27624
sbc100
force-pushed
the
windows-path-normcase
branch
from
August 30, 2026 22:33
d76fbf7 to
b43b171
Compare
kripken
reviewed
Aug 31, 2026
kripken
reviewed
Aug 31, 2026
Member
|
Seems this is breaking on Chromium CI: https://ci.chromium.org/ui/p/emscripten-releases/builders/try/win/b8671899703975760065 |
sbc100
added a commit
that referenced
this pull request
Sep 1, 2026
Sanity tests previously ran on Windows via `--crossplatform-only` after #22492, but were removed in #26365 when all tests were combined into a single parallel test suite (which made mixing parallel and non-parallel modules an error). Run `sanity.test_windows_path_casing` as a dedicated step in `test-windows` so the Windows path casing regression test from #27626 is exercised in CI.
sbc100
added a commit
that referenced
this pull request
Sep 1, 2026
In #27626, `__rootpath__` was changed to use `os.path.normcase(__file__)` to prevent caller-specified casing from propagating to `config.LLVM_ROOT` and `sanity.txt`. However, on Windows `normcase` unconditionally converts the entire path including the drive letter to lowercase (`c:\...`). This lowercases all paths derived from `path_from_root`, including default `config.CACHE` and `EMSCRIPTEN_SYSROOT`. When CMake runs on Windows, imported targets and compiler autodetection preserve uppercase drive letters (`C:\...`). Because CMake's implicit include directory checks are case-sensitive string comparisons, the mismatch between `c:\...` and `C:\...` caused CMake to treat the sysroot include directory as an explicit non-system include, injecting `-isystem` and disrupting libc++ header search order in `test_cmake_install`. It also caused assertion failures in `test_cmake_compile_commands_noforce`. The normalization of `config.LLVM_ROOT` in `generate_sanity()` in `tools/shared.py` (also added in #27626) is already sufficient to ensure that `sanity.txt` remains consistent regardless of the casing used to invoke `emcc`. Normalizing `__rootpath__` is unnecessary and harmful. See: #27626
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Windows, file systems are case-insensitive. When tools like VS Code
CMake Tools invoke the compiler through an all-lowercased path (e.g. via
its
platformNormalizePathhelper), the caller-specified casing affectsthe value of
__file__in Python which then propagates all the way toLLVM_ROOTand thesanity.txtfile (at least in the emsdk case):__file__->__rootpath__->EM_CONFIG->CFGDIR->LLVM_ROOT->
sanity.txt.Address this in two places:
tools/utils.py, normalize__file__usingnormcasewheninitializing
__rootpath__. This prevents caller-specified casingfrom polluting paths derived from the script location (default
EM_CONFIG,$CFGDIR, and defaultCACHE).tools/shared.py, normalizeconfig.LLVM_ROOTusingnormcasein
generate_sanity(). This ensures that even ifLLVM_ROOTwasconfigured explicitly (e.g. via
EM_LLVM_ROOTor an absolute pathin
.emscripten), the string written tosanity.txtis alwayscanonical on Windows.
The proximate cause of the issue was that the VS Code CMake Tools
extension explicitly lowercases compiler paths on Windows:
https://github.com/microsoft/vscode-cmake-tools/blob/09dd68b54de06469bd1b81d84d6b8666aa2dce1d/src/util.ts#L113-L115
By forcing the command line to all-lowercase, the above chain of events
kicked in whenever the IDE queried compiler settings.
See: #27624