mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
macho: allow undefined symbols in dylibs
We now respect both `-fallow-shlib-undefined` and `-Wl,"-undefined=dynamic_lookup"` flags. This is the first step towards solving issues #8180 and #3000. We currently do not expose any other ld64 equivalent flag for `-undefined` flag - we basically throw an error should the user specify a different flag. Support for those is conditional on closing #8180. As a result of this change, it is now possible to generate a valid native Node.js addon with Zig for macOS.
This commit is contained in:
parent
efdb94486b
commit
dbfcebf8d8
@ -444,6 +444,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
|
|||||||
const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
|
const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
|
||||||
const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe;
|
const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe;
|
||||||
const stack_size = self.base.options.stack_size_override orelse 0;
|
const stack_size = self.base.options.stack_size_override orelse 0;
|
||||||
|
const allow_undef = is_dyn_lib and (self.base.options.allow_shlib_undefined orelse false);
|
||||||
|
|
||||||
const id_symlink_basename = "zld.id";
|
const id_symlink_basename = "zld.id";
|
||||||
|
|
||||||
@ -847,6 +848,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
|
|||||||
try argv.append(try std.fmt.allocPrint(arena, "-F{s}", .{framework_dir}));
|
try argv.append(try std.fmt.allocPrint(arena, "-F{s}", .{framework_dir}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allow_undef) {
|
||||||
|
try argv.append("-undefined");
|
||||||
|
try argv.append("dynamic_lookup");
|
||||||
|
}
|
||||||
|
|
||||||
Compilation.dump_argv(argv.items);
|
Compilation.dump_argv(argv.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -899,6 +905,16 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
|
|||||||
};
|
};
|
||||||
_ = self.unresolved.swapRemove(resolv.where_index);
|
_ = self.unresolved.swapRemove(resolv.where_index);
|
||||||
continue;
|
continue;
|
||||||
|
} else if (allow_undef) {
|
||||||
|
const n_desc = @bitCast(
|
||||||
|
u16,
|
||||||
|
macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP * @intCast(i16, macho.N_SYMBOL_RESOLVER),
|
||||||
|
);
|
||||||
|
// TODO allow_shlib_undefined is an ELF flag so figure out macOS specific flags too.
|
||||||
|
sym.n_type = macho.N_EXT;
|
||||||
|
sym.n_desc = n_desc;
|
||||||
|
_ = self.unresolved.swapRemove(resolv.where_index);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.err("undefined reference to symbol '{s}'", .{sym_name});
|
log.err("undefined reference to symbol '{s}'", .{sym_name});
|
||||||
@ -5111,7 +5127,7 @@ fn writeDyldInfoData(self: *MachO) !void {
|
|||||||
try bind_pointers.append(.{
|
try bind_pointers.append(.{
|
||||||
.offset = binding.offset + base_offset,
|
.offset = binding.offset + base_offset,
|
||||||
.segment_id = match.seg,
|
.segment_id = match.seg,
|
||||||
.dylib_ordinal = @divExact(bind_sym.n_desc, macho.N_SYMBOL_RESOLVER),
|
.dylib_ordinal = @divExact(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER),
|
||||||
.name = self.getString(bind_sym.n_strx),
|
.name = self.getString(bind_sym.n_strx),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -5133,7 +5149,7 @@ fn writeDyldInfoData(self: *MachO) !void {
|
|||||||
try lazy_bind_pointers.append(.{
|
try lazy_bind_pointers.append(.{
|
||||||
.offset = binding.offset + base_offset,
|
.offset = binding.offset + base_offset,
|
||||||
.segment_id = match.seg,
|
.segment_id = match.seg,
|
||||||
.dylib_ordinal = @divExact(bind_sym.n_desc, macho.N_SYMBOL_RESOLVER),
|
.dylib_ordinal = @divExact(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER),
|
||||||
.name = self.getString(bind_sym.n_strx),
|
.name = self.getString(bind_sym.n_strx),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
10
src/main.zig
10
src/main.zig
@ -1703,6 +1703,16 @@ fn buildOutputType(
|
|||||||
}
|
}
|
||||||
emit_implib = .{ .yes = linker_args.items[i] };
|
emit_implib = .{ .yes = linker_args.items[i] };
|
||||||
emit_implib_arg_provided = true;
|
emit_implib_arg_provided = true;
|
||||||
|
} else if (mem.eql(u8, arg, "-undefined")) {
|
||||||
|
i += 1;
|
||||||
|
if (i >= linker_args.items.len) {
|
||||||
|
fatal("expected linker arg after '{s}'", .{arg});
|
||||||
|
}
|
||||||
|
if (mem.eql(u8, "dynamic_lookup", linker_args.items[i])) {
|
||||||
|
linker_allow_shlib_undefined = true;
|
||||||
|
} else {
|
||||||
|
fatal("unsupported -undefined option '{s}'", .{linker_args.items[i]});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
warn("unsupported linker arg: {s}", .{arg});
|
warn("unsupported linker arg: {s}", .{arg});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user