authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-02 14:05:51+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-02 22:00:16+01:00
log92deebcd668750bd4042c5874bf35b447828cd8a
tree412ac01bd1ee8c20bf4fc55281626e885e8fd0e4
parent9eda6ccefce370c76209ea50dd57fe65bfe25536

cli+build: handle -ObjC flag and route it to MachO linker


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