Commit aef8bcf776
Changed files (2)
lib
std
Build
Step
test
link
macho
search_strategy
lib/std/Build/Step/Compile.zig
@@ -149,13 +149,6 @@ entitlements: ?[]const u8 = null,
/// (Darwin) Size of the pagezero segment.
pagezero_size: ?u64 = null,
-/// (Darwin) Search strategy for searching system libraries. Either `paths_first` or `dylibs_first`.
-/// The former lowers to `-search_paths_first` linker option, while the latter to `-search_dylibs_first`
-/// option.
-/// By default, if no option is specified, the linker assumes `paths_first` as the default
-/// search strategy.
-search_strategy: ?enum { paths_first, dylibs_first } = null,
-
/// (Darwin) Set size of the padding between the end of load commands
/// and start of `__TEXT,__text` section.
headerpad_size: ?u32 = null,
@@ -242,7 +235,11 @@ pub const SystemLib = struct {
name: []const u8,
needed: bool,
weak: bool,
- use_pkg_config: enum {
+ use_pkg_config: UsePkgConfig,
+ preferred_link_mode: std.builtin.LinkMode,
+ search_strategy: SystemLib.SearchStrategy,
+
+ pub const UsePkgConfig = enum {
/// Don't use pkg-config, just pass -lfoo where foo is name.
no,
/// Try to get information on how to link the library from pkg-config.
@@ -251,7 +248,9 @@ pub const SystemLib = struct {
/// Try to get information on how to link the library from pkg-config.
/// If that fails, error out.
force,
- },
+ };
+
+ pub const SearchStrategy = enum { paths_first, mode_first, no_fallback };
};
const FrameworkLinkInfo = struct {
@@ -718,74 +717,29 @@ pub fn defineCMacroRaw(self: *Compile, name_and_value: []const u8) void {
self.c_macros.append(b.dupe(name_and_value)) catch @panic("OOM");
}
-/// This one has no integration with anything, it just puts -lname on the command line.
-/// Prefer to use `linkSystemLibrary` instead.
+/// deprecated: use linkSystemLibrary2
pub fn linkSystemLibraryName(self: *Compile, name: []const u8) void {
- const b = self.step.owner;
- self.link_objects.append(.{
- .system_lib = .{
- .name = b.dupe(name),
- .needed = false,
- .weak = false,
- .use_pkg_config = .no,
- },
- }) catch @panic("OOM");
+ return linkSystemLibrary2(self, name, .{ .use_pkg_config = .no });
}
-/// This one has no integration with anything, it just puts -needed-lname on the command line.
-/// Prefer to use `linkSystemLibraryNeeded` instead.
+/// deprecated: use linkSystemLibrary2
pub fn linkSystemLibraryNeededName(self: *Compile, name: []const u8) void {
- const b = self.step.owner;
- self.link_objects.append(.{
- .system_lib = .{
- .name = b.dupe(name),
- .needed = true,
- .weak = false,
- .use_pkg_config = .no,
- },
- }) catch @panic("OOM");
+ return linkSystemLibrary2(self, name, .{ .needed = true, .use_pkg_config = .no });
}
-/// Darwin-only. This one has no integration with anything, it just puts -weak-lname on the
-/// command line. Prefer to use `linkSystemLibraryWeak` instead.
+/// deprecated: use linkSystemLibrary2
pub fn linkSystemLibraryWeakName(self: *Compile, name: []const u8) void {
- const b = self.step.owner;
- self.link_objects.append(.{
- .system_lib = .{
- .name = b.dupe(name),
- .needed = false,
- .weak = true,
- .use_pkg_config = .no,
- },
- }) catch @panic("OOM");
+ return linkSystemLibrary2(self, name, .{ .weak = true, .use_pkg_config = .no });
}
-/// This links against a system library, exclusively using pkg-config to find the library.
-/// Prefer to use `linkSystemLibrary` instead.
+/// deprecated: use linkSystemLibrary2
pub fn linkSystemLibraryPkgConfigOnly(self: *Compile, lib_name: []const u8) void {
- const b = self.step.owner;
- self.link_objects.append(.{
- .system_lib = .{
- .name = b.dupe(lib_name),
- .needed = false,
- .weak = false,
- .use_pkg_config = .force,
- },
- }) catch @panic("OOM");
+ return linkSystemLibrary2(self, lib_name, .{ .use_pkg_config = .force });
}
-/// This links against a system library, exclusively using pkg-config to find the library.
-/// Prefer to use `linkSystemLibraryNeeded` instead.
+/// deprecated: use linkSystemLibrary2
pub fn linkSystemLibraryNeededPkgConfigOnly(self: *Compile, lib_name: []const u8) void {
- const b = self.step.owner;
- self.link_objects.append(.{
- .system_lib = .{
- .name = b.dupe(lib_name),
- .needed = true,
- .weak = false,
- .use_pkg_config = .force,
- },
- }) catch @panic("OOM");
+ return linkSystemLibrary2(self, lib_name, .{ .needed = true, .use_pkg_config = .force });
}
/// Run pkg-config for the given library name and parse the output, returning the arguments
@@ -885,21 +839,32 @@ fn runPkgConfig(self: *Compile, lib_name: []const u8) ![]const []const u8 {
}
pub fn linkSystemLibrary(self: *Compile, name: []const u8) void {
- self.linkSystemLibraryInner(name, .{});
+ self.linkSystemLibrary2(name, .{});
}
+/// deprecated: use linkSystemLibrary2
pub fn linkSystemLibraryNeeded(self: *Compile, name: []const u8) void {
- self.linkSystemLibraryInner(name, .{ .needed = true });
+ return linkSystemLibrary2(self, name, .{ .needed = true });
}
+/// deprecated: use linkSystemLibrary2
pub fn linkSystemLibraryWeak(self: *Compile, name: []const u8) void {
- self.linkSystemLibraryInner(name, .{ .weak = true });
+ return linkSystemLibrary2(self, name, .{ .weak = true });
}
-fn linkSystemLibraryInner(self: *Compile, name: []const u8, opts: struct {
+pub const LinkSystemLibraryOptions = struct {
needed: bool = false,
weak: bool = false,
-}) void {
+ use_pkg_config: SystemLib.UsePkgConfig = .yes,
+ preferred_link_mode: std.builtin.LinkMode = .Dynamic,
+ search_strategy: SystemLib.SearchStrategy = .paths_first,
+};
+
+pub fn linkSystemLibrary2(
+ self: *Compile,
+ name: []const u8,
+ options: LinkSystemLibraryOptions,
+) void {
const b = self.step.owner;
if (isLibCLibrary(name)) {
self.linkLibC();
@@ -913,9 +878,11 @@ fn linkSystemLibraryInner(self: *Compile, name: []const u8, opts: struct {
self.link_objects.append(.{
.system_lib = .{
.name = b.dupe(name),
- .needed = opts.needed,
- .weak = opts.weak,
- .use_pkg_config = .yes,
+ .needed = options.needed,
+ .weak = options.weak,
+ .use_pkg_config = options.use_pkg_config,
+ .preferred_link_mode = options.preferred_link_mode,
+ .search_strategy = options.search_strategy,
},
}) catch @panic("OOM");
}
@@ -1385,6 +1352,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try transitive_deps.add(self.link_objects.items);
var prev_has_cflags = false;
+ var prev_search_strategy: SystemLib.SearchStrategy = .paths_first;
+ var prev_preferred_link_mode: std.builtin.LinkMode = .Dynamic;
for (transitive_deps.link_objects.items) |link_object| {
switch (link_object) {
@@ -1420,6 +1389,28 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
},
.system_lib => |system_lib| {
+ if ((system_lib.search_strategy != prev_search_strategy or
+ system_lib.preferred_link_mode != prev_preferred_link_mode) and
+ self.linkage != .static)
+ {
+ switch (system_lib.search_strategy) {
+ .no_fallback => switch (system_lib.preferred_link_mode) {
+ .Dynamic => try zig_args.append("-search_dylibs_only"),
+ .Static => try zig_args.append("-search_static_only"),
+ },
+ .paths_first => switch (system_lib.preferred_link_mode) {
+ .Dynamic => try zig_args.append("-search_paths_first"),
+ .Static => try zig_args.append("-search_paths_first_static"),
+ },
+ .mode_first => switch (system_lib.preferred_link_mode) {
+ .Dynamic => try zig_args.append("-search_dylibs_first"),
+ .Static => try zig_args.append("-search_static_first"),
+ },
+ }
+ prev_search_strategy = system_lib.search_strategy;
+ prev_preferred_link_mode = system_lib.preferred_link_mode;
+ }
+
const prefix: []const u8 = prefix: {
if (system_lib.needed) break :prefix "-needed-l";
if (system_lib.weak) break :prefix "-weak-l";
@@ -1662,10 +1653,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
const size = try std.fmt.allocPrint(b.allocator, "{x}", .{pagezero_size});
try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size });
}
- if (self.search_strategy) |strat| switch (strat) {
- .paths_first => try zig_args.append("-search_paths_first"),
- .dylibs_first => try zig_args.append("-search_dylibs_first"),
- };
if (self.headerpad_size) |headerpad_size| {
const size = try std.fmt.allocPrint(b.allocator, "{x}", .{headerpad_size});
try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size });
test/link/macho/search_strategy/build.zig
@@ -17,8 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
{
// -search_dylibs_first
- const exe = createScenario(b, optimize, target, "search_dylibs_first");
- exe.search_strategy = .dylibs_first;
+ const exe = createScenario(b, optimize, target, "search_dylibs_first", .mode_first);
const check = exe.checkObject();
check.checkStart();
@@ -34,8 +33,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
{
// -search_paths_first
- const exe = createScenario(b, optimize, target, "search_paths_first");
- exe.search_strategy = .paths_first;
+ const exe = createScenario(b, optimize, target, "search_paths_first", .paths_first);
const run = b.addRunArtifact(exe);
run.skip_foreign_checks = true;
@@ -49,6 +47,7 @@ fn createScenario(
optimize: std.builtin.OptimizeMode,
target: std.zig.CrossTarget,
name: []const u8,
+ search_strategy: std.Build.Step.Compile.SystemLib.SearchStrategy,
) *std.Build.Step.Compile {
const static = b.addStaticLibrary(.{
.name = name,
@@ -73,7 +72,10 @@ fn createScenario(
.target = target,
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
- exe.linkSystemLibraryName(name);
+ exe.linkSystemLibrary2(name, .{
+ .use_pkg_config = .no,
+ .search_strategy = search_strategy,
+ });
exe.linkLibC();
exe.addLibraryPath(static.getEmittedBinDirectory());
exe.addLibraryPath(dylib.getEmittedBinDirectory());