| author | |
| committer | |
| log | 92deebcd668750bd4042c5874bf35b447828cd8a |
| tree | 412ac01bd1ee8c20bf4fc55281626e885e8fd0e4 |
| parent | 9eda6ccefce370c76209ea50dd57fe65bfe25536 |
11 files changed, 91 insertions(+), 31 deletions(-)
lib/std/Build/Step/Compile.zig+6| ... | ... | @@ -149,6 +149,9 @@ headerpad_max_install_names: bool = false, |
| 149 | 149 | /// (Darwin) Remove dylibs that are unreachable by the entry point or exported symbols. |
| 150 | 150 | dead_strip_dylibs: bool = false, |
| 151 | 151 | |
| 152 | /// (Darwin) Force load all members of static archives that implement an Objective-C class or category | |
| 153 | force_load_objc: bool = false, | |
| 154 | ||
| 152 | 155 | /// Position Independent Executable |
| 153 | 156 | pie: ?bool = null, |
| 154 | 157 | |
| ... | ... | @@ -1433,6 +1436,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1433 | 1436 | if (self.dead_strip_dylibs) { |
| 1434 | 1437 | try zig_args.append("-dead_strip_dylibs"); |
| 1435 | 1438 | } |
| 1439 | if (self.force_load_objc) { | |
| 1440 | try zig_args.append("-ObjC"); | |
| 1441 | } | |
| 1436 | 1442 | |
| 1437 | 1443 | try addFlag(&zig_args, "compiler-rt", self.bundle_compiler_rt); |
| 1438 | 1444 | try addFlag(&zig_args, "dll-export-fns", self.dll_export_fns); |
src/Compilation.zig+6-2| ... | ... | @@ -1113,6 +1113,8 @@ pub const CreateOptions = struct { |
| 1113 | 1113 | headerpad_max_install_names: bool = false, |
| 1114 | 1114 | /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols |
| 1115 | 1115 | dead_strip_dylibs: bool = false, |
| 1116 | /// (Darwin) Force load all members of static archives that implement an Objective-C class or category | |
| 1117 | force_load_objc: bool = false, | |
| 1116 | 1118 | libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default, |
| 1117 | 1119 | /// (Windows) PDB source path prefix to instruct the linker how to resolve relative |
| 1118 | 1120 | /// paths when consolidating CodeView streams into a single PDB file. |
| ... | ... | @@ -1591,6 +1593,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1591 | 1593 | .headerpad_size = options.headerpad_size, |
| 1592 | 1594 | .headerpad_max_install_names = options.headerpad_max_install_names, |
| 1593 | 1595 | .dead_strip_dylibs = options.dead_strip_dylibs, |
| 1596 | .force_load_objc = options.force_load_objc, | |
| 1594 | 1597 | .pdb_source_path = options.pdb_source_path, |
| 1595 | 1598 | .pdb_out_path = options.pdb_out_path, |
| 1596 | 1599 | .entry_addr = null, // CLI does not expose this option (yet?) |
| ... | ... | @@ -2456,7 +2459,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo |
| 2456 | 2459 | /// to remind the programmer to update multiple related pieces of code that |
| 2457 | 2460 | /// are in different locations. Bump this number when adding or deleting |
| 2458 | 2461 | /// anything from the link cache manifest. |
| 2459 | pub const link_hash_implementation_version = 11; | |
| 2462 | pub const link_hash_implementation_version = 12; | |
| 2460 | 2463 | |
| 2461 | 2464 | fn addNonIncrementalStuffToCacheManifest( |
| 2462 | 2465 | comp: *Compilation, |
| ... | ... | @@ -2465,7 +2468,7 @@ fn addNonIncrementalStuffToCacheManifest( |
| 2465 | 2468 | ) !void { |
| 2466 | 2469 | const gpa = comp.gpa; |
| 2467 | 2470 | |
| 2468 | comptime assert(link_hash_implementation_version == 11); | |
| 2471 | comptime assert(link_hash_implementation_version == 12); | |
| 2469 | 2472 | |
| 2470 | 2473 | if (comp.module) |mod| { |
| 2471 | 2474 | try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man }); |
| ... | ... | @@ -2589,6 +2592,7 @@ fn addNonIncrementalStuffToCacheManifest( |
| 2589 | 2592 | man.hash.addOptional(opts.headerpad_size); |
| 2590 | 2593 | man.hash.add(opts.headerpad_max_install_names); |
| 2591 | 2594 | man.hash.add(opts.dead_strip_dylibs); |
| 2595 | man.hash.add(opts.force_load_objc); | |
| 2592 | 2596 | |
| 2593 | 2597 | // COFF specific stuff |
| 2594 | 2598 | man.hash.addOptional(opts.subsystem); |
src/clang_options_data.zig+8-1| ... | ... | @@ -115,7 +115,14 @@ flagpd1("Mach"), |
| 115 | 115 | .pd2 = false, |
| 116 | 116 | .psl = false, |
| 117 | 117 | }, |
| 118 | flagpd1("ObjC"), | |
| 118 | .{ | |
| 119 | .name = "ObjC", | |
| 120 | .syntax = .flag, | |
| 121 | .zig_equivalent = .force_load_objc, | |
| 122 | .pd1 = true, | |
| 123 | .pd2 = false, | |
| 124 | .psl = false, | |
| 125 | }, | |
| 119 | 126 | flagpd1("ObjC++"), |
| 120 | 127 | flagpd1("P"), |
| 121 | 128 | flagpd1("Q"), |
src/link.zig+16-10| ... | ... | @@ -136,30 +136,36 @@ pub const File = struct { |
| 136 | 136 | framework_dirs: []const []const u8, |
| 137 | 137 | rpath_list: []const []const u8, |
| 138 | 138 | |
| 139 | /// (Zig compiler development) Enable dumping of linker's state as JSON. | |
| 139 | /// Zig compiler development linker flags. | |
| 140 | /// Enable dumping of linker's state as JSON. | |
| 140 | 141 | enable_link_snapshots: bool, |
| 141 | 142 | |
| 142 | /// (Darwin) Install name for the dylib | |
| 143 | /// Darwin-specific linker flags: | |
| 144 | /// Install name for the dylib | |
| 143 | 145 | install_name: ?[]const u8, |
| 144 | /// (Darwin) Path to entitlements file | |
| 146 | /// Path to entitlements file | |
| 145 | 147 | entitlements: ?[]const u8, |
| 146 | /// (Darwin) size of the __PAGEZERO segment | |
| 148 | /// size of the __PAGEZERO segment | |
| 147 | 149 | pagezero_size: ?u64, |
| 148 | /// (Darwin) set minimum space for future expansion of the load commands | |
| 150 | /// Set minimum space for future expansion of the load commands | |
| 149 | 151 | headerpad_size: ?u32, |
| 150 | /// (Darwin) set enough space as if all paths were MATPATHLEN | |
| 152 | /// Set enough space as if all paths were MATPATHLEN | |
| 151 | 153 | headerpad_max_install_names: bool, |
| 152 | /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols | |
| 154 | /// Remove dylibs that are unreachable by the entry point or exported symbols | |
| 153 | 155 | dead_strip_dylibs: bool, |
| 154 | 156 | frameworks: []const MachO.Framework, |
| 155 | 157 | darwin_sdk_layout: ?MachO.SdkLayout, |
| 158 | /// Force load all members of static archives that implement an | |
| 159 | /// Objective-C class or category | |
| 160 | force_load_objc: bool, | |
| 156 | 161 | |
| 157 | /// (Windows) PDB source path prefix to instruct the linker how to resolve relative | |
| 162 | /// Windows-specific linker flags: | |
| 163 | /// PDB source path prefix to instruct the linker how to resolve relative | |
| 158 | 164 | /// paths when consolidating CodeView streams into a single PDB file. |
| 159 | 165 | pdb_source_path: ?[]const u8, |
| 160 | /// (Windows) PDB output path | |
| 166 | /// PDB output path | |
| 161 | 167 | pdb_out_path: ?[]const u8, |
| 162 | /// (Windows) .def file to specify when linking | |
| 168 | /// .def file to specify when linking | |
| 163 | 169 | module_definition_file: ?[]const u8, |
| 164 | 170 | |
| 165 | 171 | pub const Entry = union(enum) { |
src/link/Coff/lld.zig+1-1| ... | ... | @@ -70,7 +70,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) |
| 70 | 70 | man = comp.cache_parent.obtain(); |
| 71 | 71 | self.base.releaseLock(); |
| 72 | 72 | |
| 73 | comptime assert(Compilation.link_hash_implementation_version == 11); | |
| 73 | comptime assert(Compilation.link_hash_implementation_version == 12); | |
| 74 | 74 | |
| 75 | 75 | for (comp.objects) |obj| { |
| 76 | 76 | _ = try man.addFile(obj.path, null); |
src/link/Elf.zig+1-1| ... | ... | @@ -2380,7 +2380,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !voi |
| 2380 | 2380 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 2381 | 2381 | self.base.releaseLock(); |
| 2382 | 2382 | |
| 2383 | comptime assert(Compilation.link_hash_implementation_version == 11); | |
| 2383 | comptime assert(Compilation.link_hash_implementation_version == 12); | |
| 2384 | 2384 | |
| 2385 | 2385 | try man.addOptionalFile(self.linker_script); |
| 2386 | 2386 | try man.addOptionalFile(self.version_script); |
src/link/MachO.zig+7-2| ... | ... | @@ -217,6 +217,7 @@ pub fn createEmpty( |
| 217 | 217 | .undefined_treatment = if (allow_shlib_undefined) .dynamic_lookup else .@"error", |
| 218 | 218 | .lib_dirs = options.lib_dirs, |
| 219 | 219 | .framework_dirs = options.framework_dirs, |
| 220 | .force_load_objc = options.force_load_objc, | |
| 220 | 221 | }; |
| 221 | 222 | if (use_llvm and comp.config.have_zcu) { |
| 222 | 223 | self.llvm_object = try LlvmObject.create(arena, comp); |
| ... | ... | @@ -807,6 +808,10 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { |
| 807 | 808 | try argv.append("-dead_strip_dylibs"); |
| 808 | 809 | } |
| 809 | 810 | |
| 811 | if (self.force_load_objc) { | |
| 812 | try argv.append("-ObjC"); | |
| 813 | } | |
| 814 | ||
| 810 | 815 | if (self.entry_name) |entry_name| { |
| 811 | 816 | try argv.appendSlice(&.{ "-e", entry_name }); |
| 812 | 817 | } |
| ... | ... | @@ -1247,7 +1252,7 @@ fn parseDependentDylibs(self: *MachO) !void { |
| 1247 | 1252 | try checked_paths.append(rel_path); |
| 1248 | 1253 | var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined; |
| 1249 | 1254 | const full_path = std.fs.realpath(rel_path, &buffer) catch continue; |
| 1250 | break :full_path full_path; | |
| 1255 | break :full_path try arena.dupe(u8, full_path); | |
| 1251 | 1256 | } |
| 1252 | 1257 | } else if (eatPrefix(id.name, "@loader_path/")) |_| { |
| 1253 | 1258 | try self.reportParseError2(dylib_index, "TODO handle install_name '{s}'", .{id.name}); |
| ... | ... | @@ -1260,7 +1265,7 @@ fn parseDependentDylibs(self: *MachO) !void { |
| 1260 | 1265 | try checked_paths.append(try arena.dupe(u8, id.name)); |
| 1261 | 1266 | var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined; |
| 1262 | 1267 | if (std.fs.realpath(id.name, &buffer)) |full_path| { |
| 1263 | break :full_path full_path; | |
| 1268 | break :full_path try arena.dupe(u8, full_path); | |
| 1264 | 1269 | } else |_| { |
| 1265 | 1270 | try self.reportMissingDependencyError( |
| 1266 | 1271 | self.getFile(dylib_index).?.dylib.getUmbrella(self).index, |
src/link/Wasm.zig+2-2| ... | ... | @@ -3511,7 +3511,7 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin |
| 3511 | 3511 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 3512 | 3512 | wasm.base.releaseLock(); |
| 3513 | 3513 | |
| 3514 | comptime assert(Compilation.link_hash_implementation_version == 11); | |
| 3514 | comptime assert(Compilation.link_hash_implementation_version == 12); | |
| 3515 | 3515 | |
| 3516 | 3516 | for (objects) |obj| { |
| 3517 | 3517 | _ = try man.addFile(obj.path, null); |
| ... | ... | @@ -4580,7 +4580,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !vo |
| 4580 | 4580 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 4581 | 4581 | wasm.base.releaseLock(); |
| 4582 | 4582 | |
| 4583 | comptime assert(Compilation.link_hash_implementation_version == 11); | |
| 4583 | comptime assert(Compilation.link_hash_implementation_version == 12); | |
| 4584 | 4584 | |
| 4585 | 4585 | for (comp.objects) |obj| { |
| 4586 | 4586 | _ = try man.addFile(obj.path, null); |
src/main.zig+10-1| ... | ... | @@ -559,6 +559,7 @@ const usage_build_generic = |
| 559 | 559 | \\ -headerpad_max_install_names (Darwin) set enough space as if all paths were MAXPATHLEN |
| 560 | 560 | \\ -dead_strip (Darwin) remove functions and data that are unreachable by the entry point or exported symbols |
| 561 | 561 | \\ -dead_strip_dylibs (Darwin) remove dylibs that are unreachable by the entry point or exported symbols |
| 562 | \\ -ObjC (Darwin) force load all members of static archives that implement an Objective-C class or category | |
| 562 | 563 | \\ --import-memory (WebAssembly) import memory from the environment |
| 563 | 564 | \\ --export-memory (WebAssembly) export memory to the host (Default unless --import-memory used) |
| 564 | 565 | \\ --import-symbols (WebAssembly) import missing symbols from the host environment |
| ... | ... | @@ -589,7 +590,7 @@ const usage_build_generic = |
| 589 | 590 | \\ -rpath [path] Add directory to the runtime library search path |
| 590 | 591 | \\ -framework [name] (Darwin) link against framework |
| 591 | 592 | \\ -needed_framework [name] (Darwin) link against framework (even if unused) |
| 592 | \\ -needed_library [lib] link against system library (even if unused) | |
| 593 | \\ -needed_library [lib] (Darwin) link against system library (even if unused) | |
| 593 | 594 | \\ -weak_framework [name] (Darwin) link against framework and mark it and all referenced symbols as weak |
| 594 | 595 | \\ -F[dir] (Darwin) add search path for frameworks |
| 595 | 596 | \\ --export=[value] (WebAssembly) Force a symbol to be exported |
| ... | ... | @@ -889,6 +890,7 @@ fn buildOutputType( |
| 889 | 890 | var headerpad_size: ?u32 = null; |
| 890 | 891 | var headerpad_max_install_names: bool = false; |
| 891 | 892 | var dead_strip_dylibs: bool = false; |
| 893 | var force_load_objc: bool = false; | |
| 892 | 894 | var contains_res_file: bool = false; |
| 893 | 895 | var reference_trace: ?u32 = null; |
| 894 | 896 | var pdb_out_path: ?[]const u8 = null; |
| ... | ... | @@ -1182,6 +1184,8 @@ fn buildOutputType( |
| 1182 | 1184 | linker_gc_sections = true; |
| 1183 | 1185 | } else if (mem.eql(u8, arg, "-dead_strip_dylibs")) { |
| 1184 | 1186 | dead_strip_dylibs = true; |
| 1187 | } else if (mem.eql(u8, arg, "-ObjC")) { | |
| 1188 | force_load_objc = true; | |
| 1185 | 1189 | } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) { |
| 1186 | 1190 | linker_script = args_iter.nextOrFatal(); |
| 1187 | 1191 | } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) { |
| ... | ... | @@ -2061,6 +2065,7 @@ fn buildOutputType( |
| 2061 | 2065 | .force_undefined_symbol => { |
| 2062 | 2066 | try force_undefined_symbols.put(arena, it.only_arg, {}); |
| 2063 | 2067 | }, |
| 2068 | .force_load_objc => force_load_objc = true, | |
| 2064 | 2069 | .weak_library => try create_module.system_libs.put(arena, it.only_arg, .{ |
| 2065 | 2070 | .needed = false, |
| 2066 | 2071 | .weak = true, |
| ... | ... | @@ -2167,6 +2172,8 @@ fn buildOutputType( |
| 2167 | 2172 | linker_gc_sections = true; |
| 2168 | 2173 | } else if (mem.eql(u8, arg, "-dead_strip_dylibs")) { |
| 2169 | 2174 | dead_strip_dylibs = true; |
| 2175 | } else if (mem.eql(u8, arg, "-ObjC")) { | |
| 2176 | force_load_objc = true; | |
| 2170 | 2177 | } else if (mem.eql(u8, arg, "--no-undefined")) { |
| 2171 | 2178 | linker_z_defs = true; |
| 2172 | 2179 | } else if (mem.eql(u8, arg, "--gc-sections")) { |
| ... | ... | @@ -3246,6 +3253,7 @@ fn buildOutputType( |
| 3246 | 3253 | .headerpad_size = headerpad_size, |
| 3247 | 3254 | .headerpad_max_install_names = headerpad_max_install_names, |
| 3248 | 3255 | .dead_strip_dylibs = dead_strip_dylibs, |
| 3256 | .force_load_objc = force_load_objc, | |
| 3249 | 3257 | .reference_trace = reference_trace, |
| 3250 | 3258 | .pdb_out_path = pdb_out_path, |
| 3251 | 3259 | .error_limit = error_limit, |
| ... | ... | @@ -6266,6 +6274,7 @@ pub const ClangArgIterator = struct { |
| 6266 | 6274 | compress_debug_sections, |
| 6267 | 6275 | install_name, |
| 6268 | 6276 | undefined, |
| 6277 | force_load_objc, | |
| 6269 | 6278 | }; |
| 6270 | 6279 | |
| 6271 | 6280 | const Args = struct { |
test/link/macho.zig+30-11| ... | ... | @@ -969,19 +969,38 @@ fn testObjc(b: *Build, opts: Options) *Step { |
| 969 | 969 | \\@end |
| 970 | 970 | }); |
| 971 | 971 | |
| 972 | const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = "int main() { return 0; }" }); | |
| 973 | exe.root_module.linkSystemLibrary("a", .{}); | |
| 974 | exe.root_module.linkFramework("Foundation", .{}); | |
| 975 | exe.root_module.addLibraryPath(lib.getEmittedBinDirectory()); | |
| 972 | { | |
| 973 | const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = "int main() { return 0; }" }); | |
| 974 | exe.root_module.linkSystemLibrary("a", .{}); | |
| 975 | exe.root_module.linkFramework("Foundation", .{}); | |
| 976 | exe.root_module.addLibraryPath(lib.getEmittedBinDirectory()); | |
| 976 | 977 | |
| 977 | const check = exe.checkObject(); | |
| 978 | check.checkInSymtab(); | |
| 979 | check.checkContains("_OBJC_"); | |
| 980 | test_step.dependOn(&check.step); | |
| 978 | const check = exe.checkObject(); | |
| 979 | check.checkInSymtab(); | |
| 980 | check.checkNotPresent("_OBJC_"); | |
| 981 | test_step.dependOn(&check.step); | |
| 981 | 982 | |
| 982 | const run = addRunArtifact(exe); | |
| 983 | run.expectExitCode(0); | |
| 984 | test_step.dependOn(&run.step); | |
| 983 | const run = addRunArtifact(exe); | |
| 984 | run.expectExitCode(0); | |
| 985 | test_step.dependOn(&run.step); | |
| 986 | } | |
| 987 | ||
| 988 | { | |
| 989 | const exe = addExecutable(b, opts, .{ .name = "main2", .c_source_bytes = "int main() { return 0; }" }); | |
| 990 | exe.root_module.linkSystemLibrary("a", .{}); | |
| 991 | exe.root_module.linkFramework("Foundation", .{}); | |
| 992 | exe.root_module.addLibraryPath(lib.getEmittedBinDirectory()); | |
| 993 | exe.force_load_objc = true; | |
| 994 | ||
| 995 | const check = exe.checkObject(); | |
| 996 | check.checkInSymtab(); | |
| 997 | check.checkContains("_OBJC_"); | |
| 998 | test_step.dependOn(&check.step); | |
| 999 | ||
| 1000 | const run = addRunArtifact(exe); | |
| 1001 | run.expectExitCode(0); | |
| 1002 | test_step.dependOn(&run.step); | |
| 1003 | } | |
| 985 | 1004 | |
| 986 | 1005 | return test_step; |
| 987 | 1006 | } |
tools/update_clang_options.zig+4| ... | ... | @@ -528,6 +528,10 @@ const known_options = [_]KnownOpt{ |
| 528 | 528 | .name = "x", |
| 529 | 529 | .ident = "x", |
| 530 | 530 | }, |
| 531 | .{ | |
| 532 | .name = "ObjC", | |
| 533 | .ident = "force_load_objc", | |
| 534 | }, | |
| 531 | 535 | }; |
| 532 | 536 | |
| 533 | 537 | const blacklisted_options = [_][]const u8{}; |