AppImage / AppImageKit

Package desktop applications as AppImages that run on common Linux-based operating systems, such as RHEL, CentOS, openSUSE, SLED, Ubuntu, Fedora, debian and derivatives. Join #AppImage on irc.libera.chat
http://appimage.org
Other
8.66k stars 553 forks source link

AppImage for BSD #98

Open Achrine opened 8 years ago

kskarthik commented 8 years ago

Why don't you try out yourself. I think the same process can be followed for BSD too. Just try with your native package manager. Come back when you have a problem compiling.

probonopd commented 8 years ago

I haven't tried so far; mainly because I don't have a BSD Live ISO that can be live-booted with GRUB2.

TheAssassin commented 6 years ago

@asdedhj have you ever tried to get an AppImage run on BSD? I mean, after all, the only Linux-specific dependency we have is FUSE, which I assume is available on BSD as well. There's a few Linux specific code snippets in our code we could replace, but first, someone should test what needs to be done for proper BSD support.

probonopd commented 6 years ago

It would be amazing if AppImages worked with BSD.

While I agree, we won't be working on it unless some BSD user/developer steps up to do it. That person would, of course, have our full support.

TheAssassin commented 6 years ago

Let's not close this, but add the "help wanted" flag instead. We wouldn't reject a PR implementing support for this, of course.

despair86 commented 6 years ago

libfuse: available in all the major UNIX (both free and proprietary)

I'm away-from-desk rn, I'll have to take a look at the build documentation soon

kolbycrouch commented 5 years ago

I have a tree with FreeBSD support I've just finished.

The only problem is that it currently requires "/proc/curproc/file" ( FreeBSD equivalent of /proc/self/exe ). In theory this is fine, as it works the same as on Linux. However, proc is never mounted by default on FreeBSD. On most linux distros, proc is mounted, and the fuse module is usually loaded by udev at boot. So it would seem that users that will never have root access can use AppImages. On FreeBSD, you would almost certainly have to get root access to at least setup your system for /proc and fuse.

For most FreeBSD users, I'm sure this is acceptable, but I'm not sure how you all feel about it.

Let me know, and ill clean up my changes and make a pull request. Right now my tree has dlopen for fuse removed and all binaries statically linked, so i'll just quickly patch only the stuff needed for FreeBSD in a new tree and make the request if the above issue is tolerable.

brunobiondo commented 5 years ago

@Kolbycrouch, for my freeBSD I feel that your solution could be ok. I hope you provide instruction on installation procedure. I'm challenging the endeavor to install a IOTA Crypto-wallet (Trinity) on my FreeBSD, and it comes in .Appimages (with .yml description files), linux 64 .tar.gz (but I'm not specialized in installing from .tar.gz, only from ports and packages). Thank you very much

probonopd commented 5 years ago

Hi @kolbycrouch that's great to hear! Is there any way to try it out without having to wipe a full hard disk?

TheAssassin commented 5 years ago

@probonopd you could just install to a USB disk...

@kolbycrouch that is really the only change needed? Wow, I expected more changes. I'll check how we can check whether we build for a BSD with CMake and will add some preprocessor changes to use the other path then. Would the Linux binaries "just run" on FreeBSD? Then I'd rather detect the paths during runtime, this isn't black magic. Can you push your branch somewhere? We should also check whether there's an alternative to depending on /proc which works on FreeBSD (and maybe even Linux, who knows!).

probonopd commented 5 years ago

