GUI flatpak hanging when launched only when built/bundled

The app I packaged seems to hang during launch with no errors.
It works when run inside flatpak-builder --run build-dir manifest.json sh using the launch script /app/rimpy-wrapper.sh:

Launching RimPy
ERROR: ld.so: object 'libpcre.so.3' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.

(RimPy:4): dbind-WARNING **: 01:07:23.040: Couldn't connect to accessibility bus: Failed to connect to socket /run/user/1000/at-spi/bus_0: No such file or directory
Gtk-Message: 01:07:23.065: Failed to load module "canberra-gtk-module"
Gtk-Message: 01:07:23.065: Failed to load module "pk-gtk-module"
Gtk-Message: 01:07:23.066: Failed to load module "canberra-gtk-module"
Gtk-Message: 01:07:23.066: Failed to load module "pk-gtk-module"
Sandboxing disabled by user.
ERROR: ld.so: object 'libpcre.so.3' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libpcre.so.3' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libpcre.so.3' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[47:70:0605/010733.116505:ERROR:nss_util.cc(283)] After loading Root Certs, loaded==false: /usr/lib/x86_64-linux-gnu/libnssckbi.so: undefined symbol: C_GetInterface
[47:65:0605/010733.118596:ERROR:ssl_client_socket_impl.cc(959)] handshake failed; returned -1, SSL error code 1, net_error -202
js: Uncaught TypeError: Cannot read property 'lastChild' of undefined
js: Uncaught TypeError: Cannot read property 'parentElement' of null

(Any errors/warnings in the output above are normal for this program and it still launches/runs)

After it is packaged, this is the only output when run:

Launching RimPy
ERROR: ld.so: object 'libpcre.so.3' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.

It just sits on that line, never crashing or continuing.

Here is the manifest.json:

{
  "app-id": "io.github.kuuchuu.RimPy",
  "runtime": "org.kde.Platform",
  "runtime-version": "6.7",
  "sdk": "org.kde.Sdk",
  "command": "/app/rimpy-wrapper.sh",
  "finish-args": [
    "--share=network",
    "--filesystem=home",
    "--filesystem=xdg-config/RimPy Mod Manager:create",
    "--filesystem=xdg-data/RimPy:create",
    "--socket=fallback-x11",
    "--socket=wayland",
    "--device=dri",
    "--share=ipc"
  ],
  "modules": [
    {
      "name": "rimpy",
      "buildsystem": "simple",
      "build-commands": [
        "mkdir -p /app",
        "mv src/* /app",
        "install -D io.github.kuuchuu.RimPy.png /app/share/icons/hicolor/256x256/apps/io.github.kuuchuu.RimPy.png",
        "install -D rimpy.desktop /app/share/applications/io.github.kuuchuu.RimPy.desktop",
        "install -D rimpy-wrapper.sh /app/rimpy-wrapper.sh",
        "chmod +x /app/rimpy-wrapper.sh",
        "chmod +x /app/RimPy",
        "chmod +x /app/RimPy.sh"
      ],
      "sources": [
        {
          "type": "archive",
          "url": "https://github.com/rimpy-custom/RimPy/releases/download/$RIMPYVERSION/RimPy_Linux.tar.gz",
          "sha256": "$RIMPYSHA",
          "dest": "src",
          "strip-components": 0
        },
        {
          "type": "file",
          "path": "$WKDIR/io.github.kuuchuu.RimPy.png"
        },
        {
          "type": "file",
          "path": "$WKDIR/rimpy.desktop"
        },
        {
          "type": "file",
          "path": "$WKDIR/rimpy-wrapper.sh"
        }
      ]
    }
  ]
}

Here is my build.sh:

#!/bin/bash

PAKID="io.github.kuuchuu.RimPy"

cd $PAKID || exit

RIMPYVERSION=$(awk -F '/' '{print $1}' rimpy.version)
RIMPYSHA=$(awk -F '/' '{print $2}' rimpy.version)

WKDIR=$(readlink -f $PAKID | sed 's,/*[^/]\+/*$,,')

