Follow up to https://github.com/pydantic/monty/issues/944
When building Monty’s Linux x64 addon with --use-napi-cross, the published binary fails to load on glibc 2.34:
undefined symbol: __isoc23_sscanf
The addon also has an unresolved, unversioned reference to __isoc23_strtol.
Monty 1.1.0 uses @napi-rs/cli 3.7.1. I checked 3.10.8’s source and it appears to retain the same compiler environment handling.
Suspected cause
--use-napi-cross sets the Rust linker to the downloaded glibc 2.17 toolchain, but sets the C/C++ compilers through TARGET_CC and TARGET_CXX.
For x64 builds on an x64 Linux runner, Cargo has HOST == TARGET. The cc crate and aws-lc-sys therefore select HOST_CC/CC, ignoring TARGET_CC.
This appears to allow AWS-LC’s C sources to compile against the host’s newer glibc headers while the final addon links against the older sysroot. AWS-LC defines _GNU_SOURCE, and newer glibc headers redirect its sscanf and strtol calls to the _isoc23* variants.
Relevant source:
- napi CLI compiler environment setup (https://github.com/napi-rs/napi-rs/blob/9c49b6c5d295d05e75d03b6965f080273b3116df/cli/src/api/build.ts#L1353)
- Monty’s glibc 2.17 build change (https://github.com/pydantic/monty/commit/e007685fbb06494c13b9a7b3fede9f8e6a54a2be)
- cc 1.4.6 source (https://docs.rs/crate/cc/1.4.6/source/src/lib.rs)
- aws-lc-sys 0.45.0 compiler selection (https://docs.rs/crate/aws-lc-sys/0.45.0/source/builder/main.rs)
Reproduction
On Linux x64 with glibc 2.34 and Node 22.13.1:
npm pack @pydantic/monty-linux-x64-gnu@1.1.0 tar -xzf pydantic-monty-linux-x64-gnu-1.1.0.tgz
node -e "require('./package/monty.linux-x64-gnu.node')"
readelf --dyn-syms -W package/monty.linux-x64-gnu.node
| grep -E '_isoc23(sscanf|strtol)'
Loading fails with the error above. Bun 1.4.2 reproduces the same failure. The standalone Monty worker runs successfully.
The highest versioned glibc requirement in the addon is only GLIBC_2.16. Consequently, checking only GLIBC_* versions misses these unversioned references.
Expected behavior
--use-napi-cross should ensure C/C++ dependencies use the downloaded toolchain even when the target triple matches the host.
Could it set target-specific variables such as CC_x86_64_unknown_linux_gnu and CXX_x86_64_unknown_linux_gnu, or otherwise account for native builds?
An addon-load test on an older-glibc system would also catch failures that symbol-version inspection misses
This is still present in 1.3.0 for what it's worth @samuelcolvin