@@ -31,7 +31,9 @@ pub struct Options {
3131 /// Enables verbose logging
3232 #[ clap( short, long) ]
3333 verbose : bool ,
34- /// Target triple to build against
34+ /// Target triple to build against.
35+ /// It must be one of the values outputted by `$rustc --print target-list` or `universal-apple-darwin` for an universal macOS application.
36+ /// Note that compiling an universal macOS application requires both `aarch64-apple-darwin` and `x86_64-apple-darwin` targets to be installed.
3537 #[ clap( short, long) ]
3638 target : Option < String > ,
3739 /// List of cargo features to activate
@@ -132,9 +134,6 @@ pub fn command(options: Options) -> Result<()> {
132134 cargo_features. extend ( features) ;
133135 }
134136
135- crate :: interface:: rust:: build_project ( runner, & options. target , cargo_features, options. debug )
136- . with_context ( || "failed to build app" ) ?;
137-
138137 let app_settings = crate :: interface:: rust:: AppSettings :: new ( config_) ?;
139138
140139 let out_dir = app_settings
@@ -151,6 +150,40 @@ pub fn command(options: Options) -> Result<()> {
151150 #[ cfg( not( windows) ) ]
152151 let bin_path = out_dir. join ( & bin_name) ;
153152
153+ if options. target == Some ( "universal-apple-darwin" . into ( ) ) {
154+ std:: fs:: create_dir_all ( & out_dir) . with_context ( || "failed to create project out directory" ) ?;
155+
156+ let mut lipo_cmd = Command :: new ( "lipo" ) ;
157+ lipo_cmd
158+ . arg ( "-create" )
159+ . arg ( "-output" )
160+ . arg ( out_dir. join ( & bin_name) ) ;
161+ for triple in [ "aarch64-apple-darwin" , "x86_64-apple-darwin" ] {
162+ crate :: interface:: rust:: build_project (
163+ runner. clone ( ) ,
164+ & Some ( triple. into ( ) ) ,
165+ cargo_features. clone ( ) ,
166+ options. debug ,
167+ )
168+ . with_context ( || format ! ( "failed to build {} binary" , triple) ) ?;
169+ let triple_out_dir = app_settings
170+ . get_out_dir ( Some ( triple. into ( ) ) , options. debug )
171+ . with_context ( || format ! ( "failed to get {} out dir" , triple) ) ?;
172+ lipo_cmd. arg ( triple_out_dir. join ( & bin_name) ) ;
173+ }
174+
175+ let lipo_status = lipo_cmd. status ( ) ?;
176+ if !lipo_status. success ( ) {
177+ return Err ( anyhow:: anyhow!( format!(
178+ "Result of `lipo` command was unsuccessful: {}. (Is `lipo` installed?)" ,
179+ lipo_status
180+ ) ) ) ;
181+ }
182+ } else {
183+ crate :: interface:: rust:: build_project ( runner, & options. target , cargo_features, options. debug )
184+ . with_context ( || "failed to build app" ) ?;
185+ }
186+
154187 #[ cfg( unix) ]
155188 if !options. debug {
156189 strip ( & bin_path, & logger) ?;
0 commit comments