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 {...@@ -1483,7 +1483,7 @@ pub const LibExeObjStep = struct {
1483 lib_paths: ArrayList([]const u8),1483 lib_paths: ArrayList([]const u8),
1484 rpaths: ArrayList([]const u8),1484 rpaths: ArrayList([]const u8),
1485 framework_dirs: ArrayList([]const u8),1485 framework_dirs: ArrayList([]const u8),
1486 frameworks: StringHashMap(bool),1486 frameworks: StringHashMap(FrameworkLinkInfo),
1487 verbose_link: bool,1487 verbose_link: bool,
1488 verbose_cc: bool,1488 verbose_cc: bool,
1489 emit_analysis: EmitOption = .default,1489 emit_analysis: EmitOption = .default,
...@@ -1643,6 +1643,7 @@ pub const LibExeObjStep = struct {...@@ -1643,6 +1643,7 @@ pub const LibExeObjStep = struct {
1643 pub const SystemLib = struct {1643 pub const SystemLib = struct {
1644 name: []const u8,1644 name: []const u8,
1645 needed: bool,1645 needed: bool,
1646 weak: bool,
1646 use_pkg_config: enum {1647 use_pkg_config: enum {
1647 /// Don't use pkg-config, just pass -lfoo where foo is name.1648 /// Don't use pkg-config, just pass -lfoo where foo is name.
1648 no,1649 no,
...@@ -1655,6 +1656,11 @@ pub const LibExeObjStep = struct {...@@ -1655,6 +1656,11 @@ pub const LibExeObjStep = struct {
1655 },1656 },
1656 };1657 };
16571658
1659 const FrameworkLinkInfo = struct {
1660 needed: bool = false,
1661 weak: bool = false,
1662 };
1663
1658 pub const IncludeDir = union(enum) {1664 pub const IncludeDir = union(enum) {
1659 raw_path: []const u8,1665 raw_path: []const u8,
1660 raw_path_system: []const u8,1666 raw_path_system: []const u8,
...@@ -1744,7 +1750,7 @@ pub const LibExeObjStep = struct {...@@ -1744,7 +1750,7 @@ pub const LibExeObjStep = struct {
1744 .kind = kind,1750 .kind = kind,
1745 .root_src = root_src,1751 .root_src = root_src,
1746 .name = name,1752 .name = name,
1747 .frameworks = StringHashMap(bool).init(builder.allocator),1753 .frameworks = StringHashMap(FrameworkLinkInfo).init(builder.allocator),
1748 .step = Step.init(base_id, name, builder.allocator, make),1754 .step = Step.init(base_id, name, builder.allocator, make),
1749 .version = ver,1755 .version = ver,
1750 .out_filename = undefined,1756 .out_filename = undefined,
...@@ -1893,11 +1899,19 @@ pub const LibExeObjStep = struct {...@@ -1893,11 +1899,19 @@ pub const LibExeObjStep = struct {
1893 }1899 }
18941900
1895 pub fn linkFramework(self: *LibExeObjStep, framework_name: []const u8) void {1901 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;
1897 }1903 }
18981904
1899 pub fn linkFrameworkNeeded(self: *LibExeObjStep, framework_name: []const u8) void {1905 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;
1901 }1915 }
19021916
1903 /// Returns whether the library, executable, or object depends on a particular system library.1917 /// Returns whether the library, executable, or object depends on a particular system library.
...@@ -1939,6 +1953,7 @@ pub const LibExeObjStep = struct {...@@ -1939,6 +1953,7 @@ pub const LibExeObjStep = struct {
1939 .system_lib = .{1953 .system_lib = .{
1940 .name = "c",1954 .name = "c",
1941 .needed = false,1955 .needed = false,
1956 .weak = false,
1942 .use_pkg_config = .no,1957 .use_pkg_config = .no,
1943 },1958 },
1944 }) catch unreachable;1959 }) catch unreachable;
...@@ -1952,6 +1967,7 @@ pub const LibExeObjStep = struct {...@@ -1952,6 +1967,7 @@ pub const LibExeObjStep = struct {
1952 .system_lib = .{1967 .system_lib = .{
1953 .name = "c++",1968 .name = "c++",
1954 .needed = false,1969 .needed = false,
1970 .weak = false,
1955 .use_pkg_config = .no,1971 .use_pkg_config = .no,
1956 },1972 },
1957 }) catch unreachable;1973 }) catch unreachable;
...@@ -1977,6 +1993,7 @@ pub const LibExeObjStep = struct {...@@ -1977,6 +1993,7 @@ pub const LibExeObjStep = struct {
1977 .system_lib = .{1993 .system_lib = .{
1978 .name = self.builder.dupe(name),1994 .name = self.builder.dupe(name),
1979 .needed = false,1995 .needed = false,
1996 .weak = false,
1980 .use_pkg_config = .no,1997 .use_pkg_config = .no,
1981 },1998 },
1982 }) catch unreachable;1999 }) catch unreachable;
...@@ -1989,6 +2006,20 @@ pub const LibExeObjStep = struct {...@@ -1989,6 +2006,20 @@ pub const LibExeObjStep = struct {
1989 .system_lib = .{2006 .system_lib = .{
1990 .name = self.builder.dupe(name),2007 .name = self.builder.dupe(name),
1991 .needed = true,2008 .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,
1992 .use_pkg_config = .no,2023 .use_pkg_config = .no,
1993 },2024 },
1994 }) catch unreachable;2025 }) catch unreachable;
...@@ -2001,6 +2032,7 @@ pub const LibExeObjStep = struct {...@@ -2001,6 +2032,7 @@ pub const LibExeObjStep = struct {
2001 .system_lib = .{2032 .system_lib = .{
2002 .name = self.builder.dupe(lib_name),2033 .name = self.builder.dupe(lib_name),
2003 .needed = false,2034 .needed = false,
2035 .weak = false,
2004 .use_pkg_config = .force,2036 .use_pkg_config = .force,
2005 },2037 },
2006 }) catch unreachable;2038 }) catch unreachable;
...@@ -2013,6 +2045,7 @@ pub const LibExeObjStep = struct {...@@ -2013,6 +2045,7 @@ pub const LibExeObjStep = struct {
2013 .system_lib = .{2045 .system_lib = .{
2014 .name = self.builder.dupe(lib_name),2046 .name = self.builder.dupe(lib_name),
2015 .needed = true,2047 .needed = true,
2048 .weak = false,
2016 .use_pkg_config = .force,2049 .use_pkg_config = .force,
2017 },2050 },
2018 }) catch unreachable;2051 }) catch unreachable;
...@@ -2115,14 +2148,21 @@ pub const LibExeObjStep = struct {...@@ -2115,14 +2148,21 @@ pub const LibExeObjStep = struct {
2115 }2148 }
21162149
2117 pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void {2150 pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void {
2118 self.linkSystemLibraryInner(name, false);2151 self.linkSystemLibraryInner(name, .{});
2119 }2152 }
21202153
2121 pub fn linkSystemLibraryNeeded(self: *LibExeObjStep, name: []const u8) void {2154 pub fn linkSystemLibraryNeeded(self: *LibExeObjStep, name: []const u8) void {
2122 self.linkSystemLibraryInner(name, true);2155 self.linkSystemLibraryInner(name, .{ .needed = true });
2123 }2156 }
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 {
2126 if (isLibCLibrary(name)) {2166 if (isLibCLibrary(name)) {
2127 self.linkLibC();2167 self.linkLibC();
2128 return;2168 return;
...@@ -2135,7 +2175,8 @@ pub const LibExeObjStep = struct {...@@ -2135,7 +2175,8 @@ pub const LibExeObjStep = struct {
2135 self.link_objects.append(.{2175 self.link_objects.append(.{
2136 .system_lib = .{2176 .system_lib = .{
2137 .name = self.builder.dupe(name),2177 .name = self.builder.dupe(name),
2138 .needed = needed,2178 .needed = opts.needed,
2179 .weak = opts.weak,
2139 .use_pkg_config = .yes,2180 .use_pkg_config = .yes,
2140 },2181 },
2141 }) catch unreachable;2182 }) catch unreachable;
...@@ -2513,7 +2554,14 @@ pub const LibExeObjStep = struct {...@@ -2513,7 +2554,14 @@ pub const LibExeObjStep = struct {
2513 },2554 },
25142555
2515 .system_lib => |system_lib| {2556 .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 };
2517 switch (system_lib.use_pkg_config) {2565 switch (system_lib.use_pkg_config) {
2518 .no => try zig_args.append(builder.fmt("{s}{s}", .{ prefix, system_lib.name })),2566 .no => try zig_args.append(builder.fmt("{s}{s}", .{ prefix, system_lib.name })),
2519 .yes, .force => {2567 .yes, .force => {
...@@ -3018,9 +3066,11 @@ pub const LibExeObjStep = struct {...@@ -3018,9 +3066,11 @@ pub const LibExeObjStep = struct {
3018 var it = self.frameworks.iterator();3066 var it = self.frameworks.iterator();
3019 while (it.next()) |entry| {3067 while (it.next()) |entry| {
3020 const name = entry.key_ptr.*;3068 const name = entry.key_ptr.*;
3021 const needed = entry.value_ptr.*;3069 const info = entry.value_ptr.*;
3022 if (needed) {3070 if (info.needed) {
3023 zig_args.append("-needed_framework") catch unreachable;3071 zig_args.append("-needed_framework") catch unreachable;
3072 } else if (info.weak) {
3073 zig_args.append("-weak_framework") catch unreachable;
3024 } else {3074 } else {
3025 zig_args.append("-framework") catch unreachable;3075 zig_args.append("-framework") catch unreachable;
3026 }3076 }