Guidelines and HOWTOs/Snap: Difference between revisions

From KDE Community Wiki
No edit summary
No edit summary
 
(28 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{Construction}}
= Put Your App in the Snap Store =
= Put Your App in the Snap Store =


[[File:Screenshot 20210318 150131.png|thumb|Snap Store KDE Page]]
[[File:Screenshot 20210318 150131.png|thumb|Snap Store KDE Page]]


It is a KDE goal to be [https://kde.org/goals/ All About the Apps] to deliver our apps directly to our users. Snaps is one of the ways to do this. Snaps are Linux app packages that can run on pretty much any Linux distro. There is a single centralised Snap store that delivers them to users.  Take a look at the [https://snapcraft.io/publisher/kde KDE page on the Snap Store] to see what's available.
It is a KDE goal to be [https://community.kde.org/Goals All About the Apps] to deliver our apps directly to our users. Snaps is one of the ways of doing this. Snaps are Linux app packages that can run on pretty much any Linux operating system. There is a single centralized Snap store ( https://snapcraft.io/store ) that delivers them to users.  Take a look at the [https://snapcraft.io/publisher/kde KDE page on the Snap Store] to see what's available.


== Snap intro ==
== Snap intro ==


A Snap package typically contains all the files, including libraries and data files, to run the app. There are also Content Snaps which contain reuseble libraries. In KDE land we have the [https://snapcraft.io/kde-frameworks-5-qt-5-15-core20 KDE Frameworks Content Snap] which includes recent Qt and KDE Frameworks and this is shared between all KDE apps so we do not have to waste disk space and build resources.
A Snap package typically contains all the files, including libraries and data files, to run the app. There are also Content Snaps which contain reusable libraries. KDE has the KDE Frameworks Content Snap https://snapcraft.io/search?q=kf6 and https://snapcraft.io/search?q=kf5 which includes recent Qt and KDE Frameworks and this is shared between all KDE apps so we do not have to waste disk space and build resources. With KDE / Plasma 6 the content pack has been split https://snapcraft.io/kde-qt6-core22-sdk for Qt6 and https://snapcraft.io/kf6-core22-sdk for KDE Frameworks 6.  


Give it a try by installing a package or two on your system
Give it a try by installing a package or two on your system. E.g. the KDE desktop calculator app https://snapcraft.io/kcalc
{{Input|1=<nowiki>snap install kcalc</nowiki>}}
{{Input|1=<nowiki>snap install kcalc</nowiki>}}
And run kcalc from your apps menu.
And run kcalc from your apps menu.


This will have downloaded the kcalc Snap package from the Snap store into e.g. <code>/var/lib/snapd/snaps/kcalc_73.snap</code> and mounted it into e.g. <code>/snap/kcalc/current/</code>. You can also just download it to a local directory with  <code>snap download kcalc</code>, use <code>lesspipe kcalc*snap</code> to see what it inside it.
This will have downloaded the kcalc Snap package from the Snap store into e.g. <code>/var/lib/snapd/snaps/kcalc_73.snap</code> and mounted it into e.g. <code>/snap/kcalc/current/</code>. You can also just download it to a local directory with  <code>snap download kcalc</code>, use <code>lesspipe kcalc*snap</code> to see what is inside it.
 
<code>snap list</code> will show your currently installed snaps and it will now show that you have <code>kcalc</code> and the content snap <code>kf5-5-111-qt-5-15-11-core22</code> as well as the <code>core22</code> content snap installed.
 
Snaps are containers, similar to Docker. From inside the Snap container access to the file system and system resources are limited. This is good for inter-app security but means the app sees your system quite differently from how you might expect.  You can "log" into the container with <code>snap run --shell kcalc</code> to have a look at how the snapped kcalc app sees your system.
 
To give the app controlled permissions to the system it plugs connections into resources such as the network or container snaps. Run <code>snap connections kcalc</code> to see what it gets given access to. The auto connections are controlled by the snap store and app maintainers need to ask the snap store for the desired auto-connections. Connections can also be overridden locally.
 
You can take a look at the snap package with <code>snap download kcalc</code> which will download files such as <code>kcalc_73.assert</code> and <code>kcalc_73.snap</code>. The .assert has the checksums and signatures for the package.  The .snap has the (non-store) metadata and all the files of the package. <code>lesspipe kcalc_73.snap</code> to take a look.
 
== How to contribute to Qt6 snaps ==
<br>
=kde-qt6-core22=
First we start with the Qt6 SDK snap which is located here: <br>
 
[kde-qt6-sdk](https://invent.kde.org/neon/snap-packaging/kde-qt6-snap)
 
This snap should not need much altering. Version updates mainly. <br>
 
In the snapcraft.yaml file: <br>
`version: 6.7.0` <br>
 
We should be on 6.7.0 to match Neon, to see what version Neon is on, check:
[https://build.neon.kde.org/job/jammy_unstable_qt6_qt6-base_src/](https://build.neon.kde.org/job/jammy_unstable_qt6_qt6-base_src/)
So we need to update our Qt version to match: <br>
`version: 6.7.0` <br>
 
Commit and push. Now we check to make sure builds have been triggered <br>
( Note: This will change once we have our CI in place. ) <br>
 
[SDK builds](https://launchpad.net/~kde-community/kde-qt6-core22-sdk-unstable/+snap/kde-qt6-core22-sdk-unstable) <br>
(Note: You must be logged into the KDE-community account) <br>
If builds did NOT trigger, then click the request builds at the bottom of the page. <br>
 
Once the build completes ( This will take a long time... ) you then trigger the Runtime snap: <br>
 
[Qt6-runtime](https://launchpad.net/~kde-community/kde-qt6-runtime/+snap/kde-qt6-core22-unstable) <br>
(Note: Don't forget this step! There is no automation in this step. Yet.)
 
Once both of those are complete...
 
=kf6-core22=
 
The KDE frameworks SDK snap files are located here: <br>
 
[kf6 SDK](https://invent.kde.org/neon/snap-packaging/kf6-snap) <br>
 
This file is much to long to paste here, but here is a breakdown of a part: <br>
 
{{Input|<syntaxhighlight lang="yaml" line>
extra-cmake-modules:
        after:
        - qtconf
        source: https://invent.kde.org/frameworks/extra-cmake-modules.git
        source-branch: master
        build-packages:
        - cmake
        build-snaps:
        - kde-qt6-core22-sdk
        plugin: cmake
        cmake-generator: Ninja
        cmake-parameters:
        - -DCMAKE_INSTALL_PREFIX=/usr
        - -DCMAKE_BUILD_TYPE=RelWithDebInfo
        - -DQT_MAJOR_VERSION=6
        - -DBUILD_WITH_QT6=ON
        - -DBUILD_TESTING=OFF
        - -DCMAKE_INSTALL_SYSCONFDIR=/etc
        - -DCMAKE_INSTALL_LOCALSTATEDIR=/var
        - -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
        - -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_INSTALL_RUNSTATEDIR=/run
        - -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON
        - -DCMAKE_VERBOSE_MAKEFILE=ON
        - -DCMAKE_INSTALL_LIBDIR=lib/$CRAFT_ARCH_TRIPLET
        - --log-level=STATUS
        - -DCMAKE_LIBRARY_PATH=lib/$CRAFT_ARCH_TRIPLET
        - "-DCMAKE_FIND_ROOT_PATH=$CRAFT_STAGE\\;/snap/kde-qt6-core22-sdk/current\\;/usr"
        - "-DCMAKE_PREFIX_PATH=$CRAFT_STAGE\\;/snap/kde-qt6-core22-sdk/current\\;/usr"
        build-environment:
        - PATH: /snap/kde-qt6-core22-sdk/current/usr/bin${PATH:+:$PATH}
        - XDG_DATA_DIRS: $CRAFT_STAGE/usr/share:/snap/kde-qt6-core22-sdk/current/usr/share:/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}
        - XDG_CONFIG_HOME: $CRAFT_STAGE/etc/xdg:/snap/kde-qt6-core22-sdk/current/etc/xdg:/etc/xdg${XDG_CONFIG_HOME:+:$XDG_CONFIG_HOME}
        - LD_LIBRARY_PATH: "/snap/kde-qt6-core22-sdk/current/usr/lib/${CRAFT_ARCH_TRIPLET}:/snap/kde-qt6-core22-sdk/current/usr/lib:$CRAFT_STAGE/usr/lib:$CRAFT_STAGE/lib/:$CRAFT_STAGE/usr/lib/${CRAFT_ARCH_TRIPLET}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"\
</syntaxhighlight>}}
<br>
<br>
 
`extra-cmake-module` ** Name of the framework. ** <br>
`        after:
        - qtconf` ** Build time framework dependencies listed here. ( Note: anything listed here MUST already be listed as a part. ) ** <br>
`        source: https://invent.kde.org/frameworks/extra-cmake-modules.git` ** Source repo. ** <br>
`        source-branch: master` ** Source branch ( Note: we will likely switch to source tags once stable. ) ** <br>
`        build-packages:
        - cmake` ** kde neon packages required to build. ( Note: this can be retrieved from Neon packaging aka: [https://invent.kde.org/neon/kf6/kf6-extra-cmake-modules/-/blob/Neon/unstable/debian/control?ref_type=heads](https://invent.kde.org/neon/kf6/kf6-extra-cmake-modules/-/blob/Neon/unstable/debian/control?ref_type=heads), please remove any qt6, kf6 packages from the list as we build those ourselves. ) ** <br>
`        stage-packages:
        - package` ** kde neon packages required at runtime. ( Note: Delete any qt6, kf6, standard C++ libraries packages from here. Runtime packages can be retrieved from neon build artifacts aka: [https://build.neon.kde.org/job/jammy_unstable_kf6_kf6-extra-cmake-modules_bin_amd64/lastSuccessfulBuild/artifact/result/kf6-extra-cmake-modules_6.0.0+p22.04+vunstable+git20240330.0049-0_amd64.deb.info.txt](https://build.neon.kde.org/job/jammy_unstable_kf6_kf6-extra-cmake-modules_bin_amd64/lastSuccessfulBuild/artifact/result/kf6-extra-cmake-modules_6.0.0+p22.04+vunstable+git20240330.0049-0_amd64.deb.info.txt) ** <br>
`        build-snaps:
        - kde-qt6-core22-sdk` ** Qt6 SDK build time snap, always stays the same ** <br>
`        plugin: cmake` ** Uses the cmake plugin, always stays the same ** <br>
`        cmake-generator: Ninja` ** Uses Ninja generator, always stays the same ** <br>
{{Input|<syntaxhighlight lang="yaml" line>   
        cmake-parameters:
        - -DCMAKE_INSTALL_PREFIX=/usr
        - -DCMAKE_BUILD_TYPE=RelWithDebInfo
        - -DQT_MAJOR_VERSION=6
        - -DBUILD_WITH_QT6=ON
        - -DBUILD_TESTING=OFF
        - -DCMAKE_INSTALL_SYSCONFDIR=/etc
        - -DCMAKE_INSTALL_LOCALSTATEDIR=/var
        - -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
        - -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_INSTALL_RUNSTATEDIR=/run
        - -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON
        - -DCMAKE_VERBOSE_MAKEFILE=ON
        - -DCMAKE_INSTALL_LIBDIR=lib/$CRAFT_ARCH_TRIPLET
        - --log-level=STATUS
        - -DCMAKE_LIBRARY_PATH=lib/$CRAFT_ARCH_TRIPLET
</syntaxhighlight>}}
** Cmake parameters, always stays the same ** <br>
 
<br>
<br>
 
Once you have all of your parts in place and are ready to build. Commit and push. <br>
Check to make sure builds have started here: <br>
[kf6 SDK](https://launchpad.net/~kde-community/kde-kf6-core22-snap-unstable/+snap/kf6-core22-sdk-unstable)
 
(Note: You must be logged into the KDE-community account) <br>
If builds did NOT trigger, then click the request builds at the bottom of the page. <br>
*** Note: There must **NOT** be a qt6 snap building or failed at this point, this snap depends on it. ***


<code>snap list</code> will show your currently installed snaps and it will now show that you have <code>kcalc</code> and the content snap <code>kde-frameworks-5-qt-5-15-core20</code> as well as the <code>core20</code> content snap installed.
Once the build completes ( This will take a long time... ) you then trigger the Runtime snap: <br>


Snaps are containers, similar to Docker. From inside the Snap container access to the file system and system resources are limited.  This is good for inter-app security but means the app sees your system quite differently from how it might expect.  You can "log" into the container with <code>snap run --shell kcalc</code> to have a look at how the Snapped kcalc app sees your system.
[kf6-runtime](https://launchpad.net/~kde-community/kf6-core22-runtime/+snap/kf6-core22-unstable) <br>
(Note: Don't forget this step! There is no automation in this step. Yet.)


To give the app controlled permissions to the system it plugs connections into resources such as the network or container snaps.  Run <code>snap connections kcalc</code> to see what it gets given access to.  The connections are controlled by the store and app maintainers need to ask the store to apply the auto-connections.  They can also be overridden locally.
=Applications=


You can take a look at the snap package with <code>snap download kcalc</code> which will download files such as <code>kcalc_73.assert</code> and <code>kcalc_73.snap</code>. The .assert has the checksums and signatures for the package. The .snap has the (non-store) metadata and all the files of the package. <code>lesspipe kcalc_73.snap</code> to take a look.
Fork the application into your userspace. Aka fork https://invent.kde.org/utilities/ark into your user account on invent.
Make sure you on the master branch.
Add your snapcraft.yaml
You can use the ark snapcraft.yaml as a template.
{{Input|<syntaxhighlight lang="yaml" line>
 
# SPDX-FileCopyrightText: 2023 Scarlett Moore <[email protected]>
#
# SPDX-License-Identifier: CC0-1.0
---
name: ark
confinement: strict
grade: stable
base: core22
adopt-info: ark
apps:
    ark:
        extensions:
        - kde-neon-6
        common-id: org.kde.ark.desktop
        desktop: usr/share/applications/org.kde.ark.desktop
        command: usr/bin/ark
        plugs:
        - home
        - system-backup
        command-chain:
        - snap/command-chain/desktop-launch6
slots:
    session-dbus-interface:
        interface: dbus
        name: org.kde.ark
        bus: session
package-repositories:
-  type: apt
    components:
    - main
    suites:
    - jammy
    key-id: 444DABCF3667D0283F894EDDE6D4736255751E5D
    url: http://origin.archive.neon.kde.org/user
    key-server: keyserver.ubuntu.com
parts:
    ark:
        parse-info:
        - usr/share/metainfo/org.kde.ark.appdata.xml
        plugin: cmake
        build-packages:
        - libarchive-dev
        - libbz2-dev
        - liblzma-dev
        - libzip5-dev
        - pkg-config
        - zlib1g-dev
        stage-packages:
        - bzip2
        - p7zip-full
        - unrar
        - unzip
        - zip
        - to amd64: [rar]
        - libarchive13
        - libzip4
        - zlib1g
        source: .
        source-type: local
        cmake-parameters:
        - -DCMAKE_INSTALL_PREFIX=/usr
        - -DCMAKE_BUILD_TYPE=RelWithDebInfo
        - -DQT_MAJOR_VERSION=6
        - -DBUILD_WITH_QT6=ON
        - -DBUILD_TESTING=OFF
        - -DCMAKE_INSTALL_SYSCONFDIR=/etc
        - -DCMAKE_INSTALL_LOCALSTATEDIR=/var
        - -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
        - -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_INSTALL_RUNSTATEDIR=/run
        - -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON
        - -DCMAKE_VERBOSE_MAKEFILE=ON
        - -DCMAKE_INSTALL_LIBDIR=lib/$CRAFT_ARCH_TRIPLET
        - --log-level=STATUS
        - -DCMAKE_LIBRARY_PATH=lib/$CRAFT_ARCH_TRIPLET
        prime:
        - -usr/lib/*/cmake/*
        - -usr/include/*
        - -usr/share/ECM/*
        - -usr/share/man/*
        - -usr/share/icons/breeze-dark*
        - -usr/bin/X11
        - -usr/lib/gcc/$SNAPCRAFT_ARCH_TRIPLET/6.0.0
        - -usr/lib/aspell/*
        - -usr/share/lintian
    cleanup:
        after:
        - ark
        plugin: nil
        build-snaps:
        - core22
        - kf6-core22
        override-prime: |
            set -eux
            for snap in "core22" "kf6-core22"; do
                cd "/snap/$snap/current" && find . -type f,l -exec rm -rf "${CRAFT_PRIME}/{}" \;
            done
</syntaxhighlight>}}
 
 
``` git add snapcraft.yaml ```
``` git commit ```
Add the changes you made to the commit message.
``` git push ```
Now create a merge request.


== Concepts ==
== Concepts ==


Snaps are usually one app per Snap package.  The Snap package contains all the libraries and resources it needs to run except those in the shared content kde-frameworks Snap.
Snaps are usually one app per Snap package.  The Snap package contains all the libraries and resources it needs to run except those in the shared content <code>kf5-5-111-qt-5-15-11-core22</code> Snap.


In practice this means all of Qt and KF5 including Breeze icons and themes are in the kde-frameworks content Snap and your app Snap only needs to compile its own sources.  If you apps needs other libraries it can either install these as Apt packages from the Ubuntu or KDE neon or other repository, or it can compile them from source as well. You will need to manually list the build-packages (all the -dev packages) and the stage-packages used in the final package, it'll warn you if any final libraries it expects are missing.
In practice this means all of Qt and KF(5/6) including Breeze icons and themes are in the kde-frameworks content Snap and your app Snap only needs to compile its own sources.  If you apps needs more libraries you can either install these as DEB packages e.g. from the Linux operating system Ubuntu LTS or KDE neon, or you can compile them from source as well. You will need to manually list the build-packages (all the -dev packages) and the stage-packages used in the final package, it'll warn you if any final libraries it expects are missing.


'''Snapcraft''' is used to build snaps. It can be installed as a snap with <code>snap install snapcraft --classic</code>.  Snap packages are defined with snapcraft.yaml files. Snapcraft will build them inside a virtual machine, we use LXD to build the KDE ones (the default is to use Multipass another virtual machine manager but that has problems on cloud machines). Using a virtual machine makes it reliable to build the Snaps on any system with identical results.  
'''snapcraft''' is used to build snaps. It can be installed as a snap with <code>snap install snapcraft --classic</code>.  A snap package (app) is defined in the snapcraft.yaml file. Snapcraft will build the package inside a virtual machine; it uses LXD to build the KDE snap packages. Using a virtual machine makes it reliable to build the Snaps on different Linux operating systems with identical results.  


snapcraft.yaml files are kept in either [https://invent.kde.org/neon KDE neon git repositories] or in the apps repository. They can be built on the [https://build.neon.kde.org/view/Snaps/ KDE neon Jenkins CI].  All KDE Developers have access to all these git repos and use of the Jenkins CI.  Stable versions are kept in the Neon/release branches or the stable KDE git branch of your app. Unstable versions in Neon/unstable or the unstable branch of your app (usually master).
snapcraft.yaml files are kept in their respective upstream repo. Eg. kcalc snapcraft file resides [https://invent.kde.org/utilities/kcalc/-/blob/release/23.08/snapcraft.yaml?ref%20type=heads https://invent.kde.org/utilities/kcalc/-/blob/release/23.08/snapcraft.yaml?ref_type=heads]


Our Snaps read metadata from AppStream metadata files so it is important the metadata is up to date including current release versions.
Our Snaps read metadata from AppStream metadata files so it is important the metadata is up to date including current release versions.


The [https://snapcraft.io/ Snap Store] is the centralised app store by Canonical. There is no practical way to use other stores or repositories with Snaps. It is what Snapcraft uploads built snaps to and what your local snapd will download and install snaps from. It also says what permissions those snaps should have. As an app developer if you want your app to have extra permissions (for example [https://invent.kde.org/neon/kde/kdf/-/blob/Neon/unstable/snapcraft.yaml kdf uses mount-observe]) then you need to ask for it on the [https://forum.snapcraft.io/t/request-for-connection-kdf-mount-observe/10953 snapcraft forum].
The [https://snapcraft.io/ Snap Store] is the centralized app store by Canonical. There is no practical way to use other stores or repositories with Snaps. It is what Snapcraft uploads built snaps to and what your local snapd will download and install snaps from. It also says what permissions those snaps should have. As an app developer if you want your app to have extra permissions (for example [https://invent.kde.org/utilities/kdf/-/blob/release/23.08/snapcraft.yaml?ref_type=heads kdf] uses mount-observe) then you need to ask for it on the [https://forum.snapcraft.io/t/request-for-connection-kdf-mount-observe/10953 snapcraft forum].


A Classic containment Snap has no restrictions on what files it can see on your system or what external executable can be run.  This is useful for IDEs and similar apps such as [https://forum.snapcraft.io/t/kate-as-classic-snap/23514 Kate] which runs external programs. Again this needs to be set in your [https://invent.kde.org/neon/kde/kate/-/blob/Neon/release/snapcraft.yaml#L3 snapcraft.yaml] then you need to ask on the Snap forum for the store to set it to classic. The Store will then tell snapd for anyone installing the Snap to have it installed as a Classic confinement Snap.
A Classic containment Snap has no restrictions on what files it can see on your system or what external executable can be run.  This is useful for Integrated Development Environments (IDEs) and similar apps such as [https://forum.snapcraft.io/t/kate-as-classic-snap/23514 Kate] which runs external programs. Again this needs to be set in your [https://invent.kde.org/utilities/kate/-/blob/release/23.08/snapcraft.yaml?ref_type=heads] then you need to ask on the Snap forum for the store to set it to classic. The Store will then tell snapd for anyone installing the Snap to have it installed as a Classic confinement Snap.


There is a KDE account on the Snap store which is run by the KDE neon developers Jonathan Riddell and Harald Sitter. One Snap on the store can be shared between more than one account so app maintainers can also create a separate account if they want to have more control over when their app is released and what the store says about it.
The KDE account on the Snap store is run by the Snap team developers Jonathan Esk-Riddell, Harald Sitter, Scarlett Moore, Carlos DeMaine, Kevin Ottens, Benjamin Port. One Snap on the store can be shared between more than one account so app maintainers can also create a separate account if they want to have more control over when their app is released and what the store says about it.


The store has four channels for different levels of stability. Our stable branch builds get uploaded to the Candidate channel and can be moved to the Stable channel once tested.
The store has four channels for different levels of stability. Our stable branch builds get uploaded to the Candidate channel and can be moved to the Stable channel once tested.


== Example ==
== Example ==


[https://apps.kde.org/blinken/ Blinken] is an exciting memory game from KDE.  It's [https://snapcraft.io/blinken available on the Snap store].  The Snap package is defined by a <code>snapcraft.yaml</code> file which is in the <code>Neon/release</code> branch of [https://invent.kde.org/neon/kde/blinken/-/blob/Neon/release/snapcraft.yaml KDE neon's Blinken packging].  Any update to that branch triggest a build of the [https://build.neon.kde.org/view/Snaps/job/focal_stable_kde_blinken_snap_amd64/ Blinken Snap job] in KDE neon's Jenkins builder.  If the build is successful it will be uploaded to the <code>Candidate channel</code> of the Snap store ready for review.
[https://apps.kde.org/blinken/ Blinken] is an exciting memory game from KDE.  It's [https://snapcraft.io/blinken available on the Snap store].  The Snap package is defined by a <code>snapcraft.yaml</code> file which is in the https://invent.kde.org/education/blinken/-/tree/release/23.08?ref_type=heads repo.  Any update to that branch triggers a build of the [https://launchpad.net/~kde-community/kde-snap-blinken/+snap/kde-snap-blinken-stable] in launchpad.  If the build is successful it will be uploaded to the <code>Candidate channel</code> of the Snap store ready for review.


The <code>snapcraft.yaml</code> file looks like this:
{{Input|<syntaxhighlight lang="yaml" line>


{{Input|<syntaxhighlight lang="yaml" line>
# SPDX-FileCopyrightText: 2024 Scarlett Moore <[email protected]>
#
# SPDX-License-Identifier: CC0-1.0
---
---
name: blinken
name: blinken
confinement: strict
confinement: strict
grade: stable
grade: stable
base: core20
base: core22
adopt-info: blinken
adopt-info: blinken
apps:
apps:
     blinken:
     blinken:
         extensions:
         extensions:
         - kde-neon
         - kde-neon-6
         common-id: org.kde.blinken.desktop
         common-id: org.kde.blinken.desktop
        desktop: usr/share/applications/org.kde.blinken.desktop
         command: usr/bin/blinken
         command: usr/bin/blinken
         plugs:
         plugs:
         - home
         - home
         - network
         - system-backup
         - network-bind
         command-chain:
         - audio-playback
         - snap/command-chain/desktop-launch6
        - removable-media
slots:
slots:
     session-dbus-interface:
     session-dbus-interface:
Line 78: Line 326:
     - main
     - main
     suites:
     suites:
     - focal
     - jammy
     key-id: 444DABCF3667D0283F894EDDE6D4736255751E5D
     key-id: 444DABCF3667D0283F894EDDE6D4736255751E5D
     url: http://origin.archive.neon.kde.org/user
     url: http://origin.archive.neon.kde.org/user
Line 84: Line 332:
parts:
parts:
     blinken:
     blinken:
        parse-info:
        - usr/share/metainfo/org.kde.blinken.appdata.xml
         plugin: cmake
         plugin: cmake
         build-packages:
         source: .
         - libkf5doctools-dev
         source-type: local
        - libphonon4qt5-dev
        - libphonon4qt5experimental-dev
        source: http://download.kde.org/stable/release-service/20.12.3/src/blinken-20.12.3.tar.xz
         cmake-parameters:
         cmake-parameters:
         - "-DKDE_INSTALL_USE_QT_SYS_PATHS=ON"
         - -DCMAKE_INSTALL_PREFIX=/usr
        - "-DCMAKE_INSTALL_PREFIX=/usr"
         - -DCMAKE_BUILD_TYPE=RelWithDebInfo
         - "-DCMAKE_BUILD_TYPE=Release"
         - -DQT_MAJOR_VERSION=6
         - "-DENABLE_TESTING=OFF"
         - -DBUILD_WITH_QT6=ON
         - "-DBUILD_TESTING=OFF"
         - -DBUILD_TESTING=OFF
         - "-DKDE_SKIP_TEST_SETTINGS=ON"
         - -DCMAKE_INSTALL_SYSCONFDIR=/etc
         - "-DCMAKE_FIND_ROOT_PATH=/usr\\;/root/stage\\;/snap/kde-frameworks-5-qt-5-15-core20-sdk/current"
         - -DCMAKE_INSTALL_LOCALSTATEDIR=/var
         parse-info:
         - -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON
        - usr/share/metainfo/org.kde.blinken.appdata.xml
        - -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
         filesets:
        - -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON
            exclusion:
        - -DCMAKE_INSTALL_RUNSTATEDIR=/run
            - "-usr/lib/*/cmake/*"
        - -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON
            - "-usr/include/*"
        - -DCMAKE_VERBOSE_MAKEFILE=ON
            - "-usr/share/ECM/*"
        - -DCMAKE_INSTALL_LIBDIR=lib/$CRAFT_ARCH_TRIPLET
            - "-usr/share/doc/*"
        - --log-level=STATUS
            - "-usr/share/man/*"
        - -DCMAKE_LIBRARY_PATH=lib/$CRAFT_ARCH_TRIPLET
            - "-usr/share/icons/breeze-dark*"
            - "-usr/bin/X11"
            - "-usr/lib/gcc/x86_64-linux-gnu/6.0.0"
            - "-usr/lib/aspell/*"
         prime:
         prime:
         - "$exclusion"
         - -usr/lib/*/cmake/*
        - -usr/include/*
        - -usr/share/ECM/*
        - -usr/share/man/*
        - -usr/share/icons/breeze-dark*
        - -usr/bin/X11
        - -usr/lib/gcc/$SNAPCRAFT_ARCH_TRIPLET/6.0.0
        - -usr/lib/aspell/*
        - "-usr/share/lintian"
    cleanup:
        after:
        - blinken
        plugin: nil
        build-snaps:
        - core22
        - kf6-core22
        - kde-qt6-core22
        override-prime: |
            set -eux
            for snap in "core22" "kf6-core22" "kde-qt6-core22"; do
                cd "/snap/$snap/current" && find . -type f,l -exec rm -rf "${CRAFT_PRIME}/{}" \;
            done
 
 
</syntaxhighlight>}}
</syntaxhighlight>}}


Check [https://snapcraft.io/docs/snapcraft-yaml-reference Snapcraft YAML reference] if unsure.
Check [https://snapcraft.io/docs/snapcraft-yaml-reference Snapcraft YAML reference] if unsure.
Line 122: Line 390:
* confinement: strict ← Snaps are a containerised format and can't see the outside system from inside their container.  Strict is the normal container method.  Classic is also possible which allows it to see the outside system and is used by e.g. Kate because Kate needs to run external programs like Git.  It can only be Classic on request.  Can also be devmode for testing.
* confinement: strict ← Snaps are a containerised format and can't see the outside system from inside their container.  Strict is the normal container method.  Classic is also possible which allows it to see the outside system and is used by e.g. Kate because Kate needs to run external programs like Git.  It can only be Classic on request.  Can also be devmode for testing.
* grade: stable ← It must be stable to be in a released channel, can also be devel.
* grade: stable ← It must be stable to be in a released channel, can also be devel.
* base: core20 ← which base system to build on, core20 means Ubuntu 20.04 and is the current recommended.
* base: core22 ← which base system to build on, core22 means Ubuntu 22.04 and is the current recommended.
* adopt-info: blinken ← Which Snap part to get the appstream info from.  This sets version, icon, description.
* adopt-info: blinken ← Which Snap part to get the appstream info from.  This sets version, icon, description.


Line 133: Line 401:
     blinken:
     blinken:
         extensions:
         extensions:
         - kde-neon
         - kde-neon-6
         common-id: org.kde.blinken.desktop
         common-id: org.kde.blinken.desktop
        desktop: usr/share/applications/org.kde.blinken.desktop
         command: usr/bin/blinken
         command: usr/bin/blinken
         plugs:
         plugs:
         - home
         - home
         - network
         - system-backup
         - network-bind
         command-chain:
         - audio-playback
         - snap/command-chain/desktop-launch6
        - removable-media
 
</syntaxhighlight>}}
</syntaxhighlight>}}


<code>apps</code> are the programs which the snap includes for users to run.  Usually there is only one in a Snap but sometimes e.g. [https://invent.kde.org/neon/extras/calligra/-/blob/Neon/release/snapcraft.yaml Calligra] there are more than one.
<code>apps</code> are the programs which the snap includes for users to run.  Usually there is only one in a Snap but sometimes e.g. [https://invent.kde.org/office/calligra/-/blob/calligra/3.3/snapcraft.yaml?ref_type=heads Calligra] there are more than one.


The [https://snapcraft.io/docs/kde-neon-extension KDE neon extension] adds some commonly used features to the KDE snaps including using the [https://snapcraft.io/kde-frameworks-5-qt-5-15-core20 KDE Frameworks 5 content Snap].
The [https://snapcraft.io/docs/kde-neon-extension KDE neon extension] adds some commonly used features to the KDE snaps including using the [https://snapcraft.io/kf6-core22 content Snap].


The <code>common-id</code> comes from the Appstream file.  You ''must'' check what it is in the appstream file. <code>org.kde.blinken.appdata.xml</code> contains <code><id>org.kde.blinken.desktop</id></code> so we use that.  Sometimes apps use the .desktop and sometimes they don't, this is at random.
The <code>common-id</code> comes from the Appstream file.  You ''must'' check what it is in the appstream file. <code>org.kde.blinken.appdata.xml</code> contains <code><id>org.kde.blinken.desktop</id></code> so we use that.  Sometimes apps use the .desktop and sometimes they don't, this is at random.
Line 152: Line 421:
The command to run is listed.  The KDE neon extension will run a script first which sets many necessary environment variables.
The command to run is listed.  The KDE neon extension will run a script first which sets many necessary environment variables.


The plugs give access to the outside system, see [https://snapcraft.io/docs/supported-interfaces Supported interfaces] for descriptions.  When a Snap is installed from the Store it is up to the Store to say which plugs get used.  Thost listed as auto connect in the docs are permitted.  Otherwise you must ask on the Snap forum for permission to have the Snap connected.  (Locally installed snaps with --devmode have access to everything, you can also manually connect snaps to interfaces on your local system.)
The plugs give access to the outside system, see [https://snapcraft.io/docs/supported-interfaces Supported interfaces] for descriptions.  When a Snap is installed from the Store it is up to the Store to say which plugs get used.  Those listed as auto connect in the docs are permitted.  Otherwise you must ask on the Snap forum for permission to have the Snap connected.  (Locally installed snaps with --devmode have access to everything, you can also manually connect snaps to interfaces on your local system.)


<code>slots</code> are the complement to plugs, they allow the outside system to access our Snap app.  In this case we are allowing a dbus interface into the Snap.  All KDE apps have a dbus interface and you can check what it is called by running the app and using <code>qdbus</code>.
<code>slots</code> are the complement to plugs, they allow the outside system to access our Snap app.  In this case we are allowing a dbus interface into the Snap.  All KDE apps have a dbus interface and you can check what it is called by running the app and using <code>qdbus</code>.
Line 158: Line 427:
<code>package-repositories</code> add the KDE neon apt repo to build against, this will give you the latest libraries to compile with.
<code>package-repositories</code> add the KDE neon apt repo to build against, this will give you the latest libraries to compile with.


The source of a Snap is the <code>parts</code> and some snaps have several parts made of different sources e.g. [https://invent.kde.org/neon/extras/ktorrent/-/blob/Neon/release/snapcraft.yaml KTorrent] has both libktorrent and ktorrent parts. Blinken is not complex so it has only one part made of the compiles Blinken source.
The source of a Snap is the <code>parts</code> and some snaps have several parts made of different sources e.g. [TBD] has both libktorrent and ktorrent parts. Blinken is not complex so it has only one part made of the compiles Blinken source.


=== Parts ===
=== Parts ===


* plugin ← which [https://snapcraft.io/docs/supported-plugins Snap build plugin] to use
* plugin ← which [https://snapcraft.io/docs/supported-plugins Snap build plugin] to use
* build-packages ← most build packages are in the KDE Frameworks content snap but some need added explicitly and some are not in there.  They will be downloaded from the neon and ubuntu apt repos.  [https://invent.kde.org/neon/extras/ktorrent/-/blob/Neon/release/snapcraft.yaml#L40 KTorrent] uses non-KDE libraries and it needs to list the -dev packages in the <code>build-packages</code> then the library itself in the <code>stage-packages</code>.
* build-packages ← most build packages are in the KDE Frameworks content snap but some need added explicitly and some are not in there.  They will be downloaded from the neon and ubuntu apt repos.  [TBD] uses non-KDE libraries and it needs to list the -dev packages in the <code>build-packages</code> then the library itself in the <code>stage-packages</code>.
* source ← link to the tar
* source ← link to the tar
* cmake-parameters ← copy and paste this, it sets the right paths.
* cmake-parameters ← copy and paste this, it sets the right paths.
Line 172: Line 441:
Install snapcraft with <code>snap install snapcraft --classic</code>.
Install snapcraft with <code>snap install snapcraft --classic</code>.


In the directory with the <code>snapcraft.yaml</code> run: <code>snapcraft --enable-experimental-package-repositories --enable-experimental-extensions --use-lxd</code>
In the directory with the <code>snapcraft.yaml</code> run: <code>snapcraft</code>


This will start a virtual machine and build the package. If all is well you will have <code>blinken_20.12.3_amd64.snap</code> or similar created.
This will start a virtual machine and build the package. If all is well you will have <code>blinken_24.05_amd64.snap</code> or similar created. If you had not installed lxd before, you may need to add your user to the lxd group to allow access to lxd.


Install with <code>snap install --devmode blinken_20.12.3_amd64.snap</code>
Install with <code>snap install blinken_24.05_amd64.snap --devmode</code>.


Run with <code>snap run blinken</code> or check it is in the app menu and run from there (remove any versions of blink you have installed from your normal distro packages just to be sure).
Run with <code>blinken</code> or check if blinken is available in the app menu and run it from there (remove any versions of blink you have installed from your normal distro packages just to be sure). <code>which -a blinken</code> should say that blinken is available at least as <code>/snap/bin/blinken</code>.


== Quirks ==
== Quirks ==


=== alsa ===
=== Patches ===
 
If you need to update some code in the release you can patch it in the Snap package.  But please get the patch upstream into the Git archive first.
To add a patch to a snap, one must add the snippet to the part that needs patched:
{{Input|<syntaxhighlight lang="yaml" line>
        override-pull: |
            craftctl default
              for file in ${CRAFT_PROJECT_DIR}/snap/local/patches/*
              do
                patch -i $file -p 1
              done
</syntaxhighlight>}}
 
Add add the patch in snap/local/patches/
 
== Help ==
 
[https://snapcraft.io/docs Snapcraft docs] including tutorials on using and building.


Some KDEGames use libkdegames's KgSound class which uses libopenal which uses libsnd which uses alsa.  (Most other KDE software uses QtMultimedia or Phonon which uses Pulseaudio.)  See [https://invent.kde.org/neon/kde/kblocks/-/blob/Neon/release/snapcraft.yaml KBlocks] for one way to make this work.  Use the alsa extension, use layers to move files around, exclude the pulse alsa file.
[https://snapcraft.io/docs/snap-format snapcraft.yaml format].


=== Qt Only ===
[https://forum.snapcraft.io/ Snap forum] for asking for help or asking to get the store to allow your Snaps to auto connect.


You may want to simplify your Snap by using Qt directly instead of the KDE neon extension and KDE Frameworks content Snap. Good luck :)
[https://webchat.kde.org/#/room/#kde-neon:kde.org KDE neon devs] talk to sgmoore for help getting your app into the Store.


== Glossary ==
== Glossary ==

Latest revision as of 17:18, 30 April 2024

 
Under Construction
This is a new page, currently under construction!


Put Your App in the Snap Store

Snap Store KDE Page

It is a KDE goal to be All About the Apps to deliver our apps directly to our users. Snaps is one of the ways of doing this. Snaps are Linux app packages that can run on pretty much any Linux operating system. There is a single centralized Snap store ( https://snapcraft.io/store ) that delivers them to users. Take a look at the KDE page on the Snap Store to see what's available.

Snap intro

A Snap package typically contains all the files, including libraries and data files, to run the app. There are also Content Snaps which contain reusable libraries. KDE has the KDE Frameworks Content Snap https://snapcraft.io/search?q=kf6 and https://snapcraft.io/search?q=kf5 which includes recent Qt and KDE Frameworks and this is shared between all KDE apps so we do not have to waste disk space and build resources. With KDE / Plasma 6 the content pack has been split https://snapcraft.io/kde-qt6-core22-sdk for Qt6 and https://snapcraft.io/kf6-core22-sdk for KDE Frameworks 6.

Give it a try by installing a package or two on your system. E.g. the KDE desktop calculator app https://snapcraft.io/kcalc

snap install kcalc

And run kcalc from your apps menu.

This will have downloaded the kcalc Snap package from the Snap store into e.g. /var/lib/snapd/snaps/kcalc_73.snap and mounted it into e.g. /snap/kcalc/current/. You can also just download it to a local directory with snap download kcalc, use lesspipe kcalc*snap to see what is inside it.

snap list will show your currently installed snaps and it will now show that you have kcalc and the content snap kf5-5-111-qt-5-15-11-core22 as well as the core22 content snap installed.

Snaps are containers, similar to Docker. From inside the Snap container access to the file system and system resources are limited. This is good for inter-app security but means the app sees your system quite differently from how you might expect. You can "log" into the container with snap run --shell kcalc to have a look at how the snapped kcalc app sees your system.

To give the app controlled permissions to the system it plugs connections into resources such as the network or container snaps. Run snap connections kcalc to see what it gets given access to. The auto connections are controlled by the snap store and app maintainers need to ask the snap store for the desired auto-connections. Connections can also be overridden locally.

You can take a look at the snap package with snap download kcalc which will download files such as kcalc_73.assert and kcalc_73.snap. The .assert has the checksums and signatures for the package. The .snap has the (non-store) metadata and all the files of the package. lesspipe kcalc_73.snap to take a look.

How to contribute to Qt6 snaps


kde-qt6-core22

First we start with the Qt6 SDK snap which is located here:

[kde-qt6-sdk](https://invent.kde.org/neon/snap-packaging/kde-qt6-snap)

This snap should not need much altering. Version updates mainly.

In the snapcraft.yaml file:
`version: 6.7.0`

We should be on 6.7.0 to match Neon, to see what version Neon is on, check: [1](https://build.neon.kde.org/job/jammy_unstable_qt6_qt6-base_src/) So we need to update our Qt version to match:
`version: 6.7.0`

Commit and push. Now we check to make sure builds have been triggered
( Note: This will change once we have our CI in place. )

[SDK builds](https://launchpad.net/~kde-community/kde-qt6-core22-sdk-unstable/+snap/kde-qt6-core22-sdk-unstable)
(Note: You must be logged into the KDE-community account)
If builds did NOT trigger, then click the request builds at the bottom of the page.

Once the build completes ( This will take a long time... ) you then trigger the Runtime snap:

[Qt6-runtime](https://launchpad.net/~kde-community/kde-qt6-runtime/+snap/kde-qt6-core22-unstable)
(Note: Don't forget this step! There is no automation in this step. Yet.)

Once both of those are complete...

kf6-core22

The KDE frameworks SDK snap files are located here:

[kf6 SDK](https://invent.kde.org/neon/snap-packaging/kf6-snap)

This file is much to long to paste here, but here is a breakdown of a part:

extra-cmake-modules:
        after:
        - qtconf
        source: https://invent.kde.org/frameworks/extra-cmake-modules.git
        source-branch: master
        build-packages:
        - cmake
        build-snaps:
        - kde-qt6-core22-sdk
        plugin: cmake
        cmake-generator: Ninja
        cmake-parameters:
        - -DCMAKE_INSTALL_PREFIX=/usr
        - -DCMAKE_BUILD_TYPE=RelWithDebInfo
        - -DQT_MAJOR_VERSION=6
        - -DBUILD_WITH_QT6=ON
        - -DBUILD_TESTING=OFF
        - -DCMAKE_INSTALL_SYSCONFDIR=/etc
        - -DCMAKE_INSTALL_LOCALSTATEDIR=/var
        - -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
        - -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_INSTALL_RUNSTATEDIR=/run
        - -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON
        - -DCMAKE_VERBOSE_MAKEFILE=ON
        - -DCMAKE_INSTALL_LIBDIR=lib/$CRAFT_ARCH_TRIPLET
        - --log-level=STATUS
        - -DCMAKE_LIBRARY_PATH=lib/$CRAFT_ARCH_TRIPLET
        - "-DCMAKE_FIND_ROOT_PATH=$CRAFT_STAGE\\;/snap/kde-qt6-core22-sdk/current\\;/usr"
        - "-DCMAKE_PREFIX_PATH=$CRAFT_STAGE\\;/snap/kde-qt6-core22-sdk/current\\;/usr"
        build-environment:
        - PATH: /snap/kde-qt6-core22-sdk/current/usr/bin${PATH:+:$PATH}
        - XDG_DATA_DIRS: $CRAFT_STAGE/usr/share:/snap/kde-qt6-core22-sdk/current/usr/share:/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}
        - XDG_CONFIG_HOME: $CRAFT_STAGE/etc/xdg:/snap/kde-qt6-core22-sdk/current/etc/xdg:/etc/xdg${XDG_CONFIG_HOME:+:$XDG_CONFIG_HOME}
        - LD_LIBRARY_PATH: "/snap/kde-qt6-core22-sdk/current/usr/lib/${CRAFT_ARCH_TRIPLET}:/snap/kde-qt6-core22-sdk/current/usr/lib:$CRAFT_STAGE/usr/lib:$CRAFT_STAGE/lib/:$CRAFT_STAGE/usr/lib/${CRAFT_ARCH_TRIPLET}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"\



`extra-cmake-module` ** Name of the framework. **
` after:

       - qtconf` ** Build time framework dependencies listed here. ( Note: anything listed here MUST already be listed as a part. ) ** 

` source: https://invent.kde.org/frameworks/extra-cmake-modules.git` ** Source repo. **
` source-branch: master` ** Source branch ( Note: we will likely switch to source tags once stable. ) **
` build-packages:

       - cmake` ** kde neon packages required to build. ( Note: this can be retrieved from Neon packaging aka: [2](https://invent.kde.org/neon/kf6/kf6-extra-cmake-modules/-/blob/Neon/unstable/debian/control?ref_type=heads), please remove any qt6, kf6 packages from the list as we build those ourselves. ) ** 

` stage-packages:

        - package` ** kde neon packages required at runtime. ( Note: Delete any qt6, kf6, standard C++ libraries packages from here. Runtime packages can be retrieved from neon build artifacts aka: [3](https://build.neon.kde.org/job/jammy_unstable_kf6_kf6-extra-cmake-modules_bin_amd64/lastSuccessfulBuild/artifact/result/kf6-extra-cmake-modules_6.0.0+p22.04+vunstable+git20240330.0049-0_amd64.deb.info.txt) ** 

` build-snaps:

       - kde-qt6-core22-sdk` ** Qt6 SDK build time snap, always stays the same ** 

` plugin: cmake` ** Uses the cmake plugin, always stays the same **
` cmake-generator: Ninja` ** Uses Ninja generator, always stays the same **

    
        cmake-parameters:
        - -DCMAKE_INSTALL_PREFIX=/usr
        - -DCMAKE_BUILD_TYPE=RelWithDebInfo
        - -DQT_MAJOR_VERSION=6
        - -DBUILD_WITH_QT6=ON
        - -DBUILD_TESTING=OFF
        - -DCMAKE_INSTALL_SYSCONFDIR=/etc
        - -DCMAKE_INSTALL_LOCALSTATEDIR=/var
        - -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
        - -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_INSTALL_RUNSTATEDIR=/run
        - -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON
        - -DCMAKE_VERBOSE_MAKEFILE=ON
        - -DCMAKE_INSTALL_LIBDIR=lib/$CRAFT_ARCH_TRIPLET
        - --log-level=STATUS
        - -DCMAKE_LIBRARY_PATH=lib/$CRAFT_ARCH_TRIPLET
    • Cmake parameters, always stays the same **



Once you have all of your parts in place and are ready to build. Commit and push.
Check to make sure builds have started here:
[kf6 SDK](https://launchpad.net/~kde-community/kde-kf6-core22-snap-unstable/+snap/kf6-core22-sdk-unstable)

(Note: You must be logged into the KDE-community account)
If builds did NOT trigger, then click the request builds at the bottom of the page.

      • Note: There must **NOT** be a qt6 snap building or failed at this point, this snap depends on it. ***

Once the build completes ( This will take a long time... ) you then trigger the Runtime snap:

[kf6-runtime](https://launchpad.net/~kde-community/kf6-core22-runtime/+snap/kf6-core22-unstable)
(Note: Don't forget this step! There is no automation in this step. Yet.)

Applications

Fork the application into your userspace. Aka fork https://invent.kde.org/utilities/ark into your user account on invent. Make sure you on the master branch. Add your snapcraft.yaml You can use the ark snapcraft.yaml as a template.

# SPDX-FileCopyrightText: 2023 Scarlett Moore <[email protected]>
#
# SPDX-License-Identifier: CC0-1.0
---
name: ark
confinement: strict
grade: stable
base: core22
adopt-info: ark
apps:
    ark:
        extensions:
        - kde-neon-6
        common-id: org.kde.ark.desktop
        desktop: usr/share/applications/org.kde.ark.desktop
        command: usr/bin/ark
        plugs:
        - home
        - system-backup
        command-chain:
        - snap/command-chain/desktop-launch6
slots:
    session-dbus-interface:
        interface: dbus
        name: org.kde.ark
        bus: session
package-repositories:
-   type: apt
    components:
    - main
    suites:
    - jammy
    key-id: 444DABCF3667D0283F894EDDE6D4736255751E5D
    url: http://origin.archive.neon.kde.org/user
    key-server: keyserver.ubuntu.com
parts:
    ark:
        parse-info:
        - usr/share/metainfo/org.kde.ark.appdata.xml
        plugin: cmake
        build-packages:
        - libarchive-dev
        - libbz2-dev
        - liblzma-dev
        - libzip5-dev
        - pkg-config
        - zlib1g-dev
        stage-packages:
        - bzip2
        - p7zip-full
        - unrar
        - unzip
        - zip
        - to amd64: [rar]
        - libarchive13
        - libzip4
        - zlib1g
        source: .
        source-type: local
        cmake-parameters:
        - -DCMAKE_INSTALL_PREFIX=/usr
        - -DCMAKE_BUILD_TYPE=RelWithDebInfo
        - -DQT_MAJOR_VERSION=6
        - -DBUILD_WITH_QT6=ON
        - -DBUILD_TESTING=OFF
        - -DCMAKE_INSTALL_SYSCONFDIR=/etc
        - -DCMAKE_INSTALL_LOCALSTATEDIR=/var
        - -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
        - -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_INSTALL_RUNSTATEDIR=/run
        - -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON
        - -DCMAKE_VERBOSE_MAKEFILE=ON
        - -DCMAKE_INSTALL_LIBDIR=lib/$CRAFT_ARCH_TRIPLET
        - --log-level=STATUS
        - -DCMAKE_LIBRARY_PATH=lib/$CRAFT_ARCH_TRIPLET
        prime:
        - -usr/lib/*/cmake/*
        - -usr/include/*
        - -usr/share/ECM/*
        - -usr/share/man/*
        - -usr/share/icons/breeze-dark*
        - -usr/bin/X11
        - -usr/lib/gcc/$SNAPCRAFT_ARCH_TRIPLET/6.0.0
        - -usr/lib/aspell/*
        - -usr/share/lintian
    cleanup:
        after:
        - ark
        plugin: nil
        build-snaps:
        - core22
        - kf6-core22
        override-prime: |
            set -eux
            for snap in "core22" "kf6-core22"; do
                cd "/snap/$snap/current" && find . -type f,l -exec rm -rf "${CRAFT_PRIME}/{}" \;
            done


``` git add snapcraft.yaml ``` ``` git commit ``` Add the changes you made to the commit message. ``` git push ``` Now create a merge request.

Concepts

Snaps are usually one app per Snap package. The Snap package contains all the libraries and resources it needs to run except those in the shared content kf5-5-111-qt-5-15-11-core22 Snap.

In practice this means all of Qt and KF(5/6) including Breeze icons and themes are in the kde-frameworks content Snap and your app Snap only needs to compile its own sources. If you apps needs more libraries you can either install these as DEB packages e.g. from the Linux operating system Ubuntu LTS or KDE neon, or you can compile them from source as well. You will need to manually list the build-packages (all the -dev packages) and the stage-packages used in the final package, it'll warn you if any final libraries it expects are missing.

snapcraft is used to build snaps. It can be installed as a snap with snap install snapcraft --classic. A snap package (app) is defined in the snapcraft.yaml file. Snapcraft will build the package inside a virtual machine; it uses LXD to build the KDE snap packages. Using a virtual machine makes it reliable to build the Snaps on different Linux operating systems with identical results.

snapcraft.yaml files are kept in their respective upstream repo. Eg. kcalc snapcraft file resides https://invent.kde.org/utilities/kcalc/-/blob/release/23.08/snapcraft.yaml?ref_type=heads

Our Snaps read metadata from AppStream metadata files so it is important the metadata is up to date including current release versions.

The Snap Store is the centralized app store by Canonical. There is no practical way to use other stores or repositories with Snaps. It is what Snapcraft uploads built snaps to and what your local snapd will download and install snaps from. It also says what permissions those snaps should have. As an app developer if you want your app to have extra permissions (for example kdf uses mount-observe) then you need to ask for it on the snapcraft forum.

A Classic containment Snap has no restrictions on what files it can see on your system or what external executable can be run. This is useful for Integrated Development Environments (IDEs) and similar apps such as Kate which runs external programs. Again this needs to be set in your [4] then you need to ask on the Snap forum for the store to set it to classic. The Store will then tell snapd for anyone installing the Snap to have it installed as a Classic confinement Snap.

The KDE account on the Snap store is run by the Snap team developers Jonathan Esk-Riddell, Harald Sitter, Scarlett Moore, Carlos DeMaine, Kevin Ottens, Benjamin Port. One Snap on the store can be shared between more than one account so app maintainers can also create a separate account if they want to have more control over when their app is released and what the store says about it.

The store has four channels for different levels of stability. Our stable branch builds get uploaded to the Candidate channel and can be moved to the Stable channel once tested.

Example

Blinken is an exciting memory game from KDE. It's available on the Snap store. The Snap package is defined by a snapcraft.yaml file which is in the https://invent.kde.org/education/blinken/-/tree/release/23.08?ref_type=heads repo. Any update to that branch triggers a build of the [5] in launchpad. If the build is successful it will be uploaded to the Candidate channel of the Snap store ready for review.

# SPDX-FileCopyrightText: 2024 Scarlett Moore <[email protected]>
#
# SPDX-License-Identifier: CC0-1.0
---
name: blinken
confinement: strict
grade: stable
base: core22
adopt-info: blinken
apps:
    blinken:
        extensions:
        - kde-neon-6
        common-id: org.kde.blinken.desktop
        desktop: usr/share/applications/org.kde.blinken.desktop
        command: usr/bin/blinken
        plugs:
        - home
        - system-backup
        command-chain:
        - snap/command-chain/desktop-launch6
slots:
    session-dbus-interface:
        interface: dbus
        name: org.kde.blinken
        bus: session
package-repositories:
-   type: apt
    components:
    - main
    suites:
    - jammy
    key-id: 444DABCF3667D0283F894EDDE6D4736255751E5D
    url: http://origin.archive.neon.kde.org/user
    key-server: keyserver.ubuntu.com
parts:
    blinken:
        parse-info:
        - usr/share/metainfo/org.kde.blinken.appdata.xml
        plugin: cmake
        source: .
        source-type: local
        cmake-parameters:
        - -DCMAKE_INSTALL_PREFIX=/usr
        - -DCMAKE_BUILD_TYPE=RelWithDebInfo
        - -DQT_MAJOR_VERSION=6
        - -DBUILD_WITH_QT6=ON
        - -DBUILD_TESTING=OFF
        - -DCMAKE_INSTALL_SYSCONFDIR=/etc
        - -DCMAKE_INSTALL_LOCALSTATEDIR=/var
        - -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
        - -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON
        - -DCMAKE_INSTALL_RUNSTATEDIR=/run
        - -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON
        - -DCMAKE_VERBOSE_MAKEFILE=ON
        - -DCMAKE_INSTALL_LIBDIR=lib/$CRAFT_ARCH_TRIPLET
        - --log-level=STATUS
        - -DCMAKE_LIBRARY_PATH=lib/$CRAFT_ARCH_TRIPLET
        prime:
        - -usr/lib/*/cmake/*
        - -usr/include/*
        - -usr/share/ECM/*
        - -usr/share/man/*
        - -usr/share/icons/breeze-dark*
        - -usr/bin/X11
        - -usr/lib/gcc/$SNAPCRAFT_ARCH_TRIPLET/6.0.0
        - -usr/lib/aspell/*
        - "-usr/share/lintian"
    cleanup:
        after:
        - blinken
        plugin: nil
        build-snaps:
        - core22
        - kf6-core22
        - kde-qt6-core22
        override-prime: |
            set -eux
            for snap in "core22" "kf6-core22" "kde-qt6-core22"; do
                cd "/snap/$snap/current" && find . -type f,l -exec rm -rf "${CRAFT_PRIME}/{}" \;
            done


Check Snapcraft YAML reference if unsure.

Top Level

  • name: blinken ← the snap name registered on the snap store
  • confinement: strict ← Snaps are a containerised format and can't see the outside system from inside their container. Strict is the normal container method. Classic is also possible which allows it to see the outside system and is used by e.g. Kate because Kate needs to run external programs like Git. It can only be Classic on request. Can also be devmode for testing.
  • grade: stable ← It must be stable to be in a released channel, can also be devel.
  • base: core22 ← which base system to build on, core22 means Ubuntu 22.04 and is the current recommended.
  • adopt-info: blinken ← Which Snap part to get the appstream info from. This sets version, icon, description.

You might also need to add version if it is not in the appstream file. This is just a version read by users it does not affect the revision number which is tracked by the store.

apps

apps:
    blinken:
        extensions:
        - kde-neon-6
        common-id: org.kde.blinken.desktop
        desktop: usr/share/applications/org.kde.blinken.desktop
        command: usr/bin/blinken
        plugs:
        - home
        - system-backup
        command-chain:
        - snap/command-chain/desktop-launch6

apps are the programs which the snap includes for users to run. Usually there is only one in a Snap but sometimes e.g. Calligra there are more than one.

The KDE neon extension adds some commonly used features to the KDE snaps including using the content Snap.

The common-id comes from the Appstream file. You must check what it is in the appstream file. org.kde.blinken.appdata.xml contains <id>org.kde.blinken.desktop</id> so we use that. Sometimes apps use the .desktop and sometimes they don't, this is at random.

The command to run is listed. The KDE neon extension will run a script first which sets many necessary environment variables.

The plugs give access to the outside system, see Supported interfaces for descriptions. When a Snap is installed from the Store it is up to the Store to say which plugs get used. Those listed as auto connect in the docs are permitted. Otherwise you must ask on the Snap forum for permission to have the Snap connected. (Locally installed snaps with --devmode have access to everything, you can also manually connect snaps to interfaces on your local system.)

slots are the complement to plugs, they allow the outside system to access our Snap app. In this case we are allowing a dbus interface into the Snap. All KDE apps have a dbus interface and you can check what it is called by running the app and using qdbus.

package-repositories add the KDE neon apt repo to build against, this will give you the latest libraries to compile with.

The source of a Snap is the parts and some snaps have several parts made of different sources e.g. [TBD] has both libktorrent and ktorrent parts. Blinken is not complex so it has only one part made of the compiles Blinken source.

Parts

  • plugin ← which Snap build plugin to use
  • build-packages ← most build packages are in the KDE Frameworks content snap but some need added explicitly and some are not in there. They will be downloaded from the neon and ubuntu apt repos. [TBD] uses non-KDE libraries and it needs to list the -dev packages in the build-packages then the library itself in the stage-packages.
  • source ← link to the tar
  • cmake-parameters ← copy and paste this, it sets the right paths.
  • parse-info ← where the appstream file is to be installed
  • filesets and prime ← snap parts get build then copied into a stage area, when all the parts are built they are copied into the prime area which is converted into the Snap package. This lists a common set of excluded files we do not want copied. You can add more here if you end up with unnecessary files in your snap.

Building

Install snapcraft with snap install snapcraft --classic.

In the directory with the snapcraft.yaml run: snapcraft

This will start a virtual machine and build the package. If all is well you will have blinken_24.05_amd64.snap or similar created. If you had not installed lxd before, you may need to add your user to the lxd group to allow access to lxd.

Install with snap install blinken_24.05_amd64.snap --devmode.

Run with blinken or check if blinken is available in the app menu and run it from there (remove any versions of blink you have installed from your normal distro packages just to be sure). which -a blinken should say that blinken is available at least as /snap/bin/blinken.

Quirks

Patches

If you need to update some code in the release you can patch it in the Snap package. But please get the patch upstream into the Git archive first. To add a patch to a snap, one must add the snippet to the part that needs patched:

        override-pull: |
            craftctl default
              for file in ${CRAFT_PROJECT_DIR}/snap/local/patches/*
              do
                patch -i $file -p 1
              done

Add add the patch in snap/local/patches/

Help

Snapcraft docs including tutorials on using and building.

snapcraft.yaml format.

Snap forum for asking for help or asking to get the store to allow your Snaps to auto connect.

KDE neon devs talk to sgmoore for help getting your app into the Store.

Glossary

Words you'll hear and not know what they mean:

  • snap: The actual package format.
  • snapd: The daemon that manages snap on a system.
  • snapcraft: The build tool for building a snap.
  • 'app: In the context of snapcraft/snapd this is the (portable) description of an 'executable' exposed to the outside (i.e. something snapd knows how to run).
  • parts: In the context of snapcraft a part refers to one build entity. They describe where to get the source of the entity, how to build it, how to stage it into the final snap and which other parts are a dependency and need to be built first. A part is much like a "makefile" target.
  • interfaces: A way for a snap to talk to the outside world (or another snaps). Split into slots and plugs. Each of which has their own security permissions as a client may need to be able to do different things from a server. https://docs.snapcraft.io/interface-management
  • slot: The provider part of an interface. e.g. a kwin snap might have a wayland-client slot which exposes a way for clients to talk to kwin.
  • plug: The client part of an interface. e.g. an application may plug into the wayland-client slot of kwin to talk to it.
  • Core: A special snap containing the core aspects of any Linux OS (libc/libpthread/...). All snaps depend on exactly one core which provides the snap's understanding of what will be in "/" from the snap's POV. The core does not include a kernel! Kernels may be snaps.
  • Content Snap: Special kind of snap that implements the "content" interface. It's kind of like a shared dependency between snaps allowing one snap to be bound into the scope of another snap. For example the KF5 content snap may be used to share all of KF5 across multiple snaps.
  • Build Snap: Also a special kind of snap, it's the build-time variant of the Content Snap and contains header files etc. necessary to build against a Content Snap.
  • stage, staging: As part of snapcrafting parts get "staged". This kind of means the same as make install, but it's actually a separate step after make install. For the process of staging, snapcraft will copy all files created by make install into a stage directory. You may also exclude certain files or reorganize the files (e.g. rename, or move to different directory). The stage is available for parts ordered after the current one, meaning that they for example can link against a newly built library.
  • prime, priming: Is similar to staging but happens once all parts are built and staged. Priming is the process by which the snap tree is actually constructed. Priming, like staging, allows for excluding files (e.g. dev headers may be staged so other parts can build using them but later excluded from priming and thus left out of the final bundle).