| ... | @@ -32,6 +32,7 @@ pub fn build(b: *Build) void { | ... | @@ -32,6 +32,7 @@ pub fn build(b: *Build) void { |
| 32 | | 32 | |
| 33 | for (&[_]CrossTarget{ glibc_target, musl_target }) |target| { | 33 | for (&[_]CrossTarget{ glibc_target, musl_target }) |target| { |
| 34 | elf_step.dependOn(testDsoPlt(b, .{ .target = target })); | 34 | elf_step.dependOn(testDsoPlt(b, .{ .target = target })); |
| | 35 | elf_step.dependOn(testDsoUndef(b, .{ .target = target })); |
| 35 | } | 36 | } |
| 36 | } | 37 | } |
| 37 | | 38 | |
| ... | @@ -171,6 +172,47 @@ fn testDsoPlt(b: *Build, opts: Options) *Step { | ... | @@ -171,6 +172,47 @@ fn testDsoPlt(b: *Build, opts: Options) *Step { |
| 171 | return test_step; | 172 | return test_step; |
| 172 | } | 173 | } |
| 173 | | 174 | |
| | 175 | fn testDsoUndef(b: *Build, opts: Options) *Step { |
| | 176 | const test_step = addTestStep(b, "dso-undef", opts); |
| | 177 | |
| | 178 | const dso = addSharedLibrary(b, opts); |
| | 179 | addCSourceBytes(dso, |
| | 180 | \\extern int foo; |
| | 181 | \\int bar = 5; |
| | 182 | \\int baz() { return foo; } |
| | 183 | , &.{"-fPIC"}); |
| | 184 | dso.is_linking_libc = true; |
| | 185 | |
| | 186 | const obj = addObject(b, opts); |
| | 187 | addCSourceBytes(obj, "int foo = 3;", &.{}); |
| | 188 | |
| | 189 | const lib = addStaticLibrary(b, opts); |
| | 190 | lib.addObject(obj); |
| | 191 | |
| | 192 | const exe = addExecutable(b, opts); |
| | 193 | exe.linkLibrary(dso); |
| | 194 | exe.linkLibrary(lib); |
| | 195 | addCSourceBytes(exe, |
| | 196 | \\extern int bar; |
| | 197 | \\int main() { |
| | 198 | \\ return bar - 5; |
| | 199 | \\} |
| | 200 | , &.{}); |
| | 201 | exe.is_linking_libc = true; |
| | 202 | exe.verbose_link = true; |
| | 203 | |
| | 204 | const run = addRunArtifact(exe); |
| | 205 | run.expectExitCode(0); |
| | 206 | test_step.dependOn(&run.step); |
| | 207 | |
| | 208 | const check = exe.checkObject(); |
| | 209 | check.checkInDynamicSymtab(); |
| | 210 | check.checkContains("foo"); |
| | 211 | test_step.dependOn(&check.step); |
| | 212 | |
| | 213 | return test_step; |
| | 214 | } |
| | 215 | |
| 174 | fn testEmptyObject(b: *Build, opts: Options) *Step { | 216 | fn testEmptyObject(b: *Build, opts: Options) *Step { |
| 175 | const test_step = addTestStep(b, "empty-object", opts); | 217 | const test_step = addTestStep(b, "empty-object", opts); |
| 176 | | 218 | |
| ... | @@ -422,7 +464,7 @@ fn addExecutable(b: *Build, opts: Options) *Compile { | ... | @@ -422,7 +464,7 @@ fn addExecutable(b: *Build, opts: Options) *Compile { |
| 422 | | 464 | |
| 423 | fn addObject(b: *Build, opts: Options) *Compile { | 465 | fn addObject(b: *Build, opts: Options) *Compile { |
| 424 | return b.addObject(.{ | 466 | return b.addObject(.{ |
| 425 | .name = "a.o", | 467 | .name = "a", |
| 426 | .target = opts.target, | 468 | .target = opts.target, |
| 427 | .optimize = opts.optimize, | 469 | .optimize = opts.optimize, |
| 428 | .use_llvm = opts.use_llvm, | 470 | .use_llvm = opts.use_llvm, |
| ... | @@ -432,7 +474,7 @@ fn addObject(b: *Build, opts: Options) *Compile { | ... | @@ -432,7 +474,7 @@ fn addObject(b: *Build, opts: Options) *Compile { |
| 432 | | 474 | |
| 433 | fn addStaticLibrary(b: *Build, opts: Options) *Compile { | 475 | fn addStaticLibrary(b: *Build, opts: Options) *Compile { |
| 434 | return b.addStaticLibrary(.{ | 476 | return b.addStaticLibrary(.{ |
| 435 | .name = "a.a", | 477 | .name = "a", |
| 436 | .target = opts.target, | 478 | .target = opts.target, |
| 437 | .optimize = opts.optimize, | 479 | .optimize = opts.optimize, |
| 438 | .use_llvm = opts.use_llvm, | 480 | .use_llvm = opts.use_llvm, |
| ... | @@ -442,7 +484,7 @@ fn addStaticLibrary(b: *Build, opts: Options) *Compile { | ... | @@ -442,7 +484,7 @@ fn addStaticLibrary(b: *Build, opts: Options) *Compile { |
| 442 | | 484 | |
| 443 | fn addSharedLibrary(b: *Build, opts: Options) *Compile { | 485 | fn addSharedLibrary(b: *Build, opts: Options) *Compile { |
| 444 | return b.addSharedLibrary(.{ | 486 | return b.addSharedLibrary(.{ |
| 445 | .name = "a.so", | 487 | .name = "a", |
| 446 | .target = opts.target, | 488 | .target = opts.target, |
| 447 | .optimize = opts.optimize, | 489 | .optimize = opts.optimize, |
| 448 | .use_llvm = opts.use_llvm, | 490 | .use_llvm = opts.use_llvm, |
| ... | @@ -457,28 +499,29 @@ fn addRunArtifact(comp: *Compile) *Run { | ... | @@ -457,28 +499,29 @@ fn addRunArtifact(comp: *Compile) *Run { |
| 457 | return run; | 499 | return run; |
| 458 | } | 500 | } |
| 459 | | 501 | |
| 460 | fn addZigSourceBytes(comp: *Compile, comptime bytes: []const u8) void { | 502 | fn addZigSourceBytes(comp: *Compile, bytes: []const u8) void { |
| 461 | const b = comp.step.owner; | 503 | const b = comp.step.owner; |
| 462 | const file = WriteFile.create(b).add("a.zig", bytes); | 504 | const file = WriteFile.create(b).add("a.zig", bytes); |
| 463 | file.addStepDependencies(&comp.step); | 505 | file.addStepDependencies(&comp.step); |
| 464 | comp.root_src = file; | 506 | comp.root_src = file; |
| 465 | } | 507 | } |
| 466 | | 508 | |
| 467 | fn addCSourceBytes(comp: *Compile, comptime bytes: []const u8, flags: []const []const u8) void { | 509 | fn addCSourceBytes(comp: *Compile, bytes: []const u8, flags: []const []const u8) void { |
| 468 | const b = comp.step.owner; | 510 | const b = comp.step.owner; |
| 469 | const file = WriteFile.create(b).add("a.c", bytes); | 511 | const file = WriteFile.create(b).add("a.c", bytes); |
| 470 | comp.addCSourceFile(.{ .file = file, .flags = flags }); | 512 | comp.addCSourceFile(.{ .file = file, .flags = flags }); |
| 471 | } | 513 | } |
| 472 | | 514 | |
| 473 | fn addCppSourceBytes(comp: *Compile, comptime bytes: []const u8, flags: []const []const u8) void { | 515 | fn addCppSourceBytes(comp: *Compile, bytes: []const u8, flags: []const []const u8) void { |
| 474 | const b = comp.step.owner; | 516 | const b = comp.step.owner; |
| 475 | const file = WriteFile.create(b).add("a.cpp", bytes); | 517 | const file = WriteFile.create(b).add("a.cpp", bytes); |
| 476 | comp.addCSourceFile(.{ .file = file, .flags = flags }); | 518 | comp.addCSourceFile(.{ .file = file, .flags = flags }); |
| 477 | } | 519 | } |
| 478 | | 520 | |
| 479 | fn addAsmSourceBytes(comp: *Compile, comptime bytes: []const u8) void { | 521 | fn addAsmSourceBytes(comp: *Compile, bytes: []const u8) void { |
| 480 | const b = comp.step.owner; | 522 | const b = comp.step.owner; |
| 481 | const file = WriteFile.create(b).add("a.s", bytes ++ "\n"); | 523 | const actual_bytes = std.fmt.allocPrint(b.allocator, "{s}\n", .{bytes}) catch @panic("OOM"); |
| | 524 | const file = WriteFile.create(b).add("a.s", actual_bytes); |
| 482 | comp.addAssemblyFile(file); | 525 | comp.addAssemblyFile(file); |
| 483 | } | 526 | } |
| 484 | | 527 | |