| ... | @@ -10,6 +10,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { | ... | @@ -10,6 +10,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { |
| 10 | | 10 | |
| 11 | macho_step.dependOn(testDeadStrip(b, .{ .target = default_target })); | 11 | macho_step.dependOn(testDeadStrip(b, .{ .target = default_target })); |
| 12 | macho_step.dependOn(testEntryPointDylib(b, .{ .target = default_target })); | 12 | macho_step.dependOn(testEntryPointDylib(b, .{ .target = default_target })); |
| | 13 | macho_step.dependOn(testHeaderWeakFlags(b, .{ .target = default_target })); |
| 13 | macho_step.dependOn(testHelloC(b, .{ .target = default_target })); | 14 | macho_step.dependOn(testHelloC(b, .{ .target = default_target })); |
| 14 | macho_step.dependOn(testHelloZig(b, .{ .target = default_target })); | 15 | macho_step.dependOn(testHelloZig(b, .{ .target = default_target })); |
| 15 | macho_step.dependOn(testLargeBss(b, .{ .target = default_target })); | 16 | macho_step.dependOn(testLargeBss(b, .{ .target = default_target })); |
| ... | @@ -165,6 +166,94 @@ fn testEntryPointDylib(b: *Build, opts: Options) *Step { | ... | @@ -165,6 +166,94 @@ fn testEntryPointDylib(b: *Build, opts: Options) *Step { |
| 165 | return test_step; | 166 | return test_step; |
| 166 | } | 167 | } |
| 167 | | 168 | |
| | 169 | // Adapted from https://github.com/llvm/llvm-project/blob/main/lld/test/MachO/weak-header-flags.s |
| | 170 | fn testHeaderWeakFlags(b: *Build, opts: Options) *Step { |
| | 171 | const test_step = addTestStep(b, "macho-header-weak-flags", opts); |
| | 172 | |
| | 173 | const obj1 = addObject(b, opts, .{ .name = "a", .asm_source_bytes = |
| | 174 | \\.globl _x |
| | 175 | \\.weak_definition _x |
| | 176 | \\_x: |
| | 177 | \\ ret |
| | 178 | }); |
| | 179 | |
| | 180 | const lib = addSharedLibrary(b, opts, .{ .name = "a" }); |
| | 181 | lib.addObject(obj1); |
| | 182 | |
| | 183 | { |
| | 184 | const exe = addExecutable(b, opts, .{ .name = "main1", .c_source_bytes = "int main() { return 0; }" }); |
| | 185 | exe.addObject(obj1); |
| | 186 | |
| | 187 | const check = exe.checkObject(); |
| | 188 | check.checkInHeaders(); |
| | 189 | check.checkExact("header"); |
| | 190 | check.checkContains("WEAK_DEFINES"); |
| | 191 | check.checkInHeaders(); |
| | 192 | check.checkExact("header"); |
| | 193 | check.checkContains("BINDS_TO_WEAK"); |
| | 194 | check.checkInExports(); |
| | 195 | check.checkExtract("[WEAK] {vmaddr} _x"); |
| | 196 | test_step.dependOn(&check.step); |
| | 197 | } |
| | 198 | |
| | 199 | { |
| | 200 | const obj = addObject(b, opts, .{ .name = "b" }); |
| | 201 | |
| | 202 | switch (opts.target.result.cpu.arch) { |
| | 203 | .aarch64 => addAsmSourceBytes(obj, |
| | 204 | \\.globl _main |
| | 205 | \\_main: |
| | 206 | \\ bl _x |
| | 207 | \\ ret |
| | 208 | ), |
| | 209 | .x86_64 => addAsmSourceBytes(obj, |
| | 210 | \\.globl _main |
| | 211 | \\_main: |
| | 212 | \\ callq _x |
| | 213 | \\ ret |
| | 214 | ), |
| | 215 | else => unreachable, |
| | 216 | } |
| | 217 | |
| | 218 | const exe = addExecutable(b, opts, .{ .name = "main2" }); |
| | 219 | exe.linkLibrary(lib); |
| | 220 | exe.addObject(obj); |
| | 221 | |
| | 222 | const check = exe.checkObject(); |
| | 223 | check.checkInHeaders(); |
| | 224 | check.checkExact("header"); |
| | 225 | check.checkNotPresent("WEAK_DEFINES"); |
| | 226 | check.checkInHeaders(); |
| | 227 | check.checkExact("header"); |
| | 228 | check.checkContains("BINDS_TO_WEAK"); |
| | 229 | check.checkInExports(); |
| | 230 | check.checkNotPresent("[WEAK] {vmaddr} _x"); |
| | 231 | test_step.dependOn(&check.step); |
| | 232 | } |
| | 233 | |
| | 234 | { |
| | 235 | const exe = addExecutable(b, opts, .{ .name = "main3", .asm_source_bytes = |
| | 236 | \\.globl _main, _x |
| | 237 | \\_x: |
| | 238 | \\ |
| | 239 | \\_main: |
| | 240 | \\ ret |
| | 241 | }); |
| | 242 | exe.linkLibrary(lib); |
| | 243 | |
| | 244 | const check = exe.checkObject(); |
| | 245 | check.checkInHeaders(); |
| | 246 | check.checkExact("header"); |
| | 247 | check.checkNotPresent("WEAK_DEFINES"); |
| | 248 | check.checkInHeaders(); |
| | 249 | check.checkExact("header"); |
| | 250 | check.checkNotPresent("BINDS_TO_WEAK"); |
| | 251 | test_step.dependOn(&check.step); |
| | 252 | } |
| | 253 | |
| | 254 | return test_step; |
| | 255 | } |
| | 256 | |
| 168 | fn testHelloC(b: *Build, opts: Options) *Step { | 257 | fn testHelloC(b: *Build, opts: Options) *Step { |
| 169 | const test_step = addTestStep(b, "macho-hello-c", opts); | 258 | const test_step = addTestStep(b, "macho-hello-c", opts); |
| 170 | | 259 | |
| ... | @@ -436,6 +525,7 @@ fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step { | ... | @@ -436,6 +525,7 @@ fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step { |
| 436 | return link.addTestStep(b, "macho-" ++ prefix, opts); | 525 | return link.addTestStep(b, "macho-" ++ prefix, opts); |
| 437 | } | 526 | } |
| 438 | | 527 | |
| | 528 | const addAsmSourceBytes = link.addAsmSourceBytes; |
| 439 | const addCSourceBytes = link.addCSourceBytes; | 529 | const addCSourceBytes = link.addCSourceBytes; |
| 440 | const addRunArtifact = link.addRunArtifact; | 530 | const addRunArtifact = link.addRunArtifact; |
| 441 | const addObject = link.addObject; | 531 | const addObject = link.addObject; |