GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-156780: Emscripten: support building CPython with static linking by clementperon · Pull Request #156781 · python/cpython

Conversation

@clementperon

@clementperon clementperon commented Sep 1, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Fixes #156780.

Allow Emscripten libpython.a to be embedded without -sMAIN_MODULE or wrapping the application's main(). The wrapper no longer depends on resolveGlobalSymbol().

Keep the JavaScript setup in Python/emscripten_syscalls.c and invoke it from a constructor in Programs/emscripten_beforemain.c, linked only into the interpreter and _testembed. Preserve the existing _emscripten_exit_with_live_runtime() and Module.onExit behavior. Omit the constructor when Emscripten syscall overrides are disabled.

fd_read and poll suspend only when Module.Py_EmscriptenStackSwitching is set. The interpreter sets this flag when entering its promising main(); embedders can opt in when providing their own promising entry point.

Add CI smoke tests for static embedding and for an Emscripten callback completing while main() is suspended. The latter checks that main() resumes and its exit status is preserved.

Validation with Emscripten 6.0.9 and Node 26.8.1:

  • Rebuilt the dynamic-linking interpreter; test_capi.test_emscripten, test_builtin, test_json, test_sys, and test_functools passed. test_select was skipped because socket support was unavailable.
  • Static embedding and suspended-main smoke tests passed. Also checked the suspended-main test with -sMAIN_MODULE; it fails against the previous wrapper and passes with this change.
  • Verified that --disable-emscripten-syscalls omits the constructor and syscall objects from the configuration.
  • Regenerated configure with CPython's regeneration script.
  • Issue: Emscripten: static (non-MAIN_MODULE) builds fail at startup on dynamic-linking-only JS helpers #156780

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@clementperon
clementperon requested review from AA-Turner, corona10, emmatyping, erlend-aasland and itamaro as code owners September 1, 2026 14:51
@bedevere-app bedevere-app Bot mentioned this pull request Sep 1, 2026
Emscripten: static (non-MAIN_MODULE) builds fail at startup on dynamic-linking-only JS helpers #156780
Closed
@bedevere-app bedevere-app Bot added the awaiting review label Sep 1, 2026
@clementperon

clementperon commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@hoodmane 👀 maybe ?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hoodmane

hoodmane commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Maybe let's start with a PR that adds the EM_JS_DEPS() everywhere? That seems like an easy improvement.

I think rather than using Module.Py_EmscriptenPromisingMain as a runtime flag, it would be more morally upstanding to move that logic into python.o or some other object file we only link into the interpreter program, that way embedders wouldn't get it at all. Maybe we can rename _emscripten_promising_main_js to _PyEmscripten_BeforeMain() or something and move the following to python.c or to its own object file next to it:

#ifdef __EMSCRIPTEN__
__attribute__((constructor)) void _PyEmscripten_Constructor(void) {
   _PyEmscripten_BeforeMain();
}

python.c is currently very short, so I'm not sure how people will feel about adding this there but we should find out.

And of course as traditional we need much less prose since Claude is as rambly as usual. Please rewrite all the comments and the commit message by hand. I find that helps cut them down to a more reasonable length.

Of course, it's likely that any of this will bit rot without test coverage.

cc @freakboy3742 WDYT?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@clementperon clementperon mentioned this pull request Sep 1, 2026
gh-156780: Emscripten: add missing EM_JS_DEPS #156798
Merged
@hoodmane hoodmane added the OS-emscripten label Sep 1, 2026
@clementperon
clementperon force-pushed the emscripten-static-linking branch from e0433ec to c89eb2f Compare September 1, 2026 21:27
@clementperon
clementperon requested review from JacobCoffee, ezio-melotti, freakboy3742, hugovk and webknjaz as code owners September 1, 2026 21:27
@clementperon

