Github-to-snap => cmake version < 3.11

Hi there,

I am new to snapcraft. I am working on porting several of my games to snapcraft.
The first one: https://snapcraft.io/inthecube

Now, I am trying to use github-to-snap to automate the process and support more architectures.
Unfortunately, the cmake version doesn’t match:

CMake 3.11 or higher is required.  You are running version 3.10.2

My library: https://github.com/ArthurSonzogni/smk
Requires 3.11 for cmake FetchContent.

What are my options?

  • Is there any code somewhere I can submit pull request for?
  • Can I make snapcraft to download and use a different version of cmake?

Unfortunately the default cmake plugin in snapcraft uses cmake from the ubuntu archives, so the newest you can get right now is 3.10.2 from bionic by using base: core18 in your snap.

What you can do instead is not use the cmake plugin in snapcraft and instead write a custom part which uses build-override to install cmake from source or from a tarball, etc. with a newer version than what’s in the ubuntu archives. After installing a new enough cmake from somewhere else, in your build-override snippet call cmake like you normally would building your application outside of a snap.

Thanks for your answer!
I will try “build-override” and post my configuration if it works.

Here is the “build-override” solution suggested by ijohnson:

    override-build: |
      git clone https://github.com/Kitware/CMake --depth 1 || true
      mkdir -p CMake/build
      cd CMake/build
      cmake .. -DCMAKE_INSTALL_PREFIX=../../cmake_install
      make -j 4
      make install
      cd ../..
      ./cmake_install/bin/cmake \
        -DCMAKE_INSTALL_PREFIX=$SNAPCRAFT_PART_INSTALL/usr/local \
        -DCMAKE_BUILD_TYPE=Release \
        $SNAPCRAFT_PART_SRC
      make -j 4
      make install

do you really want it to move on if cloning fails ?

When I was iterating on this (e.g. running snapcraft several times in a row). It looks like snapcraft is able sometimes to restart from the dirty previous stage.

I used " || true" to continue when the repository was already cloned.

I guess doing something like:

if [ ! -d "$FOLDER" ] ; then
    git clone "$URL" "$FOLDER"
fi

would be slightly better. Not sure if I can use sh/bash in the snapcraft.yaml config.

Does what I am doing make sense to you?

The ideal thing would be to split out cmake into a separate part and then order your actual build after the cmake part. Something like (untested and off the top of my head so YMMV):

parts:
  cmake:
    source: https://github.com/Kitware/CMake
    source-depth: 1
    plugin: make
    override-build: |
      mkdir -p CMake/build
      cd CMake/build
      cmake .. -DCMAKE_INSTALL_PREFIX=$SNAPCRAFT_STAGE/cmake_install
      make -j 4
      make install
  your-app:
    after: [cmake]
    source: . 
    plugin: make
    override-build: |
      $SNAPCRAFT_STAGE/cmake_install/bin/cmake \
        -DCMAKE_INSTALL_PREFIX=$SNAPCRAFT_PART_INSTALL/usr/local \
        -DCMAKE_BUILD_TYPE=Release \
        $SNAPCRAFT_PART_SRC
      make -j 4
      make install
1 Like

Thank you!
Here is my the final working version:

parts:

  cmake:
    source: https://github.com/Kitware/CMake
    source-type: git
    source-depth: 1
    plugin: cmake
    override-build: |
      mkdir -p build
      cd build
      cmake \
        -DCMAKE_INSTALL_PREFIX=$SNAPCRAFT_STAGE/cmake \
        $SNAPCRAFT_PART_SRC
      make -j 4
      make install

  <your app>:
    after: [cmake]
    plugin: cmake
    source: <your app src>
    source-type: git
    source-depth: 1
    override-build: |
      $SNAPCRAFT_STAGE/cmake/bin/cmake \
        -DCMAKE_INSTALL_PREFIX=$SNAPCRAFT_PART_INSTALL/usr/local \
        -DCMAKE_BUILD_TYPE=Release \
        $SNAPCRAFT_PART_SRC
      make -j 4
      make install
2 Likes

The latest CMake release is available as a snap too. Could you perhaps use parts.<your_app>.build-snaps to list the cmake snap and get a recent enough version for your purposes that way instead of building it yourself? You can also lock to a specific feature release starting from CMake 3.14, if that’s what you need.I’m the author of both the CMake snap and the FetchContent module, so I’d be doubly interested in hearing how you go if you give this a try.

1 Like

Thanks! This seems to work locally:

parts:
  <your-app>:
    build-snaps: [cmake]
    plugin: cmake
    source: <your src>

I just need to wait for the github-to-snap build to confirm:

Hmm, it doesn’t work.:
I get:

Failed to install or refresh a snap: 'cmake' does not exist or is not available on the desired channel 'latest/stable'. Use `snap info cmake` to get a list of channels the snap is available on.

I tried:

    build-snaps:
      - cmake

and

    build-snaps:
      - cmake/lstable

and

    build-snaps:
      - cmake/latest/stable

Ah, perhaps because the cmake snap only has the amd64 architecture available at the moment. I see now that you’re building for four different architectures. Did the amd64 arch at least succeed? Unfortunately, building for the other architectures isn’t on my near-term to-do list. It may happen at some point in the future, but not with my current priorities.

You are right!
Only the amd64 build succeeded.
I didn’t unerstood exactly why initially. I thought it was an old build.

Are you using build.snapcraft.io or launchpad to build the snap? If you are, then it should be easy to at least release an edge build for other architectures for folks to try and use

It builds on Travis CI at the moment.

If you’re interested, you could try building for other architectures using the remote-build feature of snapcraft, currently in testing: Preview: Snapcraft remote build, that would build non-amd64 architectures on launchpad remotely from Travis CI.

@ijohnson I have the remote-build working via a script I run locally rather than through Travis. Part of the problem with going through travis is that the builds can take forever (hours) due to the s390x architecture seeming to have longer wait times. Not quite ideal having to trigger multi-arch builds manually/locally, but good enough for producing packages for CMake releases across all six architectures. I’m still currently sticking with Travis for the nightlies (amd64 only) just because it’s already working and is pretty easy to maintain as a daily cron job there.

1 Like