Skip to content

fix(appimage): keep ld-linux bundled + recurse exclude into nested dirs#16

Merged
senamakel merged 1 commit into
tinyhumansai:feat/ceffrom
Muscolino96:fix/appimage-keep-ld-linux-and-recurse-exclude
May 20, 2026
Merged

fix(appimage): keep ld-linux bundled + recurse exclude into nested dirs#16
senamakel merged 1 commit into
tinyhumansai:feat/ceffrom
Muscolino96:fix/appimage-keep-ld-linux-and-recurse-exclude

Conversation

@Muscolino96
Copy link
Copy Markdown

@Muscolino96 Muscolino96 commented May 18, 2026

Summary

  • Remove ld-linux from the AppImage exclude_prefixes — sharun needs the loader present in shared/lib/ to bootstrap the dynamic binary; stripping it leaves every locally-built AppImage aborting with Interpreter not found! before any chromium code runs.
  • Make the exclude sweep recursive (walkdir) so nested copies of libc.so / libm.so that lib4bin pulls into mirrored snap paths like shared/lib/snap/core20/<rev>/usr/lib/x86_64-linux-gnu/ are also stripped.

Problem

PR #15's exclude list (which extended PR tauri-apps#1996's glibc precedent to NSS/NSPR for tinyhumansai/openhuman#2001) had two side effects nobody verified end-to-end:

  1. The "glibc family" entries included ld-linux. lib4bin strips INTERP from the dynamic binary and expects sharun to provide a bundled loader; deleting the loader from shared/lib/ leaves sharun aborting with Interpreter not found! before any user-visible startup.
  2. fs::read_dir only enumerates top-level entries. On build hosts with snap-managed apps (VS Code, etc.), lib4bin mirrors source paths into shared/lib/snap/..., so old libc.so.6 survives the sweep and breaks GLIBC_2.x symbol resolution on rolling/newer distros even though the intent was to defer to host glibc.

Both reproduce on Ubuntu 26.04 GNOME-Wayland with a locally-built v0.53.49 AppImage. Test plan items in tinyhumansai/openhuman#2032 for "Run the resulting AppImage in archlinux:latest" and "Smoke-test on Ubuntu 22.04 / 24.04" were never checked off.

Solution

  • Drop "ld-linux" from exclude_prefixes with an inline comment explaining why it must stay bundled. Loader ABI is stable enough that the host-vs-bundle mix here remains safe — this matches the pattern in every working CEF/Electron-style AppImage I checked.
  • Replace fs::read_dir with walkdir::WalkDir::new(&dir_path).follow_links(false) so the sweep recurses into all nested mirror paths. Also accept symlinks (lib4bin produces both regular files and symlinks).

walkdir is already a tauri-bundler dep (no new dep added).

Verification

Locally-built v0.53.49 AppImage on Ubuntu 26.04 GNOME-Wayland:

  • Before this PR: AppImage dies with Interpreter not found! from sharun.
  • After this PR (manual reproduction): ld-linux-x86-64.so.2 is present in shared/lib/, sharun bootstraps, and no libc-2.31 survives in nested shared/lib/snap/... dirs. The dynamic binary loads, reaches RunEvent::Ready, and runs.

(Local manual repro because CI runs on ubuntu-22.04 which doesn't have snap-managed apps and so doesn't surface either regression.)

Impact

Linux AppImage bundles only. Other targets unchanged. Resolves the launch regression silently introduced by #15 + tauri-apps#1996; required for tinyhumansai/openhuman#2001 to actually close end-to-end.

Related

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced Linux AppImage bundling process with comprehensive library cleanup that now thoroughly handles nested library files throughout the application bundle structure
    • Increased robustness by improving error handling for missing or inaccessible directories during the application packaging stage
    • Refined library dependency exclusion logic to ensure more consistent and complete application bundles across various system configurations

Review Change Stack

