Snapcraft Build not performing anything after the build stage

My snapcraft.yaml is:

name: tifig
version: git
summary: Converts HEIF images created on iOS 11 devices as fast as possible.
description: |
  Tifig converts HEIF images created on iOS 11 devices as fast as humanly possible.
base: core18
confinement: strict
parts:
  tifig:
    plugin: dump
    source-type: git
    source: https://github.com/monostream/tifig
    override-pull: snapcraftctl pull && mkdir build && cd build
    override-build: |
      snapcraftctl build

      wget https://github.com/jcupitt/libvips/archive/refs/tags/v8.6.1.tar.gz
      tar xzf v8.6.1.tar.gz
      rm v8.6.1.tar.gz
      cd libvips-8.6.1
      ./autogen.sh
      make
      sudo make install
      cd ..

      cmake . .
      make

      rm -rf libvips-8.6.1
    build-packages:
      - gcc
      - g++
      - cmake
      - pkg-config
      - libavcodec-dev
      - libswscale-dev
      - libvips-dev
      - libglib2.0-dev
      - libexpat1-dev
      - libjpeg-dev
      - libexif-dev
      - libpng-dev
      - libtiff-dev
      - wget
      - gtk-doc-tools
      - gobject-introspection
    stage-packages: []
  
apps:
  tifig:
    command: build/tifig

It just goes to the build stage, succeeds, and then stops. It doesn’t do any of the other stages and doesn’t produce a .snap file. Any ideas why this is happening?

you’re running autotools and cmake builds without specifying DESTDIR=. This will lead to your compiled binaries being installed into the building system’s /usr/local, and not into the snap build environment. You may use $SNAPCRAFT_PART_INSTALL for DESTDIR= e.g.:

./autogen.sh
make
DESTDIR=$SNAPCRAFT_PART_INSTALL make install
cd ..

cmake . .
make
DESTDIR=$SNAPCRAFT_PART_INSTALL make install

It’s also worth mentioning this isn’t expected, snapcraft has a $SNAPCRAFT_PART_BUILD directory which will have the contents of the git repo in it, copied from $SNAPCRAFT_PART_SRC, there’s no need to actually make a specific build folder and there’s a seperation of source and build to prevent errors with caching the build process ruining the final snap.

In this case, you can likely just remove the override-pull

With this in mind, I don’t think the cd commands in the override-build work as expected either, because they’re almost certainly not in the build folder you were intending. (To be clear, this counts whether you kept the override-pull or not, override-build will always start in $SNAPCRAFT_PART_BUILD)

Snapcraft Build not performing anything after the build stage

Lame response, but just in case this is actually what you’re doing since it’s the first though I had: snapcraft build only goes through the build stage. If you want to go all the way through the lifecycle, try just snapcraft.

2 Likes

So I moved the output executable to SNAPCRAFT_PART_INSTALL, but now its saying:

Failed to generate snap metadata: The specified command 'tifig' defined in the app 'tifig' does not exist.
Ensure that 'tifig' is installed with the correct path.

snapcraft.yaml:

name: tifig
version: git
summary: Converts HEIF images created on iOS 11 devices as fast as possible.
description: |
  Tifig converts HEIF images created on iOS 11 devices as fast as humanly possible.
base: core18
confinement: strict
license: MIT
grade: stable
parts:
  tifig:
    plugin: dump
    source-type: git
    source: https://github.com/monostream/tifig
    override-build: |
      snapcraftctl build

      wget https://github.com/jcupitt/libvips/archive/refs/tags/v8.6.1.tar.gz
      tar xzf v8.6.1.tar.gz
      rm v8.6.1.tar.gz
      cd libvips-8.6.1
      ./autogen.sh
      make
      sudo make install
      cd ..
      rm -rf libvips-8.6.1

      mkdir build
      cd build
      cmake ..
      make
      mv tifig "$(SNAPCRAFT_PART_INSTALL)/tifig"

      cd ..
    build-packages:
      - gcc
      - g++
      - cmake
      - pkg-config
      - libavcodec-dev
      - libswscale-dev
      - libglib2.0-dev
      - libexpat1-dev
      - libjpeg-dev
      - libexif-dev
      - libpng-dev
      - libtiff-dev
      - wget
      - gtk-doc-tools
      - gobject-introspection
      - libtool
      - m4
      - automake
    stage-packages: []
  
