authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-14 11:22:04+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:40+01:00
logb038bcb93b7a3e254be3fb2f1979680ffa99aa48
treef7bf5da088d094919dd05ed068d014724e0e5d8a
parentfa161c205943116f630975a097a04a9ac6ea1586

test/link/macho: test -r mode


2 files changed, 122 insertions(+), 3 deletions(-)

src/main.zig+1-3
......@@ -2823,9 +2823,7 @@ fn buildOutputType(
28232823 }
28242824 // After this point, resolved_frameworks is used instead of frameworks.
28252825
2826 if (create_module.resolved_options.output_mode == .Obj and
2827 (target.ofmt == .coff or target.ofmt == .macho))
2828 {
2826 if (create_module.resolved_options.output_mode == .Obj and target.ofmt == .coff) {
28292827 const total_obj_count = create_module.c_source_files.items.len +
28302828 @intFromBool(root_src_file != null) +
28312829 create_module.rc_source_files.items.len +
test/link/macho.zig+121
......@@ -23,6 +23,8 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
2323 macho_step.dependOn(testHelloZig(b, .{ .target = default_target }));
2424 macho_step.dependOn(testLargeBss(b, .{ .target = default_target }));
2525 macho_step.dependOn(testMhExecuteHeader(b, .{ .target = default_target }));
26 macho_step.dependOn(testRelocatable(b, .{ .target = default_target }));
27 macho_step.dependOn(testRelocatableZig(b, .{ .target = default_target }));
2628 macho_step.dependOn(testSectionBoundarySymbols(b, .{ .target = default_target }));
2729 macho_step.dependOn(testSegmentBoundarySymbols(b, .{ .target = default_target }));
2830 macho_step.dependOn(testTentative(b, .{ .target = default_target }));
......@@ -498,6 +500,125 @@ fn testNeededLibrary(b: *Build, opts: Options) *Step {
498500 return test_step;
499501}
500502
503fn testRelocatable(b: *Build, opts: Options) *Step {
504 const test_step = addTestStep(b, "macho-relocatable", opts);
505
506 const a_o = addObject(b, opts, .{ .name = "a", .cpp_source_bytes =
507 \\#include <stdexcept>
508 \\int try_me() {
509 \\ throw std::runtime_error("Oh no!");
510 \\}
511 });
512 a_o.linkLibCpp();
513
514 const b_o = addObject(b, opts, .{ .name = "b", .cpp_source_bytes =
515 \\extern int try_me();
516 \\int try_again() {
517 \\ return try_me();
518 \\}
519 });
520
521 const main_o = addObject(b, opts, .{ .name = "main", .cpp_source_bytes =
522 \\#include <iostream>
523 \\#include <stdexcept>
524 \\extern int try_again();
525 \\int main() {
526 \\ try {
527 \\ try_again();
528 \\ } catch (const std::exception &e) {
529 \\ std::cout << "exception=" << e.what();
530 \\ }
531 \\ return 0;
532 \\}
533 });
534 main_o.linkLibCpp();
535
536 const exp_stdout = "exception=Oh no!";
537
538 {
539 const c_o = addObject(b, opts, .{ .name = "c" });
540 c_o.addObject(a_o);
541 c_o.addObject(b_o);
542
543 const exe = addExecutable(b, opts, .{ .name = "main1" });
544 exe.addObject(main_o);
545 exe.addObject(c_o);
546 exe.linkLibCpp();
547
548 const run = addRunArtifact(exe);
549 run.expectStdOutEqual(exp_stdout);
550 test_step.dependOn(&run.step);
551 }
552
553 {
554 const d_o = addObject(b, opts, .{ .name = "d" });
555 d_o.addObject(a_o);
556 d_o.addObject(b_o);
557 d_o.addObject(main_o);
558
559 const exe = addExecutable(b, opts, .{ .name = "main2" });
560 exe.addObject(d_o);
561 exe.linkLibCpp();
562
563 const run = addRunArtifact(exe);
564 run.expectStdOutEqual(exp_stdout);
565 test_step.dependOn(&run.step);
566 }
567
568 return test_step;
569}
570
571fn testRelocatableZig(b: *Build, opts: Options) *Step {
572 const test_step = addTestStep(b, "macho-relocatable-zig", opts);
573
574 const a_o = addObject(b, opts, .{ .name = "a", .zig_source_bytes =
575 \\const std = @import("std");
576 \\export var foo: i32 = 0;
577 \\export fn incrFoo() void {
578 \\ foo += 1;
579 \\ std.debug.print("incrFoo={d}\n", .{foo});
580 \\}
581 });
582
583 const b_o = addObject(b, opts, .{ .name = "b", .zig_source_bytes =
584 \\const std = @import("std");
585 \\extern var foo: i32;
586 \\export fn decrFoo() void {
587 \\ foo -= 1;
588 \\ std.debug.print("decrFoo={d}\n", .{foo});
589 \\}
590 });
591
592 const main_o = addObject(b, opts, .{ .name = "main", .zig_source_bytes =
593 \\const std = @import("std");
594 \\extern var foo: i32;
595 \\extern fn incrFoo() void;
596 \\extern fn decrFoo() void;
597 \\pub fn main() void {
598 \\ const init = foo;
599 \\ incrFoo();
600 \\ decrFoo();
601 \\ if (init == foo) @panic("Oh no!");
602 \\}
603 });
604
605 const c_o = addObject(b, opts, .{ .name = "c" });
606 c_o.addObject(a_o);
607 c_o.addObject(b_o);
608 c_o.addObject(main_o);
609
610 const exe = addExecutable(b, opts, .{ .name = "main" });
611 exe.addObject(c_o);
612
613 const run = addRunArtifact(exe);
614 run.addCheck(.{ .expect_stderr_match = b.dupe("incrFoo=1") });
615 run.addCheck(.{ .expect_stderr_match = b.dupe("decrFoo=1") });
616 run.addCheck(.{ .expect_stderr_match = b.dupe("panic: Oh no!") });
617 test_step.dependOn(&run.step);
618
619 return test_step;
620}
621
501622fn testSectionBoundarySymbols(b: *Build, opts: Options) *Step {
502623 const test_step = addTestStep(b, "macho-section-boundary-symbols", opts);
503624