Need to run command before running build package snapcraft

I have a build package like this for a snapcraft.yaml part:

build-packages:
  - mesa-commin-dev
  ...
  - ggc-9

But in order to use gcc-9 I need to run:

sudo apt-get install software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-9 -y && sudo apt upgrade libstdc++6 -y

It needs to run before the build-packages get pulled in. How do I do that?

Was trying to do something like this:

 part_name:
    source: ../../sample_app/ 
    project-files: ["../../../../sample_app/sample_app.pro"] 
    plugin: qmakeppa
    after: [alsa-mixin, desktop-qt5]
    options: [WICKRQMAKECONFIGS]
    override-build: |
      
       sudo apt-get install apt-utils -y
       sudo apt-get install software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-9 -y && sudo apt upgrade libstdc++6 -y
       snapcraftctl build
    build-packages:
      - mesa-common-dev 
      - libgl1-mesa-dev 
      - libglu1-mesa-dev 
      - libgl1-mesa-glx
      - libstdc++6
      - gcc-9
    override-prime: |

      snapcraftctl prime

But it didnt work. I tried putting the snapcraftctl build before the apt get commands as well in the override-build block and that didnt work either. How do I run those apt-get commands before the gcc-9 gets hit? The situation is weird as this is with ‘snapcraft --use-lxd’ so it is inside the container doing the build.

The full yaml:

name: WICKRLCAPPNAME
version: WICKRVERSIONNUM
summary: Secure Messaging for Teams
description: >
  Wickr Secure Messaging

grade: stable
confinement: strict
base: core18
icon: snap/gui/WICKRLCAPPNAME.png

apps:

  WICKRLCAPPNAME:
    environment:
      DISABLE_WAYLAND: 1
      QT_QPA_PLATFORMTHEME: gtk3  
    command: desktop-launch alsa-launch WICKRAPPNAME
    plugs:
    - alsa
    - audio-playback
    - audio-record
    - desktop
    - desktop-legacy
    - x11
    - unity7
    - wayland
    - gsettings
    - opengl
    - home
    - removable-media
    - network
    - network-bind
    - network-manager
    - network-observe
    - network-control
    - camera
    - screen-inhibit-control
    - raw-usb

