| ... | ... | @@ -40,6 +40,7 @@ pub fn build(b: *Build) void { |
| 40 | 40 | elf_step.dependOn(testLinkingZig(b, .{ .target = musl_target })); |
| 41 | 41 | elf_step.dependOn(testTlsStatic(b, .{ .target = musl_target })); |
| 42 | 42 | |
| 43 | elf_step.dependOn(testAsNeeded(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker })); |
| 43 | 44 | elf_step.dependOn(testDsoPlt(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker })); |
| 44 | 45 | elf_step.dependOn(testDsoUndef(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker })); |
| 45 | 46 | elf_step.dependOn(testLargeAlignmentDso(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker })); |
| ... | ... | @@ -49,10 +50,92 @@ pub fn build(b: *Build) void { |
| 49 | 50 | } |
| 50 | 51 | } |
| 51 | 52 | |
| 53 | fn testAsNeeded(b: *Build, opts: Options) *Step { |
| 54 | const test_step = addTestStep(b, "as-needed", opts); |
| 55 | |
| 56 | const main_o = addObject(b, "main", opts); |
| 57 | addCSourceBytes(main_o, |
| 58 | \\#include <stdio.h> |
| 59 | \\int baz(); |
| 60 | \\int main() { |
| 61 | \\ printf("%d\n", baz()); |
| 62 | \\ return 0; |
| 63 | \\} |
| 64 | , &.{}); |
| 65 | main_o.is_linking_libc = true; |
| 66 | |
| 67 | const libfoo = addSharedLibrary(b, "foo", opts); |
| 68 | addCSourceBytes(libfoo, "int foo() { return 42; }", &.{"-fPIC"}); |
| 69 | |
| 70 | const libbar = addSharedLibrary(b, "bar", opts); |
| 71 | addCSourceBytes(libbar, "int bar() { return 42; }", &.{"-fPIC"}); |
| 72 | |
| 73 | const libbaz = addSharedLibrary(b, "baz", opts); |
| 74 | addCSourceBytes(libbaz, |
| 75 | \\int foo(); |
| 76 | \\int baz() { return foo(); } |
| 77 | , &.{"-fPIC"}); |
| 78 | |
| 79 | { |
| 80 | const exe = addExecutable(b, "test", opts); |
| 81 | exe.addObject(main_o); |
| 82 | exe.linkSystemLibrary2("foo", .{ .needed = true }); |
| 83 | exe.addLibraryPath(libfoo.getEmittedBinDirectory()); |
| 84 | exe.addRPath(libfoo.getEmittedBinDirectory()); |
| 85 | exe.linkSystemLibrary2("bar", .{ .needed = true }); |
| 86 | exe.addLibraryPath(libbar.getEmittedBinDirectory()); |
| 87 | exe.addRPath(libbar.getEmittedBinDirectory()); |
| 88 | exe.linkSystemLibrary2("baz", .{ .needed = true }); |
| 89 | exe.addLibraryPath(libbaz.getEmittedBinDirectory()); |
| 90 | exe.addRPath(libbaz.getEmittedBinDirectory()); |
| 91 | exe.is_linking_libc = true; |
| 92 | |
| 93 | const run = addRunArtifact(exe); |
| 94 | run.expectStdOutEqual("42\n"); |
| 95 | test_step.dependOn(&run.step); |
| 96 | |
| 97 | const check = exe.checkObject(); |
| 98 | check.checkInDynamicSection(); |
| 99 | check.checkExact("NEEDED libfoo.so"); |
| 100 | check.checkExact("NEEDED libbar.so"); |
| 101 | check.checkExact("NEEDED libbaz.so"); |
| 102 | test_step.dependOn(&check.step); |
| 103 | } |
| 104 | |
| 105 | { |
| 106 | const exe = addExecutable(b, "test", opts); |
| 107 | exe.addObject(main_o); |
| 108 | exe.linkSystemLibrary2("foo", .{ .needed = false }); |
| 109 | exe.addLibraryPath(libfoo.getEmittedBinDirectory()); |
| 110 | exe.addRPath(libfoo.getEmittedBinDirectory()); |
| 111 | exe.linkSystemLibrary2("bar", .{ .needed = false }); |
| 112 | exe.addLibraryPath(libbar.getEmittedBinDirectory()); |
| 113 | exe.addRPath(libbar.getEmittedBinDirectory()); |
| 114 | exe.linkSystemLibrary2("baz", .{ .needed = false }); |
| 115 | exe.addLibraryPath(libbaz.getEmittedBinDirectory()); |
| 116 | exe.addRPath(libbaz.getEmittedBinDirectory()); |
| 117 | exe.is_linking_libc = true; |
| 118 | |
| 119 | const run = addRunArtifact(exe); |
| 120 | run.expectStdOutEqual("42\n"); |
| 121 | test_step.dependOn(&run.step); |
| 122 | |
| 123 | const check = exe.checkObject(); |
| 124 | check.checkInDynamicSection(); |
| 125 | check.checkNotPresent("NEEDED libbar.so"); |
| 126 | check.checkInDynamicSection(); |
| 127 | check.checkExact("NEEDED libfoo.so"); |
| 128 | check.checkExact("NEEDED libbaz.so"); |
| 129 | test_step.dependOn(&check.step); |
| 130 | } |
| 131 | |
| 132 | return test_step; |
| 133 | } |
| 134 | |
| 52 | 135 | fn testCommonSymbols(b: *Build, opts: Options) *Step { |
| 53 | 136 | const test_step = addTestStep(b, "common-symbols", opts); |
| 54 | 137 | |
| 55 | | const exe = addExecutable(b, opts); |
| 138 | const exe = addExecutable(b, "test", opts); |
| 56 | 139 | addCSourceBytes(exe, |
| 57 | 140 | \\int foo; |
| 58 | 141 | \\int bar; |
| ... | ... | @@ -79,7 +162,7 @@ fn testCommonSymbols(b: *Build, opts: Options) *Step { |
| 79 | 162 | fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { |
| 80 | 163 | const test_step = addTestStep(b, "common-symbols-in-archive", opts); |
| 81 | 164 | |
| 82 | | const a_o = addObject(b, opts); |
| 165 | const a_o = addObject(b, "a", opts); |
| 83 | 166 | addCSourceBytes(a_o, |
| 84 | 167 | \\#include <stdio.h> |
| 85 | 168 | \\int foo; |
| ... | ... | @@ -92,25 +175,25 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { |
| 92 | 175 | , &.{"-fcommon"}); |
| 93 | 176 | a_o.is_linking_libc = true; |
| 94 | 177 | |
| 95 | | const b_o = addObject(b, opts); |
| 178 | const b_o = addObject(b, "b", opts); |
| 96 | 179 | addCSourceBytes(b_o, "int foo = 5;", &.{"-fcommon"}); |
| 97 | 180 | |
| 98 | 181 | { |
| 99 | | const c_o = addObject(b, opts); |
| 182 | const c_o = addObject(b, "c", opts); |
| 100 | 183 | addCSourceBytes(c_o, |
| 101 | 184 | \\int bar; |
| 102 | 185 | \\int two() { return 2; } |
| 103 | 186 | , &.{"-fcommon"}); |
| 104 | 187 | |
| 105 | | const d_o = addObject(b, opts); |
| 188 | const d_o = addObject(b, "d", opts); |
| 106 | 189 | addCSourceBytes(d_o, "int baz;", &.{"-fcommon"}); |
| 107 | 190 | |
| 108 | | const lib = addStaticLibrary(b, opts); |
| 191 | const lib = addStaticLibrary(b, "lib", opts); |
| 109 | 192 | lib.addObject(b_o); |
| 110 | 193 | lib.addObject(c_o); |
| 111 | 194 | lib.addObject(d_o); |
| 112 | 195 | |
| 113 | | const exe = addExecutable(b, opts); |
| 196 | const exe = addExecutable(b, "test", opts); |
| 114 | 197 | exe.addObject(a_o); |
| 115 | 198 | exe.linkLibrary(lib); |
| 116 | 199 | exe.is_linking_libc = true; |
| ... | ... | @@ -121,18 +204,18 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { |
| 121 | 204 | } |
| 122 | 205 | |
| 123 | 206 | { |
| 124 | | const e_o = addObject(b, opts); |
| 207 | const e_o = addObject(b, "e", opts); |
| 125 | 208 | addCSourceBytes(e_o, |
| 126 | 209 | \\int bar = 0; |
| 127 | 210 | \\int baz = 7; |
| 128 | 211 | \\int two() { return 2; } |
| 129 | 212 | , &.{"-fcommon"}); |
| 130 | 213 | |
| 131 | | const lib = addStaticLibrary(b, opts); |
| 214 | const lib = addStaticLibrary(b, "lib", opts); |
| 132 | 215 | lib.addObject(b_o); |
| 133 | 216 | lib.addObject(e_o); |
| 134 | 217 | |
| 135 | | const exe = addExecutable(b, opts); |
| 218 | const exe = addExecutable(b, "test", opts); |
| 136 | 219 | exe.addObject(a_o); |
| 137 | 220 | exe.linkLibrary(lib); |
| 138 | 221 | exe.is_linking_libc = true; |
| ... | ... | @@ -148,7 +231,7 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { |
| 148 | 231 | fn testDsoPlt(b: *Build, opts: Options) *Step { |
| 149 | 232 | const test_step = addTestStep(b, "dso-plt", opts); |
| 150 | 233 | |
| 151 | | const dso = addSharedLibrary(b, opts); |
| 234 | const dso = addSharedLibrary(b, "dso", opts); |
| 152 | 235 | addCSourceBytes(dso, |
| 153 | 236 | \\#include<stdio.h> |
| 154 | 237 | \\void world() { |
| ... | ... | @@ -164,7 +247,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step { |
| 164 | 247 | , &.{"-fPIC"}); |
| 165 | 248 | dso.is_linking_libc = true; |
| 166 | 249 | |
| 167 | | const exe = addExecutable(b, opts); |
| 250 | const exe = addExecutable(b, "test", opts); |
| 168 | 251 | addCSourceBytes(exe, |
| 169 | 252 | \\#include<stdio.h> |
| 170 | 253 | \\void world() { |
| ... | ... | @@ -188,7 +271,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step { |
| 188 | 271 | fn testDsoUndef(b: *Build, opts: Options) *Step { |
| 189 | 272 | const test_step = addTestStep(b, "dso-undef", opts); |
| 190 | 273 | |
| 191 | | const dso = addSharedLibrary(b, opts); |
| 274 | const dso = addSharedLibrary(b, "dso", opts); |
| 192 | 275 | addCSourceBytes(dso, |
| 193 | 276 | \\extern int foo; |
| 194 | 277 | \\int bar = 5; |
| ... | ... | @@ -196,13 +279,13 @@ fn testDsoUndef(b: *Build, opts: Options) *Step { |
| 196 | 279 | , &.{"-fPIC"}); |
| 197 | 280 | dso.is_linking_libc = true; |
| 198 | 281 | |
| 199 | | const obj = addObject(b, opts); |
| 282 | const obj = addObject(b, "obj", opts); |
| 200 | 283 | addCSourceBytes(obj, "int foo = 3;", &.{}); |
| 201 | 284 | |
| 202 | | const lib = addStaticLibrary(b, opts); |
| 285 | const lib = addStaticLibrary(b, "lib", opts); |
| 203 | 286 | lib.addObject(obj); |
| 204 | 287 | |
| 205 | | const exe = addExecutable(b, opts); |
| 288 | const exe = addExecutable(b, "test", opts); |
| 206 | 289 | exe.linkLibrary(dso); |
| 207 | 290 | exe.linkLibrary(lib); |
| 208 | 291 | addCSourceBytes(exe, |
| ... | ... | @@ -228,7 +311,7 @@ fn testDsoUndef(b: *Build, opts: Options) *Step { |
| 228 | 311 | fn testEmptyObject(b: *Build, opts: Options) *Step { |
| 229 | 312 | const test_step = addTestStep(b, "empty-object", opts); |
| 230 | 313 | |
| 231 | | const exe = addExecutable(b, opts); |
| 314 | const exe = addExecutable(b, "test", opts); |
| 232 | 315 | addCSourceBytes(exe, "int main() { return 0; }", &.{}); |
| 233 | 316 | addCSourceBytes(exe, "", &.{}); |
| 234 | 317 | exe.is_linking_libc = true; |
| ... | ... | @@ -243,7 +326,7 @@ fn testEmptyObject(b: *Build, opts: Options) *Step { |
| 243 | 326 | fn testGcSections(b: *Build, opts: Options) *Step { |
| 244 | 327 | const test_step = addTestStep(b, "gc-sections", opts); |
| 245 | 328 | |
| 246 | | const obj = addObject(b, opts); |
| 329 | const obj = addObject(b, "obj", opts); |
| 247 | 330 | addCppSourceBytes(obj, |
| 248 | 331 | \\#include <stdio.h> |
| 249 | 332 | \\int two() { return 2; } |
| ... | ... | @@ -266,7 +349,7 @@ fn testGcSections(b: *Build, opts: Options) *Step { |
| 266 | 349 | obj.is_linking_libcpp = true; |
| 267 | 350 | |
| 268 | 351 | { |
| 269 | | const exe = addExecutable(b, opts); |
| 352 | const exe = addExecutable(b, "test", opts); |
| 270 | 353 | exe.addObject(obj); |
| 271 | 354 | exe.link_gc_sections = false; |
| 272 | 355 | exe.is_linking_libc = true; |
| ... | ... | @@ -297,7 +380,7 @@ fn testGcSections(b: *Build, opts: Options) *Step { |
| 297 | 380 | } |
| 298 | 381 | |
| 299 | 382 | { |
| 300 | | const exe = addExecutable(b, opts); |
| 383 | const exe = addExecutable(b, "test", opts); |
| 301 | 384 | exe.addObject(obj); |
| 302 | 385 | exe.link_gc_sections = true; |
| 303 | 386 | exe.is_linking_libc = true; |
| ... | ... | @@ -333,7 +416,7 @@ fn testGcSections(b: *Build, opts: Options) *Step { |
| 333 | 416 | fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { |
| 334 | 417 | const test_step = addTestStep(b, "large-alignment-dso", opts); |
| 335 | 418 | |
| 336 | | const dso = addSharedLibrary(b, opts); |
| 419 | const dso = addSharedLibrary(b, "dso", opts); |
| 337 | 420 | addCSourceBytes(dso, |
| 338 | 421 | \\#include <stdio.h> |
| 339 | 422 | \\#include <stdint.h> |
| ... | ... | @@ -362,7 +445,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { |
| 362 | 445 | check.checkComputeCompare("addr2 16 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 363 | 446 | test_step.dependOn(&check.step); |
| 364 | 447 | |
| 365 | | const exe = addExecutable(b, opts); |
| 448 | const exe = addExecutable(b, "test", opts); |
| 366 | 449 | addCSourceBytes(exe, |
| 367 | 450 | \\void greet(); |
| 368 | 451 | \\int main() { greet(); } |
| ... | ... | @@ -380,7 +463,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { |
| 380 | 463 | fn testLargeAlignmentExe(b: *Build, opts: Options) *Step { |
| 381 | 464 | const test_step = addTestStep(b, "large-alignment-exe", opts); |
| 382 | 465 | |
| 383 | | const exe = addExecutable(b, opts); |
| 466 | const exe = addExecutable(b, "test", opts); |
| 384 | 467 | addCSourceBytes(exe, |
| 385 | 468 | \\#include <stdio.h> |
| 386 | 469 | \\#include <stdint.h> |
| ... | ... | @@ -423,7 +506,7 @@ fn testLargeAlignmentExe(b: *Build, opts: Options) *Step { |
| 423 | 506 | fn testLinkingC(b: *Build, opts: Options) *Step { |
| 424 | 507 | const test_step = addTestStep(b, "linking-c", opts); |
| 425 | 508 | |
| 426 | | const exe = addExecutable(b, opts); |
| 509 | const exe = addExecutable(b, "test", opts); |
| 427 | 510 | addCSourceBytes(exe, |
| 428 | 511 | \\#include <stdio.h> |
| 429 | 512 | \\int main() { |
| ... | ... | @@ -452,7 +535,7 @@ fn testLinkingC(b: *Build, opts: Options) *Step { |
| 452 | 535 | fn testLinkingCpp(b: *Build, opts: Options) *Step { |
| 453 | 536 | const test_step = addTestStep(b, "linking-cpp", opts); |
| 454 | 537 | |
| 455 | | const exe = addExecutable(b, opts); |
| 538 | const exe = addExecutable(b, "test", opts); |
| 456 | 539 | addCppSourceBytes(exe, |
| 457 | 540 | \\#include <iostream> |
| 458 | 541 | \\int main() { |
| ... | ... | @@ -482,7 +565,7 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step { |
| 482 | 565 | fn testLinkingZig(b: *Build, opts: Options) *Step { |
| 483 | 566 | const test_step = addTestStep(b, "linking-zig-static", opts); |
| 484 | 567 | |
| 485 | | const exe = addExecutable(b, opts); |
| 568 | const exe = addExecutable(b, "test", opts); |
| 486 | 569 | addZigSourceBytes(exe, |
| 487 | 570 | \\pub fn main() void { |
| 488 | 571 | \\ @import("std").debug.print("Hello World!\n", .{}); |
| ... | ... | @@ -508,7 +591,7 @@ fn testLinkingZig(b: *Build, opts: Options) *Step { |
| 508 | 591 | fn testTlsStatic(b: *Build, opts: Options) *Step { |
| 509 | 592 | const test_step = addTestStep(b, "tls-static", opts); |
| 510 | 593 | |
| 511 | | const exe = addExecutable(b, opts); |
| 594 | const exe = addExecutable(b, "test", opts); |
| 512 | 595 | addCSourceBytes(exe, |
| 513 | 596 | \\#include <stdio.h> |
| 514 | 597 | \\_Thread_local int a = 10; |
| ... | ... | @@ -555,9 +638,9 @@ fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step { |
| 555 | 638 | return b.step(name, ""); |
| 556 | 639 | } |
| 557 | 640 | |
| 558 | | fn addExecutable(b: *Build, opts: Options) *Compile { |
| 641 | fn addExecutable(b: *Build, name: []const u8, opts: Options) *Compile { |
| 559 | 642 | const exe = b.addExecutable(.{ |
| 560 | | .name = "test", |
| 643 | .name = name, |
| 561 | 644 | .target = opts.target, |
| 562 | 645 | .optimize = opts.optimize, |
| 563 | 646 | .use_llvm = opts.use_llvm, |
| ... | ... | @@ -567,9 +650,9 @@ fn addExecutable(b: *Build, opts: Options) *Compile { |
| 567 | 650 | return exe; |
| 568 | 651 | } |
| 569 | 652 | |
| 570 | | fn addObject(b: *Build, opts: Options) *Compile { |
| 653 | fn addObject(b: *Build, name: []const u8, opts: Options) *Compile { |
| 571 | 654 | return b.addObject(.{ |
| 572 | | .name = "a", |
| 655 | .name = name, |
| 573 | 656 | .target = opts.target, |
| 574 | 657 | .optimize = opts.optimize, |
| 575 | 658 | .use_llvm = opts.use_llvm, |
| ... | ... | @@ -577,9 +660,9 @@ fn addObject(b: *Build, opts: Options) *Compile { |
| 577 | 660 | }); |
| 578 | 661 | } |
| 579 | 662 | |
| 580 | | fn addStaticLibrary(b: *Build, opts: Options) *Compile { |
| 663 | fn addStaticLibrary(b: *Build, name: []const u8, opts: Options) *Compile { |
| 581 | 664 | return b.addStaticLibrary(.{ |
| 582 | | .name = "a", |
| 665 | .name = name, |
| 583 | 666 | .target = opts.target, |
| 584 | 667 | .optimize = opts.optimize, |
| 585 | 668 | .use_llvm = opts.use_llvm, |
| ... | ... | @@ -587,9 +670,9 @@ fn addStaticLibrary(b: *Build, opts: Options) *Compile { |
| 587 | 670 | }); |
| 588 | 671 | } |
| 589 | 672 | |
| 590 | | fn addSharedLibrary(b: *Build, opts: Options) *Compile { |
| 673 | fn addSharedLibrary(b: *Build, name: []const u8, opts: Options) *Compile { |
| 591 | 674 | const dso = b.addSharedLibrary(.{ |
| 592 | | .name = "a", |
| 675 | .name = name, |
| 593 | 676 | .target = opts.target, |
| 594 | 677 | .optimize = opts.optimize, |
| 595 | 678 | .use_llvm = opts.use_llvm, |