The exclude list introduced for glibc/NSS (PR tinyhumansai#15 and tauri-apps#1996's precedent)
broke AppImage launch on every host in two ways that the original PRs'
test plans didn't cover:

1. `ld-linux` was bundled in the exclude list under the "glibc family"
   rationale, but sharun *requires* a loader to be present in
   `$APPDIR/shared/lib/` to bootstrap the dynamic OpenHuman binary
   (whose INTERP is stripped during lib4bin processing). With it
   excluded, sharun aborts with "Interpreter not found!" before any
   chromium code runs. The loader is ABI-stable enough across glibc
   versions for the host-vs-bundle mix here to remain safe.

2. The exclusion sweep used `fs::read_dir` on top-level `shared/lib`
   only. lib4bin mirrors source paths when libraries are pulled in from
   nested locations (e.g.
   `shared/lib/snap/core20/<rev>/usr/lib/x86_64-linux-gnu/libc.so.6`
   when the build host has snap-managed apps like VS Code), so nested
   copies of `libc.so`, `libm.so`, etc. survived the sweep and broke
   `GLIBC_2.x` symbol lookups on the target host even though the
   intent was to defer to host glibc.

Both reproduce on Ubuntu 26.04 GNOME-Wayland with the locally-built
v0.53.49 AppImage. Without (1), launch dies at sharun bootstrap;
with (1) but without (2), launch dies at `libm.so.6: version
GLIBC_2.35 not found`. Both fixed by this change.

Refs tinyhumansai/openhuman#2001, tinyhumansai/openhuman#2032,
tinyhumansai#15
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

📝 Walkthrough

Walkthrough

This PR refines the AppImage bundling cleanup in the Tauri CEF bundler. The change clarifies glibc family exclusion rules by explicitly removing ld-linux from the exclude list and updates the library directory cleanup to recursively traverse and remove excluded files at any depth, replacing a shallow top-level-only directory scan.

Changes

AppImage AppDir library cleanup refinement

Layer / File(s) Summary
Exclusion prefix configuration
crates/tauri-bundler/src/bundle/linux/appimage/sharun_cef.rs
The "glibc family" exclusion comments are clarified to explicitly state ld-linux is intentionally not excluded, and ld-linux is removed from the exclude_prefixes list, leaving standard glibc-related shared library names.
Recursive directory traversal and removal
crates/tauri-bundler/src/bundle/linux/appimage/sharun_cef.rs
AppDir cleanup for library directories (shared/lib, shared/lib32, lib, lib32) now skips missing directories and uses recursive walkdir iteration instead of shallow read_dir to remove excluded library files/symlinks found anywhere in the subtree, including nested copies from snap-managed paths.

Possibly related PRs

  • tinyhumansai/tauri-cef#14: Modifies the same AppImage AppDir/library cleanup logic in sharun_cef.rs regarding exclude-prefix handling for glibc/loader files.
  • tinyhumansai/tauri-cef#15: Updates sharun_cef.rs bundle_project library cleanup by refining exclude_prefixes (adds NSS/NSPR library exclusions alongside glibc changes).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes


A bundler hops through lib trees so deep,
Where glibc guards and symlinks sleep.
Now walkdir finds what shallow read would miss,
No ld-linux exile—that's the fix! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: keeping ld-linux bundled (not excluded) and implementing recursive directory traversal for library cleanup in AppImage bundles.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
crates/tauri-bundler/src/bundle/linux/appimage/sharun_cef.rs (1)

246-270: 🏗️ Heavy lift

Add a regression test for this cleanup pass.

This block now depends on two subtle contracts: ld-linux* must survive, while nested libc/libm/... copies under mirrored paths must be removed recursively. Since both failure modes already slipped past CI once, a small filesystem-level test here would make future changes much safer.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tauri-bundler/src/bundle/linux/appimage/sharun_cef.rs` around lines
246 - 270, Add a filesystem-level regression test that constructs a temporary
app_dir with the nested layout exercised by the cleanup loop in sharun_cef.rs
(paths like shared/lib/snap/core20/<rev>/usr/lib/... containing libc.so.6,
libm.so, etc.) plus a surviving ld-linux* entry (e.g.,
lib/ld-linux-x86-64.so.2), then invoke the cleanup pass (the code in
sharun_cef.rs that iterates over &["shared/lib","shared/lib32","lib","lib32"]
using walkdir and exclude_prefixes) and assert that the nested libc/libm copies
are removed recursively while the ld-linux* file still exists and other
non-excluded files are unchanged; include both regular files and symlinks in the
setup to cover the file_type checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/tauri-bundler/src/bundle/linux/appimage/sharun_cef.rs`:
- Around line 246-270: Add a filesystem-level regression test that constructs a
temporary app_dir with the nested layout exercised by the cleanup loop in
sharun_cef.rs (paths like shared/lib/snap/core20/<rev>/usr/lib/... containing
libc.so.6, libm.so, etc.) plus a surviving ld-linux* entry (e.g.,
lib/ld-linux-x86-64.so.2), then invoke the cleanup pass (the code in
sharun_cef.rs that iterates over &["shared/lib","shared/lib32","lib","lib32"]
using walkdir and exclude_prefixes) and assert that the nested libc/libm copies
are removed recursively while the ld-linux* file still exists and other
non-excluded files are unchanged; include both regular files and symlinks in the
setup to cover the file_type checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dc30ef95-0ae4-4cdd-8c6a-83639b67e8e8

📥 Commits

Reviewing files that changed from the base of the PR and between f75bc21 and 4cabccf.

📒 Files selected for processing (1)
  • crates/tauri-bundler/src/bundle/linux/appimage/sharun_cef.rs

@senamakel senamakel merged commit c90c8a3 into tinyhumansai:feat/cef May 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants