Skip to content

Pip: strip symbols in manylinux wheel repair - #6525

Merged
Fedr merged 2 commits into
masterfrom
wheel-strip-symbols
Aug 5, 2026
Merged

Pip: strip symbols in manylinux wheel repair#6525
Fedr merged 2 commits into
masterfrom
wheel-strip-symbols

Conversation

@Fedr

@Fedr Fedr commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Strip symbols from MeshLib's own libraries (libMR*.so, the pybind stubs lib, and the module extensions) before building the manylinux wheels. The vcpkg-built third-party libraries and mrmeshpy.so itself are already stripped; our libs were the only unstripped ones — .symtab + .strtab are ~21% of libMRMesh.so.

.dynsym is untouched, so runtime symbol resolution is unaffected; the only cost is that native frames from our libs in user crash dumps lose names, same as the third-party libs today.

The stripping deliberately happens before auditwheel repair rather than via auditwheel's own --strip flag: auditwheel strips after patchelf-ing the grafted libs, and stripping a patchelf'ed library corrupts its ELF load command alignment. A first attempt with --strip built fine but the wheel failed to import on every distro with ImportError: libTKernel-….so.7.9.1: ELF load command address/offset not page-aligned (run 31016844725).

pip-build doesn't run on PRs, so this was verified with a dry pip-build dispatch from this branch, macOS/Windows legs disabled (run 31020073470): both manylinux builds green, and all 14 manylinux-pip-test jobs (Rocky 8, Debian 11, Ubuntu 22.04/25.10, Fedora 37/39/42 × x86_64/aarch64) installed the stripped wheel and passed the Python test suite.

Resulting x86_64 wheel from that run vs the published 3.1.3.429 wheel:

published stripped
wheel (download) 78.4 MB 77.5 MB
unpacked (installed) 250.6 MB 242.4 MB
libMRMesh.so 10.6 MB 8.4 MB
libMRViewer.so 10.2 MB 7.7 MB
libMRVoxels.so 8.5 MB 5.8 MB

The download win is modest (symbol string tables compress ~7:1), the installed-size win is ~8 MB.

Windows is unaffected (PDBs are never packed), and delocate has no equivalent hook on macOS, so those wheels are unchanged for now.

auditwheel repair --strip runs strip -s on grafted libs and extension modules; saves ~9 MB unpacked / ~1.2 MB compressed per Linux wheel.
Comment thread scripts/wheel/build_wheel.py Outdated
sys.executable, "-m", "auditwheel",
"repair",
"--plat", f"manylinux_{manylinux_version}_{platform.machine()}",
"--strip", # drop .symtab/.strtab (~9 MB unpacked); MR libs are built unstripped

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop the comment.

auditwheel --strip runs after patchelf and corrupts ELF load command alignment (import failed on every distro); stripping the source libs before repair avoids that ordering.
@Fedr
Fedr merged commit 6411892 into master Aug 5, 2026
56 checks passed
@Fedr
Fedr deleted the wheel-strip-symbols branch August 5, 2026 17:41
Fedr added a commit that referenced this pull request Aug 7, 2026
`--icf=safe` can only fold functions the compiler placed in a section of their own: without `-ffunction-sections` that is just the COMDAT ones (templates, inlines), while plain out-of-line functions share one `.text` per translation unit and never fold. Gated with the ICF flag inside the `MESHLIB_HAVE_LLD` block, non-Debug only, and restricted to C/C++ via `$<COMPILE_LANGUAGE:C,CXX>` so nvcc never receives it.

Stripped shared libraries shrink 2.0% on both arches: -921,600 B on x64, -917,504 B on arm64. The saving is mostly exception-handling tables rather than code — `.gcc_except_table` -845 KB x64 / -917 KB arm64 against about -56 KB of `.text`. `libMeshLibC2.so` alone drops its LSDA section by 79% (1,045,892 -> 220,576) while its `.text` is byte-identical: the generated C bindings are thousands of near-identical try/catch wrappers, so their unwind tables are duplicates even where the surrounding code is not.

Unstripped arm64 builds grow 2.7% instead, entirely from per-function section symbols in `.symtab`/`.strtab`. Those are not SEC_ALLOC, are never loaded at runtime, and are removed by `strip` — which every shipped artifact gets: wheels via #6525, the AppImage from linuxdeploy. The `linux-vcpkg` tar.xz is the exception, since `scripts/distribution_vcpkg.sh` does not strip; its compressed delta is unmeasured.
Fedr added a commit that referenced this pull request Aug 7, 2026
The linux-vcpkg tar.xz was the last artifact shipping unstripped libraries: the wheels (#6525) and the AppImage (linuxdeploy strips unless NO_STRIP is set) have always been stripped. `.symtab`/`.strtab` are not SEC_ALLOC, are never loaded at runtime, and linking against the package needs only `.dynsym`, which strip keeps.

The archive shrinks 1,504,076 B on x64 (-2.19%) and 2,131,340 B on arm64 (-3.26%); an unpacked install shrinks by the full 16.3 MB / 17.6 MB of symbol tables. This also removes the only place where `-ffunction-sections` (#6550) inflated `.symtab` visibly.

Third-party libraries copied from vcpkg are left alone: blanket-stripping that tree would hit `.a` archives, where it breaks linking. Backtraces inside the shipped libraries now lose the names of non-exported functions, as is already the case for every wheel and AppImage we publish.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants