| ... | ... | @@ -29,6 +29,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { |
| 29 | 29 | if (build_opts.has_symlinks_windows) { |
| 30 | 30 | macho_step.dependOn(testNeededLibrary(b, .{ .target = default_target })); |
| 31 | 31 | macho_step.dependOn(testWeakLibrary(b, .{ .target = default_target })); |
| 32 | macho_step.dependOn(testTwoLevelNamespace(b, .{ .target = default_target })); |
| 32 | 33 | |
| 33 | 34 | // Tests requiring presence of macOS SDK in system path |
| 34 | 35 | if (build_opts.has_macos_sdk) { |
| ... | ... | @@ -659,6 +660,126 @@ fn testTlsLargeTbss(b: *Build, opts: Options) *Step { |
| 659 | 660 | return test_step; |
| 660 | 661 | } |
| 661 | 662 | |
| 663 | fn testTwoLevelNamespace(b: *Build, opts: Options) *Step { |
| 664 | const test_step = addTestStep(b, "macho-two-level-namespace", opts); |
| 665 | |
| 666 | const liba = addSharedLibrary(b, opts, .{ .name = "a", .c_source_bytes = |
| 667 | \\#include <stdio.h> |
| 668 | \\int foo = 1; |
| 669 | \\int* ptr_to_foo = &foo; |
| 670 | \\int getFoo() { |
| 671 | \\ return foo; |
| 672 | \\} |
| 673 | \\void printInA() { |
| 674 | \\ printf("liba: getFoo()=%d, ptr_to_foo=%d\n", getFoo(), *ptr_to_foo); |
| 675 | \\} |
| 676 | }); |
| 677 | |
| 678 | { |
| 679 | const check = liba.checkObject(); |
| 680 | check.checkInDyldLazyBind(); |
| 681 | check.checkNotPresent("(flat lookup) _getFoo"); |
| 682 | check.checkInIndirectSymtab(); |
| 683 | check.checkNotPresent("_getFoo"); |
| 684 | test_step.dependOn(&check.step); |
| 685 | } |
| 686 | |
| 687 | const libb = addSharedLibrary(b, opts, .{ .name = "b", .c_source_bytes = |
| 688 | \\#include <stdio.h> |
| 689 | \\int foo = 2; |
| 690 | \\int* ptr_to_foo = &foo; |
| 691 | \\int getFoo() { |
| 692 | \\ return foo; |
| 693 | \\} |
| 694 | \\void printInB() { |
| 695 | \\ printf("libb: getFoo()=%d, ptr_to_foo=%d\n", getFoo(), *ptr_to_foo); |
| 696 | \\} |
| 697 | }); |
| 698 | |
| 699 | { |
| 700 | const check = libb.checkObject(); |
| 701 | check.checkInDyldLazyBind(); |
| 702 | check.checkNotPresent("(flat lookup) _getFoo"); |
| 703 | check.checkInIndirectSymtab(); |
| 704 | check.checkNotPresent("_getFoo"); |
| 705 | test_step.dependOn(&check.step); |
| 706 | } |
| 707 | |
| 708 | const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = |
| 709 | \\#include <stdio.h> |
| 710 | \\int getFoo(); |
| 711 | \\extern int* ptr_to_foo; |
| 712 | \\void printInA(); |
| 713 | \\void printInB(); |
| 714 | \\int main() { |
| 715 | \\ printf("main: getFoo()=%d, ptr_to_foo=%d\n", getFoo(), *ptr_to_foo); |
| 716 | \\ printInA(); |
| 717 | \\ printInB(); |
| 718 | \\ return 0; |
| 719 | \\} |
| 720 | }); |
| 721 | |
| 722 | { |
| 723 | const exe = addExecutable(b, opts, .{ .name = "main1" }); |
| 724 | exe.addObject(main_o); |
| 725 | exe.root_module.linkSystemLibrary("a", .{}); |
| 726 | exe.root_module.linkSystemLibrary("b", .{}); |
| 727 | exe.addLibraryPath(liba.getEmittedBinDirectory()); |
| 728 | exe.addLibraryPath(libb.getEmittedBinDirectory()); |
| 729 | exe.addRPath(liba.getEmittedBinDirectory()); |
| 730 | exe.addRPath(libb.getEmittedBinDirectory()); |
| 731 | |
| 732 | const check = exe.checkObject(); |
| 733 | check.checkInSymtab(); |
| 734 | check.checkExact("(undefined) external _getFoo (from liba)"); |
| 735 | check.checkInSymtab(); |
| 736 | check.checkExact("(undefined) external _printInA (from liba)"); |
| 737 | check.checkInSymtab(); |
| 738 | check.checkExact("(undefined) external _printInB (from libb)"); |
| 739 | test_step.dependOn(&check.step); |
| 740 | |
| 741 | const run = addRunArtifact(exe); |
| 742 | run.expectStdOutEqual( |
| 743 | \\main: getFoo()=1, ptr_to_foo=1 |
| 744 | \\liba: getFoo()=1, ptr_to_foo=1 |
| 745 | \\libb: getFoo()=2, ptr_to_foo=2 |
| 746 | \\ |
| 747 | ); |
| 748 | test_step.dependOn(&run.step); |
| 749 | } |
| 750 | |
| 751 | { |
| 752 | const exe = addExecutable(b, opts, .{ .name = "main2" }); |
| 753 | exe.addObject(main_o); |
| 754 | exe.root_module.linkSystemLibrary("b", .{}); |
| 755 | exe.root_module.linkSystemLibrary("a", .{}); |
| 756 | exe.addLibraryPath(liba.getEmittedBinDirectory()); |
| 757 | exe.addLibraryPath(libb.getEmittedBinDirectory()); |
| 758 | exe.addRPath(liba.getEmittedBinDirectory()); |
| 759 | exe.addRPath(libb.getEmittedBinDirectory()); |
| 760 | |
| 761 | const check = exe.checkObject(); |
| 762 | check.checkInSymtab(); |
| 763 | check.checkExact("(undefined) external _getFoo (from libb)"); |
| 764 | check.checkInSymtab(); |
| 765 | check.checkExact("(undefined) external _printInA (from liba)"); |
| 766 | check.checkInSymtab(); |
| 767 | check.checkExact("(undefined) external _printInB (from libb)"); |
| 768 | test_step.dependOn(&check.step); |
| 769 | |
| 770 | const run = addRunArtifact(exe); |
| 771 | run.expectStdOutEqual( |
| 772 | \\main: getFoo()=2, ptr_to_foo=2 |
| 773 | \\liba: getFoo()=1, ptr_to_foo=1 |
| 774 | \\libb: getFoo()=2, ptr_to_foo=2 |
| 775 | \\ |
| 776 | ); |
| 777 | test_step.dependOn(&run.step); |
| 778 | } |
| 779 | |
| 780 | return test_step; |
| 781 | } |
| 782 | |
| 662 | 783 | fn testUndefinedFlag(b: *Build, opts: Options) *Step { |
| 663 | 784 | const test_step = addTestStep(b, "macho-undefined-flag", opts); |
| 664 | 785 | |