Wait a second, are we talking about a port of AppImage (i.e., runtime.c is compiled to a native BSD application) or are we talking about using the Linux compatibility layer (i.e., runtime.c and/or the payload is a Linux binary that gets executed through BSD's Linux compatibility layer)?

TheAssassin commented 5 years ago

My guess was the former, but I wasn't sure hence the question.

brunobiondo commented 5 years ago

@kolbycrouch as for the first requirement for Appimages to work in FreeBSD, aka emulating a linux /proc filesysytem, I solved the issue, since FreebSD has a built-in facility for that, called linprocfs filesystem. The command for emulating linux /proc filesystem is: mount -t linprocfs linproc /compat/linux/proc and to load it at boot time open /etc/fstab and add this line: linproc /compat/linux/proc linprocfs rw 0 0

I'm now trying to solve the FUSE issue, without success. I loaded the FUSE kernel module with "kldload fuse" (you can verify with "kldstat") then installed sysutils/fusefs-libs, but when I launch an .Appimage I still see this error: "dlopen(): error loading libfuse.so.2" "Appimages require FUSE to run"

Notice that I see on my system is present /usr/local/lib/libfuse.so.2 (a symbolic link to the actual library) Working on that, and any help would be appreciated, thank you.

kolbycrouch commented 5 years ago

Wait a second, are we talking about a port of AppImage (i.e., runtime.c is compiled to a native BSD application) or are we talking about using the Linux compatibility layer (i.e., runtime.c and/or the payload is a Linux binary that gets executed through BSD's Linux compatibility layer)?

I'm talking about porting AppImage to run on FreeBSD. Now that you mention it though, I believe the OP is talking about running a Linux appimage on FreeBSD.

Right now I'm having some problem where the squashfs gets mounted, but I think something goes wrong in creating the temp directory. The appimage will start, run the binary that AppRun points too, but stalls for several minutes trying to unmount the filesystem. Trying to read the temp directory with anything (i.e. /bin/ls or /bin/du) stalls as well. Once I figure it out everything should be good to go.

Quick question though. After glancing over runtime.c some more, it looks like we remove the files that are mounted? Am I wrong about this, or is this really how it works? If so, why not simply unmount the filesystem?

@brunobiondo If you want to run a Linux appimage, you will need ALL the dependencies that AppImage needs placed in the /compat/linux directory. The easiest way to do this is probably extracting a full rootfs of the latest Ubuntu lts and perhaps even chrooting into it to install everything else you need. I'm not 100% sure if that will work, but I've seen guides on the internet about running full distros in a chroot on freebsd.

Keep in mind though. The compat layer is not complete. You may end up running into some issue where a syscall isn't implemented, and the error might be quite cryptic to you.

The best thing to do would be to see if you can build a freebsd binary from source if it's available. I messed around with a few crypto miners/wallets a couple of years ago, and was able to get everything except for the CUDA-dependent stuff working. This way you won't need linux compat or AppImage support.

TheAssassin commented 5 years ago

Quick question though. After glancing over runtime.c some more, it looks like we remove the files that are mounted? Am I wrong about this, or is this really how it works? If so, why not simply unmount the filesystem?

The workflow is:

  1. create tempdir as mountpoint
  2. mount AppImage contents to temporary mountpoint
  3. launch contents; wait for termination
  4. unmount temporary mountpoint
  5. clean up temporary mountpoint directory
brunobiondo commented 5 years ago

I'm talking about porting AppImage to run on FreeBSD

Ok, I understand you are trying to port native AppImage support to FreeBSD :) Thanks also for the help from @TheAssassin

The best thing to do would be to see if you can build a freebsd binary from source if it's available. I messed around with a few crypto miners/wallets a couple of years ago, and was able to get everything except for the CUDA-dependent stuff working. This way you won't need linux compat or AppImage support.

Yes, I'm trying to install a wallet for the upcoming groundbreaking IOTA crypto currency. UPDATE 2/2/2019 Trying to build from sources, as per instructions at https://github.com/iotaledger/trinity-wallet (or alternatively https://github.com/iotaledger/wallet), but it's a bit complicated, the application is based on ReactJs and built with React-Native (mobile) and Electron (desktop): different javascript package managers are required (yarn, npm) for installing the stuff, and I get stuck at a point in the installation, so I looked for pre-compiled packages at https://github.com/iotaledger/trinity-wallet/releases

@brunobiondo If you want to run a Linux appimage, you will need ALL the dependencies that AppImage needs placed in the /compat/linux directory. The easiest way to do this is probably extracting a full rootfs of the latest Ubuntu lts and perhaps even chrooting into it to install everything else you need. I'm not 100% sure if that will work, but I've seen guides on the internet about running full distros in a chroot on freebsd.

I follow your advice, I will not try to run a Linux AppImage, but I have a curiosity just en-passant, and would like your opinion: but in general installing a rootfs in a docker container could it be a viable solution for testing applications written for other OSes?

probonopd commented 5 years ago

If you want to run a Linux appimage, you will need ALL the dependencies that AppImage needs placed in the /compat/linux directory.

Out of curiosity, please try the Inkscape 1.0 pre-alpha AppImage from inkscape.org. Unlike most other AppImages, this one bundles everything, so there should be no external dependencies. I am wondering how it would fare with the BSD Linux compatibility layer. As a temporary workaround as long as FUSE is not working, you can extract and run it with --appimage-extract-and-run...

brunobiondo commented 5 years ago

Hi @probonopd, as per your suggestions, and after having set up linux compatibility as per instructions here https://www.freebsd.org/doc/handbook/linuxemu-lbc-install.html, this is the output from running the Inskscape pre-alpha Appimage:

/root > ./Inkscape-9dee831-x86_64.AppImage --appimage-extract-and-run [....] /tmp/appimage_extracted_42c161d9501409a8e1d6892625d64f26/usr/share/themes/Adwaita-dark/index.theme /tmp/appimage_extracted_42c161d9501409a8e1d6892625d64f26/usr/share/thumbnailers /tmp/appimage_extracted_42c161d9501409a8e1d6892625d64f26/usr/share/thumbnailers/librsvg.thumbnailer [...] ELF Binary type "0" not known /compat/linux/tmp/appimage_extracted_42c161d9501409a8e1d6892625d64f26/AppRun: line 67: /compat/linux/tmp/appimage_extracted_42c161d9501409a8e1d6892625d64f26/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2: cannot execute binary file /compat/linux/tmp/appimage_extracted_42c161d9501409a8e1d6892625d64f26/AppRun: line 67: /compat/linux/tmp/appimage_extracted_42c161d9501409a8e1d6892625d64f26/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2: Success /root >

Also notice that using 'brandelf -t linux ./Inkscape-9dee831-x86_64.AppImage' PRODUCED NO OUTPUT.

probonopd commented 5 years ago

OK, so it seems like the extraction does work but running lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 does not. Thanks for having tested it. (This AppImage is an exception; other AppImages don't usually run lib/x86_64-linux-gnu/ld-linux-x86-64.so.2.)

brunobiondo commented 5 years ago

Hi @probonopd, I've read the section about FUSE here https://github.com/AppImage/AppImageKit/wiki/FUSE, where you cite AppRun, then I noticed that AppRun is a bash shell script, and wanted to point out that the so-called she-bang (1st line) for where to search the shell interpreter, in AppRun is '#!/usr/bin/bash'. This can work for many unix flavors OSes, but in FreeBSD, by default, the interpreters are put in /usr/local/bin, and there are some (posix?) specifications that come in aid for more portability in general: specify the she-bang as '#!/usr/bin/env bash', this should rely on the $SHELL environment variable this calls the env utility that searches in the directories specified in the $PATH environment variable (unless otherwise specified), then invokes the specified argument (interpreter). (For most of my few local shell scripts, I'm lazy in still using '#!/usr/local/bin/fish', and I know they could not be portable across different platforms). I hope that this can be helpful to AppImage developers.

probonopd commented 5 years ago

Thanks @brunobiondo. The different shells are not always 100% compatible, so I explicitly set it to bash to ensure that the Bourne Again Shell is used.

Every AppImage may contain something else as the AppRun entry point. Some AppImages use a compiled (C) executable as the AppRun, others (e.g., those generated by linuxdeployqt) use just a symlink to the main executable.

So to become more "Linux compatible", BSD users might install a symlink to the Bourne Again Shell in /usr/bin/bash?

brunobiondo commented 5 years ago

Hi @probonopd, given that the AppRun I poke around is a bash shell script extracted from the AppImage available (among other packaged formats) on the IOTA Trinity wallet project at https://github.com/iotaledger/trinity-wallet/releases. I know that unfortunately :( there may exist even big behavioral and syntax differences among various kinds of unix shell interpreters that have historically occurred over the years (from Bourne to Korn to C Shell to Bourne Again to Zsh and others: I personally use the youngest, much more linear and syntactically clear, yet powerful as well and less error-prone Fish shell, but that's another story). That's why it is a normal habit to specify which interpreter to choose in the she-bang, like, in the case of the Trinity's AppRun is '#!/usr/bin/bash'. And I said that you can also specify bash by putting this shebang: '#!/usr/bin/env bash', that is more portable across different unixes and unix-likes. That said, as a FreeBSD user, if I were to make bash script with 'first-style shebang' working, I would opt for your proposal, that is making a symlink /usr/bin/bash that points to the real Bourne Again shell.

vaisarger commented 5 years ago

Hi! I think too that simplest solution is writing this shebang:

!/usr/bin/env bash

It's a good habit to write in scripts to run in GNU/Linux as well...

probonopd commented 5 years ago

Honestly, I think the shebang is the tiniest of all issues in porting AppImage to BSD... now prove me wrong ;-)

vaisarger commented 5 years ago

Hi probonopd :-) For me it's a pleasure talking with you.