JSON=$(sed "s/\$RIMPYVERSION/$RIMPYVERSION/g" < manifest.json | sed "s/\$RIMPYSHA/$RIMPYSHA/g" | sed "s/\\\$WKDIR/$(echo "$WKDIR" | sed 's/\//\\\//g')/g")

echo "$JSON" | flatpak-builder --repo=repo --force-clean build-dir /dev/stdin
flatpak build-bundle repo "rimpy.$RIMPYVERSION.flatpak" io.github.kuuchuu.RimPy

echo -e "\nFlatpak built!"
#rm -rdf .flatpak-builder build-dir repo
echo -e "\nRun \`flatpak install '$PWD/rimpy.$RIMPYVERSION.flatpak'\` to install."

rimpy-wrapper.sh:

#!/bin/sh
echo "RimPy Log: $HOME/.config/RimPy Mod Manager/rimpy.flatpak.log"
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>"$HOME/.config/RimPy Mod Manager/rimpy.flatpak.log" 2>&1
cd /app || exit
echo "Launching RimPy"
exec /app/RimPy.sh

rimpy.version:

1.2.6.29/2c83a0c3446b8391e9ab98bf5e2332e718d0f0fb10e6b0035ffa45b55311a705

temporary rimpy.desktop:

[Desktop Entry]
Version=1.0
Name=RimPy
Comment=A Mod Manager for RimWorld
Exec=/app/rimpy-wrapper.sh
Icon=io.github.kuuchuu.RimPy
Terminal=false
Type=Application
Categories=Game;Utility;

Folder structure:

.
├── build.sh
├── io.github.kuuchuu.RimPy
│  ├── io.github.kuuchuu.RimPy.png
│  ├── manifest.json
│  ├── rimpy-wrapper.sh
│  ├── rimpy.desktop
│  └── rimpy.version

Any help figuring this out would be really appreciated!

I think it might increase your chance, of getting help, if you share a git repo :slight_smile:

First this is not the proper way to test the build. You should tell flatpak-builder to install it with --install --user and the use flatpak run

Second, you unpack a prebuild binary and that might be the problem.

Currently nothing has been pushed to a repo, was hoping to get it working first. Minus the png file (which is the window.ico packaged in the RimPy_Linux.tar.gz), these are all the files. I can go ahead and push it to my repo soon.

EDIT: If you’re referencing the repo of the app I’m attempting to package, this is it: GitHub - rimpy-custom/RimPy: Mod Manager For Rimworld game
The only file really provided by the repo is the pre-built application though.

Sorry, this is my first time packaging a flatpak so I’m still working on learning the correct process.

The program I am attempting to package does not have available source code, it is only provided pre-compiled (released in Nov. 2022). The pre-compiled version has various issues if the environment it’s running in isn’t just right, but all the features worked properly when I was (incorrectly) testing with flatpak-builder --run build-dir manifest.json sh, when they fail to work when running the program normally on my computer.

EDIT: Just wanted to add, I did already attempt to run it using flatpak run as well:
flatpak run io.github.kuuchuu.RimPy
flatpak run --devel --command=sh io.github.kuuchuu.RimPy
Which is when it fails to launch:

blase@solus-blase ~/D/W/git❥ flatpak run --devel --command=sh io.github.kuuchuu.RimPy
[📦 io.github.kuuchuu.RimPy git]$ /app/rimpy-wrapper.sh
RimPy Log: /home/blase/.config/RimPy Mod Manager/rimpy.flatpak.log

rimpy.flatpak.log:

Launching RimPy
ERROR: ld.so: object 'libpcre.so.3' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
# HANGS AFTER ABOVE LINE

I don’t see what this relate to testing the build as explained. The lack a repo is irrelevant. This is the local build.

1 Like

There is no libpcre3.so in the runtime so it can’t invent it. The message is pretty clear.

That message is there when the application works as well.

EDIT: I have fixed that issue. Still hangs in the same spot after bundling it into the .flatpak

New rimpy-wrapper.sh:

#!/bin/sh
#echo "RimPy Log: $HOME/.config/RimPy Mod Manager/rimpy.flatpak.log"
#exec 3>&1 4>&2
#trap 'exec 2>&4 1>&3' 0 1 2 3
#exec 1>"$HOME/.config/RimPy Mod Manager/rimpy.flatpak.log" 2>&1
cd /app || exit
echo "Launching RimPy"
#export LD_DEBUG=libs,files
LD_PRELOAD="/app/lib/libpcre.so.3:$LD_PRELOAD" ./RimPy

New manifest.json:

{
  "app-id": "io.github.kuuchuu.RimPy",
  "runtime": "org.kde.Platform",
  "runtime-version": "6.7",
  "sdk": "org.kde.Sdk",
  "command": "/app/rimpy-wrapper.sh",
  "finish-args": [
    "--share=network",
    "--filesystem=home",
    "--filesystem=xdg-config/RimPy Mod Manager:create",
    "--filesystem=xdg-data/RimPy:create",
    "--socket=fallback-x11",
    "--socket=wayland",
    "--device=dri",
    "--share=ipc"
  ],
  "modules": [
    {
      "name": "pcre",
      "buildsystem": "autotools",
      "config-opts": [
        "--prefix=/app/lib",
        "--enable-utf",
        "--enable-unicode-properties",
        "--enable-pcre16",
        "--enable-pcre32",
        "--enable-jit",
        "--enable-pcregrep-libz",
        "--enable-pcregrep-libbz2",
        "--enable-pcretest-libreadline"
      ],
      "sources": [
        {
          "type": "archive",
          "url": "http://deb.debian.org/debian/pool/main/p/pcre3/pcre3_8.39.orig.tar.bz2",
          "sha256": "b858099f82483031ee02092711689e7245586ada49e534a06e678b8ea9549e8b"
        }
      ],
      "build-commands": [
        "./configure --prefix=/app",
        "make",
        "make install",
        "ln -s /app/lib/libpcre.so.1 /app/lib/libpcre.so.3"
      ]
    },
    {
      "name": "rimpy",
      "buildsystem": "simple",
      "build-commands": [
        "mkdir -p /app",
        "mv src/* /app",
        "install -D io.github.kuuchuu.RimPy.png /app/share/icons/hicolor/256x256/apps/io.github.kuuchuu.RimPy.png",
        "install -D rimpy.desktop /app/share/applications/io.github.kuuchuu.RimPy.desktop",
        "install -D rimpy-wrapper.sh /app/rimpy-wrapper.sh",
        "chmod +x /app/rimpy-wrapper.sh",
        "chmod +x /app/RimPy",
        "chmod +x /app/RimPy.sh"
      ],
      "sources": [
        {
          "type": "archive",
          "url": "https://github.com/rimpy-custom/RimPy/releases/download/$RIMPYVERSION/RimPy_Linux.tar.gz",
          "sha256": "$RIMPYSHA",
          "dest": "src",
          "strip-components": 0
        },
        {
          "type": "file",
          "path": "$WKDIR/io.github.kuuchuu.RimPy.png"
        },
        {
          "type": "file",
          "path": "$WKDIR/rimpy.desktop"
        },
        {
          "type": "file",
          "path": "$WKDIR/rimpy-wrapper.sh"
        }
      ]
    }
  ]
}

Going to look at the output when it’s launched with “LD_DEBUG=libs,files”

Not working, Bundled flatpak, flatpak run --devel --command=sh io.github.kuuchuu.RimPy:

blase@solus-blase ~/D/W/git [SIGINT]❥ flatpak run --devel --command=sh io.github.kuuchuu.RimPy
[📦 io.github.kuuchuu.RimPy git]$ /tmp/templauncher.sh # rimpy-wrapper.sh with LD_DEBUG=libs,files

Output log: https://0x0.st/XqR8.log

Working, Unbundled flatpak, flatpak-builder --run build-dir manifest.json sh:

