| ... | ... | @@ -53,6 +53,8 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { |
| 53 | 53 | macho_step.dependOn(testHeaderpad(b, .{ .target = b.host })); |
| 54 | 54 | macho_step.dependOn(testNeededFramework(b, .{ .target = b.host })); |
| 55 | 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 | 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 | 291 | exe.root_module.addLibraryPath(lib.getEmittedBinDirectory()); |
| 290 | 292 | |
| 291 | 293 | const run = addRunArtifact(exe); |
| 294 | run.expectExitCode(0); |
| 292 | 295 | test_step.dependOn(&run.step); |
| 293 | 296 | } |
| 294 | 297 | |
| ... | ... | @@ -299,6 +302,7 @@ fn testEntryPointArchive(b: *Build, opts: Options) *Step { |
| 299 | 302 | exe.link_gc_sections = true; |
| 300 | 303 | |
| 301 | 304 | const run = addRunArtifact(exe); |
| 305 | run.expectExitCode(0); |
| 302 | 306 | test_step.dependOn(&run.step); |
| 303 | 307 | } |
| 304 | 308 | |
| ... | ... | @@ -769,6 +773,7 @@ fn testNoDeadStrip(b: *Build, opts: Options) *Step { |
| 769 | 773 | test_step.dependOn(&check.step); |
| 770 | 774 | |
| 771 | 775 | const run = addRunArtifact(exe); |
| 776 | run.expectExitCode(0); |
| 772 | 777 | test_step.dependOn(&run.step); |
| 773 | 778 | |
| 774 | 779 | return test_step; |
| ... | ... | @@ -859,6 +864,155 @@ fn testObjc(b: *Build, opts: Options) *Step { |
| 859 | 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 | 1016 | fn testRelocatable(b: *Build, opts: Options) *Step { |
| 863 | 1017 | const test_step = addTestStep(b, "macho-relocatable", opts); |
| 864 | 1018 | |
| ... | ... | @@ -1647,3 +1801,4 @@ const BuildOptions = link.BuildOptions; |
| 1647 | 1801 | const Compile = Step.Compile; |
| 1648 | 1802 | const Options = link.Options; |
| 1649 | 1803 | const Step = Build.Step; |
| 1804 | const WriteFile = Step.WriteFile; |