Missing desktop file and executable


#1

Hi everyone, I’m new to snap and trying to learn the ins and outs by packaging a simple python gtk application but falling short and seeking some help.

My application has the following files:

root@01df2af057f9:/gtk-desktop-example# tree
.
├── build-aux
│   └── meson
│       └── postinstall.py
├── com.github.kenvandine.gtk-desktop-example.json
├── COPYING
├── data
│   ├── com.github.kenvandine.gtk-desktop-example.appdata.xml.in
│   ├── com.github.kenvandine.gtk-desktop-example.desktop.in
│   ├── com.github.kenvandine.gtk-desktop-example.gschema.xml
│   └── meson.build
├── meson.build
├── po
│   ├── LINGUAS
│   ├── meson.build
│   └── POTFILES
├── snap
│   └── snapcraft.yaml
└── src
    ├── gtk-desktop-example.in
    ├── __init__.py
    ├── main.py
    └── meson.build

The current issue is that I can build the snap, and install it, but there must be something wrong with how I’m building it because 1) the desktop icon doesn’t show up in the list of installed applications and 2) when I run the app from the cli, it doesn’t launch and instead complains that the executable doesn’t exist:

$ gtk-desktop-example
/snap/gtk-desktop-example/x1/bin/desktop-launch: line 573: /snap/gtk-desktop-example/x1/bin/gtk-desktop-example: No such file or directory

Another thing that is perhaps worth noting, is that when the snap is building (in docker), the build output mentions a slew of needed “libraries that are not included in the snap or base” and I’m not sure how to get rid of this besides explicitly staging packages like libc6 (which the documentation on staging packages to satisfy missing libraries recommends against). Perhaps I’m hitting this bug.

Here is my snapcraft.yaml file:

name: gtk-desktop-example
base: core18
version: '0.1' 
summary: What theme am I using?
description: |
  A python gtk application that lists what theme is being used.

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

# seems reasonable, taken from mailspring example: https://github.com/Foundry376/Mailspring/blob/master/snap/snapcraft.template.yaml
plugs:
  gtk-3-themes:
    interface: content
    target: $SNAP/share/themes
    default-provider: gtk-common-themes:gtk-3-themes
  icon-themes:
    interface: content
    target: $SNAP/share/icons
    default-provider: gtk-common-themes:icon-themes

apps:
  gtk-desktop-example:
    command: desktop-launch $SNAP/bin/gtk-desktop-example
    plugs:
      - desktop
      - desktop-legacy
      - wayland
      - unity7
      - gsettings
      - x11

parts:
  gtk-desktop-example:
    after: [desktop-gtk3]
    plugin: meson
    source: .
# critical for desktop-launch command to be available: https://forum.snapcraft.io/t/snapcraft-3-core18-and-desktop-apps/9520/2
  desktop-gtk3:
    build-packages:
    - build-essential
    - libgtk-3-dev
    make-parameters:
    - FLAVOR=gtk3
    plugin: make
    source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
    source-subdir: gtk
    stage-packages:
    - libxkbcommon0
    - ttf-ubuntu-font-family
    - dmz-cursor-theme
    - light-themes
    - adwaita-icon-theme
    - gnome-themes-standard
    - shared-mime-info
    - libgtk-3-0
    - libgdk-pixbuf2.0-0
    - libglib2.0-bin
    - libgtk-3-bin
    - unity-gtk3-module
    - libappindicator3-1
    - locales-all
    - xdg-user-dirs
    - ibus-gtk3
    - libibus-1.0-5
    - fcitx-frontend-gtk3

Any advice would be really helpful :slight_smile:


#2

How are you building with docker? IIRC the upstream snapcraft docker image uses an Ubuntu 16.04 based image, while you’re building with a core18 base which will need to be using an Ubuntu 18.04 base.


#3

Ah, good question. I grabbed the dockerfile and changed the 2 FROM lines to FROM ubuntu:bionic.

I’m used to using docker and so this was a natural path for me, but since the dockerfile provided still points to an aging base, I wonder what the more common method is for building with core18. I suppose folks run 18.04 on the host, even though 19.04 is out, or use a vm which seems like a heavy solution.


#4

Which version of snapcraft are you using? The recommended setup is to use snapcraft from the snap store as well as multipass. If multipass is installed, snapcraft should just do the right thing. Building in docker is not all that straight forward, but possible.