clementperon commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@hoodmane as you suggest move to a dedicated object file + reword commit + add a test

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@clementperon
clementperon force-pushed the emscripten-static-linking branch from c89eb2f to 2e46f9a Compare September 1, 2026 21:34
@clementperon
clementperon requested a review from ericsnowcurrently as a code owner September 1, 2026 21:34
hoodmane
hoodmane reviewed Sep 1, 2026
View reviewed changes
Comment thread Misc/NEWS.d/next/Build/2026-09-01-23-32-22.gh-issue-156780.Qw3nRt.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

hoodmane
hoodmane reviewed Sep 1, 2026
View reviewed changes
Comment thread Python/emscripten_syscalls.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@freakboy3742

freakboy3742 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Maybe let's start with a PR that adds the EM_JS_DEPS() everywhere? That seems like an easy improvement.

+1 to this as an approach to landing the changes.

I think rather than using Module.Py_EmscriptenPromisingMain as a runtime flag, it would be more morally upstanding to move that logic into python.o
...
python.c is currently very short, so I'm not sure how people will feel about adding this there but we should find out.

I agree that linking into the mainline is a preferable approach to a runtime flag.

As for where to put it - I can definitely see the argument for using python.c, but the fact that it is so minimal at present is at least a cause for a raised eyebrow. Is Modules/main.c perhaps a better candidate?

And of course as traditional we need much less prose since Claude is as rambly as usual. Please rewrite all the comments and the commit message by hand. I find that helps cut them down to a more reasonable length.

+1 to this as well. Claude's predilection for extraneous verbositude is usually contrary to the underlying goals of effective communication :-)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@clementperon
clementperon force-pushed the emscripten-static-linking branch from fa3261b to ee90cfa Compare September 8, 2026 09:00
@clementperon

clementperon commented Sep 8, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

@hoodmane EM_JS_DEPS has been merged thanks to @freakboy3742.

I will rework a bit this PR + clean commit message & comment.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@clementperon
clementperon marked this pull request as draft September 8, 2026 10:23
@bedevere-app bedevere-app Bot removed the awaiting review label Sep 8, 2026
@clementperon
clementperon force-pushed the emscripten-static-linking branch 3 times, most recently from 5417e3e to 7c1f523 Compare September 8, 2026 14:30
@clementperon clementperon mentioned this pull request Sep 9, 2026
gh-156780: Emscripten: drop the trampoline's dependence on exports #157238
Merged
@clementperon
clementperon force-pushed the emscripten-static-linking branch from 18d7011 to 1eaadc6 Compare September 10, 2026 14:36
@clementperon

clementperon commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Rebase on top of #157238

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@clementperon
clementperon force-pushed the emscripten-static-linking branch from f96de99 to afd1a38 Compare September 16, 2026 20:07
@clementperon

clementperon commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

@hoodmane can I have again your feedback on this PR please 🙏

Thanks

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

clementperon and others added 3 commits October 1, 2026 15:14
@clementperon @claude
pythongh-156780: Emscripten: move main() wrapping out of libpython
bf034a6
Running main() under WebAssembly.promising only makes sense when Python
is the program. Move the wrapper into Programs/emscripten_beforemain.c,
linked into the interpreter but not into libpython, and let the runtime
shut down normally afterwards so atexit handlers run and buffered output
is flushed. FS.createAsyncInputDevice() stays in libpython.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@clementperon @claude
pythongh-156780: Emscripten: gate the suspending syscalls on the main…
9a86800
…() wrapper

Suspending in fd_read or poll needs a promising entry point, which
libpython no longer sets up itself. Check Module.Py_EmscriptenStackSwitching,
set by the interpreter's wrapper, instead of WebAssembly.promising alone.
An embedder with its own promising entry point sets the flag.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@clementperon @claude
pythongh-156780: Emscripten: add an embedding smoke test
f0f808e
Link libpython.a into a program whose main() is not Python's, without
-sMAIN_MODULE or the interpreter's link flags, and run a script that
imports from the stdlib, calls through the trampoline and polls.
Platforms/emscripten/web_embed_test/run_test.sh builds and runs it in CI.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@clementperon

clementperon commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

