Build service fails to use cmake from build-snap

I’ve set up Audacity to build using cmake, but the CMakeLists.txt defined in the upstream project require a more-recent version of cmake than in the Bionic 18.04 repositories. I worked around this restraint locally by adding a build-snaps: [cmake] item to the relevant part. Now local builds work fine. However, the build service seems to be behaving differently with the Launchpad Builder using the cmake from the system instead of the overriding build-snap version.

Any idea why the Build service is not using cmake from a build-snap while locally it works just fine? Can I fix this myself or is the Build service broken?

Locally with Multipass or LXD?

In any case, I would suspect that setting PATH in build-environment would do the trick if the behavior is consistent with non --destructive-mode

I built locally in multipass. It worked there. Edit: as in snapcraft used the multipass provider.

What is the difference in the behaviour? Do you have a link to a build that looks problematic?

Here’s the build log for a failure:

https://launchpadlibrarian.net/482708502/buildlog_snap_ubuntu_bionic_amd64_5eb4b21acd8497e58908cb470f1ff49c_BUILDING.txt.gz

The invokation of the build complains that cmake isn’t new enough - the message is from Audacity’s build rules in CMakeLists.txt - even though the cmake from build-snaps is definitely new enough to satisfy the check that the Audacity CMakeLists.txt imposes.

I suspect PATH on launchpad does not prefer /snap/bin and could be solved by setting PATH in build-environment on your snapcraft.yaml.

While that did fix the issue, I feel that it is not appropriate to add workarounds just to appease the build service when locally the build works fine. The build service should “just work” in the same way as a local build!

1 Like

It’s actually more subtle than that. I’ve seen a case recently where the system had an older CMake version installed and it appears that older version was picked up instead of the snap. That led to unexpected errors coming from CMake due to new features that weren’t available in the older version. The only way that could have been happening is if /snap/bin wasn’t on their path. It’s not something a typical dev who is less familiar with snap is likely to know to look out for. I agree with Dan, the build service should have /snap/bin on the PATH and it should be ahead of the other default system paths, just like you would get on a typical desktop system with snapd installed.

1 Like

I do not disagree, I just wanted to make sure that was the root cause.

Note that the methods snapd uses to update the path (/etc/profile.d and /usr/lib/environment.d) both append /snap/bin to the path. It’s always going to lose out to a binary found in /usr/bin.

This is the opposite of how Snapcraft sets $PATH when calling into a VM or container for Multipass/LXD builds:

Launchpad is effectively doing a --destructive-mode build, which would skip over this build provider logic.

1 Like

So the solution here is to always define the PATH when building with any of the providers (including --destructive) so that we always have an identical setup no matter where or how we build.

This is something we can fix in Snapcraft for core20, I don’t want to break any existing use of the build system.

1 Like

Might it make sense for launchpad-buildd to explicitly set $PATH when calling Snapcraft, so it behaves like Multipass/LXD builds? That would paper over the difference, and shouldn’t cause problems if Snapcraft starts setting PATH itself in future.

We have run into this issue as well on Multipass. We want (need?) a newer CMake version and the CMake snap is the right answer. As @Saviq and I were discussing when trying to come up the right solution for this, why not make the cmake plugin snap aware if build-snaps: [cmake] is set. That shouldn’t affect any of the other base builds and would lead to consistent behavior no matter the build provider.

I’m more thinking a cmake-snap-channel: property for the plugin. No need to infer from build-snaps.

Ack, was just thinking off the cuff :wink:

Chris Townsend via snapcraft.io forum@forum.snapcraft.io writes:

We have run into this issue as well on Multipass. We want (need?) a newer CMake version and the CMake snap is the right answer. As @Saviq and I were discussing when trying to come up the right solution for this, why not make the cmake plugin snap aware if build-snaps: [cmake] is set. That shouldn’t affect any of the other base builds and would lead to consistent behavior no matter the build provider.

The build-environment behavior is consistent on snapcraft from edge.

We are leaning towards having plugins be more about the process of building the
artifacts and not so much about setting up the environment which is where
extensions are much more powerful and can easily be extended or modified to
fit the desired behavior a developer would want.

Isn’t the cmake plugin what pulls in the cmake package, though?