2

My build system, which uses meson, puts some files my application needs on AppDir under AppDir/usr/share/myapp/resources. The application needs both, read and write to those files when it is running. The files are in AppDir when I look at it, but when the .AppImage is generated, the standalone running executable cannot access those files. When integrating the application with the desktop, the application gets installed in ~/Applications, but it doesn't contain those files.

Here is a visualization of how it looks when the application is installed on the system without using AppImage (ninja install)

 usr
    share
         myapp
             resources
                 MainWindow.glade
                 dataCache.json

When I do DESTDIR=AppDir ninja install the structure ends like this

 AppDir
     usr
         share
             myapp
                 resources
                     MainWindow.glade
                     dataCache.json

When the application (MyApp.AppImage) is integrated into the user's desktop with AppImageLauncher, it only copies the AppImage into the Applications directory. There are no other folders or files.

Edit: I am using ./linuxdeploy-x86_64.AppImage --appdir AppDir to create the directory AppDir. Then I use DESTDIR=AppDir ninja install to install the app to AppDir, and then I use ./linuxdeploy-x86_64.AppImage --appdir AppDir --output appimage to create the AppImage

How would one go to access those files that were in AppDir once the app is bundled? Or how does one make the app integration copy those files to the Applications folder so that the application can have access to them while the application is running?

g_l
  • 621
  • 5
  • 15
  • I wonder what if you use ./appimagetool-x86_64.AppImage instead? e.g. ./appimagetool-x86_64.AppImage <>/AppDir – pmod Apr 13 '20 at 22:24
  • I tried it and the result was the same. However, I used that tool with the flag -l (./appimagetool-x86_64.AppImage -l MyApp.AppImage) to list the SOURCE in the AppImage and all the libraries, including the icons in /usr/share/icons... are in the list the command outputs. The only files that are not in the output list are MainWindow.glade and dataCache.json. Neither is the myapp directory under /usr/share. I don't understand why because they are there on the AppDir directory before bundling everything with the command. They are just not being bundled. – g_l Apr 14 '20 at 17:30
  • @g_l Hey, I'm having the exact same problem. I have a `assets` directory that I have setup as a `install_subdir` in my `meson.build` file, then I run `meson build -Dprefix=/usr`, then `DESTDIR=AppDir ninja -C build install`, all goes fine till here, when I run my app `AppDir/usr/bin/myapp` its runs fine, but it cannot fine the assets directory, throwing error saying no such file or directory `/usr/share/myapp/assets`. I followed the documentation for `appimage-builder` can't figure out how to solve this issue. As they are under `AppDir/usr/share/myapp/assets`. – apoorv569 Jul 19 '21 at 05:26

1 Answers1

6

To resolve the AppImage mount point at runtime you can use the APPDIR environment variable. For example, if you want to resolve usr/share/icons/hicolor/myicon.png you need to use the following path $APPDIR/usr/share/icons/hicolor/myicon.png.

It's recommended that you modify the application to be able to resolve its resources depending on the binary location. As an alternative, you can use a custom environment variable to set up the path or a configuration file next to your main binary.

Regarding writing files inside the AppImage. This is not possible by design. An AppImage is a read-only SquashFS image that is mounted at runtime. Any application data should be written to $HOME/.config or $HOME/.local/share depending on whether it's a configuration data or other kind of data. The recommended workflow is to copy such data on the first run.

For more information about whether to copy your application data see https://www.freedesktop.org/wiki/Software/xdg-user-dirs/

Alexis
  • 591
  • 2
  • 8
  • Thank you. That works. I used `string appdir_path = GLib.Environment.get_variable ("APPDIR");` and then I used `File glade_file = File.new_for_path (appdir_path + "/usr/share/myapp/resources/MainWindow.glade");` When querying for the existence of the file with `glade_file.query_exists ();` the result was true and I could read the file from there. Thanks. (This is Vala, if someone is using other languages they would get it in other ways, but the idea is the same as in the marked answer. To look for APPDIR in the environment variables and work the paths from there.) – g_l Apr 16 '20 at 21:28