apps:
  tifig:
    command: tifig

Run with snapcraft --debug and take a look around in the prime folder. This folder is what gets compressed to become the snap, you could try using something like find . -name 'tifig'

It’d make most sense of the tifig binary was in somewhere prime/bin/tifig, since prime at build-time is analogous to $SNAP at runtime, you’d refer to it in your command: as bin/tifig.

It’s not actually required that it’s in bin though, so as long as you can find it in prime and refer to it relative to prime/$SNAP you should be able to proceed.

If there’s no tifig binary in prime, check it’s in parts/tifig/install, if it isn’t in there, maybe it’s accidentally still in parts/tifig/build and the override-build requires further adjustments.

I moved the file to parts/tifig/install and added some stage-packages, however the override-build Manually compiles libvips and installs it to the container’s /usr/local. When I try building the snap it says

This part is missing libraries that cannot be satisfied with any available stage-packages known to snapcraft:
- libvips-cpp.so.42
- libvips.so.42

I can see these files in /usr/local/lib but where do I need to put them to have it work in the prime stage? I tried doing

DESTDIR=/root/parts/tifig/install sudo make install

after

sudo make install

so that it would install to both places however it still gave the same error.

Thisis my snapcraft.yaml now:

name: tifig
version: git
summary: Converts HEIF images created on iOS 11 devices as fast as possible.
description: |
  Tifig converts HEIF images created on iOS 11 devices as fast as humanly possible.
base: core18
confinement: strict
license: MIT
grade: stable
parts:
  tifig:
    plugin: nil
    source-type: git
    source: https://github.com/monostream/tifig
    override-build: |
      snapcraftctl build

      wget https://github.com/jcupitt/libvips/archive/refs/tags/v8.6.1.tar.gz
      tar xzf v8.6.1.tar.gz
      rm v8.6.1.tar.gz
      cd libvips-8.6.1
      ./autogen.sh
      make
      sudo make install
      DESTDIR=/root/parts/tifig/install sudo make install
      cd ..
      rm -rf libvips-8.6.1

      mkdir build
      cd build
      cmake ..
      make

      cd ..
    build-packages:
      - gcc
      - g++
      - cmake
      - pkg-config
      - libavcodec-dev
      - libswscale-dev
      - libglib2.0-dev
      - libexpat1-dev
      - libjpeg-dev
      - libexif-dev
      - libpng-dev
      - libtiff-dev
      - wget
      - gtk-doc-tools
      - gobject-introspection
      - libtool
      - m4
      - automake
    stage-packages:
      - libavcodec-dev
      - libswscale-dev
      - libglib2.0-dev
      - libexpat1-dev
      - libjpeg-dev
      - libexif-dev
      - libpng-dev
      - libtiff-dev
  
apps:
  tifig:
    command: bin/tifig

I’ve renovated your snapcraft build file, so that hopefully it’s more inline with the snappy way of building things and easier to understand.

To answer why

This part is missing libraries that cannot be satisfied ...

The answer is that compiling the libvips libraries manually means that when snapcraft does checks to help with making sure all the dynamic dependencies are bundled, it can’t quite work out what these dependencies are and hence what stage-packages to recommend because they’re locally compiled. In addition, the compiling process puts them in $SNAP/usr/local/lib, as opposed to e.g $SNAP/lib, which means at runtime they’re not found by default. Snapcraft sets up the $LD_LIBRARY_PATH variable to include $SNAP/lib automatically, so we need to add the libvips packages to this list too. That’s what the environment: section does in the snapcraft file below, and this fixes the runtime problem. Snapcraft might continue to keep showing the warning in builds but you can safely ignore it.

But otherwise, I think your snapcraft file above is complicating things by avoiding making use of both plugins and parts. By using the nil plugin you get the advantage of controlling the entire build manually, but lack the niceities of e.g setting up $DESTDIR automatically, a default set of build-packages, etc.

