Xojo apps and Snap

I’m getting well outside my comfort zone here. In the past with Xojo, I setup a build environment to generate the deb and rpm files for Feedback. Today, Snap seems to be the most desired way to distribute software to desktop Linux. Reading over the docs for a part, it’s not obvious to me which plugin I should choose. I’m guessing maybe nil or dump?

Does anybody have experience building these for their Xojo apps? Maybe willing to share their yaml file? My end goal is to have this install the app (obviously) and setup both file and url handler associations. But I’m not quite at that phase yet.

Maybe this points you in the right direction:

There are more samples, we’ve done this in the past i may be able to provide you the yaml if i find it.

You need plugin: nil

Thanks. That’s a little helpful. I seem to have run into a showstopper though, so Linux support will have to wait anyway.

1 Like

I’m just getting started with snap. Did you ever manage to create a snap? Could this be relevant:
https://snapcraft.io/docs/pre-built-apps#p-31241-why-are-snaps-good-for-pre-built-apps

2 Likes

No I did not. That guide is incredibly helpful. When I can free up some time, a Linux version of my app is looking more likely now.

2 Likes

Great. I will get back here when I manage to get it working and post how I did it.

1 Like

Well I figured I’d try with a CLI tool, since I’m trying to decide on the right strategy to get it installed on and updateable on multiple servers.

I’ve managed to get a snap built. But I haven’t managed to actually use my tool after install. I can see it’s in /snap/<name>/current/<name> and I can execute it. But the trouble is my config file. I have coded it to look next to the app first, then in /etc, and with the addition of snap, wherever the SNAP_DATA environmental variable tells me. If there’s no config file, it’ll ask a few questions to build one and attempt to write to SNAP_DATA. Except I cannot. It errors with an IOException 2. Even with sudo. This is obviously the sandbox getting in the way, but I can’t seem to figure out what the correct location is. Another problem is this data folder is /snap/<name>/current, so installing updates will wipe out the config, since the current symlink will point to the newly installed folder instead.

So yeah… supremely frustrating so far.

Edit: So the environmental variables aren’t being set. That explains the trouble. Also looks like SNAP_USER_COMMON is probably the better choice. If I were getting the variable.

Ok, some more progress. Running the tool directly (as in outside of snap) is the issue. Inside snap, all those variables are set.

But, I’m still missing some detail. When run inside snap, libunwind8 is not found. It’s absolutely installed on the system, marked as a dependency in the snap, and the tool runs fine outside of snap. So it’s some kind of sandbox issue, and I’m sure other libraries will have a similar problem.

It feels like there must be a way to solve this, but I haven’t been able to figure it out.

OK. Do you care to share your yaml file? I’m struggling a bit myself.

Sure. I did get it all working and forgot to update here.

Some of these steps are not required, but I found they make my life easier.

  1. Add a build script to your Xojo project to dump the version to a file next to your build. You’ll use this in your yaml file to detect the version automatically.
  2. Write a small shell script to build a tar archive of your build so snapcraft can include its contents. The script can delete it after the build is finished.

My snapcraft.yaml looks like this:

name: <partname>
adopt-info: <partname>
summary: <summary>
description: <description>
confinement: strict
base: core22

parts:
  <partname>:
    plugin: dump
    source: <partname>.tar.gz
    stage-packages:
      - libstdc++6:${CRAFT_ARCH_BUILD_FOR}
      - libunwind8:${CRAFT_ARCH_BUILD_FOR}
      - libsoup2.4-dev:${CRAFT_ARCH_BUILD_FOR}
    override-stage: |
      craftctl default
      craftctl set version=$( cat ${SNAPCRAFT_PROJECT_DIR}/VERSION )

apps:
  <partname>:
    command: <partname>
    daemon: simple
    plugs: [network]

architectures:
  - build-on: [amd64, arm64]
    build-for: [amd64]

package-repositories:
  - type: apt
    formats: [deb, deb-src]
    architectures: [amd64]
    components: [main, universe]
    suites: [jammy]
    key-id: F6ECB3762474EDA9D21B7022871920D1991BC93C
    url: http://archive.ubuntu.com/ubuntu/

So… let’s break down what I can. I used core22 instead of core18 because core18 is no longer supported. My system is running Ubuntu 22.04, so this made a lot of sense for me personally. This is also the version of the repository listed at the bottom of the file.

Being a command line tool, I didn’t need to list all the required libraries in stage-packages, thankfully. Because figuring out which packages I need to install is really frustrating. I wish Xojo’s system requirements would list what I need to install, not just the general names. override stage is used to pull the version from that version file that Xojo created for me.

In the apps section I added plugs: [network] because I need networking.

In architectures I told it this can be build on both x86_64 and arm64. amd64 is a synonym for x86_64. But the build target is only amd64, since that’s what my target hardware is. But since I’m building from a VM on my Mac, arm64 is needed for build-on. That added quite the challenge, because the missing libraries was due to the snap including the arm64 versions for the amd64 build.

The solution was adding ${CRAFT_ARCH_BUILD_FOR} to stage-packages and telling it which repo to use when cross-building. That’s what package-repositories is about.

Thanks. I’m trying to create snap for a desktop app. I keep running into problems regarding.

stage-packages:
      - libgtk-3-0

I tried to add - libgtk-3-dev and changing core from 20 to 22, but then needed to install LXD to no avail. Also, I’m no longer sure how to organize the Xojo folders in the

parts:
   organize:

The library issue I’m not sure I’ll be much help with. I’ll need to do the same sometime down the road with a desktop app, but that won’t be for a while. But I don’t think you need to do anything with the organize key. That’s useful for putting files in places like /usr, but your Xojo app should all be kept together, I don’t believe you need or or should organize them at all.

I tried creating a .deb file first and then snap that. It works now, but there are some errors when I try to run the final snap.

name: fatx-m4
version: '3.0'
summary: Weight-loss program
description: |
  Fatx-M4 is a simple but powerful program to plan meals and measure progress for optimum fat loss.

base: core20

confinement: strict   # Use strict confinement by default
grade: stable         # Mark as stable for production use

parts:
  fatx:
    plugin: dump
    source: ./fatx.deb  # Path to the .deb file you're including
    stage-packages:
      - libc6
      - libgcc1
      - libstdc++6
      - libunwind8  # Add libunwind8 to ensure libunwind.so.8 is available
      - locales      # Include locales package
      - libcanberra-gtk-module  # Include GTK sound module
      - hicolor-icon-theme  # Include hicolor icon theme
    organize:
      fatx.deb: opt/fatx/fatx.deb  # Place the .deb in a relative path in the Snap filesystem

  install:
    plugin: dump
    source: ./fatx.deb  # Directly reference the source .deb file
    stage:
      - opt/fatx  # Target directory for the .deb contents after extraction

apps:
  fatx-m4:
    command: opt/fatx/Fatx  # Adjust to the actual executable inside the .deb
    plugs: [x11, network, wayland]