[build] E: Build libffi.so alongside libffi.a#1
Closed
esaurez wants to merge 1 commit into
Closed
Conversation
Produce a position-independent libffi.so in addition to the existing static libffi.a. The .so leaves libposix/libc/libm symbols unresolved so they bind to the host executable's .dynsym at dlopen time -- the same model already used by libxml2.so / liblxml_etree.so on Nanvix. Two changes wired together: 1. NANVIX_LIBS now uses -L/-l form instead of explicit .a paths. When explicit archive paths are passed via configure-time LDFLAGS, libtool treats them as convenience archives and bundles their members into libffi.a (libposix.a, libc.a, libm.a as nested ar members, plus lt1-/lt2-/lt3- renamed copies). Consumers that try \--whole-archive libffi.a\ then fail because ld cannot expand a nested archive. Switching to -L/-l form lets autoconf's AC_PROG_CC conftest still link a hello-world while libtool records the libs as system deplibs (in libffi.la) and does NOT bundle them. Result: libffi.a contains only its own 8 .o files. 2. Added a SHAREDLIB target that links libffi.so from the (now PIC) libffi.a via -Wl,--whole-archive, sets DT_SONAME=libffi.so, leaves libposix/libc/libm UND. Updated z.py output_files, the package / verify-package targets, and added structural checks in test-functional (SONAME, ffi_call exported, no nested archives). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Jun 5, 2026
Owner
Author
|
Superseded by upstream PR nanvix#235, which carries the same .so build addition -- rebased onto current upstream version branch, scope-trimmed (CI workflow downgrade, nanvix.toml version downgrade, .gitignore tweaks, .zutils-version downgrade, z.ps1/z.sh additions all dropped as unrelated env drift), and esaurez/* / python.elf / nanvix-todo references cleaned from commit message and PR body. Closing this fork PR; tracking continues upstream. |
This was referenced Jun 9, 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.
Summary
Produce a position-independent
libffi.soin addition to the existing staticlibffi.a, mirroring the pattern already established by esaurez/libxml2#1. The.soleaveslibposix/libc/libmsymbols unresolved so they bind to the host executable's.dynsymat dlopen time — the same model used by all CPython extension modules on Nanvix.Why
This unblocks the Group B unbundling of
_ctypesin CPython (see tracking note). Today_ctypes.cpython-312.sostatically bundles a copy of libffi (~700 KB of duplication). Withlibffi.soavailable,_ctypes.socan drop to a thin module +DT_NEEDED libffi.so(~80 KB), and any other consumers that want to use libffi at runtime can share the same.so.Beyond the size win, this also fixes a latent correctness issue:
libffi.aas previously built was unusable underld --whole-archive, which made it impossible to pull libffi intopython.elf's.dynsymfor the Group A unbundling strategy. The root cause and fix are documented below.Implementation
Fix 1 —
libffi.anested-archive bundlingNANVIX_LIBSnow uses-L/-lform/sysroot/lib/libposix.a /toolchain/lib/libc.a /toolchain/lib/libm.apassed via configure-timeLDFLAGS. Libtool's static-link path treats explicit.apaths as "convenience archives" and bundles their members into the resultinglibffi.aviaar cr. The result before this fix:$ ar t libffi.alibposix.alibc.alibm.alt1-libposix.alt2-libc.alt3-libm.aprep_cif.o...Consumers that try
ld --whole-archive libffi.athen fail becauseldcannot expand a nested archive. Switching to-L/-lform lets autoconf'sAC_PROG_CCconftest still link a hello-world (so configure passes) while libtool records the libs as system deplibs inlibffi.laand does NOT bundle them intolibffi.a.After the fix:
Fix 2 —
libffi.sobuild target-fPICinCFLAGS.ofiles reusable for.aand.so--disable-sharedi686-nanvix; the.sois linked manually$(SHAREDLIB)targeti686-nanvix-gcc -shared -fPIC -nostdlib -Wl,--whole-archive libffi.a -Wl,--no-whole-archive -Wl,-soname,libffi.so -Wl,-z,noexecstack -o libffi.sotest-functionalextendedDT_SONAME=libffi.so,ffi_call/ffi_prep_cifexported in.dynsym, and thatlibffi.ais free of nested-archive memberspackage/verify-package.aand.so.nanvix/z.py_OUTPUT_FILESlibffi.soback from the Docker build dirValidation
End-to-end runtime resolution (CPython
dlopen→_ctypes.so→DT_NEEDED libffi.so→ loader walks chain → resolveslibposix/libc/libmUND againstpython.elf's.dynsym) will be validated in the follow-up CPython integration PR.Runtime dependencies
.init_arrayinvocation and DT_NEEDED chain walking in the user-space loader. (libffi has no global constructors of its own, but DT_RUNPATH is needed by the consumer chain.)libffi.sodoes not introduce a diamond, so esaurez/nanvix#28 is not required for this PR specifically; consumers that combine libffi with other shared libs may still rely on nanvix#28 indirectly.Downstream consumer
_ctypes.cpython-312.sotoDT_NEEDED libffi.soso the ~700 KB libffi copy is shared instead of bundled per-extension.