parts:
  qt515:
    plugin: dump
    source: /opt/qt51512/qt51512_5.15.12-wickr_amd64.deb
    source-type: deb
    stage-packages:
      - libdrm2
      - libegl1
      - libgbm1
      - libgl1
      - libglvnd0
      - libglx0
      - libpng16-16
      - libwayland-client0
      - libwayland-server0
      - libx11-6
      - libx11-xcb1
      - libxcb-glx0
      - libxcb-randr0
      - libxcb-render0
      - libxcb-shape0
      - libxcb-sync1
      - libxcb-xfixes0
      - libxdamage1
      - libxext6
      - libxfixes3


  wickr:
    source: ../../sample_app/ #../../WickrDesktopApp/ #this is relative to the "parts" directory that's created by snapcraft, different in lxc container
    project-files: ["../../../../sample_app/sample_app.pro"] #["../../../../WickrDesktopApp/desktop.pro"]  #this is relative to the "parts/wickr/src" directory, has for lxc
    plugin: qmakeppa
    after: [alsa-mixin, desktop-qt5]
    options: [WICKRQMAKECONFIGS]
    #override-build: |
      
      #sudo apt-get install apt-utils -y
      #sudo apt-get install software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-9 -y && sudo apt upgrade libstdc++6 -y
      #snapcraftctl build
    build-packages:
      - mesa-common-dev 
      - libgl1-mesa-dev 
      - libglu1-mesa-dev 
      # - libgl-dev
      - libgl1-mesa-glx
      - libstdc++6
      - gcc-9
    override-prime: |

      snapcraftctl prime

  alsa-mixin:
    plugin: nil
    source: https://github.com/diddlesnaps/snapcraft-alsa.git
    override-pull: |

      cat > asound.conf <<EOF
      pcm.!default {
          type pulse
          fallback "sysdefault"
          hint {
              show on
              description "Default ALSA Output (currently PulseAudio Sound Server)"
          }
      }
      ctl.!default {
          type pulse
          fallback "sysdefault"
      }
      EOF
      cat > alsa-launch <<EOF
      #!/bin/bash
      export ALSA_CONFIG_PATH="\$SNAP/etc/asound.conf"

      if [ -d "\$SNAP/usr/lib/alsa-lib" ]; then
          export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/usr/lib/alsa-lib"
      elif [ -d "\$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib" ]; then
          export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib"
      fi
      export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pulseaudio"
      export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/opt/qt51512/lib"

      # Make PulseAudio socket available inside the snap-specific $XDG_RUNTIME_DIR
      if [ -n "\$XDG_RUNTIME_DIR" ]; then
          pulsenative="pulse/native"
          pulseaudio_sockpath="\$XDG_RUNTIME_DIR/../\$pulsenative"

          if [ -S "\$pulseaudio_sockpath" ]; then
              export PULSE_SERVER="unix:\${pulseaudio_sockpath}"
          fi
      fi

      exec "\$@"
      EOF
      chmod +x alsa-launch
    override-build: |
      snapcraftctl build
      install -m644 -D -t $SNAPCRAFT_PART_INSTALL/etc asound.conf
      install -m755 -D -t $SNAPCRAFT_PART_INSTALL/snap/command-chain alsa-launch
    build-packages:
      - libasound2-dev
    stage-packages:
      - libasound2
      - libasound2-plugins

  ppa:
    plugin: nil
    override-pull: |
      QT_BASE_DIR=/opt/qt51512
      export QTDIR=$QT_BASE_DIR
      export PATH=$QT_BASE_DIR/bin:$PATH
      export LD_LIBRARY_PATH=$QT_BASE_DIR/lib:$LD_LIBRARY_PATH
      export PKG_CONFIG_PATH=$QT_BASE_DIR/lib/pkgconfig:$PKG_CONFIG_PATH

  desktop-qt5:
    source: https://github.com/spompelio/snapcraft-desktop-helpers.git
    source-commit: 6a4a132be505da069485473bb5f486afd69f28ba
    source-subdir: qt
    plugin: make
    after: [qt515, ppa]
    make-parameters: ["FLAVOR=qt5"]
    build-packages:
      - build-essential
      - dpkg-dev
    override-stage: |
        snapcraftctl stage
        strip --remove-section=.note.ABI-tag opt/qt51512/lib/libQt5Core.so.5
    override-prime: |
      snapcraftctl prime
      cp /usr/share/glib-2.0/schemas/org.gtk.Settings.FileChooser.gschema.xml usr/share/glib-2.0/schemas
      glib-compile-schemas usr/share/glib-2.0/schemas
    stage-packages:
      - ttf-ubuntu-font-family
      - dmz-cursor-theme
      - light-themes
      - adwaita-icon-theme
      - gnome-themes-standard
      - shared-mime-info
      - libgdk-pixbuf2.0-0
      - locales-all
      - xdg-user-dirs
      - libgtk2.0-0
      - libavahi-client3
      - libavahi-common3
      - libboost-all-dev
      - libcapnp-0.6.1 #libcapnp-0.7.0 
      - libcups2
      - libgbm1
      - libflac-dev
      - libxcomposite1
      - libxcursor1
      - libxi6
      - libxrender1
      - libxss1
      - libxtst6
      - libasyncns0
      - libfontconfig1
      - libhunspell-1.6-0 # libhunspell-1.7-0 
      - libnspr4
      - libnss3
      - libogg0
      - libpulse0
      - libsndfile1
      - libvorbis0a
      - libvorbisenc2
      - libxml2
      - libxslt1.1
      - gstreamer1.0-plugins-base
      - gstreamer1.0-plugins-good
      - libslang2
      - liborc-0.4-0
      - libxcb-xfixes0
      - libwayland-client0
      - libwayland-cursor0
      - libwayland-egl1
      - libglu1-mesa
      - libgl1-mesa-dri
      - libmtdev1
      - libdb5.3
      - libgl1-mesa-glx
      - libgpm2
      - libxcb-glx0
      - libxxf86vm1
      - libdouble-conversion1 #libdouble-conversion3
      - libxcb1
      - libsm6
      - libice6
      - libxrandr2
      - libxcb-xkb1
      - libxcb-render-util0
      - libxcb-randr0
      - libxcb-image0
      - libxcb-keysyms1
      - libxcb-icccm4
      - libxcb-shape0
      - libxcb-util1
      - libxcb-xinput0
      - libxcb-xinerama0
      - xkb-data
      - libxkbcommon0
      - libxkbcommon-x11-0
      - libuuid1
      - zlib1g
      - libsystemd0
      - liblzma5
      - liblz4-1
      - libgpg-error0
      - libsqlcipher0
      - libpsm-infinipath1
      - libstdc++6
      - xdg-utils
      - libc-bin

