Problem
The embedded-CPython python_facades test binary links to the uv-managed libpython, but the Linux dynamic loader cannot find it when the test is invoked directly. On a local Linux checkout, soldr cargo test -p fbuild-python --test python_facades -- --ignored exits 127 before any test runs:
error while loading shared libraries: libpython3.13.so.1.0: cannot open shared object file: No such file or directory
ldd target/debug/deps/python_facades-* reports libpython3.13.so.1.0 => not found; readelf -d shows a RUNPATH for the toolchain libraries but not the uv Python lib directory. The library exists under the uv-managed interpreter. This is a test-binary runtime-loader setup issue, not a serial-session failure or a Rust link error.
The python-facade-tests job in .github/workflows/check-ubuntu.yml explicitly resolves the pinned Python 3.10 LIBDIR and writes LD_LIBRARY_PATH to GITHUB_ENV before running the test. crates/fbuild-python/tests/README.md documents a similar manual export for local runs, but the ordinary approved soldr cargo test ... invocation does not provide it. The README also uses python3 for LIBDIR while PYO3_PYTHON can point to a different interpreter, which can silently select the wrong library directory.
Expected behavior / proposed scope
Provide one reproducible, interpreter-consistent way to run the embedded-CPython facade tests locally and in CI without manually discovering and exporting a separate library path. Resolve LIBDIR from the exact PYO3_PYTHON selected for the build, preserve any existing loader path, and keep this setup scoped to the embedded-Python test runner (not global Rust builds). A test-runner wrapper, stable test binary runpath, or an equivalent approach is acceptable; choose the least invasive portable option. Update the test README and CI job to use the same approach where practical.
Acceptance
- RED: On Linux with a uv-managed shared Python whose
lib directory is outside default loader paths, the direct test invocation fails before tests start with the missing libpython error.
- GREEN: The documented local test command/test-runner starts and runs
python_facades without a user-authored LD_LIBRARY_PATH export, using the same interpreter for PyO3 and library lookup.
- CI's pinned-Python facade job still runs the ignored tests, and existing
LD_LIBRARY_PATH entries are preserved.
- Add a focused check or test for interpreter/path selection so a future Python-version mismatch is caught.
Decisions
Problem
The embedded-CPython
python_facadestest binary links to the uv-managedlibpython, but the Linux dynamic loader cannot find it when the test is invoked directly. On a local Linux checkout,soldr cargo test -p fbuild-python --test python_facades -- --ignoredexits 127 before any test runs:ldd target/debug/deps/python_facades-*reportslibpython3.13.so.1.0 => not found;readelf -dshows a RUNPATH for the toolchain libraries but not the uv Pythonlibdirectory. The library exists under the uv-managed interpreter. This is a test-binary runtime-loader setup issue, not a serial-session failure or a Rust link error.The
python-facade-testsjob in.github/workflows/check-ubuntu.ymlexplicitly resolves the pinned Python 3.10LIBDIRand writesLD_LIBRARY_PATHtoGITHUB_ENVbefore running the test.crates/fbuild-python/tests/README.mddocuments a similar manual export for local runs, but the ordinary approvedsoldr cargo test ...invocation does not provide it. The README also usespython3forLIBDIRwhilePYO3_PYTHONcan point to a different interpreter, which can silently select the wrong library directory.Expected behavior / proposed scope
Provide one reproducible, interpreter-consistent way to run the embedded-CPython facade tests locally and in CI without manually discovering and exporting a separate library path. Resolve
LIBDIRfrom the exactPYO3_PYTHONselected for the build, preserve any existing loader path, and keep this setup scoped to the embedded-Python test runner (not global Rust builds). A test-runner wrapper, stable test binary runpath, or an equivalent approach is acceptable; choose the least invasive portable option. Update the test README and CI job to use the same approach where practical.Acceptance
libdirectory is outside default loader paths, the direct test invocation fails before tests start with the missinglibpythonerror.python_facadeswithout a user-authoredLD_LIBRARY_PATHexport, using the same interpreter for PyO3 and library lookup.LD_LIBRARY_PATHentries are preserved.Decisions
LD_LIBRARY_PATHpath.libpython,LD_LIBRARY_PATH, andpython_facades(issue Should serial monitor be fully async? Shared session core; promote AsyncSerialMonitor out of experimental #1485 is the parent feature only).