I have downloaded Waterfox browser in appimage format. Launching it, it looks for "libfuse.so.2", but it doesn't find it for a mere path problem: libs, in FreeBSD, are in /usr/local/lib. Anyway, I linked /usr/local/lib to a "/usr/lib64" and I downloaded there a libfuse.so.2. It worked, as S.O. loaded the library, but (and this is the real problem) afterwards it complained:

error while loading shared libraries: /usr/lib64/libfuse.so.2: ELF file OS ABI invalid

You have to use proper ABI's libs for BSD. Hence, my tip:

[ ${#OSTYPE} -gt 0 ] && os=${OSTYPE} || os="$(uname -s )" [ $(echo -n "${os}" | grep -i "bsd" | wc -c ) -gt 0 ] && mascotte="Beastie" || mascotte="Tux" So, if mascotte is Beastie, you should give a customized lib for FreeBSD.

Maybe it makes sense... I'm trying to help... What do you think about?

probonopd commented 5 years ago

The following has been reported to work on FreeBSD 11.2-RELEASE-p7:

wget https://github.com/AppImage/AppImageKit/releases/download/12/appimagetool-x86_64.AppImage
chmod +x ./appimagetool-x86_64.AppImage
./appimagetool-x86_64.AppImage --help --appimage-extract-and-run

If we want to make it work without --appimage-extract-and-run, then we need a way to make libfuse work on *BSD. It seems that there have been some BSD specific patches to libfuse lately: https://github.com/libfuse/libfuse/issues/173

probonopd commented 4 years ago

Can someone who has BSD please check whether https://github.com/kost/static-appimage/releases works there? Construct a zip that contains an executable .AppRun bash script, and append that zip to one of the runtimes from https://github.com/kost/static-appimage/releases. I'd be interested to see whether it works on BSD. Those runtimes are statically linked, which means they need no libfuse...

vaisarger commented 4 years ago

Nope!

vittorio@ThinkpadFreeBSDVITT:~/Programmi$ chmod +x ./appimagetool-x86_64.AppImage vittorio@ThinkpadFreeBSDVITT:~/Programmi$ ./appimagetool-x86_64.AppImage --help --appimage-extract-and-run ELF binary type "0" not known. bash: ./appimagetool-x86_64.AppImage: cannot execute binary file: Exec format error

It seems to have still problems... :(

Vittorio

Il giorno mar 16 lug 2019 alle ore 17:19 probonopd notifications@github.com ha scritto:

The following has been reported to work on FreeBSD 11.2-RELEASE-p7:

wget https://github.com/AppImage/AppImageKit/releases/download/12/appimagetool-x86_64.AppImage chmod +x ./appimagetool-x86_64.AppImage ./appimagetool-x86_64.AppImage --help --appimage-extract-and-run

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/AppImage/AppImageKit/issues/98?email_source=notifications&email_token=ABDFPQZYPCWWS7GCNTI5H5TP7XRJXA5CNFSM4B4S7YIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2BGORI#issuecomment-511862597, or mute the thread https://github.com/notifications/unsubscribe-auth/ABDFPQZRR7GZTGB3A76ZC2DP7XRJXANCNFSM4B4S7YIA .

kolbycrouch commented 4 years ago

FreeBSD has a working FUSE. With a few short changes to the build system, you can get AppImageKit to build against FreeBSD without issue. You can also create an appimage.

The problem is when you start the appimage. the process hangs for about ~1 minute around the time that it creates the tmp directory/mounts the appimage. Any reads into /tmp even freeze up for the whole time.

There were no unique compiler warnings compared to a linux build, and I didn't have enough time to figure out why that was happening. It could be the kernel, the libfuse port or the porting I did.

I'm currently building a statically linked AppImage runtime and libfuse for full portability. Dynamically linking the runtime and using dlopen() for libfuse make the AppImage a lot less portable. Static linking works great using musl and freebsd's libc, it's probably safe enough for glibc too.

probonopd commented 4 years ago

The problem is when you start the appimage. the process hangs for about ~1 minute around the time that it creates the tmp directory/mounts the appimage. Any reads into /tmp even freeze up for the whole time.

Hi @kolbycrouch does this also happen with the ones from https://github.com/kost/static-appimage/releases? That is an entirely different code base, written in Go.

probonopd commented 4 years ago

In 2016 I wrote:

I haven't tried so far; mainly because I don't have a BSD Live ISO that can be live-booted with GRUB2.

Four years later, I found one that finally works for me:

https://www.furybsd.org/

So let's give it a try, let's see whether we can get Linux AppImages to run on FuryBSD.

TL;DR: --appimage-extract works, but FUSE mounting currently gives a strange "File name too long" error that I do not understand the reason for yet.

Finally I can boot a BSD graphical desktop from a Live ISO using Ventoy. Great!

liveuser@furybsd:~ % mount
/dev/md2 on / (ufs, local, soft-updates)
devfs on /dev (devfs, local, multilabel)
/dev/iso9660/FURYBSD on /cdrom (cd9660, local, read-only)
/dev/md5.uzip on /usr (ufs, local, read-only)
/dev/md6 on /union (ufs, local, soft-updates)
<above>:/union on /usr (unionfs, local)

Comes with XFCE. Great!

And it comes with unionfs and linux compatibility in the kernel:

root@furybsd:/home/liveuser # kldstat
Id Refs Address                Size Name
 1   44 0xffffffff80200000  2448f20 kernel
 2    1 0xffffffff82649000    11c30 unionfs.ko
 3    1 0xffffffff8265b000    11d40 tmpfs.ko
 4    1 0xffffffff8342d000     5a48 fstab
 5    1 0xffffffff83433000     7718 nullfs.ko
 6    1 0xffffffff8343b000     8460 geom_uzip.ko
 7    2 0xffffffff83444000     4810 xz.ko
 8    1 0xffffffff83621000     1508 sysctlinfo.ko
 9    1 0xffffffff83623000     5954 cuse.ko
10    1 0xffffffff83629000      f20 utouch.ko
11    1 0xffffffff8362a000     18a0 uhid.ko
12    1 0xffffffff8362c000     1aa0 wmt.ko
13    1 0xffffffff8362e000     2928 ums.ko
14    1 0xffffffff83631000    3df60 linux.ko
15    2 0xffffffff8366f000     3178 linux_common.ko
16    1 0xffffffff83673000    35b20 linux64.ko

Now, with this Linux compatibility layer in place, I wonder whether it is capable of running Linux AppImages.

Does not work immediately though:

liveuser@furybsd:~ % chmod +x Downloads/appimaged-552-x86_64.AppImage 
liveuser@furybsd:~ % Downloads/appimaged-552-x86_64.AppImage
ELF interpreter /lib64/ld-linux-x86-64.so.2 not found, error 2
Abort

We have to install the emulators/linux_base-c7 package

root@furybsd:/home/liveuser # pkg install emulators/linux_base-c7

Then we can do:

liveuser@furybsd:~ % Downloads/appimaged-552-x86_64.AppImage
Cannot open /proc/self/exe: No such file or directory
Failed to get fs offset for /proc/self/exe

liveuser@furybsd:~ % Downloads/appimaged-552-x86_64.AppImage --appimage-extract
Cannot open /proc/self/exe: No such file or directory
Failed to get fs offset for /proc/self/exe

liveuser@furybsd:~ % Downloads/appimaged-552-x86_64.AppImage --appimage-version
Cannot open /proc/self/exe: No such file or directory
Failed to get fs offset for /proc/self/exe

We can do

root@furybsd:/home/liveuser #  mount -t linprocfs linproc /compat/linux/proc

root@furybsd:/home/liveuser # mount
/dev/md2 on / (ufs, local, soft-updates)
devfs on /dev (devfs, local, multilabel)
/dev/iso9660/FURYBSD on /cdrom (cd9660, local, read-only)
/dev/md5.uzip on /usr (ufs, local, read-only)
/dev/md6 on /union (ufs, local, soft-updates)
<above>:/union on /usr (unionfs, local)
linprocfs on /compat/linux/proc (linprocfs, local)

liveuser@furybsd:~ % Downloads/appimaged-552-x86_64.AppImage --appimage-version
Version: 0880085

liveuser@furybsd:~ % Downloads/appimaged-552-x86_64.AppImage --appimage-extract
squashfs-root/.DirIcon
squashfs-root/AppRun
squashfs-root/appimage.png
squashfs-root/appimaged.desktop
squashfs-root/usr
squashfs-root/usr/bin
squashfs-root/usr/bin/appimaged
squashfs-root/usr/bin/bsdtar
squashfs-root/usr/bin/unsquashfs

liveuser@furybsd:~ % Downloads/appimaged-552-x86_64.AppImage 
dlopen(): error loading libfuse.so.2

AppImages require FUSE to run. 
You might still be able to extract the contents of this AppImage 
if you run it with the --appimage-extract option. 
See https://github.com/AppImage/AppImageKit/wiki/FUSE 
for more information

Let' copy it from a Linux system into /compat/linux on the FreeBSD system

root@furybsd:/home/liveuser # pkg install dpkg
liveuser@furybsd:~ % dpkg -x Downloads/libfuse2_2.9.4-1ubuntu3_amd64.deb .
root@furybsd:/home/liveuser # cp lib/x86_64-linux-gnu/libfuse.so.* /compat/linux/lib64/

This indeed gets us a little further:

liveuser@furybsd:~ % Downloads/appimaged-552-x86_64.AppImage
fuse: device not found, try 'modprobe fuse' first

Cannot mount AppImage, please check your FUSE setup.
You might still be able to extract the contents of this AppImage 
if you run it with the --appimage-extract option. 
See https://github.com/AppImage/AppImageKit/wiki/FUSE 
for more information
open dir error: No such file or directory

We need to load the FUSE kernel module:

root@furybsd:/home/liveuser # kldload fuse.ko

Now we are getting fuse: mount failed: File name too long:

liveuser@furybsd:~ % Downloads/appimaged-552-x86_64.AppImage
fuse: mount failed: File name too long

Cannot mount AppImage, please check your FUSE setup.
You might still be able to extract the contents of this AppImage 
if you run it with the --appimage-extract option. 
See https://github.com/AppImage/AppImageKit/wiki/FUSE 
for more information
open dir error: No such file or directory

Not sure whether Linux libfuse is supposed to be able to use FreeBSD /dev/fuse in the first place. Does anyone know?

Interestingly, someone over at https://forums.freebsd.org/threads/appimage-support.75097/#post-460768 came to the same conclusion.

Where is this "File name too long" error coming from? The string does not appear in the AppImage runtime, nor in squashfuse.

Let's see what is going on using truss, the BSD equivalent of strace:

 1718: linux_mkdir("/tmp/.mount_appimaXKx4KJ",448) = 0 (0x0)
 1718: linux_pipe(0x62aec8)          = 0 (0x0)
 2125: <new process>
 1718: linux_clone(0x1200011,0x0,0x0,0x8006530d0,0x800652e00) = 2125 (0x84d)
 2125: linux_set_robust_list(0x8006530e0,0x18)   = 0 (0x0)
 1718: close(4)                  = 0 (0x0)
 2125: close(3)                  = 0 (0x0)
 2125: linux_newlstat(0x62b780,0x7fffffff71e0)   = 0 (0x0)
 2125: linux_newlstat(0x62b780,0x7fffffff71e0)   = 0 (0x0)
 2125: linux_readlink("/proc/self","2125",4095)  = 4 (0x4)
 2125: linux_newlstat(0x62b780,0x7fffffff71e0)   = 0 (0x0)
 2125: linux_newlstat(0x62b780,0x7fffffff71e0)   = 0 (0x0)
 2125: linux_readlink("/proc/2125/exe","/usr/home/liveuser/Downloads/appimaged-552-x86_64.AppImage",4095) = 58 (0x3a)
 2125: linux_newlstat(0x62b780,0x7fffffff71e0)   = 0 (0x0)
 2125: linux_newlstat(0x62b780,0x7fffffff71e0)   = 0 (0x0)
 2125: linux_newlstat(0x62b780,0x7fffffff71e0)   = 0 (0x0)
 2125: linux_newlstat(0x62b780,0x7fffffff71e0)   = 0 (0x0)
 2125: linux_newlstat(0x62b780,0x7fffffff71e0)   = 0 (0x0)
 2125: linux_newlstat(0x7fffffff5ef0,0x7fffffff5e20) = 0 (0x0)
 2125: linux_newlstat(0x7fffffff5ef0,0x7fffffff5e20) = 0 (0x0)
 2125: linux_open("/usr/home/liveuser/Downloads/appimaged-552-x86_64.AppImage",0x0,01) = 3 (0x3)
 2125: linux_pread(0x3,0x62ca40,0x60,0x2e028)    = 96 (0x60)
 2125: linux_pread(0x3,0x62c7e0,0x8,0x6d849b)    = 8 (0x8)
 2125: linux_pread(0x3,0x62c800,0x8,0x6d845d)    = 8 (0x8)
 2125: linux_pread(0x3,0x62c910,0x8,0x6d848d)    = 8 (0x8)
 2125: linux_open("/dev/null",0x2,030544460)     = 5 (0x5)
 2125: close(5)                  = 0 (0x0)
 2125: linux_newstat("/tmp/.mount_appimaXKx4KJ",0x7fffffff6e50) = 0 (0x0)
 2125: linux_openat(0xffffffffffffff9c,0x62c930,0x90800,0x0) = 5 (0x5)
 2125: linux_getdents(0x5,0x62cf00,0x8000)   = 48 (0x30)
 2125: linux_getdents(0x5,0x62cf00,0x8000)   = 0 (0x0)
 2125: close(5)                  = 0 (0x0)
 2125: linux_open("/dev/fuse",0x2,0270400)   = 5 (0x5)
 2125: linux_getgid()                = 0 (0x0)
 2125: linux_getuid()                = 0 (0x0)
 2125: linux_mount(0x62c840,0x62c930,0x62c890,0x7,0x62c990) ERR#-36 'File name too long'
fuse: mount failed: File name too long

Not sure which filename is "too long".

liveuser@furybsd:~ % mkdir -p /tmp/.mount_appimaXKx4KJ
liveuser@furybsd:~ % ls /tmp/.mount_appimaXKx4KJ

This is certainly not "too long"...

probonopd commented 4 years ago

Now, let's try to run some of the extracted AppImages. Let's try appimageupdatetol, for example:

liveuser@furybsd:~ % ./squashfs-root/AppRun 
./squashfs-root/AppRun: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./squashfs-root/AppRun)
./squashfs-root/AppRun: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./squashfs-root/AppRun)
./squashfs-root/AppRun: /lib64/libc.so.6: version `GLIBC_2.22' not found (required by /usr/home/liveuser/squashfs-root/usr/bin/../lib/libappimageupdate.so)
./squashfs-root/AppRun: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /usr/home/liveuser/squashfs-root/usr/bin/../lib/libappimageupdate.so)
./squashfs-root/AppRun: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/home/liveuser/squashfs-root/usr/bin/../lib/libappimageupdate.so)

This means that we need to ensure that all files from the excludelist get installed on FreeBSD. Probably we could write a little downloader script (based on pkg2appimage) that takes them from debian and installs them to /compat/linux/lib64/.

Let's try some others:

liveuser@furybsd:~ % ./squashfs-root/usr/bin/desktop-file-validate 
ELF binary type "0" not known.
./squashfs-root/usr/bin/desktop-file-validate: Exec format error. Binary file not executable.

liveuser@furybsd:~ % ./squashfs-root/usr/bin/mksquashfs 
ELF binary type "0" not known.
./squashfs-root/usr/bin/mksquashfs: Exec format error. Binary file not executable.

These ones do not work.

liveuser@furybsd:~ % ./squashfs-root/usr/bin/patchelf 
syntax: ./squashfs-root/usr/bin/patchelf
  [--set-interpreter FILENAME]
  (...)

This one works! Why the difference?

What is the difference? Turns out we need to brand the Linux executables, and then they work:

liveuser@furybsd:~ % brandelf -t linux ./squashfs-root/usr/bin/mksquashfs 
liveuser@furybsd:~ %  ./squashfs-root/usr/bin/mksquashfs 
SYNTAX:./squashfs-root/usr/bin/mksquashfs source1 source2 ...  dest [options] [-e list of exclude
dirs/files]

Filesystem build options:
-comp <comp>        select <comp> compression
(...)

liveuser@furybsd:~ % ./squashfs-root/usr/bin/desktop-file-validate              See "desktop-file-validate --help" for correct usage.

This is even true for bundled ld-linux:

[liveuser@furybsd ~]$ ./squashfs-root/opt/libc/lib64/ld-linux-x86-64.so.2 
ELF binary type "0" not known.

[liveuser@furybsd ~]$ brandelf -t linux  ./squashfs-root/opt/libc/lib64/ld-linux-x86-64.so.2 

[liveuser@furybsd ~]$ ./squashfs-root/opt/libc/lib64/ld-linux-x86-64.so.2 
Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
(...)

Proably the tools that create AppDirs should brand all Linux ELFs. On Ubuntu, brandelf is availabe from the freebsd-buildutils package in universe.

probonopd commented 4 years ago

For AppImages that have been built using @azubieta's AppImageCrafters/AppRun (such as the experimental Glimpse AppImage), we are running into

root@furybsd:/home/liveuser # truss -f squashfs-root/AppRun
(...)
32610: linux_access("/tmp/appimage-e0c659c1-504f-47e4-8b2c-6a9e694b7705-ld-linux.so.2",F_OK) = 0 (0x0)
32610: linux_chmod(0x6e0d7f,0x1f8)       = 0 (0x0)
Program headers not in the first page
32610: linux_execve("/usr/home/liveuser/squashfs-root/usr/bin/glimpse",0x6e08b0,0x6e3330) ERR#-8 'Exec format error'
32610: linux_exit_group(0x1)            
32610: process exit, rval = 1

Not sure why it says Program headers not in the first page when trying to load glimpse.

azubieta commented 4 years ago

Those are the kind of issues that you get when the wrong glibc dependencies get mixed. That's why I rely on the system package manager to select what is a dependency. They have walked this way before.

probonopd commented 4 years ago

I think the Program headers not in the first page message is a BSD specific thing...

probonopd commented 4 years ago

Let's try to mount an AppImage using FreeBSD's own squashfuse:

root@furybsd:/home/liveuser # pkg install sysutils/fusefs-squashfuse

root@furybsd:/home/liveuser # Downloads/appimagetool-552-x86_64.AppImage --appimage-offset
188456

root@furybsd:/home/liveuser # squashfuse --offset=188456 Downloads/appimagetool-552-x86_64.AppImage /mnt
This doesn't look like a squashfs image.

Is that squashfuse simply too old?

probonopd commented 4 years ago

Does anyone have an idea how to debug this fuse: mount failed: File name too long error?

vaisarger commented 4 years ago

My guess is that this issue is related to Fuse FreeBSD porting. I mean it's very unlikely that porters have put a char file name limit, deliberately... Maybe it could be a C/C++ oversight. However, this issue is rather known, but AFAIK no bug fix yet.

Il giorno gio 27 ago 2020 alle ore 21:50 probonopd notifications@github.com ha scritto:

Does anyone have an idea how to debug this fuse: mount failed: File name too long error?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/AppImage/AppImageKit/issues/98#issuecomment-682156604, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABDFPQ5ZW4UN53WWKWYXG3TSC22INANCNFSM4B4S7YIA .

probonopd commented 4 years ago

Hi @vaisarger do you know which filename is too long? Can we shorten it?

vaisarger commented 4 years ago

I do not know (sorry). I tried some time ago to use Appimage on FreeBSD, I couldn't, but have no much time nowadays for testing...

Il giorno ven 28 ago 2020 alle ore 19:28 probonopd notifications@github.com ha scritto:

Hi @vaisarger https://github.com/vaisarger do you know which filename is too long? Can we shorten it?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AppImage/AppImageKit/issues/98#issuecomment-682966501, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABDFPQ5JDOB5D5PX23OV26LSC7SLTANCNFSM4B4S7YIA .

probonopd commented 4 years ago

Here is what brandelf does on x86_64 "linux64" ELFs:

-00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
+00000000  7f 45 4c 46 02 01 01 03  00 00 00 00 00 00 00 00  |.ELF............|
probonopd commented 4 years ago

Getting the same error when trying to use squashfuse from debian packages on FreeBSD to mount a squashfs image produced on FreeBSD with its native mksquashfs:

[root@NomadBSD /home/user/test]# export LD_LIBRARY_PATH=/home/user/test/lib/x86_64-linux-gnu/:/compat/linux/lib64/
[root@NomadBSD /home/user/test]# ./usr/bin/squashfuse test.squashfs /mnt
fuse: mount failed: File name too long

I was using this set of packages on FreeBSD's Linux emulation layer:

[root@NomadBSD /home/user/test]# ls *.deb
libfuse2_2.9.4-1ubuntu3.1_amd64.deb
liblzo2-2_2.08-1.2_amd64.deb
squashfuse_0.1.100-0ubuntu1~ubuntu16.04.1_amd64.deb
[root@NomadBSD /home/user/test]# truss ./usr/bin/squashfuse test.squashfs /mnt

linux_open("/dev/null",0x2,00)           = 4 (0x4)
close(4)                     = 0 (0x0)
linux_newstat("/mnt",0x7fffffffd530)         = 0 (0x0)
linux_openat(0xffffffffffffff9c,0x122b0b0,0x90800,0x0) = 4 (0x4)
linux_getdents(0x4,0x122b620,0x8000)         = 48 (0x30)
linux_getdents(0x4,0x122b620,0x8000)         = 0 (0x0)
close(4)                     = 0 (0x0)
linux_open("/dev/fuse",0x2,0267077740)       = 4 (0x4)
linux_getgid()                   = 0 (0x0)
linux_getuid()                   = 0 (0x0)
linux_mount(0x122b5f0,0x122b0b0,0x122b630,0x6,0x122b0d0) ERR#-36 'File name too long'
fuse: mount failed: File name too long
write(2,"fuse: mount failed: File name to"...,39) = 39 (0x27)
close(4)                     = 0 (0x0)
linux_exit_group(0x1)               
process exit, rval = 1

So this is not AppImage-specific. More investigation needed.

Any help from BSD experts is greatly appreciated.

probonopd commented 4 years ago

We are getting somewhere... https://github.com/akiraux/Akira/issues/3#issuecomment-686786377

vaisarger commented 4 years ago

Wow! :D It's worth waiting for your tweeks to avoid manual configurations, or it will be done in future and it's better to try it now (configuring something manually)?

probonopd commented 4 years ago

@vaisarger most aspects I think how to tweak, but I really need help on this one:

linux_mount(0x122b5f0,0x122b0b0,0x122b630,0x6,0x122b0d0) ERR#-36 'File name too long'

To reproduce this, you shouldn't need any special tweaks.

vaisarger commented 4 years ago

To reproduce this, you shouldn't need any special tweaks.

I know, but as I said before, that bug is beyond my knowledge (unfortunately).

cmatomic commented 4 years ago

Here is a script to create a native uncompressed appimage " chromium browser " on FreeBSD or FreeBSD variants

I created this script in NomadBSD

#!/bin/sh
#change the name nomad for your user name and group .
USER=nomad
GROUP=nomad
#GROUP=wheel

mkdir FreeBSDappimage
cd FreeBSDappimage
sudo pkg fetch  -d -o . chromium-84.0.4147.135
sudo chown -R $USER:$GROUP All/
cd All
mkdir chromium.AppImage
ls *.txz | xargs -n1 tar  -C  "chromium.AppImage" -xzvf
cd chromium.AppImage

 cat > AppRun <<\EOF
#!/bin/sh
HERE=$(dirname $(readlink -f "${0}"))
export LD_PRELOAD="${HERE}/usr/local/lib/alsa-lib/libasound_module_pcm_oss.so"

export GDK_PIXBUF_MODULEDIR="${HERE}/usr/local/lib/gdk-pixbuf-2.0/loaders"
export GDK_PIXBUF_MODULE_FILE="${HERE}/usr/loacl/lib/gdk-pixbuf-2.0/loaders.cache"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$GDK_PIXBUF_MODULEDIR"
export GTK_PATH="$HERE/usr/local/lib/gtk-2.0"
export GTK_IM_MODULE_FILE="$HERE/usr/local/lib/gtk-2.0:$GTK_PATH"
export PANGO_LIBDIR="$HERE/usr/local/lib"

export PATH="${HERE}"/usr/local/bin:"${HERE}"/usr/local/sbin:"${HERE}"/usr/local/include/gtk-3.0/gdk:"${PATH}"
export LD_LIBRARY_PATH="${HERE}"/usr/local/lib/:"${LD_LIBRARY_PATH}"
export PYTHONPATH="${HERE}"/usr/local/lib/gobject-introspection/giscanner/doctemplates/Python:"${PYTHONPATH}"
export PYTHONHOME="${HERE}"/usr/
export XDG_DATA_DIRS="${HERE}"/usr/local/share/:"${XDG_DATA_DIRS}"
export PERLLIB="${HERE}"/usr/local/share/perl5/:"${HERE}"/usr/local/lib/perl5/:"${PERLLIB}"
export GSETTINGS_SCHEMA_DIR="${HERE}"/usr/local/share/glib-2.0/schemas/:"${GSETTINGS_SCHEMA_DIR}"
export QT_PLUGIN_PATH="${HERE}"/usr/local/lib/qt5/:"${HERE}"/usr/local/lib/qt5/plugins:"${QT_PLUGIN_PATH}"
export QT_DEBUG_PLUGINS=1
export LD_LIBRARY_PATH="${HERE}"_LIBRARY_PATH:$LD_LIBRARY_PATH
EXEC=$(grep -e '^Exec=.*' "${HERE}"/*.desktop | head -n 1 | cut -d "=" -f 2- | sed -e 's|%.||g')
exec ${EXEC} "$@"
EOF

  cat > chromium-browser.desktop <<EOF
[Desktop Entry]
Type=Application
Version=1.0
Encoding=UTF-8
Name=Chromium
Comment=Google web browser based on WebKit
Icon=chrome
Exec=./usr/local/share/chromium/chrome %U
Categories=Application;Network;WebBrowser;
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp;
StartupNotify=true
EOF

chmod a+x AppRun 
cp ./usr/local/share/icons/hicolor/256x256/apps/chrome.png  .

how to generate AppImage in FreeBSD ?

probonopd commented 3 years ago

Hi @cmatomic, right now my focus is getting existing Linux AppImages running on FreeBSD, like the ones from LibreOffice. Probably a 1:1 port of the AppImage concepts is not desirable for FreeBSD, since we have a different set of constraints on this platform compared to the diverse Linux desktop distribution and desktop landscape. Possibly we can make a much better solution for native FreeBSD! (I already have some ideas...)

probonopd commented 3 years ago

TL:DR: This post summarizes what is already working, what is not working yet, and what we need help with.

https://twitter.com/FreeBSDHelp/status/1318881614013739008

FreeBSD contributors get your yak shaving hats on! First step: an up to date doc (wiki page or GitHub readme) with clear steps to test/install @appimages with a clear list of issues (errors, missing bits) so it’s quick and easy for people to know what needs doing.

What is an AppImage how can it be beneficial to FreeBSD?

image

An AppImage is a squashfs filesystem image that contains a tiny ELF executable at the beginning of the file which mounts the filesystem image using FUSE and executes the contained application.

This allows for "one app = one file" distribution of applications, and has gained some traction in the Linux world. With many applications already available in AppImage format for Linux, it would be desirable to be able to run those same AppImages on FreeBSD, effectively increasing app choice and availablily significantly for FreeBSD desktop users.

Goal 1: Get existing Linux AppImages to run on FreeBSD

The objective here is to allow existing AppImages, e.g., those from https://www.libreoffice.org/download/appimage/, to run on FreeBSD.

What already works

You can download an AppImage from https://www.libreoffice.org/download/appimage/, extract it, and run the contents on FreeBSD using the Linuxulator.

How to test

like this:

wget -c https://libreoffice.soluzioniopen.com/stable/still/LibreOffice-still.basic-x86_64.AppImage
chmod +x LibreOffice-still.basic-x86_64.AppImage
./LibreOffice-still.basic-x86_64.AppImage --appimage-extract
./squashfs-root/AppRun

image

What does not work yet

  1. Running AppImages without the --appimage-extract step
  2. Running AppImages that were built e.g., with Ubuntu xenial, rather than CentOS7, in mind

What we need help with

Regarding issue 1

linux_mount(0x122b5f0,0x122b0b0,0x122b630,0x6,0x122b0d0) ERR#-36 'File name too long'

See above in this thread.

Regarding issue 2

A way to loop-mount e.g., an Ubuntu xenial Live ISO and use that as the compat libraries for the Linuxulator. This should improve compatibility with many existing Linux AppImages a lot, since most have been tested against Ubuntu.

NODE=$(sudo mdconfig -a -t vnode -f /home/user/Downloads/ubuntu-18.04-desktop-amd64.iso)
mkdir -p /tmp/cdrom
sudo mount -t cd9660 /dev/$NODE /tmp/cdrom
ls -lh /tmp/cdrom/casper/filesystem.squashfs
sudo squashfuse /tmp/cdrom/casper/filesystem.squashfs  /compat/linux -o allow_other
sudo sysctl compat.linux.osrelease=4.0.0

What worked perfectly before does not work properly anymore now...

user@FreeBSD$ /home/user/Downloads/LibreOffice/LibreOffice_3.3.0.AppDir/AppRun 
ELF interpreter /lib64/ld-linux-x86-64.so.2 not found, error 2
Abort trap

user@FreeBSD$ file /compat/linux/lib64/ld-linux-x86-64.so.2 
/compat/linux/lib64/ld-linux-x86-64.so.2: broken symbolic link to /lib/x86_64-linux-gnu/ld-2.27.so

user@FreeBSD$ file /compat/linux/lib/x86_64-linux-gnu/ld-2.27.so
/compat/linux/lib/x86_64-linux-gnu/ld-2.27.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=64df1b961228382fe18684249ed800ab1dceaad4, stripped

Why?

user@FreeBSD$ LANG="" /compat/linux/lib/x86_64-linux-gnu/ld-2.27.so
ELF binary type "0" not known.
bash: /compat/linux/lib/x86_64-linux-gnu/ld-2.27.so: cannot execute binary file: Exec format error

Wouldn't it be cool if this could somehow be fixed? E.g., what ever is in /compat/linux assume to be linux by default, unless specifically branded otherwise? (The code for this would probably go somewhere around https://github.com/freebsd/freebsd/blob/f18df350f1aafb3b85e31975e341d2fd292c6cac/sys/kern/imgact_elf.c#L436?)

So I try to follow https://forums.freebsd.org/threads/howto-install-ubuntu-under-compat-linux.26086/ which claims that you need to copy files and

sudo umount /compat/linux
sudo mv /compat /compat.original
sudo mkdir -p /compat
cd /compat
sudo unsquashfs -d linux /tmp/cdrom/casper/filesystem.squashfs
cd linux
sudo brandelf -t linux bin/* sbin/* usr/bin/* usr/sbin/* usr/local/bin/* usr/local/sbin/* lib/x86_64-linux-gnu/* lib/* usr/lib/* usr/lib/x86_64-linux-gnu/*

Still...

user@FreeBSD$ /home/user/Downloads/LibreOffice/LibreOffice_3.3.0.AppDir/AppRun 
ELF interpreter /lib64/ld-linux-x86-64.so.2 not found, error 2
Abort trap

Goal 2: Create native AppImage-like system for FreeBSD

Possibly a 1:1 port of the AppImage concepts is not desirable for FreeBSD, since we have a different set of constraints on this platform compared to the diverse Linux desktop distribution and desktop landscape. Possibly a clever combination of the existing ports/pkg system with some aspects of AppDir and AppImage can produce more desirable results than what we have with AppImage on Linux, where we have to essentially work around distributions. I am thinking of an AppImage-like (but better) system as part of a larger plan that would change how systems are put together.

Questions:

There is one more wrinkle in the loader magic: the emulation path. This allows Linux branded binaries to "re-root" themselves under a different file path. For Linux, this path is /compat/linux. By having an emulation path, a Linux binary loading the C library (e.g. libc.so), for example, will pick up the libc.so under /compat/linux instead of using the base system's version of the library.

Can an "emulation path" also be used for non-Linux binaries, and if so, how?

Contact

AppImage channel on freenode.

cc @ctuffli @trasz

trasz commented 3 years ago

Okay, so:

Regarding issue 1: Could you show me what the arguments to linux_mount() actually are? Running it with Linux strace should do the trick.

Regarding issue 2: The way to get Ubuntu userspace by using debootstrap is described at https://wiki.freebsd.org/LinuxJails. Let me know how it works in this case.

The ELF branding issue ("ELF binary type "0" not known") should be fixed in 12.2-RELEASE; it boils down to sysctl kern.elf64.fallback_brand=3, which is now done by /etc/rc.d/linux script.

I believe the ELF interpreter path is just a broken symlink.