Fix building against glibc older than 2.29 - #104
Open
bernardladenthin wants to merge 2 commits into
Open
Conversation
posix_spawn_file_actions_addchdir_np arrived in glibc 2.29, so subprocess_create_ex fails to compile and link on older systems such as manylinux2014. Add a SUBPROCESS_HAVE_CWD probe, report a requested cwd as ENOSYS where the call is unavailable, and skip the cwd test there.
musl gained posix_spawn_file_actions_addchdir_np in 1.1.24 but exposes no version macro, so the detection cannot cover older releases. Skip it when the macro is already defined, letting those users set it themselves.
This was referenced Aug 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
subprocess.hdoes not compile on glibc older than 2.29 oncesubprocess_create_exisused.
posix_spawn_file_actions_addchdir_np(added by #83, macOS branch added by #99)only exists from glibc 2.29 onwards, and the POSIX path calls it unconditionally.
On manylinux2014 (CentOS 7, glibc 2.17, devtoolset-10 / GCC 10.2) the failure appears in
three shapes depending on the language mode:
The third one matters: in
gnu89the implicit declaration is only a warning, so thecompiler is happy and the linker fails instead. The symbol is genuinely absent from
libc.so. This is therefore not the_GNU_SOURCEvisibility issue thattest/CMakeLists.txtalready works around — no feature-test macro can conjure a symbolthat does not exist.
Affected in practice: manylinux2014 (glibc 2.17) and manylinux_2_28 (glibc 2.28), i.e. the
standard build environments for redistributable Linux binaries. llama.cpp vendors this
header, so its manylinux jobs hit this too.
Fix
Add a
SUBPROCESS_HAVE_CWDcompile-time probe next to the POSIX includes, and report arequested
process_cwdasENOSYSwhere the platform cannot honour it. Thecwdtest iscompiled only where the capability exists.
Four deliberate choices:
cwd, not how it is implemented.#if !defined(_WIN32). An undefined macroevaluates to 0 inside
#if, which would have silently dropped the test on Windows.#if, not#if defined(__GLIBC__) && !__GLIBC_PREREQ(2, 29). Thepreprocessor replaces unknown identifiers with
0before evaluating, so the flat formbecomes
0 (2, 29)— a syntax error on macOS, musl and Windows.&&does not help,because this fails at parse time, not evaluation time.
it cannot recognise are not stuck with the wrong answer. See the limitation below.
Behaviour on glibc >= 2.29 and on every non-glibc platform is byte-for-byte unchanged.
The macro is documented in
README.mdnext to theprocess_cwdargument.Testing
Full test suite in Docker, one container per row, sanitizer probes pinned off for
reproducibility. Windows was built natively with MSVC.
SUBPROCESS_HAVE_CWDBefore this change, the first two rows do not build at all.
The 2.29 boundary is hit exactly: 2.28 → 0, 2.29 → 1, 2.31 → 1. The 9
cwdtest cases areexcluded only where the function is missing — all 432 are still compiled and green
everywhere else, including musl, where the
#elsebranch applies. On Windows all 9 arepresent and pass; the total of 387 there is 432 minus the 45 cases (5 tests x 9 language
modes) that
test_shared.halready excludes under#if !defined(_MSC_VER).macOS was not tested locally — CI covers it.
Limitation: musl older than 1.1.24
musl gained
posix_spawn_file_actions_addchdir_npin 1.1.24, so the#elsebranch iswrong for releases before that: Alpine 3.10 (musl 1.1.22) still fails to link. musl
deliberately exposes no version macro, so this cannot be detected. That is what the
override is for —
-DSUBPROCESS_HAVE_CWD=0builds cleanly there, verified.Pre-existing failures on glibc 2.17, unrelated to this change
The 18 remaining failures on manylinux2014 are
create_ex_subprocess_create_failure_preserves_errorand
create_ex_subprocess_create_failure_does_not_leak_resourcesacross the 9 languagemodes. They expect
subprocess_error_not_foundand get0.The cause is in glibc, not in this library. A standalone probe on the same image:
Old
posix_spawndoes not report a failedexecback to the caller; glibc reworked thisin 2.24 — the same probe returns
rc=0on 2.17 and 2.23, andrc=2on 2.24 and 2.28.AlmaLinux 8 (glibc 2.28) shows the same
SUBPROCESS_HAVE_CWD=0code path withzero failures, which isolates it cleanly. These failures were simply never observable
before, because the library did not build there at all. Not addressed here.
Also noticed
test/CMakeLists.txtpasses-std=c++20, which GCC 8 (the RHEL 8 system compiler) rejectsin favour of
-std=c++2a— the suite cannot be built with it, though the library itselfcompiles fine. Not touched here; #105 fixes it separately.