cross icon indicating copy to clipboard operation
cross copied to clipboard

Add concept of a native Dockerfile.

Open Alexhuszagh opened this issue 2 years ago • 13 comments

Alexhuszagh avatar Jul 28 '22 16:07 Alexhuszagh

The idea behind this is so we can provide native toolchains if the image platform and the cross-compilation target are the same. This simplifies our logic for say, linux/arm64 images for an aarch64-unknown-linux-gnu toolchain. There's still some work to do, however:

  1. Need to change x86_64-unknown-linux-gnu to actually work when cross-compiled.
  2. Change i686-unknown-linux-gnu and i586-unknown-linux-gnu to allow use from a non-x86_64 image.
  3. Test the Native toolchain on a non-x86_64 image.

We might require slightly more complex logic for i586/i686 since the default package we'd install for x86_64 (g++-x86-64-linux-gnu) I don't believe is multilib (although I could be wrong here).

Alexhuszagh avatar Jul 28 '22 16:07 Alexhuszagh

I'm not sure I understand what this does and how it differs. How is it used?

Emilgardis avatar Jul 28 '22 17:07 Emilgardis

I'm not sure I understand what this does and how it differs. How is it used?

Say if I want to build aarch64-unknown-linux-gnu for an image running Ubuntu:20.04 on linux/arm64: I just want to install GCC, G++, glibc, and don't want a cross-compiler: I just want the same logic as the current Dockerfile.x86_64-unknown-linux-gnu. And doing this generic logic for every possible host is a lot: we can just make a generic native Dockerfile and use it for every native toolchain for the image.

Alexhuszagh avatar Jul 28 '22 17:07 Alexhuszagh

with buildkit it's possible to do conditional stages, I think that could help to not use a script file

# arm64-specific stage
FROM base AS build-arm64
RUN echo "This stage is used on arm64"

# amd64-specific stage
FROM base AS build-amd64
RUN echo "This stage is used on amd64 (x86)"

# common steps
FROM build-${TARGETARCH} AS build
RUN echo "This stage is used on all architectures"

for example

Emilgardis avatar Jul 28 '22 18:07 Emilgardis

with buildkit it's possible to do conditional stages, I think that could help to not use a script file

# arm64-specific stage
FROM base AS build-arm64
RUN echo "This stage is used on arm64"

# amd64-specific stage
FROM base AS build-amd64
RUN echo "This stage is used on amd64 (x86)"

# common steps
FROM build-${TARGETARCH} AS build
RUN echo "This stage is used on all architectures"

for example

In retrospect, I don't think we need a script (just native/non-native) unless we want to support targets where we have to build from source (which I think we can omit) or use Debian repositories only for a different architecture (specifically, MIPS).

Alexhuszagh avatar Jul 28 '22 18:07 Alexhuszagh

bors try --target x86_64-unknown-linux-gnu

Alexhuszagh avatar Jul 28 '22 20:07 Alexhuszagh

try

Build succeeded:

bors[bot] avatar Jul 28 '22 21:07 bors[bot]

Based on comments elsewhere, I should clarify that this is not used to publish a ghcr.io/cross-rs/native:$tag image: it is meant so Dockerfile.native is used for ghcr.io/cross-rs/x86_64-unknown-linux-gnu:$tag on linux/amd64 and ghcr.io/cross-rs/aarch64-unknown-linux-gnu:$tag on linux/arm64, and that Dockerfile.x86_64-unknown-linux-gnu is only used if the platform is not linux/amd64 (same with Dockerfile.aarch64-unknown-linux-gnu and linux/arm64).

When building the image, we change the Dockerfile used for the build. If the image architecture is the same as the target architecture, and the target triple is *-linux-gnu, then use Dockerfile.native. Otherwise, use the normal Dockerfile. This is required since packages like g++ are not for x86_64 on a linux/arm64 platform, and packages like g++-x86-64-linux-gnu and g++-aarch64-linux-gnu are not available on linux/amd64 and linux/arm64, respectively.

Alexhuszagh avatar Aug 10 '22 18:08 Alexhuszagh

Waiting on #1006 to merge, since this will be handy for native/non-native Dockerfiles for CentOS.

Alexhuszagh avatar Sep 06 '22 13:09 Alexhuszagh