@freakboy3742 what do you think of this PR ? Do you want me to update something ?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@clementperon clementperon mentioned this pull request Oct 8, 2026
[depends][python][wasm] build and run a statically linked CPython xbmc/xbmc#29169
Merged
3 of 15 tasks
hoodmane
hoodmane reviewed Oct 19, 2026
View reviewed changes
Comment thread Programs/emscripten_beforemain.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

hoodmane
hoodmane reviewed Oct 19, 2026
View reviewed changes
Comment thread Programs/emscripten_beforemain.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

hoodmane
hoodmane reviewed Oct 19, 2026
View reviewed changes
Comment thread Programs/emscripten_beforemain.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@clementperon
pythongh-156780: preserve Emscripten main wrapper behavior
09b9faf
Keep the JavaScript setup in emscripten_syscalls.c and only the constructor in the interpreter object. Restore the existing live-runtime exit behavior and omit the constructor when syscall overrides are disabled.

Add a smoke test that resumes main after an Emscripten callback and verifies its exit status.
@clementperon
clementperon force-pushed the emscripten-static-linking branch from afd1a38 to 09b9faf Compare October 19, 2026 20:32
@clementperon
clementperon requested a review from StanFromIreland as a code owner October 19, 2026 20:32
@clementperon

clementperon commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

@hoodmane thanks for your review, I hope i understand correctly what you wanted

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

hoodmane
hoodmane reviewed Oct 21, 2026
View reviewed changes
Comment thread Platforms/emscripten/web_embed_test/promising_main.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@clementperon @claude
pythongh-156780: Emscripten: drop the promising_main test
84b96aa
The main() wrapper is unchanged from main, so there is nothing new to cover.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
hoodmane
hoodmane approved these changes Oct 22, 2026
View reviewed changes

@hoodmane hoodmane left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Thanks for your patience @clementperon. Lgtm.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-app bedevere-app Bot added awaiting core review and removed awaiting review labels Oct 22, 2026
@clementperon

clementperon commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for your review !

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

freakboy3742
freakboy3742 approved these changes Oct 22, 2026
View reviewed changes

@freakboy3742 freakboy3742 left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I think this all makes sense, with one minor tweak related to making the Py_EmscriptenStackSwitching symbol private. Thanks for the PR!

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

clementperon reacted with heart emoji
All reactions
  • ❤️ 1 reaction
Comment thread Python/emscripten_syscalls.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_testinternalcapi.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Python/emscripten_syscalls.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Python/emscripten_syscalls.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Python/emscripten_syscalls.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting core review labels Oct 22, 2026
@freakboy3742
Make stack-switching symbol private
139c1e2
@freakboy3742
freakboy3742 enabled auto-merge (squash) October 22, 2026 18:42
@freakboy3742
freakboy3742 merged commit d6b77c8 into python:main Oct 22, 2026
74 of 76 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting merge label Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@freakboy3742 freakboy3742 freakboy3742 approved these changes
@hoodmane hoodmane hoodmane approved these changes
@erlend-aasland erlend-aasland Awaiting requested review from erlend-aasland erlend-aasland is a code owner
@corona10 corona10 Awaiting requested review from corona10 corona10 is a code owner
@AA-Turner AA-Turner Awaiting requested review from AA-Turner AA-Turner is a code owner
@emmatyping emmatyping Awaiting requested review from emmatyping emmatyping is a code owner
@itamaro itamaro Awaiting requested review from itamaro itamaro is a code owner
@ezio-melotti ezio-melotti Awaiting requested review from ezio-melotti
@hugovk hugovk Awaiting requested review from hugovk
@webknjaz webknjaz Awaiting requested review from webknjaz
@JacobCoffee JacobCoffee Awaiting requested review from JacobCoffee
@ericsnowcurrently ericsnowcurrently Awaiting requested review from ericsnowcurrently
@StanFromIreland StanFromIreland Awaiting requested review from StanFromIreland

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

OS-emscripten

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Emscripten: static (non-MAIN_MODULE) builds fail at startup on dynamic-linking-only JS helpers

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@clementperon @hoodmane @freakboy3742
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.