| ... | @@ -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 | }; |
| 1657 | | 1658 | |
| | 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 | } |
| 1894 | | 1900 | |
| 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 | } |
| 1898 | | 1904 | |
| 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 | } |
| 1902 | | 1916 | |
| 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 | } |
| 2116 | | 2149 | |
| 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 | } |
| 2120 | | 2153 | |
| 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 | } |
| 2124 | | 2157 | |
| 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 | }, |
| 2514 | | 2555 | |
| 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 | } |