| ... | @@ -53,6 +53,8 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { | ... | @@ -53,6 +53,8 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { |
| 53 | macho_step.dependOn(testHeaderpad(b, .{ .target = b.host })); | 53 | macho_step.dependOn(testHeaderpad(b, .{ .target = b.host })); |
| 54 | macho_step.dependOn(testNeededFramework(b, .{ .target = b.host })); | 54 | macho_step.dependOn(testNeededFramework(b, .{ .target = b.host })); |
| 55 | macho_step.dependOn(testObjc(b, .{ .target = b.host })); | 55 | macho_step.dependOn(testObjc(b, .{ .target = b.host })); |
| | 56 | macho_step.dependOn(testObjcStubs(b, .{ .target = b.host })); |
| | 57 | macho_step.dependOn(testObjcStubs2(b, .{ .target = b.host })); |
| 56 | macho_step.dependOn(testWeakFramework(b, .{ .target = b.host })); | 58 | macho_step.dependOn(testWeakFramework(b, .{ .target = b.host })); |
| 57 | } | 59 | } |
| 58 | } | 60 | } |
| ... | @@ -289,6 +291,7 @@ fn testEntryPointArchive(b: *Build, opts: Options) *Step { | ... | @@ -289,6 +291,7 @@ fn testEntryPointArchive(b: *Build, opts: Options) *Step { |
| 289 | exe.root_module.addLibraryPath(lib.getEmittedBinDirectory()); | 291 | exe.root_module.addLibraryPath(lib.getEmittedBinDirectory()); |
| 290 | | 292 | |
| 291 | const run = addRunArtifact(exe); | 293 | const run = addRunArtifact(exe); |
| | 294 | run.expectExitCode(0); |
| 292 | test_step.dependOn(&run.step); | 295 | test_step.dependOn(&run.step); |
| 293 | } | 296 | } |
| 294 | | 297 | |
| ... | @@ -299,6 +302,7 @@ fn testEntryPointArchive(b: *Build, opts: Options) *Step { | ... | @@ -299,6 +302,7 @@ fn testEntryPointArchive(b: *Build, opts: Options) *Step { |
| 299 | exe.link_gc_sections = true; | 302 | exe.link_gc_sections = true; |
| 300 | | 303 | |
| 301 | const run = addRunArtifact(exe); | 304 | const run = addRunArtifact(exe); |
| | 305 | run.expectExitCode(0); |
| 302 | test_step.dependOn(&run.step); | 306 | test_step.dependOn(&run.step); |
| 303 | } | 307 | } |
| 304 | | 308 | |
| ... | @@ -769,6 +773,7 @@ fn testNoDeadStrip(b: *Build, opts: Options) *Step { | ... | @@ -769,6 +773,7 @@ fn testNoDeadStrip(b: *Build, opts: Options) *Step { |
| 769 | test_step.dependOn(&check.step); | 773 | test_step.dependOn(&check.step); |
| 770 | | 774 | |
| 771 | const run = addRunArtifact(exe); | 775 | const run = addRunArtifact(exe); |
| | 776 | run.expectExitCode(0); |
| 772 | test_step.dependOn(&run.step); | 777 | test_step.dependOn(&run.step); |
| 773 | | 778 | |
| 774 | return test_step; | 779 | return test_step; |
| ... | @@ -859,6 +864,155 @@ fn testObjc(b: *Build, opts: Options) *Step { | ... | @@ -859,6 +864,155 @@ fn testObjc(b: *Build, opts: Options) *Step { |
| 859 | return test_step; | 864 | return test_step; |
| 860 | } | 865 | } |
| 861 | | 866 | |
| | 867 | fn testObjcStubs(b: *Build, opts: Options) *Step { |
| | 868 | const test_step = addTestStep(b, "macho-objc-stubs", opts); |
| | 869 | |
| | 870 | const exe = addExecutable(b, opts, .{ |
| | 871 | .name = "main", |
| | 872 | .objc_source_bytes = |
| | 873 | \\@import Foundation; |
| | 874 | \\@interface Foo : NSObject |
| | 875 | \\@property (nonatomic, assign) NSString* name; |
| | 876 | \\@end |
| | 877 | \\@implementation Foo |
| | 878 | \\- (void)bar { |
| | 879 | \\ printf("%s", [self.name UTF8String]); |
| | 880 | \\} |
| | 881 | \\@end |
| | 882 | \\int main() { |
| | 883 | \\ Foo *foo = [[Foo alloc] init]; |
| | 884 | \\ foo.name = @"Foo"; |
| | 885 | \\ [foo bar]; |
| | 886 | \\ return 0; |
| | 887 | \\} |
| | 888 | , |
| | 889 | .objc_source_flags = &.{ "-fmodules", "-fobjc-msgsend-selector-stubs" }, |
| | 890 | }); |
| | 891 | exe.root_module.linkFramework("Foundation", .{}); |
| | 892 | |
| | 893 | const run = addRunArtifact(exe); |
| | 894 | run.expectStdOutEqual("Foo"); |
| | 895 | test_step.dependOn(&run.step); |
| | 896 | |
| | 897 | const check = exe.checkObject(); |
| | 898 | check.checkInHeaders(); |
| | 899 | check.checkExact("sectname __objc_stubs"); |
| | 900 | check.checkInHeaders(); |
| | 901 | check.checkExact("sectname __objc_methname"); |
| | 902 | check.checkInHeaders(); |
| | 903 | check.checkExact("sectname __objc_selrefs"); |
| | 904 | check.checkInSymtab(); |
| | 905 | check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$bar"); |
| | 906 | check.checkInSymtab(); |
| | 907 | check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$name"); |
| | 908 | check.checkInSymtab(); |
| | 909 | check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$setName"); |
| | 910 | test_step.dependOn(&check.step); |
| | 911 | |
| | 912 | return test_step; |
| | 913 | } |
| | 914 | |
| | 915 | fn testObjcStubs2(b: *Build, opts: Options) *Step { |
| | 916 | const test_step = addTestStep(b, "macho-objc-stubs-2", opts); |
| | 917 | |
| | 918 | const all_h = all_h: { |
| | 919 | const wf = WriteFile.create(b); |
| | 920 | break :all_h wf.add("all.h", |
| | 921 | \\#import <Foundation/Foundation.h> |
| | 922 | \\ |
| | 923 | \\@interface Foo : NSObject |
| | 924 | \\@property (nonatomic, assign) NSString* name; |
| | 925 | \\- (void) foo; |
| | 926 | \\@end |
| | 927 | \\@interface Bar : NSObject |
| | 928 | \\@property (nonatomic, assign) NSString* name; |
| | 929 | \\- (void) bar; |
| | 930 | \\- (void) foobar: (Foo*) foo; |
| | 931 | \\@end |
| | 932 | ); |
| | 933 | }; |
| | 934 | |
| | 935 | const foo_o = addObject(b, opts, .{ |
| | 936 | .name = "foo", |
| | 937 | .objc_source_bytes = |
| | 938 | \\#import <Foundation/Foundation.h> |
| | 939 | \\#import "all.h" |
| | 940 | \\@implementation Foo |
| | 941 | \\- (void)foo { |
| | 942 | \\ printf("%s", [self.name UTF8String]); |
| | 943 | \\} |
| | 944 | \\@end |
| | 945 | , |
| | 946 | .objc_source_flags = &.{"-fobjc-msgsend-selector-stubs"}, |
| | 947 | }); |
| | 948 | foo_o.root_module.addIncludePath(all_h.dirname()); |
| | 949 | |
| | 950 | const bar_o = addObject(b, opts, .{ |
| | 951 | .name = "bar", |
| | 952 | .objc_source_bytes = |
| | 953 | \\#import <Foundation/Foundation.h> |
| | 954 | \\#import "all.h" |
| | 955 | \\@implementation Bar |
| | 956 | \\- (void)bar { |
| | 957 | \\ printf("%s", [self.name UTF8String]); |
| | 958 | \\} |
| | 959 | \\- (void)foobar: (Foo*) foo { |
| | 960 | \\ printf("%s%s", [foo.name UTF8String], [self.name UTF8String]); |
| | 961 | \\} |
| | 962 | \\@end |
| | 963 | , |
| | 964 | .objc_source_flags = &.{"-fobjc-msgsend-selector-stubs"}, |
| | 965 | }); |
| | 966 | bar_o.root_module.addIncludePath(all_h.dirname()); |
| | 967 | |
| | 968 | const main_o = addObject(b, opts, .{ |
| | 969 | .name = "main", |
| | 970 | .objc_source_bytes = |
| | 971 | \\#import <Foundation/Foundation.h> |
| | 972 | \\#import "all.h" |
| | 973 | \\int main() { |
| | 974 | \\ Foo *foo = [[Foo alloc] init]; |
| | 975 | \\ foo.name = @"Foo"; |
| | 976 | \\ Bar *bar = [[Bar alloc] init]; |
| | 977 | \\ bar.name = @"Bar"; |
| | 978 | \\ [foo foo]; |
| | 979 | \\ [bar bar]; |
| | 980 | \\ [bar foobar:foo]; |
| | 981 | \\ return 0; |
| | 982 | \\} |
| | 983 | , |
| | 984 | .objc_source_flags = &.{"-fobjc-msgsend-selector-stubs"}, |
| | 985 | }); |
| | 986 | main_o.root_module.addIncludePath(all_h.dirname()); |
| | 987 | |
| | 988 | const exe = addExecutable(b, opts, .{ .name = "main" }); |
| | 989 | exe.addObject(main_o); |
| | 990 | exe.addObject(foo_o); |
| | 991 | exe.addObject(bar_o); |
| | 992 | exe.root_module.linkFramework("Foundation", .{}); |
| | 993 | |
| | 994 | const run = addRunArtifact(exe); |
| | 995 | run.expectStdOutEqual("FooBarFooBar"); |
| | 996 | test_step.dependOn(&run.step); |
| | 997 | |
| | 998 | const check = exe.checkObject(); |
| | 999 | check.checkInHeaders(); |
| | 1000 | check.checkExact("sectname __objc_stubs"); |
| | 1001 | check.checkInHeaders(); |
| | 1002 | check.checkExact("sectname __objc_methname"); |
| | 1003 | check.checkInHeaders(); |
| | 1004 | check.checkExact("sectname __objc_selrefs"); |
| | 1005 | check.checkInSymtab(); |
| | 1006 | check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$foo"); |
| | 1007 | check.checkInSymtab(); |
| | 1008 | check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$bar"); |
| | 1009 | check.checkInSymtab(); |
| | 1010 | check.checkContains("(__TEXT,__objc_stubs) (was private external) _objc_msgSend$foobar"); |
| | 1011 | test_step.dependOn(&check.step); |
| | 1012 | |
| | 1013 | return test_step; |
| | 1014 | } |
| | 1015 | |
| 862 | fn testRelocatable(b: *Build, opts: Options) *Step { | 1016 | fn testRelocatable(b: *Build, opts: Options) *Step { |
| 863 | const test_step = addTestStep(b, "macho-relocatable", opts); | 1017 | const test_step = addTestStep(b, "macho-relocatable", opts); |
| 864 | | 1018 | |
| ... | @@ -1647,3 +1801,4 @@ const BuildOptions = link.BuildOptions; | ... | @@ -1647,3 +1801,4 @@ const BuildOptions = link.BuildOptions; |
| 1647 | const Compile = Step.Compile; | 1801 | const Compile = Step.Compile; |
| 1648 | const Options = link.Options; | 1802 | const Options = link.Options; |
| 1649 | const Step = Build.Step; | 1803 | const Step = Build.Step; |
| | 1804 | const WriteFile = Step.WriteFile; |