Currently adding the concept of a native CentOS image and then have a specialized x86_64 one since we now support an aarch64 CentOS image. I'll be factoring in the requested changes shortly.

Update: I've added support for native CentOS images (currently untested on x86_64 and aarch64), and need to add an x86_64 image for non-x86_64 hosts.

Alexhuszagh avatar Sep 08 '22 14:09 Alexhuszagh

Other things: TargetTriple::DEFAULT should support more than just X86_64UnknownLinuxGnu. This should likely be the default Docker platform, if we provide images for it, or X86_64UnknownLinuxGnu, if possible.

Alexhuszagh avatar Sep 08 '22 15:09 Alexhuszagh

How does one build the native image for other platforms?

Emilgardis avatar Sep 08 '22 16:09 Emilgardis

How does one build the native image for other platforms?

Just using cargo build-docker-image aarch64-unknown-linux-gnu if using an ARMv8 Linux or mac M1 Docker host, or by doing cargo build-docker-image --platform=arch64-unknown-linux-gnu aarch64-unknown-linux-gnu (on any host).

Basically, it detects if the Docker platform and the target platform match. If so, it uses a native Dockerfile to build the image. This should work (theoretically, tested on only i686, x86_64, and aarch64) on any platform with a Ubuntu port that contains the required packages for a native toolchain (it should work for ppc64le as well, currently untested).

Update: I should mention the implicit platform will only work when the default image platform is no longer always x86_64.

Alexhuszagh avatar Sep 08 '22 16:09 Alexhuszagh

A re-review of this would be wonderful, since then it can form the basis of adding Alpine images as well easily which should solve #902 and #1013. It would also ensure our builds for aarch64-unknown-linux-gnu would work without requiring emulation of an x86_64 platform.

Alexhuszagh avatar Oct 04 '22 15:10 Alexhuszagh

I'm not sure I agree with adding alpine as a sub target, but I'm excited to see what you have in mind :D

Emilgardis avatar Oct 04 '22 17:10 Emilgardis

I'm not sure I agree with adding alpine as a sub target, but I'm excited to see what you have in mind :D

It would only be for the native image, so Dockerfile.alpine.native, and not any other targets, since we have broken C++ builds for these. We can also do the Linux image similar to our CentOS images, so we'd only have to worry about qemu.sh and dropbear.sh for package installations. But we'll see, I'll propose something soon.

This is to try to fix the native C++ support. I'll see if there's another way around it, however, for the existing GNU images. It's been tricky, however, so far.

Alexhuszagh avatar Oct 04 '22 18:10 Alexhuszagh

bors r=Emilgardis

Alexhuszagh avatar Oct 05 '22 14:10 Alexhuszagh

Build failed:

  • conclusion

bors[bot] avatar Oct 05 '22 16:10 bors[bot]

bors try --target x86_64-unknown-linux-gnu.centos

Alexhuszagh avatar Oct 05 '22 20:10 Alexhuszagh

try

Build failed:

bors[bot] avatar Oct 05 '22 20:10 bors[bot]

bors try --target x86_64-unknown-linux-gnu.centos

Alexhuszagh avatar Oct 05 '22 20:10 Alexhuszagh

try

Build succeeded:

bors[bot] avatar Oct 05 '22 21:10 bors[bot]

bors r=Emilgardis

Alexhuszagh avatar Oct 05 '22 21:10 Alexhuszagh

bors r-

We've got a minor issue with CROSS_TARGET_TRIPLE being the target triple without the substitutions and uppercase. Since the runners are native, this won't show up in tests. I think this was accidentally introduced when I refactored to use target.name rather than the original triple.

Alexhuszagh avatar Oct 05 '22 22:10 Alexhuszagh

Canceled.

bors[bot] avatar Oct 05 '22 22:10 bors[bot]

bors r=Emilgardis

Alexhuszagh avatar Oct 05 '22 22:10 Alexhuszagh

Build failed:

bors[bot] avatar Oct 06 '22 00:10 bors[bot]

bors try --target x86_64-unknown-linux-gnu*

Emilgardis avatar Oct 06 '22 17:10 Emilgardis

try

Build succeeded:

bors[bot] avatar Oct 06 '22 17:10 bors[bot]

bors cancel

Emilgardis avatar Oct 07 '22 20:10 Emilgardis