authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-28 09:13:45+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-06-28 09:19:01+02:00
log20bd722464699bd11a05fe8e250f9f8086853cf2
treec7f656b95936a06410cffacf360461ef71b4b5b3
parentcd5dcfbf41dc6f40a853b2a207bd3ab0ea0dc0ee

build: handle weakly imported libs and frameworks


1 files changed, 61 insertions(+), 11 deletions(-)

lib/std/build.zig+61-11
......@@ -1483,7 +1483,7 @@ pub const LibExeObjStep = struct {
14831483 lib_paths: ArrayList([]const u8),
14841484 rpaths: ArrayList([]const u8),
14851485 framework_dirs: ArrayList([]const u8),
1486 frameworks: StringHashMap(bool),
1486 frameworks: StringHashMap(FrameworkLinkInfo),
14871487 verbose_link: bool,
14881488 verbose_cc: bool,
14891489 emit_analysis: EmitOption = .default,
......@@ -1643,6 +1643,7 @@ pub const LibExeObjStep = struct {
16431643 pub const SystemLib = struct {
16441644 name: []const u8,
16451645 needed: bool,
1646 weak: bool,
16461647 use_pkg_config: enum {
16471648 /// Don't use pkg-config, just pass -lfoo where foo is name.
16481649 no,
......@@ -1655,6 +1656,11 @@ pub const LibExeObjStep = struct {
16551656 },
16561657 };
16571658
1659 const FrameworkLinkInfo = struct {
1660 needed: bool = false,
1661 weak: bool = false,
1662 };
1663
16581664 pub const IncludeDir = union(enum) {
16591665 raw_path: []const u8,
16601666 raw_path_system: []const u8,
......@@ -1744,7 +1750,7 @@ pub const LibExeObjStep = struct {
17441750 .kind = kind,
17451751 .root_src = root_src,
17461752 .name = name,
1747 .frameworks = StringHashMap(bool).init(builder.allocator),
1753 .frameworks = StringHashMap(FrameworkLinkInfo).init(builder.allocator),
17481754 .step = Step.init(base_id, name, builder.allocator, make),
17491755 .version = ver,
17501756 .out_filename = undefined,
......@@ -1893,11 +1899,19 @@ pub const LibExeObjStep = struct {
18931899 }
18941900
18951901 pub fn linkFramework(self: *LibExeObjStep, framework_name: []const u8) void {
1896 self.frameworks.put(self.builder.dupe(framework_name), false) catch unreachable;
1902 self.frameworks.put(self.builder.dupe(framework_name), .{}) catch unreachable;
18971903 }
18981904
18991905 pub fn linkFrameworkNeeded(self: *LibExeObjStep, framework_name: []const u8) void {
1900 self.frameworks.put(self.builder.dupe(framework_name), true) catch unreachable;
1906 self.frameworks.put(self.builder.dupe(framework_name), .{
1907 .needed = true,
1908 }) catch unreachable;
1909 }
1910
1911 pub fn linkFrameworkWeak(self: *LibExeObjStep, framework_name: []const u8) void {
1912 self.frameworks.put(self.builder.dupe(framework_name), .{
1913 .weak = true,
1914 }) catch unreachable;
19011915 }
19021916
19031917 /// Returns whether the library, executable, or object depends on a particular system library.
......@@ -1939,6 +1953,7 @@ pub const LibExeObjStep = struct {
19391953 .system_lib = .{
19401954 .name = "c",
19411955 .needed = false,
1956 .weak = false,
19421957 .use_pkg_config = .no,
19431958 },
19441959 }) catch unreachable;
......@@ -1952,6 +1967,7 @@ pub const LibExeObjStep = struct {
19521967 .system_lib = .{
19531968 .name = "c++",
19541969 .needed = false,
1970 .weak = false,
19551971 .use_pkg_config = .no,
19561972 },
19571973 }) catch unreachable;
......@@ -1977,6 +1993,7 @@ pub const LibExeObjStep = struct {
19771993 .system_lib = .{
19781994 .name = self.builder.dupe(name),
19791995 .needed = false,
1996 .weak = false,
19801997 .use_pkg_config = .no,
19811998 },
19821999 }) catch unreachable;
......@@ -1989,6 +2006,20 @@ pub const LibExeObjStep = struct {
19892006 .system_lib = .{
19902007 .name = self.builder.dupe(name),
19912008 .needed = true,
2009 .weak = false,
2010 .use_pkg_config = .no,
2011 },
2012 }) catch unreachable;
2013 }
2014
2015 /// Darwin-only. This one has no integration with anything, it just puts -weak-lname on the
2016 /// command line. Prefer to use `linkSystemLibraryWeak` instead.
2017 pub fn linkSystemLibraryWeakName(self: *LibExeObjStep, name: []const u8) void {
2018 self.link_objects.append(.{
2019 .system_lib = .{
2020 .name = self.builder.dupe(name),
2021 .needed = false,
2022 .weak = true,
19922023 .use_pkg_config = .no,
19932024 },
19942025 }) catch unreachable;
......@@ -2001,6 +2032,7 @@ pub const LibExeObjStep = struct {
20012032 .system_lib = .{
20022033 .name = self.builder.dupe(lib_name),
20032034 .needed = false,
2035 .weak = false,
20042036 .use_pkg_config = .force,
20052037 },
20062038 }) catch unreachable;
......@@ -2013,6 +2045,7 @@ pub const LibExeObjStep = struct {
20132045 .system_lib = .{
20142046 .name = self.builder.dupe(lib_name),
20152047 .needed = true,
2048 .weak = false,
20162049 .use_pkg_config = .force,
20172050 },
20182051 }) catch unreachable;
......@@ -2115,14 +2148,21 @@ pub const LibExeObjStep = struct {
21152148 }
21162149
21172150 pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void {
2118 self.linkSystemLibraryInner(name, false);
2151 self.linkSystemLibraryInner(name, .{});
21192152 }
21202153
21212154 pub fn linkSystemLibraryNeeded(self: *LibExeObjStep, name: []const u8) void {
2122 self.linkSystemLibraryInner(name, true);
2155 self.linkSystemLibraryInner(name, .{ .needed = true });
21232156 }
21242157
2125 fn linkSystemLibraryInner(self: *LibExeObjStep, name: []const u8, needed: bool) void {
2158 pub fn linkSystemLibraryWeak(self: *LibExeObjStep, name: []const u8) void {
2159 self.linkSystemLibraryInner(name, .{ .weak = true });
2160 }
2161
2162 fn linkSystemLibraryInner(self: *LibExeObjStep, name: []const u8, opts: struct {
2163 needed: bool = false,
2164 weak: bool = false,
2165 }) void {
21262166 if (isLibCLibrary(name)) {
21272167 self.linkLibC();
21282168 return;
......@@ -2135,7 +2175,8 @@ pub const LibExeObjStep = struct {
21352175 self.link_objects.append(.{
21362176 .system_lib = .{
21372177 .name = self.builder.dupe(name),
2138 .needed = needed,
2178 .needed = opts.needed,
2179 .weak = opts.weak,
21392180 .use_pkg_config = .yes,
21402181 },
21412182 }) catch unreachable;
......@@ -2513,7 +2554,14 @@ pub const LibExeObjStep = struct {
25132554 },
25142555
25152556 .system_lib => |system_lib| {
2516 const prefix: []const u8 = if (system_lib.needed) "-needed-l" else "-l";
2557 const prefix: []const u8 = prefix: {
2558 if (system_lib.needed) break :prefix "-needed-l";
2559 if (system_lib.weak) {
2560 if (self.target.isDarwin()) break :prefix "-weak-l";
2561 warn("Weak library import used for a non-darwin target, this will be converted to normally library import `-lname`\n", .{});
2562 }
2563 break :prefix "-l";
2564 };
25172565 switch (system_lib.use_pkg_config) {
25182566 .no => try zig_args.append(builder.fmt("{s}{s}", .{ prefix, system_lib.name })),
25192567 .yes, .force => {
......@@ -3018,9 +3066,11 @@ pub const LibExeObjStep = struct {
30183066 var it = self.frameworks.iterator();
30193067 while (it.next()) |entry| {
30203068 const name = entry.key_ptr.*;
3021 const needed = entry.value_ptr.*;
3022 if (needed) {
3069 const info = entry.value_ptr.*;
3070 if (info.needed) {
30233071 zig_args.append("-needed_framework") catch unreachable;
3072 } else if (info.weak) {
3073 zig_args.append("-weak_framework") catch unreachable;
30243074 } else {
30253075 zig_args.append("-framework") catch unreachable;
30263076 }