I need to build images for an application in Python. Cross-build Docker images? I haven't heard of anything like that. I need to build images for an application in Python. Cross-build Docker images? I haven't heard of anything like that.
Did you mean cross-compilations for compiled languages? It doesn't fit Python.
I am sorry but I am having a difficult time understanding your comment. If you are coding in Python, why does the underlying architecture matter at all?
The architecture of the docker image matters. If you build a docker image on an ARM machine (like a m1 or m2 Mac) you can't run it in x86 architecture (like a T3 or M5 AWS instance). If you build on x86 architecture, you can't run it on ARM architecture.
That is, unless you use Docker's cross platform build capability (buildx). Which was still considered experimental the last time I looked at it (about a year ago).
You can build other-arch images with regular `build`. You'll of course need QEMU hooked up through binfmt to be able to execute `RUN` steps while building the image, but you can do that yourself without involving `buildx`.
For systemd distros, you might already have systemd-binfmt.service in the systemd package, which when started will automatically register all architectures specified in config files under /usr/lib/binfmt.d with the kernel. Then your qemu package will probably contain one config file in that directory for every arch. So if you enable and start the systemd-binfmt service, you'll automatically have a bajillion architectures registered with the kernel to run under qemu and you don't have to do anything else.
Or you can register manually by writing to /proc/sys/fs/binfmt_misc/register . Note that you'll want to register the statically linked version of qemu (qemu-user-static or whatever your distro calls it), and that you'll want to use at least the O and F flags so that the binary works inside containers automatically insead of needing to be mounted from the host.
At $dayjob we build packages of our software for a bunch of Linux distros, which means the software has to be compiled individually for each distro to get external dependencies right. Some of those distros like the RHEL 7 family don't support cross-compilation, so we run them in QEMU.
You just need a sysroot for that distribution... you actually don't want to compile ON that distribution as it makes having a consistent and modern/working toolchain a lot more difficult.
Notably, I compile for CentOS 6 (ancient, right?) on whatever the latest version of Ubuntu is--using the most recent versions of clang and rust and whatever--and simply build my sysroot using this trivial script.
(You can do this in some sense even easier using Docker--though in other senses it is a lot more complex as now you need docker--if you are into that sort of thing. You don't run the compiler in docker: you just install the dependency packages and then docker export the filesystem as your sysroot.)
Using this script and clang I can actually compile to target CentOS 6 on macOS (and I get the exact same binary if I use a consistent version of clang; I actually have a GitHub action that verifies that I reproduce the same binary compiling on both macOS and Ubuntu).
>You just need a sysroot for that distribution... you actually don't want to compile ON that distribution
We compile in a Docker container of the distro. It's the same concept as having a sysroot.
>as it makes having a consistent toolchain a lot more difficult.
>using the most recent versions of clang and rust and whatever
The external dependencies I mentioned are libraries like glibc or openssl, where you want to use the distro version. Similarly the packages should be consistent with what the users of the distro would build themselves if they used rpmbuild / debbuild / whatever. The toolchain not being consistent across distros is the point.
Also, none of this is relevant to cross-compiling for ARM. As I said, RHEL 7 doesn't have a cross compiler - specifically it has gcc but not glibc, because the cross compiler is only meant for compiling the kernel.
> We compile in a Docker container of the distro. It's the same concept as having a sysroot.
It isn't the same concept as using a sysroot, as you are now using the compiler from that potentially-ancient different distribution. I see people constantly twisting themselves into knots being like "CentOS has some broken/limited build of gcc/clang so I can't use X" and it is like "if there is one thing you as a developer control it is the compiler".
> The external dependencies I mentioned are libraries like glibc or openssl, where you want to use the distro version.
I understood this: that's what you put in your sysroot (and is easily seen in the example script I showed for CentOS 6; my scripts for building Ubuntu sysroots are much more complicated as I am trying to avoid nesting docker and so now have some crazy fallback involving debootstrap and proot).
> Similarly the packages should be consistent with what the users of the distro would build themselves if they used rpmbuild / debbuild / whatever.
Ok, this is where we differ, then: I am not trying to simultaneously support users building on CentOS using "rpmbuild". I want to be able to use the latest build of C++ and Rust and Python and essentially have a "modern"/easy development stack but "target"/support other distributions so they can install my software as packages.
Given the goal of being able to provide source code that can itself be compiled on these random distributions I see the problem. I personally feel like it would still be better to work around that by requesting (which can itself be automated by your build) that the user compile their own toolchain that has more functionality, though.
>it is like "if there is one thing you as a developer control it is the compiler".
>I understood this: that's what you put in your sysroot
You're advocating mixing compilers and libraries that are not from the same distro release. While it may work for you it's generally a recipe for disaster.
The correct and least-mental-overhead way of building packages for $distro is to build on $distro. The fact that users of $distro can then build your package themselves using the standard distro method is an extra benefit.
> You're advocating mixing compilers and libraries that are not from the same distro release. While it may work for you it's generally a recipe for disaster.
What libraries on Linux don't use the SystemV C ABI on x86?
Did you mean cross-compilations for compiled languages? It doesn't fit Python.