Skip to content

Add native windows launcher to replace the current .bat files#24858

Open
sbc100 wants to merge 1 commit intoemscripten-core:mainfrom
sbc100:win32_launcher
Open

Add native windows launcher to replace the current .bat files#24858
sbc100 wants to merge 1 commit intoemscripten-core:mainfrom
sbc100:win32_launcher

Conversation

@sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Aug 4, 2025

Its not clear if this will lead to issues with virus/security scanners. For this reason, I'm leaving the old .bat files
around for now and user can opt out of this by running tools/maint/create_entry_points.py --bat-files.

Assuming we don't run into any issues I hope to eventually completely remove support for the .bat files.

There are several reasons to want to do this:

  1. Batch files are notoriously painful to work with and mis-understood.
  2. Should be faster (no need to launch cmd.exe).
  3. Works around several known issues with .bat files including one that is known unsolvable one (see emcc.bat for more details)
  4. In the future we could potentially launch clang directly, bypassing the python completely (or at least only invoking python for the link stage).

Fixes: #26229
Fixes: #19207

@sbc100 sbc100 force-pushed the win32_launcher branch 12 times, most recently from 6c9f005 to a6f3fc0 Compare August 4, 2025 23:44
@sbc100 sbc100 changed the title Add a windows launcher program to replace the current .bat files [WIP] Add a windows launcher program to replace the current .bat files Aug 6, 2025
@sbc100
Copy link
Collaborator Author

sbc100 commented Aug 6, 2025

@dschuff @kripken WDYT?

@kripken
Copy link
Member

kripken commented Aug 6, 2025

I don't know much about windows, but would we need to build this as part of the emsdk, ship it, etc.? How important are the issues solved by this?

@sbc100
Copy link
Collaborator Author

sbc100 commented Aug 7, 2025

I don't know much about windows, but would we need to build this as part of the emsdk, ship it, etc.? How important are the issues solved by this?

I think since its just a tiny .exe we could just check it into git once.. then the create_entry_points.py script would make N copies of it, one for each script.

@kripken
Copy link
Member

kripken commented Aug 7, 2025

I think since its just a tiny .exe we could just check it into git once..

Isn't there windows-on-arm, so a single binary wouldn't work?

@sbc100
Copy link
Collaborator Author

sbc100 commented Aug 7, 2025

I think since its just a tiny .exe we could just check it into git once..

Isn't there windows-on-arm, so a single binary wouldn't work?

True! Although I'm not sure anyone is using that yet. We certainly don't yet provide emsdk binaries for windows/arm64.

@dschuff
Copy link
Member

dschuff commented Aug 7, 2025

I haven't reviewed the code yet but I think this idea is generally good We did something similar for the NaCl compiler (for a different reason, but a similar technique). I think I have a mild preference for building it with emsdk rather than checking it in, but I could be convinced.

}