passthrough:
  layout:
    /etc/asound.conf:
      bind-file: $SNAP/etc/asound.conf
    /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib:
      bind: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib
    /usr/share/alsa/alsa.conf:
      bind-file: $SNAP/usr/share/alsa/alsa.conf

plugs:
  # Support for common GTK themes
  # https://forum.snapcraft.io/t/how-to-use-the-system-gtk-theme-via-the-gtk-common-themes-snap/6235
  gsettings:
  gtk-3-themes:
    interface: content
    target: $SNAP/data-dir/themes
    default-provider: gtk-common-themes
  icon-themes:
    interface: content
    target: $SNAP/data-dir/icons
    default-provider: gtk-common-themes
  sound-themes:
    interface: content
    target: $SNAP/data-dir/sounds
    default-provider: gtk-common-themes
  browser-sandbox:
    interface: browser-support
    allow-sandbox: false

@jamesh How would I do this? I have been trying to stick sudo apt-get install software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-9 -y && sudo apt upgrade libstdc++6 -y In numerous places but I keep getting Could not find a required package in 'build-packages': gcc-9. I am using snapcraft --use-lxd. I can get arround this error by on the side logging into the lxc container and quicly running those apt commands. So far cant figure out how to do it autonomously. I even tried lxc exec container_name -- "apt commands" before running snapcraft and still doesnt work.

is this a plain copy-paste ? then you should definitely fix the typo in your snapcraft.yaml, there is indeed no ggc-9 package anywhere in ubuntu :slight_smile:

No here is the full build-packages, I just showed a shortened list earlier:

build-packages:
  - mesa-common-dev 
  - libgl1-mesa-dev 
  - libglu1-mesa-dev 
  - libgl1-mesa-glx
  - libstdc++6
  - gcc-9

Before adding gcc-9 I was getting this error with my build: /opt/qt51512/bin/qmlcachegen: /root/stage/usr/lib/x86_64-linux-gnu/libstdc++.so.6: version 'GLIBCXX_3.4.26' not found (required by /opt/qt51512/bin/../lib/libQt5Core.so.5). Which I think means /opt/qt51512/bin/qmlcachegen is an executable and it’s not finding the right version of glibc.

And running this command on the container: /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX

I get:

GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25
GLIBCXX_DEBUG_MESSAGE_LENGTH

Showing the version 26 is missing, which resides with gcc-9. Then following from https://askubuntu.com/a/1328208 took me to needing this command run before adding gcc-9 in the build-packages:

sudo apt-get install software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-9 -y && sudo apt upgrade libstdc++6 -y

@ogra So it seems my build needs gcc-9. Unless there is a better way? Or I need to somehow run the apt commands above before it checks the build packages which I dont know how to do.

But even running sudo apt-get install software-properties-common -y && sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt update && sudo apt install gcc-9 -y && sudo apt upgrade libstdc++6 -y before snapcraft --use-lxd I will eventually get this error:

Project MESSAGE: *** Enterprise config
Project MESSAGE: *** Pro Alpha Release Build
Project MESSAGE: *** SNAPCRAFT
Project MESSAGE: *** QMAKE_RPATHDIR = /opt/qt51512 /opt/qt51512/lib /usr/lib/wickr-client/plugins /usr/lib/wickr-client/lib /root/parts/wickr/build/clients/enterprise/../../libs/qzxing/src /root/parts/wickr/build/clients/enterprise/../../wickr-sdk/libs/quazip/quazip /WickrDesktopApp/clients/enterprise/../../wickr-sdk/wickr-core-c/localRepo/wickr-crypto/unix/lib
/WickrDesktopApp/clients/enterprise/enterprise.qrc: Warning: potential duplicate alias detected: 'defaulttheme.json'
enterprise_qmlcache.qrc: Warning: potential duplicate alias detected: 'defaulttheme.json'
make[2]: *** No rule to make target '/root/parts/wickr/build/clients/enterprise/../../wickr-sdk/src/libwickr-sdk.a', needed by 'libwickr-client.a'.  Stop.
make[1]: *** [sub-enterprise-make_first-ordered] Error 2
make: *** [sub-clients-make_first-ordered] Error 2
Failed to run 'make -j4' for 'wickr': Exited with code 2.

