3

Base problem/goal:

I want to be able to use some shared libraries, that should be fetched before cmake step(plugin) from a custom PPA.

snapcraft.yaml:

name: mraa-blink-example
version: 'Latest' 
summary: mraa for snapcraft
description: |
  Blink Example from MRAA lib

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

apps:
  blinkapp:
    command: bin/blink    

parts:
  blink:
    plugin: cmake
    build-packages:
      - libmraa1 
      - libmraa-dev 
      - mraa-tools 
      - python-mraa 
      - python3-mraa

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.9)
project (MRAA)

file(GLOB SOURCES "src/*.cpp")

#For the shared library:
set ( PROJECT_LINK_LIBS libmraa.so )
add_executable(blink ${SOURCES})
target_link_libraries(blink ${PROJECT_LINK_LIBS} )
install(TARGETS blink DESTINATION /bin)

Because the build-packages are from a custom PPA, i get the error:

Could not find a required package in 'build-packages': "The cache has no package named 'libmraa-dev'"

Is there a way to solve this problem?

2 Answers2

2

Background:

There's an effort to abstract the Gnome Libraries into a separate "platform" snap which is built on Launchpad using the Ubuntu Desktop Team's Gnome-3-26 PPA. The PPA contains the gnome platform compiled to suit Ubuntu Xenial (16.04)'s runtime environment which will allow for snaps to be built against newer Gnome than the build environment usually contains. But this requires the custom PPA in the build environment, and like you I struggled with working out how to do this.

Once you've got the gnome-platform PPA enabled you still need to link your snap to the runtime snap. This is handled by adding a plug which connects to gnome-3-26-1604, and using the desktop-gnome-platform helper

My Solution:

I settled on using a multiple-part build where the main Application "part" depended upon a part declared as using the "nil" plugin which means that it doesn't actually do anything. I then added a "prepare" script to the nil part which does the necessary for adding the PPA, it's PGP key, and forcing an update/upgrade cycle.

I believe this needed to be a separate part rather than as a prepare script on the main app because the build-packages are fetched before the prepare script is run, meaning that it will fail to find the packages for the dependencies and die with a nice error message. This is fixed by doing the multiple parts method. I used this to build the gnome-twitch snap, which was announced a couple of days ago, on behalf of the Snapcrafters effort.

Example:

Below is an incomplete paste of the gnome-twitch snapcraft.yaml to explain how I did this:

parts:
  prepare:
    plugin: nil
    prepare: |
      echo "deb http://ppa.launchpad.net/ubuntu-desktop/gnome-3-26/ubuntu xenial main" | tee /etc/apt/sources.list.d/gnome-3-24.list
      apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 399B698EEA9EF163B6F9A0F62CC98497A1231595
      apt update
      apt upgrade -yy
    prime: [-*]
  ...
  gnome-twitch:
    after: [prepare, desktop-gnome-platform]
    ...

plugs:
  gnome-3-26-1604:
    interface: content
    content: gnome-3-26-1604
    target: gnome-platform
    default-provider: gnome-3-26-1604

apps:
  gnome-twitch:
    command: desktop-launch $SNAP/usr/bin/gnome-twitch
    plugs:
      - ... # all the plugs required
      - gnome-3-26-1604
Lucy Llewellyn
  • 1,011
  • 6
  • 5
1

Unfortunately, the answer above no longer works with recent changes to snapcraft. A setup that currently works, based on Daniel's answer above, looks like this:

First, in the root scope, we need to set up architectures to match the built packages in our PPA:

architectures:
  - build-on: amd64
    run-on: amd64

We need software-properties-common and dirmngr to have access to apt and apt-key:

build-packages:
  [... other packages ...]
  - software-properties-common
  - dirmngr

The package installation is handled as a separate part, by overriding the pull stage:

parts:
  add-ppa:
    plugin: nil
    override-pull: |
      echo "deb http://ppa.launchpad.net/[... your ppa ...]/ubuntu bionic main" | tee /etc/apt/sources.list.d/custom.list
      apt-key adv --keyserver keyserver.ubuntu.com --recv-keys [... your key ...]
      apt update
      apt upgrade -yy

Finally, we add add-ppa part as a dependency of our "main" part:

parts:
  [... other parts ...]

  core:
    after: [add-ppa]
Martin Prazak
  • 1,476
  • 12
  • 20