int main() {
char exePath[MAX_PATH];
Copy link
Member

Choose a reason for hiding this comment

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

Does this work with non-ascii directory/path names?

Copy link
Collaborator

Choose a reason for hiding this comment

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

There's a whole world of TCHAR pain and Win32 file API coming someone's way...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The new versions handles all that I believe.

@RReverser
Copy link
Collaborator

3. Works around several known issues with .bat files including one that is known unsolvable one (see emcc.bat for more details)

FWIW PowerShell scripts I added a while back should also already solve this issue, and they're chosen by default on Windows when users type emcc ... in PowerShell.

I don't mind the .exe approach, it might make it easier to solve the long-standing issue with Ctrl+C as well - that one is somewhat difficult to solve with either of scripting systems - just want to make sure it's not a burden to maintain.

@RReverser
Copy link
Collaborator

We certainly don't yet provide emsdk binaries for windows/arm64.

Windows have long had system similar to macOS Rosetta, it's just that Windows on ARM has only picked up in popularity recently with new laptops, but essentially any x64 .exe is automatically supported on ARM via translation layer.

Native ARM might be nice to have for wasm-binaries, but for something as simple as this invocation script perf shouldn't matter as much.

@sbc100
Copy link
Collaborator Author

sbc100 commented Aug 9, 2025

  1. Works around several known issues with .bat files including one that is known unsolvable one (see emcc.bat for more details)

FWIW PowerShell scripts I added a while back should also already solve this issue, and they're chosen by default on Windows when users type emcc ... in PowerShell.

I don't mind the .exe approach, it might make it easier to solve the long-standing issue with Ctrl+C as well - that one is somewhat difficult to solve with either of scripting systems - just want to make sure it's not a burden to maintain.

Having to maintain the .ps1 and .bat files in parallel is another reason to make this switch.

Sadly I don't think the .ps1 files can actually replace the .bat files because IIRC powershell is somehow optional in windows so its not guaranteed to always be there.

@RReverser
Copy link
Collaborator

Perhaps worth looking at py2exe than rolling something own?

@sbc100
Copy link
Collaborator Author

sbc100 commented Aug 9, 2025

Perhaps worth looking at py2exe than rolling something own?

I have looked at things like that over the years but the complexity always scared me off. It would also be little sad to loose the "edit-in-place" abilities of the plain-old-python files.

@sbc100
Copy link
Collaborator Author

sbc100 commented Aug 11, 2025

I asked Gemini CLI to help me write a better version. Its seems to have done it!

I asked it to find any discrpencies between these two and it came
up with:

launcher.c Analysis:

The C code replaces the batch script by directly launching Python or ccache. It correctly determines the Python executable and the script to run. Key features include:

  • Long Path Support: It uses the \?\ prefix, removing the 260-character MAX_PATH limit, a major improvement over the batch script.
  • Robust Path Discovery: It uses GetModuleFileNameW to reliably find its own path, avoiding the complex workarounds present in the batch script for PATH lookups.
  • ccache Handling: The ccache logic is similar to the batch script.
  • Argument and Stdin Handling: It uses the robust CommandLineToArgvW for arguments and a more reliable method for the Python stdin bug workaround.

Potential Issues & Discrepancies:

  1. Filename Length Limits: The C launcher is superior. It removes the MAX_PATH limitation of the batch script, so there are no new length restrictions. This is a clear advantage.

  2. Features Missing from launcher.c:

    • EM_WORKAROUND_WIN7_BAD_ERRORLEVEL_BUG: The batch script contains a workaround for a Windows 7 bug causing incorrect exit codes. The C launcher, despite being compiled for Windows 7
      compatibility, lacks this workaround. This is a potential regression for Windows 7 users.
    • %~f0 / %~dp0 Workaround: The batch script's workaround for a PATH lookup bug is obsolete, as the C launcher's method of finding its path is more reliable. This is an improvement.

Conclusion:

The primary concern is the missing EM_WORKAROUND_WIN7_BAD_ERRORLEVEL_BUG handling in launcher.c. This could cause issues for users on Windows 7. Otherwise, the C launcher is a significant
improvement, particularly in its handling of long file paths and command-line arguments. It does not introduce any new filename length limitations. I will now prepare my final answer based on
this.

@sbc100 sbc100 force-pushed the win32_launcher branch 2 times, most recently from 3aabac6 to 10988a1 Compare August 11, 2025 22:02
@sbc100 sbc100 changed the title [WIP] Add a windows launcher program to replace the current .bat files Add a windows launcher program to replace the current .bat files Aug 11, 2025
inolen pushed a commit to inolen/emscripten that referenced this pull request Feb 13, 2026
In particular, on windows, when looking for llvm / binaryen / emscripten
entry points allow them to end with the normal set of executable
extensions.

This allows folks use, for example, a clang.bat wrapper around clang and
also allows us to start using `emcc.exe` over `emcc.bat` at some point.
See emscripten-core#24858

The old `exe_suffix` helper still exists but is now moved to the test
framework.
sbc100 added a commit to sbc100/emscripten that referenced this pull request Feb 13, 2026
Folks who use git need to run `./bootstrap` to have these launchers
created.  This has been true now since emscripten-core#23761.

However, I initially left these commonly used launchers checked in so
that folks could run them and they would report the "you need to run
`bootstrap` message".

Now that its been 6 months we removed the launcher I think existing
users should all now be aware of the `./bootstrap` script.   I'm also
hoping to move to `.exe` files on windows soon, and this change will
help smooth the way: emscripten-core#24858
sbc100 added a commit to sbc100/emscripten that referenced this pull request Feb 13, 2026
Folks who use git need to run `./bootstrap` to have these launchers
created.  This has been true now since emscripten-core#23761.

However, I initially left these commonly used launchers checked in so
that folks could run them and they would report the "you need to run
`bootstrap` message".

Now that its been 6 months we removed the launcher I think existing
users should all now be aware of the `./bootstrap` script.   I'm also
hoping to move to `.exe` files on windows soon, and this change will
help smooth the way: emscripten-core#24858
sbc100 added a commit to sbc100/emscripten that referenced this pull request Feb 13, 2026
Folks who use git need to run `./bootstrap` to have these launchers
created.  This has been true now since emscripten-core#23761.

However, I initially left these commonly used launchers checked in so
that folks could run them and they would report the "you need to run
`bootstrap` message".

Now that its been 6 months we removed the launcher I think existing
users should all now be aware of the `./bootstrap` script.   I'm also
hoping to move to `.exe` files on windows soon, and this change will
help smooth the way: emscripten-core#24858
sbc100 added a commit to sbc100/emscripten that referenced this pull request Feb 13, 2026
Folks who use git need to run `./bootstrap` to have these launchers
created.  This has been true now since emscripten-core#23761.

However, I initially left these commonly used launchers checked in so
that folks could run them and they would report the "you need to run
`bootstrap` message".

Now that its been 6 months we removed the launcher I think existing
users should all now be aware of the `./bootstrap` script.   I'm also
hoping to move to `.exe` files on windows soon, and this change will
help smooth the way: emscripten-core#24858
sbc100 added a commit that referenced this pull request Feb 13, 2026
Folks who use git need to run `./bootstrap` to have these launchers
created.
This has been true now since #23761.

However, I initially left these commonly used launchers checked in so
that
folks could run them and they would report the "you need to run
`bootstrap`
message".

Now that its been 6 months we removed the launcher I think existing
users should all now be aware of the `./bootstrap` script.   I'm also
hoping to move to `.exe` files on windows soon, and this change will
help smooth the way: #24858
@sbc100 sbc100 force-pushed the win32_launcher branch 5 times, most recently from b1e0833 to 3febb50 Compare February 13, 2026 22:58
@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 13, 2026

@juj, I'd like to try and experiment where we land this and see if you can use it?

I've added an escape hatch of EMCC_USE_BAT_FILES to allow you to keep the old behaviour if it doesn't work out. We can also revert before the next release if needs be.

@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 13, 2026

The executable being checked in here was build on the circleci bot and downloaded as an artifact of the new build-windows-launcher job.

@sbc100 sbc100 changed the title Add a windows launcher program to replace the current .bat files Add native windows launcher to replace the current .bat files Feb 13, 2026
@sbc100 sbc100 force-pushed the win32_launcher branch 3 times, most recently from 59ff9e4 to f10b565 Compare February 19, 2026 01:37
@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 19, 2026

Perf number seem fairly negligable:

.exe:

[1/1] test_emcc_noop (test_benchmark.benchmark.test_emcc_noop) ... 

        clang: mean: 0.033 (+-0.008) secs  median: 0.037  range: 0.022-0.042  (noise: 24.282%)  (5 runs)   Relative: No baseli
ne recorded yet
         emcc: mean: 0.259 (+-0.008) secs  median: 0.255  range: 0.251-0.270  (noise: 3.041%)  (5 runs)   Relative: 7.73 X slo
wer
ok

.bat:

[1/1] test_emcc_noop (test_benchmark.benchmark.test_emcc_noop) ... 

        clang: mean: 0.035 (+-0.007) secs  median: 0.037  range: 0.024-0.042  (noise: 18.888%)  (5 runs)   Relative: No baseli
ne recorded yet
         emcc: mean: 0.287 (+-0.011) secs  median: 0.292  range: 0.265-0.294  (noise: 3.952%)  (5 runs)   Relative: 8.17 X slo
wer
ok

@sbc100 sbc100 force-pushed the win32_launcher branch 4 times, most recently from 7ce0669 to 497c2bd Compare February 19, 2026 22:33
@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 19, 2026

@dschuff @kripken @juj, I'd like to land this today and get it running out our bots and in the hands of users.

I will send out a message to mailing list.

If we run into the security scanner issues we can investigate more or revert.

@dschuff
Copy link
Member

dschuff commented Feb 19, 2026

I wonder if we should build the exes with the same compiler we use to build the emsdk binaries, just to minimize the chances of there being any interesting differences. I'm also not super enthusiastic about checking in binaries, but I guess if we want to maintain the invariant that you can just check out emscripten and use it without emsdk or other dependencies, then there aren't too many other options?

This is still just an experiment but eventually I hope to remove
the `.bat` files in favor of this executable.

Users who have issues can opt out via `EMCC_USE_BAT_FILES`.

There are several reasons to want to do this:

1. Batch files are notoriously painful to work with and mis-understood.
2. Should be faster (no need to launch cmd.exe).
3. Works around several known issues with .bat files including one that
   is known unsolvable one (see emcc.bat for more details)
@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 19, 2026

I wonder if we should build the exes with the same compiler we use to build the emsdk binaries

Yes, perhaps we can do that on the emscripten-releases waterfall? I think that can happen later though, if we do run into issue.

I'm also not super enthusiastic about checking in binaries, but I guess if we want to maintain the invariant that you can just check out emscripten and use it without emsdk or other dependencies, then there aren't too many other options?

Yes, I'm normally completely against that too, but I think this is good example of case where an exception that rule makes sense. Since the binary is so small we can think of it more like a binary shell script :)

set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
if (DEFINED USE_BAT_FILES)
# See https://github.com/emscripten-core/emscripten/issues/2386
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 1)

Choose a reason for hiding this comment

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

.exe also need this, as for .exe, the command line length still limits to
32768 wchar_t, for linux the command line length are about 2MBbyte, so this still needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

em++.bat emcc.bat and other bat files do not support for very long command line on windows. Incorrect path resolution in emcc.bat/em++.bat

7 participants

Comments