Skip to content

Conversation

@anutosh491
Copy link
Collaborator

Description

Discovered this while moving to emscripten 4-x for xeus-cpp.

Problem : The following works for our native kernel but not our wasm kernel

  1. native
image 2) wasm image

Type of change

Please tick all options which are relevant.

  • Bug fix
  • New feature
  • Added/removed dependencies
  • Required documentation updates

@anutosh491
Copy link
Collaborator Author

anutosh491 commented Nov 11, 2025

What's Happening here ?

So on native builds, clang automatically discovers <xlocale.h> through the system SDK or libc include paths.
In the Emscripten sysroot, however, legacy headers like <xlocale.h> reside under /include/compat, which isn’t part of the default search list.

How emcc does it

anutosh491@Anutoshs-MacBook-Air xeus-cpp % cat xlocale_test.c
#include <stdio.h>
#include <locale.h>
#include <xlocale.h>

int main(void) {
    locale_t loc = newlocale(LC_NUMERIC_MASK, "C", NULL);

    const char *s = "3.14159";
    long double v = strtold_l(s, NULL, loc);

    printf("Parsed value: %.5Lf\n", v);

    freelocale(loc);
    return 0;
}

anutosh491@Anutoshs-MacBook-Air xeus-cpp % emcc -v xlocale_test.c -o xlocale_test.html
 /Users/anutosh491/work/emsdk/upstream/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/Users/anutosh491/work/emsdk/upstream/emscripten/cache/sysroot -DEMSCRIPTEN -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -v -c xlocale_test.c -o /var/folders/m1/cdn74f917994jd99d_2cpf440000gn/T/emscripten_temp_v4f2uvqa/xlocale_test.o
clang version 22.0.0git (https:/github.com/llvm/llvm-project c13ac9cadf1f9b4fa886b82d1e84a5feb0439023)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /Users/anutosh491/work/emsdk/upstream/bin
 (in-process)
 "/Users/anutosh491/work/emsdk/upstream/bin/clang-22" -cc1 -triple wasm32-unknown-emscripten -emit-obj -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name xlocale_test.c -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -fvisibility=hidden -debugger-tuning=gdb -fdebug-compilation-dir=/Users/anutosh491/work/xeus-cpp -v -fcoverage-compilation-dir=/Users/anutosh491/work/xeus-cpp -resource-dir /Users/anutosh491/work/emsdk/upstream/lib/clang/22 -D EMSCRIPTEN -isysroot /Users/anutosh491/work/emsdk/upstream/emscripten/cache/sysroot -internal-isystem /Users/anutosh491/work/emsdk/upstream/lib/clang/22/include -internal-isystem /Users/anutosh491/work/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /Users/anutosh491/work/emsdk/upstream/emscripten/cache/sysroot/include -ferror-limit 19 -fmessage-length=141 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fignore-exceptions -fcolor-diagnostics -iwithsysroot/include/fakesdl -iwithsysroot/include/compat -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o /var/folders/m1/cdn74f917994jd99d_2cpf440000gn/T/emscripten_temp_v4f2uvqa/xlocale_test.o -x c xlocale_test.c
clang -cc1 version 22.0.0git based upon LLVM 22.0.0git default target 
ignoring nonexistent directory "/Users/anutosh491/work/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
 /Users/anutosh491/work/emsdk/upstream/emscripten/cache/sysroot/include/compat
 /Users/anutosh491/work/emsdk/upstream/lib/clang/22/include
 /Users/anutosh491/work/emsdk/upstream/emscripten/cache/sysroot/include
End of search list.

This shows 3 paths
i) sysroot/include and lib/clang/22/include (resource dir) which we address as of now
ii) What we don't address is sysroot/include/compat !!!!

As can be seen this is addressed through -iwithsysroot/include/compat as can be seen above and here

This PR adds the same (check right side of the img below as now we're able to search through compat for xlocale.h)

image

@codecov-commenter
Copy link

codecov-commenter commented Nov 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.94%. Comparing base (659e968) to head (6eb1b70).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #409      +/-   ##
==========================================
- Coverage   82.05%   81.94%   -0.11%     
==========================================
  Files          21       21              
  Lines         858      853       -5     
  Branches       89       87       -2     
==========================================
- Hits          704      699       -5     
  Misses        154      154              
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@anutosh491
Copy link
Collaborator Author

anutosh491 commented Nov 11, 2025

cc @mcbarton

The same change would be needed in cppinterop to run the emscripten tests (cause iostream and other stream based headers from emsdk 4-x started including xlocale.h) once we migrate.

Otherwise some tests would just fail through

1: [ RUN      ] CppInterOpTest/InProcessJIT.ScopeReflectionTestIsBuiltin
1: In file included from <<< inputs >>>:1:
1: In file included from input_line_2:1:
1: In file included from /include/c++/v1/complex:273:
1: In file included from /include/c++/v1/sstream:323:
1: In file included from /include/c++/v1/__ostream/basic_ostream.h:20:
1: In file included from /include/c++/v1/__ostream/put_character_sequence.h:19:
1: In file included from /include/c++/v1/__locale_dir/pad_and_output.h:16:
1: In file included from /include/c++/v1/ios:223:
1: In file included from /include/c++/v1/__locale:17:
1: /include/c++/v1/__locale_dir/locale_base_api.h:131:16: fatal error: 'xlocale.h' file not found
1:   131 | #      include <xlocale.h>
1:       |                ^~~~~~~~~~~
1: wasm://wasm/13cfc366:1

I just ran the cppinterop tests (after building both cppinterop and llvm against latest emsdk 4-x) and this is where I caught the above.

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@mcbarton
Copy link
Collaborator

cc @mcbarton

The same change would be needed in cppinterop to run the emscripten tests (cause iostream from emsdk 4-x started including xlocale.h) once we migrate.

Otherwise some tests would just fail through

1: [ RUN      ] CppInterOpTest/InProcessJIT.ScopeReflectionTestIsBuiltin
1: In file included from <<< inputs >>>:1:
1: In file included from input_line_2:1:
1: In file included from /include/c++/v1/complex:273:
1: In file included from /include/c++/v1/sstream:323:
1: In file included from /include/c++/v1/__ostream/basic_ostream.h:20:
1: In file included from /include/c++/v1/__ostream/put_character_sequence.h:19:
1: In file included from /include/c++/v1/__locale_dir/pad_and_output.h:16:
1: In file included from /include/c++/v1/ios:223:
1: In file included from /include/c++/v1/__locale:17:
1: /include/c++/v1/__locale_dir/locale_base_api.h:131:16: fatal error: 'xlocale.h' file not found
1:   131 | #      include <xlocale.h>
1:       |                ^~~~~~~~~~~
1: wasm://wasm/13cfc366:1

I just ran the cppinterop tests (after building both cppinterop and llvm against latest emsdk 4-x) and this is where I caught the above.

Thanks the tip @anutosh491 . I will look into this. Did you run the llvm Emscripten tests to see if a change is needed to get them to still pass too?

@anutosh491
Copy link
Collaborator Author

Did you run the llvm Emscripten tests to see if a change is needed to get them to still pass too?

Not yet !

But we probably won't need any change there as this is the only real change I could spot. The llvm emscripten tests don't really process any "#Include" 's as such which means no include path searching change !

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

1 similar comment
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

1 similar comment
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@anutosh491 anutosh491 changed the title Add Emscripten compat include paths to interpreter initialization Add Emscripten compat include paths to wasm kernel specs Nov 13, 2025
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Contributor

@vgvassilev vgvassilev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@anutosh491
Copy link
Collaborator Author

Hi,

Thanks for the approval here.

This is very much needed cause I was able to build xeus-cpp on emscripten-forge's emscripten 4-x branch and got this.

image

Because all the stream based headers (iostream, sstream, fstream etc) defined in emsdk's 4-x sysroot started including xlocale.h. And without this fix, we would have the above error.

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@anutosh491 anutosh491 merged commit 62268e7 into compiler-research:main Nov 20, 2025
17 of 18 checks passed
@anutosh491 anutosh491 deleted the compat branch November 20, 2025 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants