| author | |
| committer | |
| log | 7320b24e0ea768cf8dffaaeaa058db8e9134b444 |
| tree | 66b14e8b17373b4578529f30540ffc6414668e1f |
| parent | acca16c8cee4529bcb11c150c2c99b7de32ce21f |
| parent | 3cd646869b1791b8833134294d3f415cb6fddcf7 |
| signature |
Add support for `--(no-)undefined-version`9 files changed, 100 insertions(+), 7 deletions(-)
lib/std/Build/Step/Compile.zig+6| ... | @@ -110,6 +110,9 @@ linker_dynamicbase: bool = true, | ... | @@ -110,6 +110,9 @@ linker_dynamicbase: bool = true, |
| 110 | 110 | ||
| 111 | linker_allow_shlib_undefined: ?bool = null, | 111 | linker_allow_shlib_undefined: ?bool = null, |
| 112 | 112 | ||
| 113 | /// Allow version scripts to refer to undefined symbols. | ||
| 114 | linker_allow_undefined_version: ?bool = null, | ||
| 115 | |||
| 113 | /// Permit read-only relocations in read-only segments. Disallowed by default. | 116 | /// Permit read-only relocations in read-only segments. Disallowed by default. |
| 114 | link_z_notext: bool = false, | 117 | link_z_notext: bool = false, |
| 115 | 118 | ||
| ... | @@ -1451,6 +1454,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -1451,6 +1454,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1451 | try zig_args.append("--version-script"); | 1454 | try zig_args.append("--version-script"); |
| 1452 | try zig_args.append(version_script.getPath(b)); | 1455 | try zig_args.append(version_script.getPath(b)); |
| 1453 | } | 1456 | } |
| 1457 | if (self.linker_allow_undefined_version) |x| { | ||
| 1458 | try zig_args.append(if (x) "--undefined-version" else "--no-undefined-version"); | ||
| 1459 | } | ||
| 1454 | 1460 | ||
| 1455 | if (self.kind == .@"test") { | 1461 | if (self.kind == .@"test") { |
| 1456 | if (self.exec_cmd_args) |exec_cmd_args| { | 1462 | if (self.exec_cmd_args) |exec_cmd_args| { |
src/Compilation.zig+5-2| ... | @@ -1033,6 +1033,7 @@ pub const CreateOptions = struct { | ... | @@ -1033,6 +1033,7 @@ pub const CreateOptions = struct { |
| 1033 | link_emit_relocs: bool = false, | 1033 | link_emit_relocs: bool = false, |
| 1034 | linker_script: ?[]const u8 = null, | 1034 | linker_script: ?[]const u8 = null, |
| 1035 | version_script: ?[]const u8 = null, | 1035 | version_script: ?[]const u8 = null, |
| 1036 | linker_allow_undefined_version: bool = false, | ||
| 1036 | soname: ?[]const u8 = null, | 1037 | soname: ?[]const u8 = null, |
| 1037 | linker_gc_sections: ?bool = null, | 1038 | linker_gc_sections: ?bool = null, |
| 1038 | linker_allow_shlib_undefined: ?bool = null, | 1039 | linker_allow_shlib_undefined: ?bool = null, |
| ... | @@ -1572,6 +1573,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1572,6 +1573,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1572 | .stack_size = options.stack_size, | 1573 | .stack_size = options.stack_size, |
| 1573 | .image_base = options.image_base, | 1574 | .image_base = options.image_base, |
| 1574 | .version_script = options.version_script, | 1575 | .version_script = options.version_script, |
| 1576 | .allow_undefined_version = options.linker_allow_undefined_version, | ||
| 1575 | .gc_sections = options.linker_gc_sections, | 1577 | .gc_sections = options.linker_gc_sections, |
| 1576 | .emit_relocs = options.link_emit_relocs, | 1578 | .emit_relocs = options.link_emit_relocs, |
| 1577 | .soname = options.soname, | 1579 | .soname = options.soname, |
| ... | @@ -2458,7 +2460,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo | ... | @@ -2458,7 +2460,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo |
| 2458 | /// to remind the programmer to update multiple related pieces of code that | 2460 | /// to remind the programmer to update multiple related pieces of code that |
| 2459 | /// are in different locations. Bump this number when adding or deleting | 2461 | /// are in different locations. Bump this number when adding or deleting |
| 2460 | /// anything from the link cache manifest. | 2462 | /// anything from the link cache manifest. |
| 2461 | pub const link_hash_implementation_version = 10; | 2463 | pub const link_hash_implementation_version = 11; |
| 2462 | 2464 | ||
| 2463 | fn addNonIncrementalStuffToCacheManifest( | 2465 | fn addNonIncrementalStuffToCacheManifest( |
| 2464 | comp: *Compilation, | 2466 | comp: *Compilation, |
| ... | @@ -2467,7 +2469,7 @@ fn addNonIncrementalStuffToCacheManifest( | ... | @@ -2467,7 +2469,7 @@ fn addNonIncrementalStuffToCacheManifest( |
| 2467 | ) !void { | 2469 | ) !void { |
| 2468 | const gpa = comp.gpa; | 2470 | const gpa = comp.gpa; |
| 2469 | 2471 | ||
| 2470 | comptime assert(link_hash_implementation_version == 10); | 2472 | comptime assert(link_hash_implementation_version == 11); |
| 2471 | 2473 | ||
| 2472 | if (comp.module) |mod| { | 2474 | if (comp.module) |mod| { |
| 2473 | const main_zig_file = try mod.main_mod.root.joinString(arena, mod.main_mod.root_src_path); | 2475 | const main_zig_file = try mod.main_mod.root.joinString(arena, mod.main_mod.root_src_path); |
| ... | @@ -2541,6 +2543,7 @@ fn addNonIncrementalStuffToCacheManifest( | ... | @@ -2541,6 +2543,7 @@ fn addNonIncrementalStuffToCacheManifest( |
| 2541 | 2543 | ||
| 2542 | try man.addOptionalFile(opts.linker_script); | 2544 | try man.addOptionalFile(opts.linker_script); |
| 2543 | try man.addOptionalFile(opts.version_script); | 2545 | try man.addOptionalFile(opts.version_script); |
| 2546 | man.hash.add(opts.allow_undefined_version); | ||
| 2544 | 2547 | ||
| 2545 | man.hash.addOptional(opts.stack_size); | 2548 | man.hash.addOptional(opts.stack_size); |
| 2546 | man.hash.addOptional(opts.image_base); | 2549 | man.hash.addOptional(opts.image_base); |
src/link.zig+1| ... | @@ -113,6 +113,7 @@ pub const File = struct { | ... | @@ -113,6 +113,7 @@ pub const File = struct { |
| 113 | minor_subsystem_version: ?u16, | 113 | minor_subsystem_version: ?u16, |
| 114 | gc_sections: ?bool, | 114 | gc_sections: ?bool, |
| 115 | allow_shlib_undefined: ?bool, | 115 | allow_shlib_undefined: ?bool, |
| 116 | allow_undefined_version: bool, | ||
| 116 | subsystem: ?std.Target.SubSystem, | 117 | subsystem: ?std.Target.SubSystem, |
| 117 | linker_script: ?[]const u8, | 118 | linker_script: ?[]const u8, |
| 118 | version_script: ?[]const u8, | 119 | version_script: ?[]const u8, |
src/link/Coff/lld.zig+1-1| ... | @@ -70,7 +70,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) | ... | @@ -70,7 +70,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) |
| 70 | man = comp.cache_parent.obtain(); | 70 | man = comp.cache_parent.obtain(); |
| 71 | self.base.releaseLock(); | 71 | self.base.releaseLock(); |
| 72 | 72 | ||
| 73 | comptime assert(Compilation.link_hash_implementation_version == 10); | 73 | comptime assert(Compilation.link_hash_implementation_version == 11); |
| 74 | 74 | ||
| 75 | for (comp.objects) |obj| { | 75 | for (comp.objects) |obj| { |
| 76 | _ = try man.addFile(obj.path, null); | 76 | _ = try man.addFile(obj.path, null); |
src/link/Elf.zig+9-1| ... | @@ -22,6 +22,7 @@ soname: ?[]const u8, | ... | @@ -22,6 +22,7 @@ soname: ?[]const u8, |
| 22 | bind_global_refs_locally: bool, | 22 | bind_global_refs_locally: bool, |
| 23 | linker_script: ?[]const u8, | 23 | linker_script: ?[]const u8, |
| 24 | version_script: ?[]const u8, | 24 | version_script: ?[]const u8, |
| 25 | allow_undefined_version: bool, | ||
| 25 | print_icf_sections: bool, | 26 | print_icf_sections: bool, |
| 26 | print_map: bool, | 27 | print_map: bool, |
| 27 | entry_name: ?[]const u8, | 28 | entry_name: ?[]const u8, |
| ... | @@ -325,6 +326,7 @@ pub fn createEmpty( | ... | @@ -325,6 +326,7 @@ pub fn createEmpty( |
| 325 | .bind_global_refs_locally = options.bind_global_refs_locally, | 326 | .bind_global_refs_locally = options.bind_global_refs_locally, |
| 326 | .linker_script = options.linker_script, | 327 | .linker_script = options.linker_script, |
| 327 | .version_script = options.version_script, | 328 | .version_script = options.version_script, |
| 329 | .allow_undefined_version = options.allow_undefined_version, | ||
| 328 | .print_icf_sections = options.print_icf_sections, | 330 | .print_icf_sections = options.print_icf_sections, |
| 329 | .print_map = options.print_map, | 331 | .print_map = options.print_map, |
| 330 | }; | 332 | }; |
| ... | @@ -2410,10 +2412,11 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !voi | ... | @@ -2410,10 +2412,11 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !voi |
| 2410 | // We are about to obtain this lock, so here we give other processes a chance first. | 2412 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 2411 | self.base.releaseLock(); | 2413 | self.base.releaseLock(); |
| 2412 | 2414 | ||
| 2413 | comptime assert(Compilation.link_hash_implementation_version == 10); | 2415 | comptime assert(Compilation.link_hash_implementation_version == 11); |
| 2414 | 2416 | ||
| 2415 | try man.addOptionalFile(self.linker_script); | 2417 | try man.addOptionalFile(self.linker_script); |
| 2416 | try man.addOptionalFile(self.version_script); | 2418 | try man.addOptionalFile(self.version_script); |
| 2419 | man.hash.add(self.allow_undefined_version); | ||
| 2417 | for (comp.objects) |obj| { | 2420 | for (comp.objects) |obj| { |
| 2418 | _ = try man.addFile(obj.path, null); | 2421 | _ = try man.addFile(obj.path, null); |
| 2419 | man.hash.add(obj.must_link); | 2422 | man.hash.add(obj.must_link); |
| ... | @@ -2789,6 +2792,11 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !voi | ... | @@ -2789,6 +2792,11 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !voi |
| 2789 | try argv.append("-version-script"); | 2792 | try argv.append("-version-script"); |
| 2790 | try argv.append(version_script); | 2793 | try argv.append(version_script); |
| 2791 | } | 2794 | } |
| 2795 | if (self.allow_undefined_version) { | ||
| 2796 | try argv.append("--undefined-version"); | ||
| 2797 | } else { | ||
| 2798 | try argv.append("--no-undefined-version"); | ||
| 2799 | } | ||
| 2792 | } | 2800 | } |
| 2793 | 2801 | ||
| 2794 | // Positional arguments to the linker such as object files. | 2802 | // Positional arguments to the linker such as object files. |
src/link/MachO/zld.zig+1-1| ... | @@ -55,7 +55,7 @@ pub fn linkWithZld( | ... | @@ -55,7 +55,7 @@ pub fn linkWithZld( |
| 55 | // We are about to obtain this lock, so here we give other processes a chance first. | 55 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 56 | macho_file.base.releaseLock(); | 56 | macho_file.base.releaseLock(); |
| 57 | 57 | ||
| 58 | comptime assert(Compilation.link_hash_implementation_version == 10); | 58 | comptime assert(Compilation.link_hash_implementation_version == 11); |
| 59 | 59 | ||
| 60 | for (objects) |obj| { | 60 | for (objects) |obj| { |
| 61 | _ = try man.addFile(obj.path, null); | 61 | _ = try man.addFile(obj.path, null); |
src/link/Wasm.zig+2-2| ... | @@ -3547,7 +3547,7 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin | ... | @@ -3547,7 +3547,7 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin |
| 3547 | // We are about to obtain this lock, so here we give other processes a chance first. | 3547 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 3548 | wasm.base.releaseLock(); | 3548 | wasm.base.releaseLock(); |
| 3549 | 3549 | ||
| 3550 | comptime assert(Compilation.link_hash_implementation_version == 10); | 3550 | comptime assert(Compilation.link_hash_implementation_version == 11); |
| 3551 | 3551 | ||
| 3552 | for (objects) |obj| { | 3552 | for (objects) |obj| { |
| 3553 | _ = try man.addFile(obj.path, null); | 3553 | _ = try man.addFile(obj.path, null); |
| ... | @@ -4633,7 +4633,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !vo | ... | @@ -4633,7 +4633,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !vo |
| 4633 | // We are about to obtain this lock, so here we give other processes a chance first. | 4633 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 4634 | wasm.base.releaseLock(); | 4634 | wasm.base.releaseLock(); |
| 4635 | 4635 | ||
| 4636 | comptime assert(Compilation.link_hash_implementation_version == 10); | 4636 | comptime assert(Compilation.link_hash_implementation_version == 11); |
| 4637 | 4637 | ||
| 4638 | for (comp.objects) |obj| { | 4638 | for (comp.objects) |obj| { |
| 4639 | _ = try man.addFile(obj.path, null); | 4639 | _ = try man.addFile(obj.path, null); |
src/main.zig+12| ... | @@ -500,6 +500,8 @@ const usage_build_generic = | ... | @@ -500,6 +500,8 @@ const usage_build_generic = |
| 500 | \\Global Link Options: | 500 | \\Global Link Options: |
| 501 | \\ -T[script], --script [script] Use a custom linker script | 501 | \\ -T[script], --script [script] Use a custom linker script |
| 502 | \\ --version-script [path] Provide a version .map file | 502 | \\ --version-script [path] Provide a version .map file |
| 503 | \\ --undefined-version Allow version scripts to refer to undefined symbols | ||
| 504 | \\ --no-undefined-version (default) Disallow version scripts from referring to undefined symbols | ||
| 503 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) | 505 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) |
| 504 | \\ --sysroot [path] Set the system root directory (usually /) | 506 | \\ --sysroot [path] Set the system root directory (usually /) |
| 505 | \\ --version [ver] Dynamic library semver | 507 | \\ --version [ver] Dynamic library semver |
| ... | @@ -826,6 +828,7 @@ fn buildOutputType( | ... | @@ -826,6 +828,7 @@ fn buildOutputType( |
| 826 | var want_compiler_rt: ?bool = null; | 828 | var want_compiler_rt: ?bool = null; |
| 827 | var linker_script: ?[]const u8 = null; | 829 | var linker_script: ?[]const u8 = null; |
| 828 | var version_script: ?[]const u8 = null; | 830 | var version_script: ?[]const u8 = null; |
| 831 | var linker_allow_undefined_version: bool = false; | ||
| 829 | var disable_c_depfile = false; | 832 | var disable_c_depfile = false; |
| 830 | var linker_sort_section: ?link.File.Elf.SortSection = null; | 833 | var linker_sort_section: ?link.File.Elf.SortSection = null; |
| 831 | var linker_gc_sections: ?bool = null; | 834 | var linker_gc_sections: ?bool = null; |
| ... | @@ -1200,6 +1203,10 @@ fn buildOutputType( | ... | @@ -1200,6 +1203,10 @@ fn buildOutputType( |
| 1200 | linker_script = args_iter.nextOrFatal(); | 1203 | linker_script = args_iter.nextOrFatal(); |
| 1201 | } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) { | 1204 | } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) { |
| 1202 | version_script = args_iter.nextOrFatal(); | 1205 | version_script = args_iter.nextOrFatal(); |
| 1206 | } else if (mem.eql(u8, arg, "--undefined-version")) { | ||
| 1207 | linker_allow_undefined_version = true; | ||
| 1208 | } else if (mem.eql(u8, arg, "--no-undefined-version")) { | ||
| 1209 | linker_allow_undefined_version = false; | ||
| 1203 | } else if (mem.eql(u8, arg, "--library") or mem.eql(u8, arg, "-l")) { | 1210 | } else if (mem.eql(u8, arg, "--library") or mem.eql(u8, arg, "-l")) { |
| 1204 | // We don't know whether this library is part of libc | 1211 | // We don't know whether this library is part of libc |
| 1205 | // or libc++ until we resolve the target, so we append | 1212 | // or libc++ until we resolve the target, so we append |
| ... | @@ -2153,6 +2160,10 @@ fn buildOutputType( | ... | @@ -2153,6 +2160,10 @@ fn buildOutputType( |
| 2153 | create_module.opts.rdynamic = true; | 2160 | create_module.opts.rdynamic = true; |
| 2154 | } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) { | 2161 | } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) { |
| 2155 | version_script = linker_args_it.nextOrFatal(); | 2162 | version_script = linker_args_it.nextOrFatal(); |
| 2163 | } else if (mem.eql(u8, arg, "--undefined-version")) { | ||
| 2164 | linker_allow_undefined_version = true; | ||
| 2165 | } else if (mem.eql(u8, arg, "--no-undefined-version")) { | ||
| 2166 | linker_allow_undefined_version = false; | ||
| 2156 | } else if (mem.eql(u8, arg, "-O")) { | 2167 | } else if (mem.eql(u8, arg, "-O")) { |
| 2157 | linker_optimization = linker_args_it.nextOrFatal(); | 2168 | linker_optimization = linker_args_it.nextOrFatal(); |
| 2158 | } else if (mem.startsWith(u8, arg, "-O")) { | 2169 | } else if (mem.startsWith(u8, arg, "-O")) { |
| ... | @@ -3166,6 +3177,7 @@ fn buildOutputType( | ... | @@ -3166,6 +3177,7 @@ fn buildOutputType( |
| 3166 | .hash_style = hash_style, | 3177 | .hash_style = hash_style, |
| 3167 | .linker_script = linker_script, | 3178 | .linker_script = linker_script, |
| 3168 | .version_script = version_script, | 3179 | .version_script = version_script, |
| 3180 | .linker_allow_undefined_version = linker_allow_undefined_version, | ||
| 3169 | .disable_c_depfile = disable_c_depfile, | 3181 | .disable_c_depfile = disable_c_depfile, |
| 3170 | .soname = resolved_soname, | 3182 | .soname = resolved_soname, |
| 3171 | .linker_sort_section = linker_sort_section, | 3183 | .linker_sort_section = linker_sort_section, |
test/link/elf.zig+63| ... | @@ -94,6 +94,8 @@ pub fn testAll(b: *Build) *Step { | ... | @@ -94,6 +94,8 @@ pub fn testAll(b: *Build) *Step { |
| 94 | elf_step.dependOn(testLinkOrder(b, .{ .target = glibc_target })); | 94 | elf_step.dependOn(testLinkOrder(b, .{ .target = glibc_target })); |
| 95 | elf_step.dependOn(testLdScript(b, .{ .target = glibc_target })); | 95 | elf_step.dependOn(testLdScript(b, .{ .target = glibc_target })); |
| 96 | elf_step.dependOn(testLdScriptPathError(b, .{ .target = glibc_target })); | 96 | elf_step.dependOn(testLdScriptPathError(b, .{ .target = glibc_target })); |
| 97 | elf_step.dependOn(testLdScriptAllowUndefinedVersion(b, .{ .target = glibc_target, .use_lld = true })); | ||
| 98 | elf_step.dependOn(testLdScriptDisallowUndefinedVersion(b, .{ .target = glibc_target, .use_lld = true })); | ||
| 97 | elf_step.dependOn(testMismatchedCpuArchitectureError(b, .{ .target = glibc_target })); | 99 | elf_step.dependOn(testMismatchedCpuArchitectureError(b, .{ .target = glibc_target })); |
| 98 | // https://github.com/ziglang/zig/issues/17451 | 100 | // https://github.com/ziglang/zig/issues/17451 |
| 99 | // elf_step.dependOn(testNoEhFrameHdr(b, .{ .target = glibc_target })); | 101 | // elf_step.dependOn(testNoEhFrameHdr(b, .{ .target = glibc_target })); |
| ... | @@ -2008,6 +2010,67 @@ fn testLdScriptPathError(b: *Build, opts: Options) *Step { | ... | @@ -2008,6 +2010,67 @@ fn testLdScriptPathError(b: *Build, opts: Options) *Step { |
| 2008 | return test_step; | 2010 | return test_step; |
| 2009 | } | 2011 | } |
| 2010 | 2012 | ||
| 2013 | fn testLdScriptAllowUndefinedVersion(b: *Build, opts: Options) *Step { | ||
| 2014 | const test_step = addTestStep(b, "ld-script-allow-undefined-version", opts); | ||
| 2015 | |||
| 2016 | const so = addSharedLibrary(b, opts, .{ | ||
| 2017 | .name = "add", | ||
| 2018 | .zig_source_bytes = | ||
| 2019 | \\export fn add(a: i32, b: i32) i32 { | ||
| 2020 | \\ return a + b; | ||
| 2021 | \\} | ||
| 2022 | , | ||
| 2023 | }); | ||
| 2024 | const ld = b.addWriteFiles().add("add.ld", "VERSION { ADD_1.0 { global: add; sub; local: *; }; }"); | ||
| 2025 | so.setLinkerScript(ld); | ||
| 2026 | so.linker_allow_undefined_version = true; | ||
| 2027 | |||
| 2028 | const exe = addExecutable(b, opts, .{ | ||
| 2029 | .name = "main", | ||
| 2030 | .zig_source_bytes = | ||
| 2031 | \\const std = @import("std"); | ||
| 2032 | \\extern fn add(a: i32, b: i32) i32; | ||
| 2033 | \\pub fn main() void { | ||
| 2034 | \\ std.debug.print("{d}\n", .{add(1, 2)}); | ||
| 2035 | \\} | ||
| 2036 | , | ||
| 2037 | }); | ||
| 2038 | exe.linkLibrary(so); | ||
| 2039 | exe.linkLibC(); | ||
| 2040 | |||
| 2041 | const run = addRunArtifact(exe); | ||
| 2042 | run.expectStdErrEqual("3\n"); | ||
| 2043 | test_step.dependOn(&run.step); | ||
| 2044 | |||
| 2045 | return test_step; | ||
| 2046 | } | ||
| 2047 | |||
| 2048 | fn testLdScriptDisallowUndefinedVersion(b: *Build, opts: Options) *Step { | ||
| 2049 | const test_step = addTestStep(b, "ld-script-disallow-undefined-version", opts); | ||
| 2050 | |||
| 2051 | const so = addSharedLibrary(b, opts, .{ | ||
| 2052 | .name = "add", | ||
| 2053 | .zig_source_bytes = | ||
| 2054 | \\export fn add(a: i32, b: i32) i32 { | ||
| 2055 | \\ return a + b; | ||
| 2056 | \\} | ||
| 2057 | , | ||
| 2058 | }); | ||
| 2059 | const ld = b.addWriteFiles().add("add.ld", "VERSION { ADD_1.0 { global: add; sub; local: *; }; }"); | ||
| 2060 | so.setLinkerScript(ld); | ||
| 2061 | so.linker_allow_undefined_version = false; | ||
| 2062 | |||
| 2063 | expectLinkErrors( | ||
| 2064 | so, | ||
| 2065 | test_step, | ||
| 2066 | .{ | ||
| 2067 | .contains = "error: ld.lld: version script assignment of 'ADD_1.0' to symbol 'sub' failed: symbol not defined", | ||
| 2068 | }, | ||
| 2069 | ); | ||
| 2070 | |||
| 2071 | return test_step; | ||
| 2072 | } | ||
| 2073 | |||
| 2011 | fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step { | 2074 | fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step { |
| 2012 | const test_step = addTestStep(b, "mismatched-cpu-architecture-error", opts); | 2075 | const test_step = addTestStep(b, "mismatched-cpu-architecture-error", opts); |
| 2013 | 2076 |