#5

I’m using snapcraft 3.6 and there is no multipass installed in my docker container, so perhaps I just dove into the deep end with docker! For now, I’ll just give it a shot on 18.04 with multipass instead, and revisit the docker method later.


#6

Now I’m building without docker, just on an ubuntu 18.04 system (vm) and I am still getting the same error when launching the application from the command line:

/snap/gtk-desktop-example/x1/bin/desktop-launch: line 573: /snap/gtk-desktop-example/x1/bin/gtk-desktop-example: No such file or directory

The executable is in two locations within my working directory:

./stage/usr/bin/gtk-desktop-example*
./parts/gtk-desktop-example/build/snapbuild/src/gtk-desktop-example*

How can I make sure this executable is placed in the right location when the snap is installed?

The snapcraft.yaml file has changed slightly (make pip use a specific meson version, stage additional packages to meet library requirements), but nothing to do with the apps section. I believe this is what is missing something… I define all sorts of plugs (trying to cover all the possible bases). Do I need to expose any slots to the desktop interface? Could there be some other piece I’m missing to install the executable in the right location?

Thanks again for any nudge in the right direction :slight_smile:


#7

If you want your snap to make a desktop file available to launch your app, you should add a desktop: key to the command defined under apps:. It should point to the path where you install the .desktop file within your snap.

As for actually launching the app, if your part is installing the application to $SNAP/usr/bin/gtk-desktop-example, then the command: line for your app should instead read:

command: desktop-launch $SNAP/usr/bin/gtk-desktop-example

#8

Yep the desktop line was definitely missing so after adding that I continued down the rabbit hole. Now I can build the snap but can’t install it. It fails with:

- Ensure prerequisites for "gtk-desktop-example" are available (no snap revision available as specified)

@jamesh, when searching for a solution to this error, I actually found your post on using gtk-common-themes, but even putting these plugs in place (using gnome-3-32-1804), I still can’t get past the “Ensure prerequisites are available” error. Do you have any thoughts on what generally causes such an error?


#9

Can you post what your current snapcraft.yaml file looks like now? Or if you’ve published the whole project somewhere, a URL to the repository would help. It’s a bit hard to guess what is going on from just that message.


#10

Good point, here is my evolved snapcraft.yaml.


#11

Okay. I think the “no snap revision available” message is due to the gnome-3-32-1804 plug. What is happening is that snapd is trying to download the snap you’ve listed as the default-provider, but nothing has been published to the stable channel yet.

There is a snap on the edge channel, but it won’t be automatically installed as a prerequisite. You can manually install it with the following command:

snap install --edge gnome-3-32-1804

That will allow your own snap to install since the prerequisite is already installed. Note that any users of your snap will face the same error until gnome-3-32-1804 has been published to the stable channel. Ken created the snap fairly recently, so I don’t know when that will be.

With all that said, it doesn’t look like you should need to add that plug at present: it looks like you’re staging GTK, etc into your snap directly. So your snap should be self contained. For now I’d recommend dropping that plug all together.

In future if you want to slim down your snap using the GNOME platform snap, you can replace the desktop-gtk3 part definition with something based on desktop-gnome-platform. I’d only recommend pursuing this once your comfortable with the build tools and have a working snap though, since it introduces an extra failure mode.


#12

Oh great, this was really very useful, thanks jamesh man, it was really helpful


#13

Ah thank you for the explanation. Without the gnome-3-32-1804 block, I can install the snap. However, when I run the application, it fails with:

Traceback (most recent call last):
  File "/snap/gtk-desktop-example/x1/usr/bin/gtk-desktop-example", line 34, in <module>
    import gi
ModuleNotFoundError: No module named 'gi'

I tried to include the gnome-3-32-1804 platform to solve this - because of this thread.

If I instead replace the plug with the existing stable gnome-3-28-1804 plug, then I still hit the No module named 'gi' issue.

So then maybe the real question is: what is the proper way to workaround the missing gi module issue?


#14

For anyone else that hits a similar issue, the solution I went with was to:

  1. use the gnome-3-28-1804 plug
  2. include the PYTHONPATH variable in my application part environment:
PYTHONPATH: $SNAP/usr/lib/python3/dist-packages:$SNAP/gnome-platform/usr/lib/python3/dist-packages:$SNAP/usr/share/gtk-desktop-example