Which I do not know how to solve either.

You are using a binary qt release from somewhere else that was simply built for a newer libc… is there any particular reason why you force your package to be run on an 18.04 system (base: core18) ? You should just move to something more recent (core20 or core22) and will get the newer libc symbols for free :wink:

I am trying to maintain backwards compatibility with 18.04 for users with 18.04 machines who want to use our app @ogra. We also use a custom plugin which is deprecated for core 20, how would I convert the custom plugin to the new way of doing things then? If you scroll to my first post you will see my full yaml file. Here is the contents of the custom plugin called qmakeppa.py:

# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2016 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""The qmake plugin is useful for building qmake-based parts.

These are projects that are built using .pro files.

This plugin uses the common plugin keywords as well as those for "sources".
For more information check the 'plugins' topic for the former and the
'sources' topic for the latter.

Additionally, this plugin uses the following plugin-specific keywords:

    - options:
      (list of strings)
      additional options to pass to the qmake invocation.
    - qt-version:
      (string; default: qt5)
      Version of Qt to use with qmake. Valid options are: qt5
    - project-files:
      (list of strings)
      list of .pro files to pass to the qmake invocation.
"""

import os

import snapcraft
from snapcraft import common


class QmakePlugin(snapcraft.BasePlugin):
    @classmethod
    def schema(cls):
        schema = super().schema()

        schema["properties"]["options"] = {
            "type": "array",
            "minitems": 1,
            "uniqueItems": True,
            "items": {"type": "string"},
            "default": [],
        }
        schema["properties"]["qt-version"] = {
            "type": "string",
            "enum": ["qt5"],
            "default": "qt5",
        }
        schema["properties"]["project-files"] = {
            "type": "array",
            "minitems": 1,
            "uniqueItems": True,
            "items": {"type": "string"},
            "default": [],
        }

        # schema.pop("required")

        return schema

    @classmethod
    def get_pull_properties(cls):
        # Inform Snapcraft of the properties associated with pulling. If these
        # change in the YAML Snapcraft will consider the pull step dirty.
        return ["qt-version"]

    @classmethod
    def get_build_properties(cls):
        # Inform Snapcraft of the properties associated with building. If these
        # change in the YAML Snapcraft will consider the build step dirty.
        return ["options", "project-files"]

    def __init__(self, name, options, project):
        super().__init__(name, options, project)

        self.build_packages.append("make")

    def build(self):
        super().build()

        env = self._build_environment()

        sources = []
        if self.options.project_files:
            sourcedir = self.sourcedir
            source_subdir = getattr(self.options, "source_subdir", None)
            if source_subdir:
                sourcedir = os.path.join(sourcedir, source_subdir)
            sources = [
                os.path.join(sourcedir, project_file)
                for project_file in self.options.project_files
            ]

        self.run(
            ["/opt/qt51512/bin/qmake"] + self._extra_config() + self.options.options + sources, env=env
        )

        self.run(["make", "-j{}".format(self.parallel_build_count)], env=env)

        self.run(["make", "install", "INSTALL_ROOT=" + self.installdir], env=env)

        self.run(["mkdir", "-p", self.installdir + "/usr/bin"], env=env)
        self.run(["cp", "/opt/qt51512/resources/icudtl.dat", self.installdir + "/usr/bin"], env=env)
        self.run(["cp", "/opt/qt51512/resources/qtwebengine_devtools_resources.pak", self.installdir + "/usr/bin"], env=env)
        self.run(["cp", "/opt/qt51512/resources/qtwebengine_resources_100p.pak", self.installdir + "/usr/bin"], env=env)
        self.run(["cp", "/opt/qt51512/resources/qtwebengine_resources_200p.pak", self.installdir + "/usr/bin"], env=env)
        self.run(["cp", "/opt/qt51512/resources/qtwebengine_resources.pak", self.installdir + "/usr/bin"], env=env)
        self.run(["cp", "/opt/qt51512/libexec/QtWebEngineProcess", self.installdir + "/usr/bin"], env=env)

    def _extra_config(self):
        extra_config = []

        for root in [self.installdir, self.project.stage_dir]:
            paths = common.get_library_paths(root, self.project.arch_triplet)
            for path in paths:
                extra_config.append('LIBS+="-L{}"'.format(path))

            paths = common.get_include_paths(root, self.project.arch_triplet)
            for path in paths:
                extra_config.append('INCLUDEPATH+="{}"'.format(path))

        return extra_config

    def _build_environment(self):
        env = os.environ.copy()
        env["QT_SELECT"] = self.options.qt_version

        return env

In the snap world this does not matter at all, 18.04 users can run base: core22 snaps just fine… (even 14.04 and 16.04 users can…)

I am learning things… Ok so how do I take my custom plugin work and replace it with the new way of doing things @ogra?

Hmm, I thought custom plugins were only deprecated with core22 ICBW though… but the plugin doesn’t look like you couldn’t reimplement it via override-* bits with a mid-sized amount of work… at runtime your libc comes from the base snap you use, trying to ship a newer one from your snap will surely introduce interesting new problems at runtime

See @ogra doesnt work with base 20, the error I get:

The plugin used by part 'wickr' does not support snaps using base 'core20'.

read again what the output says :wink:

your plugin is based on an old (core18) qmake plugin, not based on the core20 (see below) one …

it doesnt mean there is no plugin support on core20, just that yours uses an outdated base …

@ogra Ah! I see. Do you recommend to use this newer custom plugin, or is it better to move away from it and do it the new way without custom plugin? (I do not know how to do that yet)

custom plugins have indeed been fully dropped from core22 onwards … so to be future proof you might be wanting to consider doing it without a plugin completely (not a qmake expert here, so i dont really know how much work it is to do it from overrides, but snapcraft is flexible enough to do such stuff without plugins (just a bit more complex then))

just porting the existing custom plugin from 18 to 20 might be the easier path for the moment though (but then you will hit the same prob with the next libc bump of the qt binaries you use) …

@ogra So I just replaced the qmakeppa.py with the new one you gave (with my changes) and put core20. But now I get this error:

Failed to load plugin: unknown plugin: 'qmakeppa'

What I have now for qmakeppa.py which resides in snap/plugins/ where snapcraft.yaml is in the same folder where the snap folder is held:

# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2020 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""The qmake plugin is useful for building qmake-based parts.
These are projects that are built using .pro files.
This plugin uses the common plugin keywords as well as those for "sources".
For more information check the 'plugins' topic for the former and the
'sources' topic for the latter.
Additionally, this plugin uses the following plugin-specific keywords:
    - qmake-parameters:
      (list of strings)
      additional options to pass to the qmake invocation.
    - qmake-project-file:
      (string)
      the qmake project file to use. This is usually only needed if
      qmake can not determine what project file to use on its own.
"""

