@@ -247,7 +247,35 @@ pub fn flush(self: *MachO) !void {
247
247
}
248
248
249
249
if (self .options .cpu_arch == null ) {
250
- try self .inferCpuArchAndPlatform (resolved_objects .items );
250
+ var has_parse_error = false ;
251
+ var platforms = std .ArrayList (struct { std .Target .Cpu .Arch , ? Options .Platform }).init (self .base .allocator );
252
+ defer platforms .deinit ();
253
+ try platforms .ensureUnusedCapacity (resolved_objects .items .len );
254
+
255
+ for (resolved_objects .items ) | obj | {
256
+ self .inferCpuArchAndPlatform (obj , & platforms ) catch | err | {
257
+ has_parse_error = true ;
258
+ switch (err ) {
259
+ error .UnhandledCpuArch = > {}, // already reported
260
+ else = > | e | {
261
+ self .base .fatal ("{s}: unexpected error occurred while parsing input file: {s}" , .{
262
+ obj .path , @errorName (e ),
263
+ });
264
+ return e ;
265
+ },
266
+ }
267
+ };
268
+ }
269
+ if (has_parse_error ) return error .ParseFailed ;
270
+ if (platforms .items .len == 0 ) {
271
+ self .base .fatal ("could not infer CPU architecture" , .{});
272
+ return error .InferCpuFailed ;
273
+ }
274
+
275
+ self .options .cpu_arch = platforms .items [0 ][0 ];
276
+ self .options .platform = for (platforms .items ) | platform | {
277
+ if (platform [1 ]) | p | break p ;
278
+ } else null ;
251
279
}
252
280
253
281
if (self .options .platform == null ) {
@@ -498,44 +526,48 @@ fn resolveFramework(
498
526
}
499
527
}
500
528
501
- fn inferCpuArchAndPlatform (self : * MachO , objs : [] const LinkObject ) ! void {
529
+ fn inferCpuArchAndPlatform (self : * MachO , obj : LinkObject , platforms : anytype ) ! void {
502
530
const gpa = self .base .allocator ;
503
- for (objs ) | obj | {
504
- const file = try std .fs .cwd ().openFile (obj .path , .{});
505
- defer file .close ();
506
531
507
- const header = file . reader ().readStruct ( macho . mach_header_64 ) catch continue ;
508
- if ( header . filetype != macho . MH_OBJECT ) continue ;
532
+ const file = try std . fs . cwd ().openFile ( obj . path , .{}) ;
533
+ defer file . close () ;
509
534
510
- const cpu_arch : std.Target.Cpu.Arch = switch (header .cputype ) {
511
- macho .CPU_TYPE_ARM64 = > .aarch64 ,
512
- macho .CPU_TYPE_X86_64 = > .x86_64 ,
513
- else = > @panic ("unhandled CPU arch" ), // TODO error
514
- };
535
+ const header = file .reader ().readStruct (macho .mach_header_64 ) catch return ;
536
+ if (header .filetype != macho .MH_OBJECT ) return ;
537
+
538
+ const cpu_arch : std.Target.Cpu.Arch = switch (header .cputype ) {
539
+ macho .CPU_TYPE_ARM64 = > .aarch64 ,
540
+ macho .CPU_TYPE_X86_64 = > .x86_64 ,
541
+ else = > {
542
+ self .base .fatal ("{s}: unhandled CPU architecture: {d}" , .{
543
+ obj .path ,
544
+ header .cputype ,
545
+ });
546
+ return error .UnhandledCpuArch ;
547
+ },
548
+ };
515
549
516
- const cmds_buffer = try gpa .alloc (u8 , header .sizeofcmds );
517
- defer gpa .free (cmds_buffer );
518
- const amt = file .reader ().readAll (cmds_buffer ) catch continue ;
519
- if (amt != header .sizeofcmds ) continue ;
550
+ const out = platforms .addOneAssumeCapacity ();
551
+ out .* = .{ cpu_arch , null };
520
552
521
- var it = macho.LoadCommandIterator {
522
- . ncmds = header . ncmds ,
523
- . buffer = cmds_buffer ,
524
- } ;
525
- const platform : Options.Platform = while ( it . next ()) | cmd | switch ( cmd . cmd ()) {
526
- .BUILD_VERSION ,
527
- .VERSION_MIN_MACOSX ,
528
- .VERSION_MIN_IPHONEOS ,
529
- .VERSION_MIN_TVOS ,
530
- .VERSION_MIN_WATCHOS ,
531
- = > break Options . Platform . fromLoadCommand ( cmd ) ,
532
- else = > {} ,
533
- } else continue ;
534
-
535
- self . options . cpu_arch = cpu_arch ;
536
- self . options . platform = platform ;
537
- break ;
538
- }
553
+ const cmds_buffer = try gpa . alloc ( u8 , header . sizeofcmds );
554
+ defer gpa . free ( cmds_buffer );
555
+ const amt = file . reader (). readAll ( cmds_buffer ) catch return ;
556
+ if ( amt != header . sizeofcmds ) return ;
557
+
558
+ var it = macho.LoadCommandIterator {
559
+ . ncmds = header . ncmds ,
560
+ . buffer = cmds_buffer ,
561
+ };
562
+ out [ 1 ] = while ( it . next ()) | cmd | switch ( cmd . cmd ()) {
563
+ .BUILD_VERSION ,
564
+ .VERSION_MIN_MACOSX ,
565
+ .VERSION_MIN_IPHONEOS ,
566
+ .VERSION_MIN_TVOS ,
567
+ .VERSION_MIN_WATCHOS ,
568
+ = > break Options . Platform . fromLoadCommand ( cmd ),
569
+ else = > {},
570
+ } else null ;
539
571
}
540
572
541
573
fn validateCpuArch (self : * MachO , index : File.Index ) void {
0 commit comments