#27723·emscripten

No supported way to negate `-pthread`: `USE_PTHREADS` is deprecated but is the only working off-switch

Author: zommuterCreated Sep 16, 2026Updated Sep 16, 2026

Summary

USE_PTHREADS is deprecated in favour of -pthread, but -pthread has no negation, so a project that consumes a build system which passes -pthread unconditionally has no supported way to turn threads off. The only mechanism that works is the deprecated setting itself, which is a hard error under STRICT.

I am filing because the deprecation message explicitly invites it ("Please open a bug if you have a continuing need for this setting"), and a tracker search for -no-pthread, for negating -pthread, and for the USE_PTHREADS deprecation turned up nothing similar.

What I tried, on emsdk 6.0.9

Baseline, matching what the upstream build passes:

emcc -pthread -sALLOW_MEMORY_GROWTH=1 -o out.js hello.c
# -> (import "env" "memory" (memory $mimport$0 256 32768 shared))

Then each candidate negation, injected via EMCC_CFLAGS so it lands after the command line (the same shape a downstream build system leaves you with):

Flag Result
-no-pthread still shared -- the string does not occur in emcc.py, tools/ or docs/emcc.txt; it is forwarded to clang, which reports it unused
-sSHARED_MEMORY=0 still shared
-sPTHREADS=0 hard error: PTHREADS is an internal setting and cannot be set from command line
-sUSE_PTHREADS=0 works -- (memory $0 258 32768), non-shared, no PThread/Worker references in the glue

emcc.py (around the user_settings handling) maps USE_PTHREADS onto the internal PTHREADS, and that appears to be the only path that can negate it. tools/settings.py lists USE_PTHREADS in LEGACY_SETTINGS with "No longer needed. Use -pthread instead", and legacy settings are fatal when STRICT is on.

Why this matters downstream

We are building Lean 4 for WebAssembly. Its CMake sets

cmake
set(EMSCRIPTEN_SETTINGS "-s ALLOW_MEMORY_GROWTH=1 -fwasm-exceptions -pthread -flto")
string(APPEND LEANC_EXTRA_CC_FLAGS " -pthread")

unconditionally in its Emscripten branch, with no option to disable it. We want a thread-free comparison build (no SharedArrayBuffer requirement, so the artifact can load without cross-origin isolation). Our only route is -sUSE_PTHREADS=0, i.e. a deprecated setting that a future emsdk may remove and that EMCC_STRICT already rejects.

What would help

Any one of these would remove the dead end, in rough order of preference:

  1. A supported negation of -pthread -- -no-pthread is the spelling most people try first (clang accepts it for the host, which is why it fails silently here).
  2. Keep -sUSE_PTHREADS=0 working, or exempt it from STRICT, until a negation exists.
  3. Failing both, a documentation note in docs/emcc.txt stating that -pthread cannot be negated and that -sUSE_PTHREADS=0 is the workaround, so the deprecation warning does not lead people to remove their only working option.

Happy to open a PR for (3) if that would be welcome, and happy to test a patch for (1).

Versions

emsdk / emscripten 6.0.9, Linux 6.18 (Manjaro), node 24.


Disclosure: this report was researched and drafted by Claude Opus 5 (Claude Code) working at my direction. Every flag result in the table above is from a real local probe on 6.0.9, not a hypothetical, and the cited source behaviour was checked against the installed emscripten before filing.

Source: emscripten-core/emscripten