from typing import Any, Dict, List, Set

from snapcraft_legacy.plugins.v2 import PluginV2


class QMakePlugin(PluginV2):
    @classmethod
    def get_schema(cls) -> Dict[str, Any]:
        return {
            "$schema": "http://json-schema.org/draft-04/schema#",
            "type": "object",
            "additionalProperties": False,
            "properties": {
                "qmake-parameters": {
                    "type": "array",
                    "uniqueItems": True,
                    "items": {"type": "string"},
                    "default": [],
                },
                "qmake-project-file": {"type": "string", "default": ""},
            },
        }

    def get_build_snaps(self) -> Set[str]:
        return set()

    def get_build_packages(self) -> Set[str]:
        return {"g++", "make", "qt5-qmake"}

    def get_build_environment(self) -> Dict[str, str]:
        return {"QT_SELECT": "qt5"}

    @property
    def out_of_source_build(self):
        return True

    def _get_qmake_configure_command(self) -> str:
        cmd = [
            "/opt/qt51512/bin/qmake",
            'QMAKE_CFLAGS+="${CFLAGS:-}"',
            'QMAKE_CXXFLAGS+="${CXXFLAGS:-}"',
            'QMAKE_LFLAGS+="${LDFLAGS:-}"',
        ] + self.options.qmake_parameters

        if self.options.qmake_project_file:
            cmd.append(
                '"${{SNAPCRAFT_PART_SRC_WORK}}/{}"'.format(
                    self.options.qmake_project_file
                )
            )
        else:
            cmd.append('"${SNAPCRAFT_PART_SRC_WORK}"')

        return " ".join(cmd)

    def get_build_commands(self) -> List[str]:
        return [
            self._get_qmake_configure_command(),
            # Avoid overriding the CFLAGS and CXXFLAGS environment
            # variables qmake sets in the generated Makefile
            'env -u CFLAGS -u CXXFLAGS make -j"${SNAPCRAFT_PARALLEL_BUILD_COUNT}"',
            'make install INSTALL_ROOT="${SNAPCRAFT_PART_INSTALL}"',
            'mkdir -p "${SNAPCRAFT_PART_INSTALL}" /usr/bin',
            'cp /opt/qt51512/resources/icudtl.dat "${SNAPCRAFT_PART_INSTALL}" /usr/bin',
            'cp /opt/qt51512/resources/qtwebengine_devtools_resources.pak "${SNAPCRAFT_PART_INSTALL}" /usr/bin',
            'cp /opt/qt51512/resources/qtwebengine_resources_100p.pak "${SNAPCRAFT_PART_INSTALL}" /usr/bin',
            'cp /opt/qt51512/resources/qtwebengine_resources_200p.pak "${SNAPCRAFT_PART_INSTALL}" /usr/bin',
            'cp /opt/qt51512/resources/qtwebengine_resources.pak "${SNAPCRAFT_PART_INSTALL}" /usr/bin',
            'cp /opt/qt51512/libexec/QtWebEngineProcess "${SNAPCRAFT_PART_INSTALL}" /usr/bin'
        ]

