@@ -269,43 +269,57 @@ export class AtomicServer {
269269 }
270270
271271 @func ( )
272+ /** Doesn't work on M1 macs */
272273 rustCrossBuild ( @argument ( ) target : string ) : Container {
274+ let engineSvc = dag . docker ( ) . engine ( ) ;
273275 const source = this . source ;
274- const cargoCache = dag . cacheVolume ( "cargo" ) ;
275-
276- // Use rust-musl-cross images which support multi-arch builds
277- // Map target to the appropriate image tag
278- let imageTag : string ;
279- switch ( target ) {
280- case "x86_64-unknown-linux-musl" :
281- imageTag = "x86_64-musl" ;
282- break ;
283- case "aarch64-unknown-linux-musl" :
284- imageTag = "aarch64-musl" ;
285- break ;
286- case "armv7-unknown-linux-musleabihf" :
287- imageTag = "armv7-musleabihf" ;
288- break ;
289- default :
290- throw new Error ( `Unsupported cross-compilation target: ${ target } ` ) ;
291- }
292276
293- const rustContainer = dag
277+ const sourceContainer = dag
294278 . container ( )
295- . from ( `ghcr.io/rust-cross/rust-musl-cross:${ imageTag } ` )
296- . withExec ( [ "apt-get" , "update" , "-qq" ] )
297- . withExec ( [ "apt-get" , "install" , "-y" , "nasm" ] )
298- . withMountedCache ( "/home/rust/.cargo/registry" , cargoCache ) ;
299-
300- const sourceContainer = rustContainer
279+ . from ( "docker:cli" )
280+ . withServiceBinding ( "docker" , engineSvc )
281+ . withEnvVariable ( "DOCKER_HOST" , "tcp://docker:2375" )
282+ . withExec ( [ "docker" , "ps" ] )
283+ . withExec ( [
284+ "apk" ,
285+ "add" ,
286+ "--no-cache" ,
287+ // For installing rust
288+ "curl" ,
289+ // CC linker deps, compiling cross
290+ "build-base" ,
291+ "gcc" ,
292+ "musl-dev" ,
293+ "cmake" ,
294+ ] )
295+ . withExec ( [
296+ "sh" ,
297+ "-c" ,
298+ "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable" ,
299+ ] )
300+ . withEnvVariable (
301+ "PATH" ,
302+ "/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
303+ )
304+ . withExec ( [ "docker" , "ps" ] )
305+ . withExec ( [ "cargo" , "install" , "cross" ] )
306+ . withExec ( [ "rustup" , "target" , "add" , target ] )
307+ . withExec ( [
308+ "rustup" ,
309+ "toolchain" ,
310+ "add" ,
311+ "stable-x86_64-unknown-linux-gnu" ,
312+ "--profile" ,
313+ "minimal" ,
314+ "--force-non-host" ,
315+ ] )
301316 . withFile ( "/home/rust/src/Cargo.toml" , source . file ( "Cargo.toml" ) )
302317 . withFile ( "/home/rust/src/Cargo.lock" , source . file ( "Cargo.lock" ) )
303318 . withDirectory ( "/home/rust/src/server" , source . directory ( "server" ) )
304319 . withDirectory ( "/home/rust/src/lib" , source . directory ( "lib" ) )
305320 . withDirectory ( "/home/rust/src/cli" , source . directory ( "cli" ) )
306321 . withMountedCache ( "/home/rust/src/target" , dag . cacheVolume ( "rust-target" ) )
307- . withWorkdir ( "/home/rust/src" )
308- . withExec ( [ "cargo" , "fetch" ] ) ;
322+ . withWorkdir ( "/home/rust/src" ) ;
309323
310324 // Include frontend assets for the server build
311325 const browserDir = this . jsBuild ( ) . directory ( "/app/data-browser/dist" ) ;
@@ -314,15 +328,12 @@ export class AtomicServer {
314328 browserDir
315329 ) ;
316330
317- // Build using the pre-configured cross-compilation environment
331+ // Build using native cargo with target specification
332+ const binaryPath = `./target/${ target } /release/atomic-server` ;
333+
318334 return containerWithAssets
319- . withExec ( [ "cargo" , "build" , "--target" , target , "--release" ] )
320- . withExec ( [ `./target/${ target } /release/atomic-server` , "--version" ] )
321- . withExec ( [
322- "cp" ,
323- `./target/${ target } /release/atomic-server` ,
324- "/atomic-server-binary" ,
325- ] ) ;
335+ . withExec ( [ "cross" , "build" , "--target" , target , "--release" ] )
336+ . withExec ( [ "cp" , binaryPath , "/atomic-server-binary" ] ) ;
326337 }
327338
328339 @func ( )
@@ -470,4 +481,34 @@ export class AtomicServer {
470481
471482 return `Deployment to ${ remoteHost } completed successfully:\n${ deployResult } ` ;
472483 }
484+
485+ @func ( )
486+ async rustCrossMultiBuild (
487+ @argument ( )
488+ targets : string [ ] = [
489+ "x86_64-unknown-linux-musl" ,
490+ "aarch64-unknown-linux-musl" ,
491+ "armv7-unknown-linux-musleabihf" ,
492+ ]
493+ ) : Promise < Directory > {
494+ const builds = targets . map ( ( target ) => {
495+ const container = this . rustCrossBuild ( target ) ;
496+ return {
497+ target,
498+ binary : container . file ( "/atomic-server-binary" ) ,
499+ } ;
500+ } ) ;
501+
502+ // Create a directory with all the binaries
503+ let outputDir = dag . directory ( ) ;
504+
505+ for ( const build of builds ) {
506+ outputDir = outputDir . withFile (
507+ `atomic-server-${ build . target } ` ,
508+ build . binary
509+ ) ;
510+ }
511+
512+ return outputDir ;
513+ }
473514}
0 commit comments