@@ -3,6 +3,7 @@ use std::path::Path;
3
3
4
4
use crate :: util:: { cargo_metadata, gha_error, gha_output, gha_print} ;
5
5
use clap:: Args ;
6
+ use cross:: docker:: Architecture ;
6
7
use cross:: docker:: ImagePlatform ;
7
8
use cross:: shell:: MessageInfo ;
8
9
use cross:: { docker, CommandExt , ToUtf8 } ;
@@ -165,6 +166,7 @@ pub fn build_docker_image(
165
166
platform
166
167
} ;
167
168
169
+ let native_dockerfile = docker_root. join ( "Dockerfile.native" ) . to_utf8 ( ) ?. to_string ( ) ;
168
170
let mut results = vec ! [ ] ;
169
171
for ( platform, ( target, dockerfile) ) in targets
170
172
. iter ( )
@@ -179,7 +181,66 @@ pub fn build_docker_image(
179
181
docker_build. args ( & [ "buildx" , "build" ] ) ;
180
182
docker_build. current_dir ( & docker_root) ;
181
183
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
+ }
183
244
184
245
if push {
185
246
docker_build. arg ( "--push" ) ;
@@ -259,7 +320,7 @@ pub fn build_docker_image(
259
320
) ,
260
321
] ) ;
261
322
262
- docker_build. args ( & [ "-f" , dockerfile] ) ;
323
+ docker_build. args ( & [ "-f" , & dockerfile] ) ;
263
324
264
325
if gha || progress == "plain" {
265
326
docker_build. args ( & [ "--progress" , "plain" ] ) ;
@@ -321,6 +382,24 @@ pub fn build_docker_image(
321
382
Ok ( ( ) )
322
383
}
323
384
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
+
324
403
pub fn determine_image_name (
325
404
target : & crate :: ImageTarget ,
326
405
repository : & str ,
0 commit comments