Looking at that plugin, the main things it seems to be doing are:

  1. Using an alternate copy of qmake. You could probably achieve the same using build-environment to set PATH: "/opt/qt51512/bin:$PATH".
  2. Copying a bunch of files from your Qt install after the regular build. You could do this using override-build.

Those options are likely to be a lot more robust than the plugin, and should make it easier to migrate to newer bases.

1 Like

@jamesh

I see! Ok but what would be the correct way to rewrite the copy commands? What would be the self.installdir (or “${SNAPCRAFT_PART_INSTALL}”)

How to rewrite this: 'cp /opt/qt51512/resources/icudtl.dat "${SNAPCRAFT_PART_INSTALL}"/usr/bin'

Something like this (the override-build $PWD gives /root/parts/part_name/src and the install directory is in the part_name directory)? Unsure that it will use /opt/qt51512/bin/qmake instead though:

  wickr:
    source:  ../../WickrDesktopApp/ #this is relative to the "parts" directory that's created by snapcraft
    qmake-project-file: ["../../../../WickrDesktopApp/desktop.pro"]  #this is relative to the "parts/wickr/src" directory
    plugin: qmake
    after: [alsa-mixin, desktop-qt5]
    qmake-parameters: [WICKRQMAKECONFIGS]
    build-environment:
    - PATH: "/opt/qt51512/bin:$PATH"
    override-build: |
      snapcraftctl build
      mkdir -p ../install/usr/bin
      cp /opt/qt51512/resources/icudtl.dat ../install/usr/bin
      cp /opt/qt51512/resources/qtwebengine_devtools_resources.pak ../install/usr/bin
      cp /opt/qt51512/resources/qtwebengine_resources_100p.pak ../install/usr/bin
      cp /opt/qt51512/resources/qtwebengine_resources_200p.pak ../install/usr/bin
      cp /opt/qt51512/resources/qtwebengine_resources.pak ../install/usr/bin
      cp /opt/qt51512/libexec/QtWebEngineProcess ../install/usr/bin

Also a side question. When I run the snapcraft --use-lxd command with core20, now my alsa-mixin part complains

