AppImageKit icon indicating copy to clipboard operation
AppImageKit copied to clipboard

Regarding running i386 AppImages on x86_64 architecture

Open kero990 opened this issue 7 months ago • 3 comments

Hi everyone,

I’ve been trying to package some old i386 applications/games as AppImages, but I’m not satisfied with the current approach of targeting either x86_64 or i386 exclusively. In reality, if I bundle all the necessary i386 runtime libraries, the AppImage should run on an x86_64 system even without i386 support enabled. To achieve this, I need to modify the program’s rpath and interpreter to make it fully portable and work seamlessly with both 32-bit and 64-bit systems when double-clicked or executed.

However, when packaging this as an AppImage, a major issue arises: the hardcoded relative interpreter path (/lib/ld-linux.so.2). While I can use patchelf --set-interpreter to modify it, the interpreter path doesn’t accept environment variables like $ORIGIN (unlike rpath). For the main application binary, this isn’t a big deal since it can still handle . or .., but for the AppImage or AppRun, it’s a problem. The mount path changes every time, making it impossible to specify a fixed path for ld-linux.so.2 in AppRun.

The current dilemma is this: if I modify AppRun with patchelf, it won’t support dynamic paths. I’ve seen some experimental projects that attempt to address this, but unfortunately, they only support 64-bit architectures, so they’re not helpful for our case. like this:https://github.com/corsix/polyfill-glibc/blob/main/docs/Relative_interpreter.md

If I abandon the binary AppRun and instead use a shell script named AppRun, the AppImage itself (as a binary) still hardcodes /lib/ld-linux.so.2. Of course, we could enable i386 libraries system-wide to ensure /lib/ld-linux.so.2 exists, but that clearly goes against the spirit of AppImage—the whole point of AppImage is to avoid installing dependencies, isn’t it?

This isn’t a problem report or a feature request—just a discussion to see if anyone has better ideas to make this work.

Personally, I think the solution lies in making AppRun dynamically recognize $APPDIR/lib/ld-linux.so.2 while ensuring the AppImage binary can still execute properly. But I’m not sure how to achieve that.

kero990 avatar May 29 '25 06:05 kero990

Hi @kero990, thanks for bringing up this interesting subject. Indeed I have been looking for a way to use $ORIGIN to set the interpreter for a long time, didn't know about https://github.com/corsix/polyfill-glibc/blob/main/docs/Relative_interpreter.md, so thank you very much for mentioning it.

They write

The tool is currently only available for x86_64. If other architectures are of interest to you, open a GitHub issue so that we can gauge demand.

So I've done just that:

  • https://github.com/corsix/polyfill-glibc/issues/19

Maybe you'd like to give it a thumbs up?

As to your concrete issue, I don't fully understand what you are trying to accomplish, and how.

It should be possible to put a 32-bit binary (and libraries) into a 64-bit AppImage with no issues, if you bundle libc entirely (or use a static build). In fact, I have done it before to run 32-bit software on 64-bit machines.

Or are you saying you need your 32-bit binary (and libraries) in a 32-bit AppImage, and this is not running on a 64-bit machine for some reason?

In any case, please show the concrete script you are using to produce the AppImage. Thanks!

probonopd avatar May 29 '25 06:05 probonopd

 the AppImage itself (as a binary) still hardcodes /lib/ld-linux.so.2

Are you talking about the appimage runtime? Use the static runtime in that case.

In any case if you are ok with changing the current working dir, the solution is having an AppRun script that changes the current working dir to the top level of the AppDir (usually the HERE var) and have a relative interpreter for the 32 and 64 bit binaries.

I think the solution lies in making AppRun dynamically recognize $APPDIR/lib/ld-linux.so.2 while ensuring the AppImage binary can still execute properly. But I’m not sure how to achieve that.

https://github.com/VHSgunzo/sharun

While the code has support for 32bit, including automatically separating 32bit libs from 64bit libs and checking the respective dynamic linker, sharun only has 64bit releases.

Samueru-sama avatar May 31 '25 11:05 Samueru-sama

the AppImage itself (as a binary) still hardcodes /lib/ld-linux.so.2

Are you talking about the appimage runtime? Use the static runtime in that case.

Which is the default nowadays anyway.

AppRun.c's AppRun binary should not be used by anyone randomly without knowing exactly what they do!

TheAssassin avatar May 31 '25 12:05 TheAssassin

As to your concrete issue, I don't fully understand what you are trying to accomplish, and how.

sorry,It's possible that I have been too focused on detailing specifics while overlooking the description of requirements. Here's the situation: If I package all the i386 libraries (including libc and ld-linux, everything that's needed), this i386 package can run in a pure 64-bit environment, even if the system does not have i386 support enabled. In other words, this package can run on both i386 and x64 systems without requiring any modifications from the user.

However, I am attempting to package it as an AppImage, and here's where the issue arises: an AppImage is either i386 or x64; the appimage file can run on both 32-bit and 64-bit systems simultaneously, even though its content is fully capable of doing so.

The obstacle to achieving this lies in what I mentioned initially: both AppRun and the AppImage file are binary files, and they must have /lib/ld-linux.so.2 hard-coded. This linker must reside in /lib and not anywhere else, even if the AppImage itself already packages the linker. The binary files will only search for /lib/ld-linux.so.2, not the one included in the package.

In summary, I am seeking a method that allows a 32-bit AppImage to run on both 32-bit and 64-bit systems, to avoid distributing two packages with identical content. While the packaged content itself is capable of achieving this, the AppImage format currently does not support it.

kero990 avatar Jul 11 '25 03:07 kero990