What is the current state of cross-compiling snaps for Core24? Specifically, is it possible to build snaps for ARM64 on an AMD64 machine?
On Core20, I was able to use the --target-arch and --enable-experimental-target-arch flags to achieve this. Outside of Snapcraft, I can cross-compile most software using CMake and appropriate toolchains. I cannot use Launchpad build farms, as the software is proprietary, and I don’t currently have access to a decent ARM64 build server.
For Core24, is there a way to emulate ARM64 for snap builds, or is building directly on an ARM64 machine still required?
We’ve recently improved cross-compiling for core24. See this how-to for more information. It’s currently only available on the latest/edge channel, but will be included in the Snapcraft 8.8 release later this month.
We do not use autotools, but I get the gist of it.
In principle, this means that I should be able to cross compile our software by normal means, then use dump plugin to dump the resulting ARM64 executables into a snap. Then I can use stage-dependencies to source ARM64 run-time dependencies from ubuntu-ports as long as I remember to suffix the packages with :$CRAFT_ARCH_BUILD_FOR (except for those dependencies with architecture all).
I tried it out, but I have some trouble pulling dependencies outside of ubuntu and ubuntu-ports. Consider this minimal example - I create part foo with dependency libc6 and ros-jazzy-ros-base, the latter of which is available in the ROS2 repo. The following snapcraft.yaml builds fine on Ubuntu 24.04.2 LTS (AMD64) with snapcraft 8.7.4.post91:
Stage package not found in part 'foo': ros-jazzy-ros-base:arm64.
I think it is odd that libc6:arm64 is successfully marked and installed while ros-jazzy-ros-base:arm64 is not. I wanted to file a bug, but I am not sure if this is intentional or I am missing something.
Thanks for trying it out! This smells like a bug to me.
I suspect it’s related to craft-parts passing the host architecture when downloading the package here. It appears this causes craft-parts to see if the package is available for the host arch and then download it for the foreign arch. In your scenario, it fails because ros-jazzy-ros-base isn’t available for AMD64. (edit: I don’t think this is the root cause anymore)