authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-07 00:08:50+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-16 19:33:05+02:00
log149dd82d5465abc136d9ef2f4270ed041a3b6e3e
tree4455233c8efc0900b35e586a17ba06bdcc243207
parent7ff9461b88678d4bc02ee31fc5159f57a1d7e2b2

elf: add --as-needed test


1 files changed, 118 insertions(+), 35 deletions(-)

test/link/elf.zig+118-35
...@@ -40,6 +40,7 @@ pub fn build(b: *Build) void {...@@ -40,6 +40,7 @@ pub fn build(b: *Build) void {
40 elf_step.dependOn(testLinkingZig(b, .{ .target = musl_target }));40 elf_step.dependOn(testLinkingZig(b, .{ .target = musl_target }));
41 elf_step.dependOn(testTlsStatic(b, .{ .target = musl_target }));41 elf_step.dependOn(testTlsStatic(b, .{ .target = musl_target }));
4242
43 elf_step.dependOn(testAsNeeded(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));
43 elf_step.dependOn(testDsoPlt(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));44 elf_step.dependOn(testDsoPlt(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));
44 elf_step.dependOn(testDsoUndef(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));45 elf_step.dependOn(testDsoUndef(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));
45 elf_step.dependOn(testLargeAlignmentDso(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));46 elf_step.dependOn(testLargeAlignmentDso(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));
...@@ -49,10 +50,92 @@ pub fn build(b: *Build) void {...@@ -49,10 +50,92 @@ pub fn build(b: *Build) void {
49 }50 }
50}51}
5152
53fn 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
52fn testCommonSymbols(b: *Build, opts: Options) *Step {135fn testCommonSymbols(b: *Build, opts: Options) *Step {
53 const test_step = addTestStep(b, "common-symbols", opts);136 const test_step = addTestStep(b, "common-symbols", opts);
54137
55 const exe = addExecutable(b, opts);138 const exe = addExecutable(b, "test", opts);
56 addCSourceBytes(exe,139 addCSourceBytes(exe,
57 \\int foo;140 \\int foo;
58 \\int bar;141 \\int bar;
...@@ -79,7 +162,7 @@ fn testCommonSymbols(b: *Build, opts: Options) *Step {...@@ -79,7 +162,7 @@ fn testCommonSymbols(b: *Build, opts: Options) *Step {
79fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {162fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
80 const test_step = addTestStep(b, "common-symbols-in-archive", opts);163 const test_step = addTestStep(b, "common-symbols-in-archive", opts);
81164
82 const a_o = addObject(b, opts);165 const a_o = addObject(b, "a", opts);
83 addCSourceBytes(a_o,166 addCSourceBytes(a_o,
84 \\#include <stdio.h>167 \\#include <stdio.h>
85 \\int foo;168 \\int foo;
...@@ -92,25 +175,25 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {...@@ -92,25 +175,25 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
92 , &.{"-fcommon"});175 , &.{"-fcommon"});
93 a_o.is_linking_libc = true;176 a_o.is_linking_libc = true;
94177
95 const b_o = addObject(b, opts);178 const b_o = addObject(b, "b", opts);
96 addCSourceBytes(b_o, "int foo = 5;", &.{"-fcommon"});179 addCSourceBytes(b_o, "int foo = 5;", &.{"-fcommon"});
97180
98 {181 {
99 const c_o = addObject(b, opts);182 const c_o = addObject(b, "c", opts);
100 addCSourceBytes(c_o,183 addCSourceBytes(c_o,
101 \\int bar;184 \\int bar;
102 \\int two() { return 2; }185 \\int two() { return 2; }
103 , &.{"-fcommon"});186 , &.{"-fcommon"});
104187
105 const d_o = addObject(b, opts);188 const d_o = addObject(b, "d", opts);
106 addCSourceBytes(d_o, "int baz;", &.{"-fcommon"});189 addCSourceBytes(d_o, "int baz;", &.{"-fcommon"});
107190
108 const lib = addStaticLibrary(b, opts);191 const lib = addStaticLibrary(b, "lib", opts);
109 lib.addObject(b_o);192 lib.addObject(b_o);
110 lib.addObject(c_o);193 lib.addObject(c_o);
111 lib.addObject(d_o);194 lib.addObject(d_o);
112195
113 const exe = addExecutable(b, opts);196 const exe = addExecutable(b, "test", opts);
114 exe.addObject(a_o);197 exe.addObject(a_o);
115 exe.linkLibrary(lib);198 exe.linkLibrary(lib);
116 exe.is_linking_libc = true;199 exe.is_linking_libc = true;
...@@ -121,18 +204,18 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {...@@ -121,18 +204,18 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
121 }204 }
122205
123 {206 {
124 const e_o = addObject(b, opts);207 const e_o = addObject(b, "e", opts);
125 addCSourceBytes(e_o,208 addCSourceBytes(e_o,
126 \\int bar = 0;209 \\int bar = 0;
127 \\int baz = 7;210 \\int baz = 7;
128 \\int two() { return 2; }211 \\int two() { return 2; }
129 , &.{"-fcommon"});212 , &.{"-fcommon"});
130213
131 const lib = addStaticLibrary(b, opts);214 const lib = addStaticLibrary(b, "lib", opts);
132 lib.addObject(b_o);215 lib.addObject(b_o);
133 lib.addObject(e_o);216 lib.addObject(e_o);
134217
135 const exe = addExecutable(b, opts);218 const exe = addExecutable(b, "test", opts);
136 exe.addObject(a_o);219 exe.addObject(a_o);
137 exe.linkLibrary(lib);220 exe.linkLibrary(lib);
138 exe.is_linking_libc = true;221 exe.is_linking_libc = true;
...@@ -148,7 +231,7 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {...@@ -148,7 +231,7 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
148fn testDsoPlt(b: *Build, opts: Options) *Step {231fn testDsoPlt(b: *Build, opts: Options) *Step {
149 const test_step = addTestStep(b, "dso-plt", opts);232 const test_step = addTestStep(b, "dso-plt", opts);
150233
151 const dso = addSharedLibrary(b, opts);234 const dso = addSharedLibrary(b, "dso", opts);
152 addCSourceBytes(dso,235 addCSourceBytes(dso,
153 \\#include<stdio.h>236 \\#include<stdio.h>
154 \\void world() {237 \\void world() {
...@@ -164,7 +247,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {...@@ -164,7 +247,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {
164 , &.{"-fPIC"});247 , &.{"-fPIC"});
165 dso.is_linking_libc = true;248 dso.is_linking_libc = true;
166249
167 const exe = addExecutable(b, opts);250 const exe = addExecutable(b, "test", opts);
168 addCSourceBytes(exe,251 addCSourceBytes(exe,
169 \\#include<stdio.h>252 \\#include<stdio.h>
170 \\void world() {253 \\void world() {
...@@ -188,7 +271,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {...@@ -188,7 +271,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {
188fn testDsoUndef(b: *Build, opts: Options) *Step {271fn testDsoUndef(b: *Build, opts: Options) *Step {
189 const test_step = addTestStep(b, "dso-undef", opts);272 const test_step = addTestStep(b, "dso-undef", opts);
190273
191 const dso = addSharedLibrary(b, opts);274 const dso = addSharedLibrary(b, "dso", opts);
192 addCSourceBytes(dso,275 addCSourceBytes(dso,
193 \\extern int foo;276 \\extern int foo;
194 \\int bar = 5;277 \\int bar = 5;
...@@ -196,13 +279,13 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {...@@ -196,13 +279,13 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {
196 , &.{"-fPIC"});279 , &.{"-fPIC"});
197 dso.is_linking_libc = true;280 dso.is_linking_libc = true;
198281
199 const obj = addObject(b, opts);282 const obj = addObject(b, "obj", opts);
200 addCSourceBytes(obj, "int foo = 3;", &.{});283 addCSourceBytes(obj, "int foo = 3;", &.{});
201284
202 const lib = addStaticLibrary(b, opts);285 const lib = addStaticLibrary(b, "lib", opts);
203 lib.addObject(obj);286 lib.addObject(obj);
204287
205 const exe = addExecutable(b, opts);288 const exe = addExecutable(b, "test", opts);
206 exe.linkLibrary(dso);289 exe.linkLibrary(dso);
207 exe.linkLibrary(lib);290 exe.linkLibrary(lib);
208 addCSourceBytes(exe,291 addCSourceBytes(exe,
...@@ -228,7 +311,7 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {...@@ -228,7 +311,7 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {
228fn testEmptyObject(b: *Build, opts: Options) *Step {311fn testEmptyObject(b: *Build, opts: Options) *Step {
229 const test_step = addTestStep(b, "empty-object", opts);312 const test_step = addTestStep(b, "empty-object", opts);
230313
231 const exe = addExecutable(b, opts);314 const exe = addExecutable(b, "test", opts);
232 addCSourceBytes(exe, "int main() { return 0; }", &.{});315 addCSourceBytes(exe, "int main() { return 0; }", &.{});
233 addCSourceBytes(exe, "", &.{});316 addCSourceBytes(exe, "", &.{});
234 exe.is_linking_libc = true;317 exe.is_linking_libc = true;
...@@ -243,7 +326,7 @@ fn testEmptyObject(b: *Build, opts: Options) *Step {...@@ -243,7 +326,7 @@ fn testEmptyObject(b: *Build, opts: Options) *Step {
243fn testGcSections(b: *Build, opts: Options) *Step {326fn testGcSections(b: *Build, opts: Options) *Step {
244 const test_step = addTestStep(b, "gc-sections", opts);327 const test_step = addTestStep(b, "gc-sections", opts);
245328
246 const obj = addObject(b, opts);329 const obj = addObject(b, "obj", opts);
247 addCppSourceBytes(obj,330 addCppSourceBytes(obj,
248 \\#include <stdio.h>331 \\#include <stdio.h>
249 \\int two() { return 2; }332 \\int two() { return 2; }
...@@ -266,7 +349,7 @@ fn testGcSections(b: *Build, opts: Options) *Step {...@@ -266,7 +349,7 @@ fn testGcSections(b: *Build, opts: Options) *Step {
266 obj.is_linking_libcpp = true;349 obj.is_linking_libcpp = true;
267350
268 {351 {
269 const exe = addExecutable(b, opts);352 const exe = addExecutable(b, "test", opts);
270 exe.addObject(obj);353 exe.addObject(obj);
271 exe.link_gc_sections = false;354 exe.link_gc_sections = false;
272 exe.is_linking_libc = true;355 exe.is_linking_libc = true;
...@@ -297,7 +380,7 @@ fn testGcSections(b: *Build, opts: Options) *Step {...@@ -297,7 +380,7 @@ fn testGcSections(b: *Build, opts: Options) *Step {
297 }380 }
298381
299 {382 {
300 const exe = addExecutable(b, opts);383 const exe = addExecutable(b, "test", opts);
301 exe.addObject(obj);384 exe.addObject(obj);
302 exe.link_gc_sections = true;385 exe.link_gc_sections = true;
303 exe.is_linking_libc = true;386 exe.is_linking_libc = true;
...@@ -333,7 +416,7 @@ fn testGcSections(b: *Build, opts: Options) *Step {...@@ -333,7 +416,7 @@ fn testGcSections(b: *Build, opts: Options) *Step {
333fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {416fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {
334 const test_step = addTestStep(b, "large-alignment-dso", opts);417 const test_step = addTestStep(b, "large-alignment-dso", opts);
335418
336 const dso = addSharedLibrary(b, opts);419 const dso = addSharedLibrary(b, "dso", opts);
337 addCSourceBytes(dso,420 addCSourceBytes(dso,
338 \\#include <stdio.h>421 \\#include <stdio.h>
339 \\#include <stdint.h>422 \\#include <stdint.h>
...@@ -362,7 +445,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {...@@ -362,7 +445,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {
362 check.checkComputeCompare("addr2 16 %", .{ .op = .eq, .value = .{ .literal = 0 } });445 check.checkComputeCompare("addr2 16 %", .{ .op = .eq, .value = .{ .literal = 0 } });
363 test_step.dependOn(&check.step);446 test_step.dependOn(&check.step);
364447
365 const exe = addExecutable(b, opts);448 const exe = addExecutable(b, "test", opts);
366 addCSourceBytes(exe,449 addCSourceBytes(exe,
367 \\void greet();450 \\void greet();
368 \\int main() { greet(); }451 \\int main() { greet(); }
...@@ -380,7 +463,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {...@@ -380,7 +463,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {
380fn testLargeAlignmentExe(b: *Build, opts: Options) *Step {463fn testLargeAlignmentExe(b: *Build, opts: Options) *Step {
381 const test_step = addTestStep(b, "large-alignment-exe", opts);464 const test_step = addTestStep(b, "large-alignment-exe", opts);
382465
383 const exe = addExecutable(b, opts);466 const exe = addExecutable(b, "test", opts);
384 addCSourceBytes(exe,467 addCSourceBytes(exe,
385 \\#include <stdio.h>468 \\#include <stdio.h>
386 \\#include <stdint.h>469 \\#include <stdint.h>
...@@ -423,7 +506,7 @@ fn testLargeAlignmentExe(b: *Build, opts: Options) *Step {...@@ -423,7 +506,7 @@ fn testLargeAlignmentExe(b: *Build, opts: Options) *Step {
423fn testLinkingC(b: *Build, opts: Options) *Step {506fn testLinkingC(b: *Build, opts: Options) *Step {
424 const test_step = addTestStep(b, "linking-c", opts);507 const test_step = addTestStep(b, "linking-c", opts);
425508
426 const exe = addExecutable(b, opts);509 const exe = addExecutable(b, "test", opts);
427 addCSourceBytes(exe,510 addCSourceBytes(exe,
428 \\#include <stdio.h>511 \\#include <stdio.h>
429 \\int main() {512 \\int main() {
...@@ -452,7 +535,7 @@ fn testLinkingC(b: *Build, opts: Options) *Step {...@@ -452,7 +535,7 @@ fn testLinkingC(b: *Build, opts: Options) *Step {
452fn testLinkingCpp(b: *Build, opts: Options) *Step {535fn testLinkingCpp(b: *Build, opts: Options) *Step {
453 const test_step = addTestStep(b, "linking-cpp", opts);536 const test_step = addTestStep(b, "linking-cpp", opts);
454537
455 const exe = addExecutable(b, opts);538 const exe = addExecutable(b, "test", opts);
456 addCppSourceBytes(exe,539 addCppSourceBytes(exe,
457 \\#include <iostream>540 \\#include <iostream>
458 \\int main() {541 \\int main() {
...@@ -482,7 +565,7 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step {...@@ -482,7 +565,7 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step {
482fn testLinkingZig(b: *Build, opts: Options) *Step {565fn testLinkingZig(b: *Build, opts: Options) *Step {
483 const test_step = addTestStep(b, "linking-zig-static", opts);566 const test_step = addTestStep(b, "linking-zig-static", opts);
484567
485 const exe = addExecutable(b, opts);568 const exe = addExecutable(b, "test", opts);
486 addZigSourceBytes(exe,569 addZigSourceBytes(exe,
487 \\pub fn main() void {570 \\pub fn main() void {
488 \\ @import("std").debug.print("Hello World!\n", .{});571 \\ @import("std").debug.print("Hello World!\n", .{});
...@@ -508,7 +591,7 @@ fn testLinkingZig(b: *Build, opts: Options) *Step {...@@ -508,7 +591,7 @@ fn testLinkingZig(b: *Build, opts: Options) *Step {
508fn testTlsStatic(b: *Build, opts: Options) *Step {591fn testTlsStatic(b: *Build, opts: Options) *Step {
509 const test_step = addTestStep(b, "tls-static", opts);592 const test_step = addTestStep(b, "tls-static", opts);
510593
511 const exe = addExecutable(b, opts);594 const exe = addExecutable(b, "test", opts);
512 addCSourceBytes(exe,595 addCSourceBytes(exe,
513 \\#include <stdio.h>596 \\#include <stdio.h>
514 \\_Thread_local int a = 10;597 \\_Thread_local int a = 10;
...@@ -555,9 +638,9 @@ fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step {...@@ -555,9 +638,9 @@ fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step {
555 return b.step(name, "");638 return b.step(name, "");
556}639}
557640
558fn addExecutable(b: *Build, opts: Options) *Compile {641fn addExecutable(b: *Build, name: []const u8, opts: Options) *Compile {
559 const exe = b.addExecutable(.{642 const exe = b.addExecutable(.{
560 .name = "test",643 .name = name,
561 .target = opts.target,644 .target = opts.target,
562 .optimize = opts.optimize,645 .optimize = opts.optimize,
563 .use_llvm = opts.use_llvm,646 .use_llvm = opts.use_llvm,
...@@ -567,9 +650,9 @@ fn addExecutable(b: *Build, opts: Options) *Compile {...@@ -567,9 +650,9 @@ fn addExecutable(b: *Build, opts: Options) *Compile {
567 return exe;650 return exe;
568}651}
569652
570fn addObject(b: *Build, opts: Options) *Compile {653fn addObject(b: *Build, name: []const u8, opts: Options) *Compile {
571 return b.addObject(.{654 return b.addObject(.{
572 .name = "a",655 .name = name,
573 .target = opts.target,656 .target = opts.target,
574 .optimize = opts.optimize,657 .optimize = opts.optimize,
575 .use_llvm = opts.use_llvm,658 .use_llvm = opts.use_llvm,
...@@ -577,9 +660,9 @@ fn addObject(b: *Build, opts: Options) *Compile {...@@ -577,9 +660,9 @@ fn addObject(b: *Build, opts: Options) *Compile {
577 });660 });
578}661}
579662
580fn addStaticLibrary(b: *Build, opts: Options) *Compile {663fn addStaticLibrary(b: *Build, name: []const u8, opts: Options) *Compile {
581 return b.addStaticLibrary(.{664 return b.addStaticLibrary(.{
582 .name = "a",665 .name = name,
583 .target = opts.target,666 .target = opts.target,
584 .optimize = opts.optimize,667 .optimize = opts.optimize,
585 .use_llvm = opts.use_llvm,668 .use_llvm = opts.use_llvm,
...@@ -587,9 +670,9 @@ fn addStaticLibrary(b: *Build, opts: Options) *Compile {...@@ -587,9 +670,9 @@ fn addStaticLibrary(b: *Build, opts: Options) *Compile {
587 });670 });
588}671}
589672
590fn addSharedLibrary(b: *Build, opts: Options) *Compile {673fn addSharedLibrary(b: *Build, name: []const u8, opts: Options) *Compile {
591 const dso = b.addSharedLibrary(.{674 const dso = b.addSharedLibrary(.{
592 .name = "a",675 .name = name,
593 .target = opts.target,676 .target = opts.target,
594 .optimize = opts.optimize,677 .optimize = opts.optimize,
595 .use_llvm = opts.use_llvm,678 .use_llvm = opts.use_llvm,