Skip to content

Commit 395e0a7

Browse files
committed
Fixes for the emscripten build.
1 parent 89574cb commit 395e0a7

7 files changed

Lines changed: 196 additions & 51 deletions

File tree

Tools/configure/conf_extlibs.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,17 @@ def detect_sqlite3(v):
163163
"""Detect sqlite3 and handle --enable-loadable-sqlite-extensions."""
164164
v.have_sqlite3 = False
165165
v.have_supported_sqlite3 = False
166-
v.LIBSQLITE3_CFLAGS = ""
167-
v.LIBSQLITE3_LIBS = "-lsqlite3"
168166

169-
# Emscripten port check (stub — pyconf.check_emscripten_port is a no-op)
167+
# Emscripten port check — must run before defaults are set so that
168+
# check_emscripten_port sees empty CFLAGS/LIBS and can set them.
170169
pyconf.check_emscripten_port("LIBSQLITE3", "-sUSE_SQLITE3")
171170

171+
# Set defaults only if not already provided (by emscripten port or user).
172+
if not v.LIBSQLITE3_CFLAGS:
173+
v.LIBSQLITE3_CFLAGS = ""
174+
if not v.LIBSQLITE3_LIBS:
175+
v.LIBSQLITE3_LIBS = "-lsqlite3"
176+
172177
# pkg-config probe
173178
pkg = pyconf.find_prog("pkg-config")
174179
if pkg:

Tools/configure/conf_net.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -356,20 +356,26 @@ def check_getaddrinfo(v):
356356
return 1;
357357
}
358358
"""
359-
pyconf.checking("getaddrinfo bug")
360-
if pyconf.cross_compiling:
361-
if v.ac_sys_system in ("Linux-android", "iOS"):
362-
ac_cv_buggy_getaddrinfo = False
363-
elif v.enable_ipv6 != "":
364-
ac_cv_buggy_getaddrinfo = (
365-
"no -- configured with --(en|dis)able-ipv6"
366-
)
359+
ac_cv_buggy_getaddrinfo = pyconf.cache_check(
360+
"getaddrinfo bug", "ac_cv_buggy_getaddrinfo"
361+
)
362+
if ac_cv_buggy_getaddrinfo is None:
363+
if pyconf.cross_compiling:
364+
if v.ac_sys_system in ("Linux-android", "iOS"):
365+
ac_cv_buggy_getaddrinfo = False
366+
elif v.enable_ipv6 != "":
367+
ac_cv_buggy_getaddrinfo = (
368+
"no -- configured with --(en|dis)able-ipv6"
369+
)
370+
else:
371+
ac_cv_buggy_getaddrinfo = True
367372
else:
368-
ac_cv_buggy_getaddrinfo = True
369-
else:
370-
ok = pyconf.run_check(GETADDRINFO_TEST)
371-
ac_cv_buggy_getaddrinfo = not ok
372-
pyconf.result(ac_cv_buggy_getaddrinfo)
373+
ok = pyconf.run_check(GETADDRINFO_TEST)
374+
ac_cv_buggy_getaddrinfo = not ok
375+
pyconf.cache_store(
376+
"ac_cv_buggy_getaddrinfo", ac_cv_buggy_getaddrinfo
377+
)
378+
pyconf.result(ac_cv_buggy_getaddrinfo)
373379
else:
374380
ac_cv_buggy_getaddrinfo = True
375381

Tools/configure/conf_wasm.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def setup_wasm_flags(v):
6868
_setup_wasi_flags(v)
6969

7070
# Force/suppress ac_cv_func_dlopen for WASM dynamic linking
71-
if v.enable_wasm_dynamic_linking is True:
71+
if v.enable_wasm_dynamic_linking == "yes":
7272
v.ac_cv_func_dlopen = True
7373
elif v.enable_wasm_dynamic_linking is False:
7474
v.ac_cv_func_dlopen = False
@@ -95,7 +95,10 @@ def setup_wasm_flags(v):
9595

9696
def _setup_emscripten_flags(v):
9797
"""Set Emscripten-specific flags."""
98-
v.wasm_debug = v.Py_DEBUG is True
98+
# configure.ac: AS_VAR_IF([Py_DEBUG], [yes], [wasm_debug=yes], [wasm_debug=no])
99+
# In autoconf Py_DEBUG is "true" not "yes", so this is currently always
100+
# false. We translate the comparison literally.
101+
v.wasm_debug = v.Py_DEBUG == "yes"
99102

100103
v.LINKFORSHARED += " -sALLOW_MEMORY_GROWTH -sINITIAL_MEMORY=20971520"
101104
v.LDFLAGS_NODIST += " -sWASM_BIGINT"
@@ -113,10 +116,10 @@ def _setup_emscripten_flags(v):
113116
v.LINKFORSHARED += " -sSTACK_SIZE=5MB"
114117
v.LINKFORSHARED += " -sTEXTDECODER=2"
115118

116-
if v.enable_wasm_dynamic_linking is True:
119+
if v.enable_wasm_dynamic_linking == "yes":
117120
v.LINKFORSHARED += " -sMAIN_MODULE"
118121

119-
if v.enable_wasm_pthreads is True:
122+
if v.enable_wasm_pthreads == "yes":
120123
v.CFLAGS_NODIST += " -pthread"
121124
v.LDFLAGS_NODIST += " -sUSE_PTHREADS"
122125
v.LINKFORSHARED += " -sPROXY_TO_PTHREAD"
@@ -150,7 +153,7 @@ def _setup_wasi_flags(v):
150153
)
151154
v.LIBS += " -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks"
152155

153-
if v.enable_wasm_pthreads is True:
156+
if v.enable_wasm_pthreads == "yes":
154157
v.CFLAGS_NODIST += " -target wasm32-wasi-threads -pthread"
155158
v.LDFLAGS_NODIST += (
156159
" -target wasm32-wasi-threads -pthread"

Tools/configure/pyconf.py

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,47 @@ def result(value: Any) -> None:
13961396
checking_fn = checking # alias used by link_check to avoid param shadowing
13971397

13981398

1399+
def cache_check(description: str, cache_var: str) -> Any:
1400+
"""AC_CACHE_CHECK — check the cache before running a probe.
1401+
1402+
Prints "checking <description>..." and looks up *cache_var* in the
1403+
cache (which may have been pre-seeded from CONFIG_SITE).
1404+
1405+
Returns the cached value on a hit (also prints "(cached) <value>")
1406+
or None on a miss. The caller is responsible for running the actual
1407+
probe on a miss and storing the result with
1408+
``cache_store(cache_var, value)`` followed by ``result(value)``.
1409+
1410+
Typical usage::
1411+
1412+
val = pyconf.cache_check("getaddrinfo bug", "ac_cv_buggy_getaddrinfo")
1413+
if val is None:
1414+
val = <run probe>
1415+
pyconf.cache_store("ac_cv_buggy_getaddrinfo", val)
1416+
pyconf.result(val)
1417+
"""
1418+
checking(description)
1419+
cached = cache.get(cache_var)
1420+
if cached is not None:
1421+
result(f"(cached) {_format_result(cached)}")
1422+
return cached
1423+
return None
1424+
1425+
1426+
def cache_store(cache_var: str, value: Any) -> None:
1427+
"""Store *value* in the cache under *cache_var*."""
1428+
cache[cache_var] = value
1429+
1430+
1431+
def _format_result(value: Any) -> str:
1432+
"""Format a cache value for display (True→'yes', False→'no')."""
1433+
if value is True:
1434+
return "yes"
1435+
if value is False:
1436+
return "no"
1437+
return str(value)
1438+
1439+
13991440
def _flush_result(value: Any) -> None:
14001441
"""Emit result(value) if a checking() is pending, otherwise do nothing.
14011442
@@ -1763,7 +1804,14 @@ def _identify_compiler() -> None:
17631804
except (subprocess.CalledProcessError, OSError):
17641805
ver = ""
17651806

1766-
if "clang" in ver.lower():
1807+
# Detect emcc (Emscripten) before clang — emcc's --version output
1808+
# contains "clang" but autoconf identifies it as "emcc" via the
1809+
# __EMSCRIPTEN__ preprocessor macro.
1810+
if cc_basename == "emcc" or "emscripten" in ver.lower():
1811+
ac_cv_cc_name = "emcc"
1812+
ac_cv_gcc_compat = True
1813+
GCC = True # emcc is gcc-compatible
1814+
elif "clang" in ver.lower():
17671815
ac_cv_cc_name = "clang"
17681816
ac_cv_gcc_compat = True
17691817
GCC = True # clang is gcc-compatible
@@ -3207,7 +3255,20 @@ def pkg_check_modules(pkg_var: str, module_spec: str) -> Any:
32073255
Returns a SimpleNamespace with .cflags and .libs on success, None if
32083256
pkg-config is unavailable or the module is not found.
32093257
Sets <PKG_VAR>_CFLAGS and <PKG_VAR>_LIBS in pyconf.substs.
3258+
3259+
Like autoconf's PKG_CHECK_MODULES, if the CFLAGS/LIBS variables are
3260+
already set (e.g. by check_emscripten_port or the user), the pkg-config
3261+
query is skipped and the existing values are used.
32103262
"""
3263+
cflags_name = f"{pkg_var}_CFLAGS"
3264+
libs_name = f"{pkg_var}_LIBS"
3265+
# If variables are already set (by user, environment, or emscripten port),
3266+
# honour them without querying pkg-config — matches autoconf behaviour.
3267+
existing_cflags = getattr(vars, cflags_name, "")
3268+
existing_libs = getattr(vars, libs_name, "")
3269+
if existing_cflags or existing_libs:
3270+
ns = types.SimpleNamespace(cflags=existing_cflags, libs=existing_libs)
3271+
return ns
32113272
pkg_config = shutil.which("pkg-config")
32123273
if not pkg_config:
32133274
return None
@@ -3224,10 +3285,10 @@ def pkg_check_modules(pkg_var: str, module_spec: str) -> Any:
32243285
).strip()
32253286
except subprocess.CalledProcessError:
32263287
return None
3227-
substs[f"{pkg_var}_CFLAGS"] = cflags
3228-
substs[f"{pkg_var}_LIBS"] = libs
3229-
setattr(vars, f"{pkg_var}_CFLAGS", cflags)
3230-
setattr(vars, f"{pkg_var}_LIBS", libs)
3288+
substs[cflags_name] = cflags
3289+
substs[libs_name] = libs
3290+
setattr(vars, cflags_name, cflags)
3291+
setattr(vars, libs_name, libs)
32313292
ns = types.SimpleNamespace(cflags=cflags, libs=libs)
32323293
return ns
32333294

Tools/configure/transpiler/lint_transpilable.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,11 @@
157157
"stdlib_module_simple",
158158
"stdlib_module_set_na",
159159
# Misc
160-
"run",
161-
"macro",
160+
"cache_check",
161+
"cache_store",
162162
"is_defined",
163+
"macro",
164+
"run",
163165
}
164166
)
165167

Tools/configure/transpiler/pyconf.awk

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,27 @@ function _pyconf_print_cached(val) {
125125
printf "%s (cached)\n", val
126126
}
127127

128+
# AC_CACHE_CHECK — check CACHE before running a probe.
129+
# Returns cached value on hit (prints "(cached) value"), "" on miss.
130+
function pyconf_cache_check(description, cache_var) {
131+
pyconf_checking(description)
132+
if (cache_var in CACHE) {
133+
pyconf_result("(cached) " _pyconf_format_result(CACHE[cache_var]))
134+
return CACHE[cache_var]
135+
}
136+
return ""
137+
}
138+
139+
function pyconf_cache_store(cache_var, value) {
140+
CACHE[cache_var] = value
141+
}
142+
143+
function _pyconf_format_result(val) {
144+
if (val == "yes") return "yes"
145+
if (val == "no") return "no"
146+
return val
147+
}
148+
128149
function pyconf_warn(msg) {
129150
printf "WARNING: %s\n", msg > "/dev/stderr"
130151
}
@@ -1989,8 +2010,13 @@ function pyconf_find_compiler(user_cc, user_cpp, cc, cpp, ver) {
19892010
}
19902011
pyconf_CPP = cpp
19912012
# Identify compiler via --version output
2013+
# Detect emcc before clang — emcc's version contains "clang"
19922014
ver = _cmd_output(cc " --version 2>/dev/null")
1993-
if (tolower(ver) ~ /clang/) {
2015+
if (pyconf_basename(cc) == "emcc" || tolower(ver) ~ /emscripten/) {
2016+
pyconf_ac_cv_cc_name = "emcc"
2017+
pyconf_ac_cv_gcc_compat = "yes"
2018+
pyconf_GCC = "yes"
2019+
} else if (tolower(ver) ~ /clang/) {
19942020
pyconf_ac_cv_cc_name = "clang"
19952021
pyconf_ac_cv_gcc_compat = "yes"
19962022
pyconf_GCC = "yes"

0 commit comments

Comments
 (0)