Logically, libvips and tifig are two seperate parts, with two seperate sources, and two seperate build toolchains. They’re linked in that one needs to be built first and exposed to the other to compile against, snapcraft solves this with the after: keyword, which ensures libvips is compiled first and then it’s made available for tifig to build against.

Otherwise, I’ve taken the liberty of knocking the base to core20 just to get the newer compiler tools and push back having to worry about rebasing in the future by another 2 years. And I’ve changed the version tag from git to '1' since git didn’t make sense to me, but you can set it back to git if it makes sense for you.

Unfortunately, I don’t have the time to work out why tifig keeps putting its build files in $SNAPCRAFT_PART_BUILD, but since it’s just the one single binary that’s produced, I use build-override to copy it into $SNAPCRAFT_PART_INSTALL manually. There might be something in the CMake files that’s interfering, but I’m not a CMake expert.

So feel free to try this file, run snapcraft clean before snapcraft to make sure the build environment is nice and tidy, and hopefully the resulting snap should work for you.

name: tifig
version: '1'
summary: Converts HEIF images created on iOS 11 devices as fast as possible.
description: |
  Tifig converts HEIF images created on iOS 11 devices as fast as humanly possible.
base: core20
confinement: strict
license: MIT
grade: stable
parts:
  tifig:
    plugin: cmake
    source: https://github.com/monostream/tifig.git
    build-packages:
      - libavcodec-dev
      - libswscale-dev
      - wget
      - gtk-doc-tools
      - gobject-introspection
      - libtool
    stage-packages: 
      - libaom0
      - libavcodec58
      - libavutil56
      - libcairo-gobject2
      - libcairo2
      - libcodec2-0.9
      - libdatrie1
      - libdrm2
      - libfontconfig1
      - libfreetype6
      - libfribidi0
      - libgdk-pixbuf2.0-0
      - libgomp1
      - libgraphite2-3
      - libgsm1
      - libharfbuzz0b
      - libicu66
      - libmp3lame0
      - libnuma1
      - libogg0
      - libopenjp2-7
      - libopus0
      - libpango-1.0-0
      - libpangocairo-1.0-0
      - libpangoft2-1.0-0
      - libpixman-1-0
      - librsvg2-2
      - libshine3
      - libsnappy1v5
      - libsoxr0
      - libspeex1
      - libswresample3
      - libswscale5
      - libthai0
      - libtheora0
      - libtwolame0
      - libva-drm2
      - libva-x11-2
      - libva2
      - libvdpau1
      - libvorbis0a
      - libvorbisenc2
      - libvpx6
      - libwavpack1
      - libwebpmux3
      - libx11-6
      - libx264-155
      - libx265-179
      - libxau6
      - libxcb-render0
      - libxcb-shm0
      - libxcb1
      - libxdmcp6
      - libxext6
      - libxfixes3
      - libxml2
      - libxrender1
      - libxvidcore4
      - libzvbi0
      - ocl-icd-libopencl1
    override-build: |
      snapcraftctl build
      mkdir -p $SNAPCRAFT_PART_INSTALL/bin
      cp $SNAPCRAFT_PART_BUILD/tifig $SNAPCRAFT_PART_INSTALL/bin/tifig
    after: [libvips]
      
  libvips:
    plugin: autotools
    source: https://github.com/jcupitt/libvips/archive/refs/tags/v8.6.1.tar.gz
    build-packages:
      - libglib2.0-dev 
      - libexpat1-dev 
      - libjpeg-dev 
      - libexif-dev 
      - libpng-dev 
      - libtiff-dev
    stage-packages:
      - libexif12
      - libjbig0
      - libjpeg-turbo8
      - libpng16-16
      - libtiff5

apps:
  tifig:
    command: bin/tifig
    environment:
      LD_LIBRARY_PATH: $SNAP/usr/local/lib
    plugs: 
      - home

You might need to add some more interfaces to fix sandboxing, and maybe there’s a need for some other modifications if e.g it opens any desktop windows or the like, but this should at least build, install, and actually make the tifig binary available to the system.

Doing snapcraft clean and then snapcraft made it work, thanks for the help!