blase@solus-blase ~/D/W/git [SIGINT]❥ flatpak-builder --run build-dir manifest.json sh
[📦 io.github.kuuchuu.RimPy git]$ /tmp/templauncher.sh # rimpy-wrapper.sh with LD_DEBUG=libs,files

Output log: https://0x0.st/XqRP.log

The output is pretty identical until it reaches

       #:	calling init: /app/pyexpat.so
       #:	
       #:	opening file=/app/pyexpat.so [0]; direct_opencount=1

After that line the bundled flatpak doesn’t have any further output, while the unbundled continues:

    ....
       177:	calling init: /app/pyexpat.so
       177:	
       177:	opening file=/app/pyexpat.so [0]; direct_opencount=1
       177:	
       177:	
       177:	file=/app/PyQt5/qt-plugins/platforms/libqxcb.so.avx2 [0];  dynamically loaded by /app/PyQt5/../libQt5Core.so.5 [0]
       177:	
       177:	file=/app/PyQt5/qt-plugins/platforms/libqxcb.so [0];  dynamically loaded by /app/PyQt5/../libQt5Core.so.5 [0]
       177:	file=/app/PyQt5/qt-plugins/platforms/libqxcb.so [0];  generating link map
       177:	  dynamic: 0x00007f91a5402bd0  base: 0x00007f91a5200000   size: 0x00000000002030d8
       177:	    entry: 0x00007f91a5201420  phdr: 0x00007f91a5200040  phnum:                  7
       177:	
       177:	
       177:	file=libQt5XcbQpa.so.5 [0];  needed by /app/PyQt5/qt-plugins/platforms/libqxcb.so [0]
       177:	find library=libQt5XcbQpa.so.5 [0]; searching
       177:	 search path=/app/lib:/usr/lib/x86_64-linux-gnu/GL/default/lib:/usr/lib/x86_64-linux-gnu/GL/nvidia-550-78/lib:/usr/lib/x86_64-linux-gnu/openh264/extra		(LD_LIBRARY_PATH)
       177:	  trying file=/app/lib/libQt5XcbQpa.so.5
       177:	  trying file=/usr/lib/x86_64-linux-gnu/GL/default/lib/libQt5XcbQpa.so.5
       177:	  trying file=/usr/lib/x86_64-linux-gnu/GL/nvidia-550-78/lib/libQt5XcbQpa.so.5
       177:	  trying file=/usr/lib/x86_64-linux-gnu/openh264/extra/libQt5XcbQpa.so.5
       177:	 search path=/app/PyQt5/qt-plugins/platforms/../../../glibc-hwcaps/x86-64-v3:/app/PyQt5/qt-plugins/platforms/../../../glibc-hwcaps/x86-64-v2:/app/PyQt5/qt-plugins/platforms/../../..		(RUNPATH from file /app/PyQt5/qt-plugins/platforms/libqxcb.so)
       177:	  trying file=/app/PyQt5/qt-plugins/platforms/../../../glibc-hwcaps/x86-64-v3/libQt5XcbQpa.so.5
       177:	  trying file=/app/PyQt5/qt-plugins/platforms/../../../glibc-hwcaps/x86-64-v2/libQt5XcbQpa.so.5
       177:	  trying file=/app/PyQt5/qt-plugins/platforms/../../../libQt5XcbQpa.so.5
       177:	
       177:	file=libQt5XcbQpa.so.5 [0];  generating link map
       177:	  dynamic: 0x00007f91a4f53a10  base: 0x00007f91a4c00000   size: 0x00000000003584f0
       177:	    entry: 0x00007f91a4c37530  phdr: 0x00007f91a4c00040  phnum:                  7
       177:	
       177:	
       177:	file=libxcb-icccm.so.4 [0];  needed by /app/PyQt5/qt-plugins/platforms/libqxcb.so [0]
       177:	find library=libxcb-icccm.so.4 [0]; searching
       177:	 search path=/app/lib:/usr/lib/x86_64-linux-gnu/GL/default/lib:/usr/lib/x86_64-linux-gnu/GL/nvidia-550-78/lib:/usr/lib/x86_64-linux-gnu/openh264/extra		(LD_LIBRARY_PATH)
       177:	  trying file=/app/lib/libxcb-icccm.so.4
       177:	  trying file=/usr/lib/x86_64-linux-gnu/GL/default/lib/libxcb-icccm.so.4
       177:	  trying file=/usr/lib/x86_64-linux-gnu/GL/nvidia-550-78/lib/libxcb-icccm.so.4
       177:	  trying file=/usr/lib/x86_64-linux-gnu/openh264/extra/libxcb-icccm.so.4
       177:	 search path=/app/PyQt5/qt-plugins/platforms/../../..		(RUNPATH from file /app/PyQt5/qt-plugins/platforms/libqxcb.so)
       177:	  trying file=/app/PyQt5/qt-plugins/platforms/../../../libxcb-icccm.so.4
       177:	
       177:	file=libxcb-icccm.so.4 [0];  generating link map
       177:	  dynamic: 0x00007f91b8396000  base: 0x00007f91b838f000   size: 0x00000000000080f8
       177:	    entry: 0x00007f91b8391330  phdr: 0x00007f91b838f040  phnum:                 12
    ....

I think I got it figured out. It seems that because “/app” is a read-only file system after packaging it fails to launch.

Here is my unconventional and likely frowned upon solution / rimpy-wrapper.sh modification:

#!/bin/sh
app_dir="/app"
rimpy_dir="/var/rimpy"

rimpyLink() {
    mkdir -p "$rimpy_dir"

    find "$app_dir" -type d | while read -r dir; do
        new_dir="${dir/$app_dir/$rimpy_dir}"
        mkdir -p "$new_dir"
    done

    find "$app_dir" -type f | while read -r file; do
        new_file="${file/$app_dir/$rimpy_dir}"
        ln -s "$file" "$new_file"
    done

    echo "Directory structure replicated and files linked from $app_dir to $rimpy_dir."
}

if [ ! -f "$rimpy_dir/RimPy" ]; then
    rimpyLink
fi

echo
echo "Launching RimPy"

echo "RimPy Log: $HOME/.config/RimPy Mod Manager/rimpy.flatpak.log"
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>"$HOME/.config/RimPy Mod Manager/rimpy.flatpak.log" 2>&1
#export LD_DEBUG=libs,files
cd /var/rimpy || exit
LD_PRELOAD="/app/lib/libpcre.so.3:$LD_PRELOAD" ./RimPy

It is currently sym linking all the files in /app into a directory in /var, then launching from there.

If there is a better way to set up the application so that it runs in a read/write file system rather than a read-only file system, I’d be interested in trying it.

In general, the application files in /app are always read-only & there is no way to change that. Copying them would be the only way.

But since it works with the symlinks (which still point to read-only files), I’d assume the application itself can be read-only. Is it just creating additional files / directories inside the application directory?

If that’s the case then you can try to just symlink these files / directories at build time into writable locations (i.e. via the manifest, ln -s <destination> /app/<source>). Your script then just has to ensure that the destinations of the symlinks are created.

User data you can put into the corresponding locations (XDG_DATA_HOME, XDG_CACHE_HOME & XDG_CONFIG_HOME) to persist it:
The app-specific variants (inside ~/.var/app/<ID>) are available at the static, user independent, locations /var/data, /var/cache & /var/config, to be easily symlinked at build time.

Speaking of XDG base directories:
You shouldn’t hard code $HOME/.config into the application. This will work most of the time but the location can be changed by the user.

You can just use $XDG_CONFIG_HOME/<your folders>: The directories from --filesystem=<your folders> will be available in the app specific folder, too (see Sandbox Permissions Footnote #3).

An alternative would be to use $HOST_XDG_CONFIG_HOME (see flatpak-run). But unlike XDG_CONFIG_HOME this is not always set (so you’ll have to handle the fallback).
If a user decides to remove the filesystem access then the files won’t be persisted anymore. With $XDG_CONFIG_HOME there’s always a fallback inside .var/app/<id>/config.

(As a suggestion: I’d argue a log file is either cache or data but never config)