Skip to content

Commit 0f89fee

Browse files
committed
Add concept of native Dockerfile.
1 parent 557bac5 commit 0f89fee

File tree

4 files changed

+115
-2
lines changed

4 files changed

+115
-2
lines changed

docker/Dockerfile.native

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
FROM ubuntu:20.04
2+
ARG DEBIAN_FRONTEND=noninteractive
3+
4+
COPY common.sh lib.sh /
5+
RUN /common.sh
6+
7+
COPY cmake.sh /
8+
RUN /cmake.sh
9+
10+
COPY xargo.sh /
11+
RUN /xargo.sh
12+
13+
ARG TARGET_ARCH
14+
ARG QEMU_ARCH=$TARGET_ARCH
15+
16+
COPY qemu.sh /
17+
RUN /qemu.sh $QEMU_ARCH softmmu
18+
19+
COPY dropbear.sh /
20+
RUN /dropbear.sh
21+
22+
COPY linux-image.sh /
23+
RUN /linux-image.sh $TARGET_ARCH
24+
25+
COPY linux-runner /
26+
27+
ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="/linux-runner $TARGET_ARCH"

xtask/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[package]
2+
build = "src/build.rs"
23
documentation = "https://github.com/cross-rs/cross"
34
license = "MIT OR Apache-2.0"
45
name = "xtask"

xtask/src/build.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
println!(
3+
"cargo:rustc-cfg=cross_triple=\"{}\"",
4+
std::env::var("TARGET").expect("rustc must set the TARGET environment variable")
5+
);
6+
}

xtask/src/build_docker_image.rs

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::path::Path;
33

44
use crate::util::{cargo_metadata, gha_error, gha_output, gha_print};
55
use clap::Args;
6+
use cross::docker::Architecture;
67
use cross::docker::ImagePlatform;
78
use cross::shell::MessageInfo;
89
use cross::{docker, CommandExt, ToUtf8};
@@ -165,6 +166,7 @@ pub fn build_docker_image(
165166
platform
166167
};
167168

169+
let native_dockerfile = docker_root.join("Dockerfile.native").to_utf8()?.to_string();
168170
let mut results = vec![];
169171
for (platform, (target, dockerfile)) in targets
170172
.iter()
@@ -179,7 +181,66 @@ pub fn build_docker_image(
179181
docker_build.args(&["buildx", "build"]);
180182
docker_build.current_dir(&docker_root);
181183

182-
docker_build.args(&["--platform", &platform.docker_platform()]);
184+
// add our platform, and determine if we need to use a native docker image
185+
let docker_platform = platform.docker_platform();
186+
let mut dockerfile = dockerfile.clone();
187+
docker_build.args(&["--platform", &docker_platform]);
188+
if target.sub.is_none() {
189+
match (
190+
engine.arch.as_ref(),
191+
docker_platform.as_str(),
192+
target.name.as_str(),
193+
) {
194+
(Some(Architecture::I386), "linux/386", "i686-unknown-linux-gnu") => {
195+
dockerfile = native_dockerfile.clone();
196+
docker_build.args(&["--build-arg", "TARGET_ARCH=i686"]);
197+
docker_build.args(&["--build-arg", "QEMU_ARCH=i386"]);
198+
}
199+
(Some(Architecture::Amd64), "linux/amd64", "x86_64-unknown-linux-gnu") => {
200+
dockerfile = native_dockerfile.clone();
201+
docker_build.args(&["--build-arg", "TARGET_ARCH=x86_64"]);
202+
}
203+
(Some(Architecture::Arm), "linux/arm/v6", "arm-unknown-linux-gnueabi")
204+
if is_armv6() =>
205+
{
206+
note_host_target_detection(msg_info)?;
207+
dockerfile = native_dockerfile.clone();
208+
docker_build.args(&["--build-arg", "TARGET_ARCH=arm"]);
209+
}
210+
(
211+
Some(Architecture::Arm),
212+
"linux/arm" | "linux/arm/v7",
213+
"armv7-unknown-linux-gnueabihf",
214+
) if is_armv7() => {
215+
note_host_target_detection(msg_info)?;
216+
dockerfile = native_dockerfile.clone();
217+
docker_build.args(&["--build-arg", "TARGET_ARCH=armv7"]);
218+
docker_build.args(&["--build-arg", "QEMU_ARCH=arm"]);
219+
}
220+
(
221+
Some(Architecture::Arm64),
222+
"linux/arm64" | "linux/arm64/v8",
223+
"aarch64-unknown-linux-gnu",
224+
) => {
225+
dockerfile = native_dockerfile.clone();
226+
docker_build.args(&["--build-arg", "TARGET_ARCH=aarch64"]);
227+
}
228+
(Some(Architecture::Ppc64Le), "linux/ppc64le", "powerpc64le-unknown-linux-gnu") => {
229+
dockerfile = native_dockerfile.clone();
230+
docker_build.args(&["--build-arg", "TARGET_ARCH=powerpc64le"]);
231+
docker_build.args(&["--build-arg", "QEMU_ARCH=ppc64le"]);
232+
}
233+
(Some(Architecture::Riscv64), "linux/riscv64", "riscv64gc-unknown-linux-gnu") => {
234+
dockerfile = native_dockerfile.clone();
235+
docker_build.args(&["--build-arg", "TARGET_ARCH=riscv64"]);
236+
}
237+
(Some(Architecture::S390x), "linux/s390x", "s390x-unknown-linux-gnu") => {
238+
dockerfile = native_dockerfile.clone();
239+
docker_build.args(&["--build-arg", "TARGET_ARCH=s390x"]);
240+
}
241+
_ => (),
242+
}
243+
}
183244

184245
if push {
185246
docker_build.arg("--push");
@@ -259,7 +320,7 @@ pub fn build_docker_image(
259320
),
260321
]);
261322

262-
docker_build.args(&["-f", dockerfile]);
323+
docker_build.args(&["-f", &dockerfile]);
263324

264325
if gha || progress == "plain" {
265326
docker_build.args(&["--progress", "plain"]);
@@ -321,6 +382,24 @@ pub fn build_docker_image(
321382
Ok(())
322383
}
323384

385+
fn is_armv6() -> bool {
386+
cfg!(any(
387+
cross_triple = "arm-unknown-linux-gnueabi",
388+
cross_triple = "arm-unknown-linux-musleabi"
389+
))
390+
}
391+
392+
fn is_armv7() -> bool {
393+
cfg!(any(
394+
cross_triple = "armv7-unknown-linux-gnueabihf",
395+
cross_triple = "armv7-unknown-linux-musleabihf"
396+
))
397+
}
398+
399+
fn note_host_target_detection(msg_info: &mut MessageInfo) -> cross::Result<()> {
400+
msg_info.note("using the rust target triple to determine the host triple to determine if the docker platform is native. this may fail if cross-compiling xtask.")
401+
}
402+
324403
pub fn determine_image_name(
325404
target: &crate::ImageTarget,
326405
repository: &str,

0 commit comments

Comments
 (0)