the part:

  alsa-mixin:
    plugin: nil
    source: https://github.com/diddlesnaps/snapcraft-alsa.git
    override-pull: |
      cat > asound.conf <<EOF
      pcm.!default {
          type pulse
          fallback "sysdefault"
          hint {
              show on
              description "Default ALSA Output (currently PulseAudio Sound Server)"
          }
      }
      ctl.!default {
          type pulse
          fallback "sysdefault"
      }
      EOF
      cat > alsa-launch <<EOF
      #!/bin/bash
      export ALSA_CONFIG_PATH="\$SNAP/etc/asound.conf"
      export XDG_RUNTIME_DIR=/run/user/$(id -u)

      if [ -d "\$SNAP/usr/lib/alsa-lib" ]; then
          export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/usr/lib/alsa-lib"
      elif [ -d "\$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib" ]; then
          export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib"
      fi
      export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pulseaudio"
      export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/opt/qt51512/lib"

      # Make PulseAudio socket available inside the snap-specific $XDG_RUNTIME_DIR
      if [ -n "\$XDG_RUNTIME_DIR" ]; then
          pulsenative="pulse/native"
          pulseaudio_sockpath="\$XDG_RUNTIME_DIR/../\$pulsenative"
          if [ -S "\$pulseaudio_sockpath" ]; then
              export PULSE_SERVER="unix:\$pulseaudio_sockpath"
          fi
      fi

      exec "\$@"
      EOF
      chmod +x alsa-launch
    override-build: |
      snapcraftctl build
      install -m644 -D -t $SNAPCRAFT_PART_INSTALL/etc asound.conf
      install -m755 -D -t $SNAPCRAFT_PART_INSTALL/snap/command-chain alsa-launch
    build-packages:
      - libasound2-dev
    stage-packages:
      - libasound2
      - libasound2-plugins

The error:

/bin/bash: line 44: XDG_RUNTIME_DIR: unbound variable
Failed to run 'override-pull': Exit code was 1.

You keep it exactly as is … you might want to update to the newer “$CRAFT_PART_INSTALL” variable name that snapcraft 7 uses to prevent depreciation warnings, but the code should work exactly the same as from the plugin…

@ogra I see. How do I ensure it uses /opt/qt51512/bin/qmake instead? I also have this situation:

When I run the snapcraft --use-lxd command with core20, now my alsa-mixin part complains. I get this error:

/bin/bash: line 44: XDG_RUNTIME_DIR: unbound variable
Failed to run 'override-pull': Exit code was 1.

the part:

 alsa-mixin:
    plugin: nil
    source: https://github.com/diddlesnaps/snapcraft-alsa.git
    override-pull: |
      cat > asound.conf <<EOF
      pcm.!default {
          type pulse
          fallback "sysdefault"
          hint {
              show on
              description "Default ALSA Output (currently PulseAudio Sound Server)"
          }
      }
      ctl.!default {
          type pulse
          fallback "sysdefault"
      }
      EOF
      cat > alsa-launch <<EOF
      #!/bin/bash
      export ALSA_CONFIG_PATH="\$SNAP/etc/asound.conf"
      export XDG_RUNTIME_DIR=/run/user/$(id -u)

      if [ -d "\$SNAP/usr/lib/alsa-lib" ]; then
          export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/usr/lib/alsa-lib"
      elif [ -d "\$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib" ]; then
          export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/alsa-lib"
      fi
      export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pulseaudio"
      export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:\$SNAP/opt/qt51512/lib"

      # Make PulseAudio socket available inside the snap-specific $XDG_RUNTIME_DIR
      if [ -n "\$XDG_RUNTIME_DIR" ]; then
          pulsenative="pulse/native"
          pulseaudio_sockpath="\$XDG_RUNTIME_DIR/../\$pulsenative"
          if [ -S "\$pulseaudio_sockpath" ]; then
              export PULSE_SERVER="unix:\$pulseaudio_sockpath"
          fi
      fi

      exec "\$@"
      EOF
      chmod +x alsa-launch
    override-build: |
      snapcraftctl build
      install -m644 -D -t $SNAPCRAFT_PART_INSTALL/etc asound.conf
      install -m755 -D -t $SNAPCRAFT_PART_INSTALL/snap/command-chain alsa-launch
    build-packages:
      - libasound2-dev
    stage-packages:
      - libasound2
      - libasound2-plugins

the snippet in your snapcraft.yaml should take care for this:

I have no idea about the XDG_RUNTIME_DIR bit, might be that newer snapcraft has issues with embedded here-doc like you use up there …