| author | |
| committer | |
| log | c4e62be62e8d8a006cc9d7861232f511c5a05385 |
| tree | 2e28a575a3eef3bbf80ddd7d8f27ab607d720d85 |
| parent | f887b0251822f75dc4a3e24ca5337cb681c1eb1f |
| parent | d0fd67cffe664ff70d9a70dd4d2d28aba5a378e8 |
| signature |
compiler: resolve library paths in the frontend21 files changed, 914 insertions(+), 717 deletions(-)
build.zig+3-4| ... | @@ -204,10 +204,9 @@ pub fn build(b: *std.Build) !void { | ... | @@ -204,10 +204,9 @@ pub fn build(b: *std.Build) !void { |
| 204 | ); | 204 | ); |
| 205 | 205 | ||
| 206 | if (!no_bin) { | 206 | if (!no_bin) { |
| 207 | const install_exe = b.addInstallArtifact(exe, .{}); | 207 | const install_exe = b.addInstallArtifact(exe, .{ |
| 208 | if (flat) { | 208 | .dest_dir = if (flat) .{ .override = .prefix } else .default, |
| 209 | install_exe.dest_dir = .prefix; | 209 | }); |
| 210 | } | ||
| 211 | b.getInstallStep().dependOn(&install_exe.step); | 210 | b.getInstallStep().dependOn(&install_exe.step); |
| 212 | } | 211 | } |
| 213 | 212 |
ci/aarch64-linux-debug.sh+1-1| ... | @@ -72,7 +72,7 @@ stage3-debug/bin/zig build test docs \ | ... | @@ -72,7 +72,7 @@ stage3-debug/bin/zig build test docs \ |
| 72 | 72 | ||
| 73 | # Look for HTML errors. | 73 | # Look for HTML errors. |
| 74 | # TODO: move this to a build.zig flag (-Denable-tidy) | 74 | # TODO: move this to a build.zig flag (-Denable-tidy) |
| 75 | tidy --drop-empty-elements no -qe "zig-out/doc/langref.html" | 75 | tidy --drop-empty-elements no -qe "../zig-out/doc/langref.html" |
| 76 | 76 | ||
| 77 | # Ensure that updating the wasm binary from this commit will result in a viable build. | 77 | # Ensure that updating the wasm binary from this commit will result in a viable build. |
| 78 | stage3-debug/bin/zig build update-zig1 | 78 | stage3-debug/bin/zig build update-zig1 |
ci/aarch64-linux-release.sh+1-1| ... | @@ -72,7 +72,7 @@ stage3-release/bin/zig build test docs \ | ... | @@ -72,7 +72,7 @@ stage3-release/bin/zig build test docs \ |
| 72 | 72 | ||
| 73 | # Look for HTML errors. | 73 | # Look for HTML errors. |
| 74 | # TODO: move this to a build.zig flag (-Denable-tidy) | 74 | # TODO: move this to a build.zig flag (-Denable-tidy) |
| 75 | tidy --drop-empty-elements no -qe "zig-out/doc/langref.html" | 75 | tidy --drop-empty-elements no -qe "../zig-out/doc/langref.html" |
| 76 | 76 | ||
| 77 | # Ensure that updating the wasm binary from this commit will result in a viable build. | 77 | # Ensure that updating the wasm binary from this commit will result in a viable build. |
| 78 | stage3-release/bin/zig build update-zig1 | 78 | stage3-release/bin/zig build update-zig1 |
ci/x86_64-linux-debug.sh+1-1| ... | @@ -72,7 +72,7 @@ stage3-debug/bin/zig build test docs \ | ... | @@ -72,7 +72,7 @@ stage3-debug/bin/zig build test docs \ |
| 72 | 72 | ||
| 73 | # Look for HTML errors. | 73 | # Look for HTML errors. |
| 74 | # TODO: move this to a build.zig flag (-Denable-tidy) | 74 | # TODO: move this to a build.zig flag (-Denable-tidy) |
| 75 | tidy --drop-empty-elements no -qe "zig-out/doc/langref.html" | 75 | tidy --drop-empty-elements no -qe "../zig-out/doc/langref.html" |
| 76 | 76 | ||
| 77 | # Ensure that updating the wasm binary from this commit will result in a viable build. | 77 | # Ensure that updating the wasm binary from this commit will result in a viable build. |
| 78 | stage3-debug/bin/zig build update-zig1 | 78 | stage3-debug/bin/zig build update-zig1 |
ci/x86_64-linux-release.sh+1-1| ... | @@ -73,7 +73,7 @@ stage3-release/bin/zig build test docs \ | ... | @@ -73,7 +73,7 @@ stage3-release/bin/zig build test docs \ |
| 73 | 73 | ||
| 74 | # Look for HTML errors. | 74 | # Look for HTML errors. |
| 75 | # TODO: move this to a build.zig flag (-Denable-tidy) | 75 | # TODO: move this to a build.zig flag (-Denable-tidy) |
| 76 | tidy --drop-empty-elements no -qe "zig-out/doc/langref.html" | 76 | tidy --drop-empty-elements no -qe "../zig-out/doc/langref.html" |
| 77 | 77 | ||
| 78 | # Ensure that stage3 and stage4 are byte-for-byte identical. | 78 | # Ensure that stage3 and stage4 are byte-for-byte identical. |
| 79 | stage3-release/bin/zig build \ | 79 | stage3-release/bin/zig build \ |
lib/std/Build/Step/Compile.zig+63-76| ... | @@ -149,13 +149,6 @@ entitlements: ?[]const u8 = null, | ... | @@ -149,13 +149,6 @@ entitlements: ?[]const u8 = null, |
| 149 | /// (Darwin) Size of the pagezero segment. | 149 | /// (Darwin) Size of the pagezero segment. |
| 150 | pagezero_size: ?u64 = null, | 150 | pagezero_size: ?u64 = null, |
| 151 | 151 | ||
| 152 | /// (Darwin) Search strategy for searching system libraries. Either `paths_first` or `dylibs_first`. | ||
| 153 | /// The former lowers to `-search_paths_first` linker option, while the latter to `-search_dylibs_first` | ||
| 154 | /// option. | ||
| 155 | /// By default, if no option is specified, the linker assumes `paths_first` as the default | ||
| 156 | /// search strategy. | ||
| 157 | search_strategy: ?enum { paths_first, dylibs_first } = null, | ||
| 158 | |||
| 159 | /// (Darwin) Set size of the padding between the end of load commands | 152 | /// (Darwin) Set size of the padding between the end of load commands |
| 160 | /// and start of `__TEXT,__text` section. | 153 | /// and start of `__TEXT,__text` section. |
| 161 | headerpad_size: ?u32 = null, | 154 | headerpad_size: ?u32 = null, |
| ... | @@ -242,7 +235,11 @@ pub const SystemLib = struct { | ... | @@ -242,7 +235,11 @@ pub const SystemLib = struct { |
| 242 | name: []const u8, | 235 | name: []const u8, |
| 243 | needed: bool, | 236 | needed: bool, |
| 244 | weak: bool, | 237 | weak: bool, |
| 245 | use_pkg_config: enum { | 238 | use_pkg_config: UsePkgConfig, |
| 239 | preferred_link_mode: std.builtin.LinkMode, | ||
| 240 | search_strategy: SystemLib.SearchStrategy, | ||
| 241 | |||
| 242 | pub const UsePkgConfig = enum { | ||
| 246 | /// Don't use pkg-config, just pass -lfoo where foo is name. | 243 | /// Don't use pkg-config, just pass -lfoo where foo is name. |
| 247 | no, | 244 | no, |
| 248 | /// Try to get information on how to link the library from pkg-config. | 245 | /// Try to get information on how to link the library from pkg-config. |
| ... | @@ -251,7 +248,9 @@ pub const SystemLib = struct { | ... | @@ -251,7 +248,9 @@ pub const SystemLib = struct { |
| 251 | /// Try to get information on how to link the library from pkg-config. | 248 | /// Try to get information on how to link the library from pkg-config. |
| 252 | /// If that fails, error out. | 249 | /// If that fails, error out. |
| 253 | force, | 250 | force, |
| 254 | }, | 251 | }; |
| 252 | |||
| 253 | pub const SearchStrategy = enum { paths_first, mode_first, no_fallback }; | ||
| 255 | }; | 254 | }; |
| 256 | 255 | ||
| 257 | const FrameworkLinkInfo = struct { | 256 | const FrameworkLinkInfo = struct { |
| ... | @@ -718,74 +717,29 @@ pub fn defineCMacroRaw(self: *Compile, name_and_value: []const u8) void { | ... | @@ -718,74 +717,29 @@ pub fn defineCMacroRaw(self: *Compile, name_and_value: []const u8) void { |
| 718 | self.c_macros.append(b.dupe(name_and_value)) catch @panic("OOM"); | 717 | self.c_macros.append(b.dupe(name_and_value)) catch @panic("OOM"); |
| 719 | } | 718 | } |
| 720 | 719 | ||
| 721 | /// This one has no integration with anything, it just puts -lname on the command line. | 720 | /// deprecated: use linkSystemLibrary2 |
| 722 | /// Prefer to use `linkSystemLibrary` instead. | ||
| 723 | pub fn linkSystemLibraryName(self: *Compile, name: []const u8) void { | 721 | pub fn linkSystemLibraryName(self: *Compile, name: []const u8) void { |
| 724 | const b = self.step.owner; | 722 | return linkSystemLibrary2(self, name, .{ .use_pkg_config = .no }); |
| 725 | self.link_objects.append(.{ | ||
| 726 | .system_lib = .{ | ||
| 727 | .name = b.dupe(name), | ||
| 728 | .needed = false, | ||
| 729 | .weak = false, | ||
| 730 | .use_pkg_config = .no, | ||
| 731 | }, | ||
| 732 | }) catch @panic("OOM"); | ||
| 733 | } | 723 | } |
| 734 | 724 | ||
| 735 | /// This one has no integration with anything, it just puts -needed-lname on the command line. | 725 | /// deprecated: use linkSystemLibrary2 |
| 736 | /// Prefer to use `linkSystemLibraryNeeded` instead. | ||
| 737 | pub fn linkSystemLibraryNeededName(self: *Compile, name: []const u8) void { | 726 | pub fn linkSystemLibraryNeededName(self: *Compile, name: []const u8) void { |
| 738 | const b = self.step.owner; | 727 | return linkSystemLibrary2(self, name, .{ .needed = true, .use_pkg_config = .no }); |
| 739 | self.link_objects.append(.{ | ||
| 740 | .system_lib = .{ | ||
| 741 | .name = b.dupe(name), | ||
| 742 | .needed = true, | ||
| 743 | .weak = false, | ||
| 744 | .use_pkg_config = .no, | ||
| 745 | }, | ||
| 746 | }) catch @panic("OOM"); | ||
| 747 | } | 728 | } |
| 748 | 729 | ||
| 749 | /// Darwin-only. This one has no integration with anything, it just puts -weak-lname on the | 730 | /// deprecated: use linkSystemLibrary2 |
| 750 | /// command line. Prefer to use `linkSystemLibraryWeak` instead. | ||
| 751 | pub fn linkSystemLibraryWeakName(self: *Compile, name: []const u8) void { | 731 | pub fn linkSystemLibraryWeakName(self: *Compile, name: []const u8) void { |
| 752 | const b = self.step.owner; | 732 | return linkSystemLibrary2(self, name, .{ .weak = true, .use_pkg_config = .no }); |
| 753 | self.link_objects.append(.{ | ||
| 754 | .system_lib = .{ | ||
| 755 | .name = b.dupe(name), | ||
| 756 | .needed = false, | ||
| 757 | .weak = true, | ||
| 758 | .use_pkg_config = .no, | ||
| 759 | }, | ||
| 760 | }) catch @panic("OOM"); | ||
| 761 | } | 733 | } |
| 762 | 734 | ||
| 763 | /// This links against a system library, exclusively using pkg-config to find the library. | 735 | /// deprecated: use linkSystemLibrary2 |
| 764 | /// Prefer to use `linkSystemLibrary` instead. | ||
| 765 | pub fn linkSystemLibraryPkgConfigOnly(self: *Compile, lib_name: []const u8) void { | 736 | pub fn linkSystemLibraryPkgConfigOnly(self: *Compile, lib_name: []const u8) void { |
| 766 | const b = self.step.owner; | 737 | return linkSystemLibrary2(self, lib_name, .{ .use_pkg_config = .force }); |
| 767 | self.link_objects.append(.{ | ||
| 768 | .system_lib = .{ | ||
| 769 | .name = b.dupe(lib_name), | ||
| 770 | .needed = false, | ||
| 771 | .weak = false, | ||
| 772 | .use_pkg_config = .force, | ||
| 773 | }, | ||
| 774 | }) catch @panic("OOM"); | ||
| 775 | } | 738 | } |
| 776 | 739 | ||
| 777 | /// This links against a system library, exclusively using pkg-config to find the library. | 740 | /// deprecated: use linkSystemLibrary2 |
| 778 | /// Prefer to use `linkSystemLibraryNeeded` instead. | ||
| 779 | pub fn linkSystemLibraryNeededPkgConfigOnly(self: *Compile, lib_name: []const u8) void { | 741 | pub fn linkSystemLibraryNeededPkgConfigOnly(self: *Compile, lib_name: []const u8) void { |
| 780 | const b = self.step.owner; | 742 | return linkSystemLibrary2(self, lib_name, .{ .needed = true, .use_pkg_config = .force }); |
| 781 | self.link_objects.append(.{ | ||
| 782 | .system_lib = .{ | ||
| 783 | .name = b.dupe(lib_name), | ||
| 784 | .needed = true, | ||
| 785 | .weak = false, | ||
| 786 | .use_pkg_config = .force, | ||
| 787 | }, | ||
| 788 | }) catch @panic("OOM"); | ||
| 789 | } | 743 | } |
| 790 | 744 | ||
| 791 | /// Run pkg-config for the given library name and parse the output, returning the arguments | 745 | /// 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 { | ... | @@ -885,21 +839,32 @@ fn runPkgConfig(self: *Compile, lib_name: []const u8) ![]const []const u8 { |
| 885 | } | 839 | } |
| 886 | 840 | ||
| 887 | pub fn linkSystemLibrary(self: *Compile, name: []const u8) void { | 841 | pub fn linkSystemLibrary(self: *Compile, name: []const u8) void { |
| 888 | self.linkSystemLibraryInner(name, .{}); | 842 | self.linkSystemLibrary2(name, .{}); |
| 889 | } | 843 | } |
| 890 | 844 | ||
| 845 | /// deprecated: use linkSystemLibrary2 | ||
| 891 | pub fn linkSystemLibraryNeeded(self: *Compile, name: []const u8) void { | 846 | pub fn linkSystemLibraryNeeded(self: *Compile, name: []const u8) void { |
| 892 | self.linkSystemLibraryInner(name, .{ .needed = true }); | 847 | return linkSystemLibrary2(self, name, .{ .needed = true }); |
| 893 | } | 848 | } |
| 894 | 849 | ||
| 850 | /// deprecated: use linkSystemLibrary2 | ||
| 895 | pub fn linkSystemLibraryWeak(self: *Compile, name: []const u8) void { | 851 | pub fn linkSystemLibraryWeak(self: *Compile, name: []const u8) void { |
| 896 | self.linkSystemLibraryInner(name, .{ .weak = true }); | 852 | return linkSystemLibrary2(self, name, .{ .weak = true }); |
| 897 | } | 853 | } |
| 898 | 854 | ||
| 899 | fn linkSystemLibraryInner(self: *Compile, name: []const u8, opts: struct { | 855 | pub const LinkSystemLibraryOptions = struct { |
| 900 | needed: bool = false, | 856 | needed: bool = false, |
| 901 | weak: bool = false, | 857 | weak: bool = false, |
| 902 | }) void { | 858 | use_pkg_config: SystemLib.UsePkgConfig = .yes, |
| 859 | preferred_link_mode: std.builtin.LinkMode = .Dynamic, | ||
| 860 | search_strategy: SystemLib.SearchStrategy = .paths_first, | ||
| 861 | }; | ||
| 862 | |||
| 863 | pub fn linkSystemLibrary2( | ||
| 864 | self: *Compile, | ||
| 865 | name: []const u8, | ||
| 866 | options: LinkSystemLibraryOptions, | ||
| 867 | ) void { | ||
| 903 | const b = self.step.owner; | 868 | const b = self.step.owner; |
| 904 | if (isLibCLibrary(name)) { | 869 | if (isLibCLibrary(name)) { |
| 905 | self.linkLibC(); | 870 | self.linkLibC(); |
| ... | @@ -913,9 +878,11 @@ fn linkSystemLibraryInner(self: *Compile, name: []const u8, opts: struct { | ... | @@ -913,9 +878,11 @@ fn linkSystemLibraryInner(self: *Compile, name: []const u8, opts: struct { |
| 913 | self.link_objects.append(.{ | 878 | self.link_objects.append(.{ |
| 914 | .system_lib = .{ | 879 | .system_lib = .{ |
| 915 | .name = b.dupe(name), | 880 | .name = b.dupe(name), |
| 916 | .needed = opts.needed, | 881 | .needed = options.needed, |
| 917 | .weak = opts.weak, | 882 | .weak = options.weak, |
| 918 | .use_pkg_config = .yes, | 883 | .use_pkg_config = options.use_pkg_config, |
| 884 | .preferred_link_mode = options.preferred_link_mode, | ||
| 885 | .search_strategy = options.search_strategy, | ||
| 919 | }, | 886 | }, |
| 920 | }) catch @panic("OOM"); | 887 | }) catch @panic("OOM"); |
| 921 | } | 888 | } |
| ... | @@ -1385,6 +1352,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -1385,6 +1352,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1385 | try transitive_deps.add(self.link_objects.items); | 1352 | try transitive_deps.add(self.link_objects.items); |
| 1386 | 1353 | ||
| 1387 | var prev_has_cflags = false; | 1354 | var prev_has_cflags = false; |
| 1355 | var prev_search_strategy: SystemLib.SearchStrategy = .paths_first; | ||
| 1356 | var prev_preferred_link_mode: std.builtin.LinkMode = .Dynamic; | ||
| 1388 | 1357 | ||
| 1389 | for (transitive_deps.link_objects.items) |link_object| { | 1358 | for (transitive_deps.link_objects.items) |link_object| { |
| 1390 | switch (link_object) { | 1359 | switch (link_object) { |
| ... | @@ -1420,6 +1389,28 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -1420,6 +1389,28 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1420 | }, | 1389 | }, |
| 1421 | 1390 | ||
| 1422 | .system_lib => |system_lib| { | 1391 | .system_lib => |system_lib| { |
| 1392 | if ((system_lib.search_strategy != prev_search_strategy or | ||
| 1393 | system_lib.preferred_link_mode != prev_preferred_link_mode) and | ||
| 1394 | self.linkage != .static) | ||
| 1395 | { | ||
| 1396 | switch (system_lib.search_strategy) { | ||
| 1397 | .no_fallback => switch (system_lib.preferred_link_mode) { | ||
| 1398 | .Dynamic => try zig_args.append("-search_dylibs_only"), | ||
| 1399 | .Static => try zig_args.append("-search_static_only"), | ||
| 1400 | }, | ||
| 1401 | .paths_first => switch (system_lib.preferred_link_mode) { | ||
| 1402 | .Dynamic => try zig_args.append("-search_paths_first"), | ||
| 1403 | .Static => try zig_args.append("-search_paths_first_static"), | ||
| 1404 | }, | ||
| 1405 | .mode_first => switch (system_lib.preferred_link_mode) { | ||
| 1406 | .Dynamic => try zig_args.append("-search_dylibs_first"), | ||
| 1407 | .Static => try zig_args.append("-search_static_first"), | ||
| 1408 | }, | ||
| 1409 | } | ||
| 1410 | prev_search_strategy = system_lib.search_strategy; | ||
| 1411 | prev_preferred_link_mode = system_lib.preferred_link_mode; | ||
| 1412 | } | ||
| 1413 | |||
| 1423 | const prefix: []const u8 = prefix: { | 1414 | const prefix: []const u8 = prefix: { |
| 1424 | if (system_lib.needed) break :prefix "-needed-l"; | 1415 | if (system_lib.needed) break :prefix "-needed-l"; |
| 1425 | if (system_lib.weak) break :prefix "-weak-l"; | 1416 | if (system_lib.weak) break :prefix "-weak-l"; |
| ... | @@ -1662,10 +1653,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -1662,10 +1653,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1662 | const size = try std.fmt.allocPrint(b.allocator, "{x}", .{pagezero_size}); | 1653 | const size = try std.fmt.allocPrint(b.allocator, "{x}", .{pagezero_size}); |
| 1663 | try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size }); | 1654 | try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size }); |
| 1664 | } | 1655 | } |
| 1665 | if (self.search_strategy) |strat| switch (strat) { | ||
| 1666 | .paths_first => try zig_args.append("-search_paths_first"), | ||
| 1667 | .dylibs_first => try zig_args.append("-search_dylibs_first"), | ||
| 1668 | }; | ||
| 1669 | if (self.headerpad_size) |headerpad_size| { | 1656 | if (self.headerpad_size) |headerpad_size| { |
| 1670 | const size = try std.fmt.allocPrint(b.allocator, "{x}", .{headerpad_size}); | 1657 | const size = try std.fmt.allocPrint(b.allocator, "{x}", .{headerpad_size}); |
| 1671 | try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size }); | 1658 | try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size }); |
lib/std/zig/system/NativePaths.zig+32-74| ... | @@ -1,6 +1,5 @@ | ... | @@ -1,6 +1,5 @@ |
| 1 | const std = @import("../../std.zig"); | 1 | const std = @import("../../std.zig"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const ArrayList = std.ArrayList; | ||
| 4 | const Allocator = std.mem.Allocator; | 3 | const Allocator = std.mem.Allocator; |
| 5 | const process = std.process; | 4 | const process = std.process; |
| 6 | const mem = std.mem; | 5 | const mem = std.mem; |
| ... | @@ -8,28 +7,18 @@ const mem = std.mem; | ... | @@ -8,28 +7,18 @@ const mem = std.mem; |
| 8 | const NativePaths = @This(); | 7 | const NativePaths = @This(); |
| 9 | const NativeTargetInfo = std.zig.system.NativeTargetInfo; | 8 | const NativeTargetInfo = std.zig.system.NativeTargetInfo; |
| 10 | 9 | ||
| 11 | include_dirs: ArrayList([:0]u8), | 10 | arena: Allocator, |
| 12 | lib_dirs: ArrayList([:0]u8), | 11 | include_dirs: std.ArrayListUnmanaged([]const u8) = .{}, |
| 13 | framework_dirs: ArrayList([:0]u8), | 12 | lib_dirs: std.ArrayListUnmanaged([]const u8) = .{}, |
| 14 | rpaths: ArrayList([:0]u8), | 13 | framework_dirs: std.ArrayListUnmanaged([]const u8) = .{}, |
| 15 | warnings: ArrayList([:0]u8), | 14 | rpaths: std.ArrayListUnmanaged([]const u8) = .{}, |
| 15 | warnings: std.ArrayListUnmanaged([]const u8) = .{}, | ||
| 16 | 16 | ||
| 17 | pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths { | 17 | pub fn detect(arena: Allocator, native_info: NativeTargetInfo) !NativePaths { |
| 18 | const native_target = native_info.target; | 18 | const native_target = native_info.target; |
| 19 | 19 | var self: NativePaths = .{ .arena = arena }; | |
| 20 | var self: NativePaths = .{ | ||
| 21 | .include_dirs = ArrayList([:0]u8).init(allocator), | ||
| 22 | .lib_dirs = ArrayList([:0]u8).init(allocator), | ||
| 23 | .framework_dirs = ArrayList([:0]u8).init(allocator), | ||
| 24 | .rpaths = ArrayList([:0]u8).init(allocator), | ||
| 25 | .warnings = ArrayList([:0]u8).init(allocator), | ||
| 26 | }; | ||
| 27 | errdefer self.deinit(); | ||
| 28 | |||
| 29 | var is_nix = false; | 20 | var is_nix = false; |
| 30 | if (process.getEnvVarOwned(allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { | 21 | if (process.getEnvVarOwned(arena, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { |
| 31 | defer allocator.free(nix_cflags_compile); | ||
| 32 | |||
| 33 | is_nix = true; | 22 | is_nix = true; |
| 34 | var it = mem.tokenizeScalar(u8, nix_cflags_compile, ' '); | 23 | var it = mem.tokenizeScalar(u8, nix_cflags_compile, ' '); |
| 35 | while (true) { | 24 | while (true) { |
| ... | @@ -58,9 +47,7 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths | ... | @@ -58,9 +47,7 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths |
| 58 | error.EnvironmentVariableNotFound => {}, | 47 | error.EnvironmentVariableNotFound => {}, |
| 59 | error.OutOfMemory => |e| return e, | 48 | error.OutOfMemory => |e| return e, |
| 60 | } | 49 | } |
| 61 | if (process.getEnvVarOwned(allocator, "NIX_LDFLAGS")) |nix_ldflags| { | 50 | if (process.getEnvVarOwned(arena, "NIX_LDFLAGS")) |nix_ldflags| { |
| 62 | defer allocator.free(nix_ldflags); | ||
| 63 | |||
| 64 | is_nix = true; | 51 | is_nix = true; |
| 65 | var it = mem.tokenizeScalar(u8, nix_ldflags, ' '); | 52 | var it = mem.tokenizeScalar(u8, nix_ldflags, ' '); |
| 66 | while (true) { | 53 | while (true) { |
| ... | @@ -89,17 +76,16 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths | ... | @@ -89,17 +76,16 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths |
| 89 | return self; | 76 | return self; |
| 90 | } | 77 | } |
| 91 | 78 | ||
| 79 | // TODO: consider also adding homebrew paths | ||
| 80 | // TODO: consider also adding macports paths | ||
| 92 | if (comptime builtin.target.isDarwin()) { | 81 | if (comptime builtin.target.isDarwin()) { |
| 93 | try self.addIncludeDir("/usr/include"); | 82 | if (std.zig.system.darwin.isSdkInstalled(arena)) sdk: { |
| 94 | try self.addLibDir("/usr/lib"); | 83 | const sdk = std.zig.system.darwin.getSdk(arena, native_target) orelse break :sdk; |
| 95 | try self.addFrameworkDir("/System/Library/Frameworks"); | 84 | try self.addLibDir(try std.fs.path.join(arena, &.{ sdk.path, "usr/lib" })); |
| 96 | 85 | try self.addFrameworkDir(try std.fs.path.join(arena, &.{ sdk.path, "System/Library/Frameworks" })); | |
| 97 | if (builtin.target.os.version_range.semver.min.major < 11) { | 86 | try self.addIncludeDir(try std.fs.path.join(arena, &.{ sdk.path, "usr/include" })); |
| 98 | try self.addIncludeDir("/usr/local/include"); | 87 | return self; |
| 99 | try self.addLibDir("/usr/local/lib"); | ||
| 100 | try self.addFrameworkDir("/Library/Frameworks"); | ||
| 101 | } | 88 | } |
| 102 | |||
| 103 | return self; | 89 | return self; |
| 104 | } | 90 | } |
| 105 | 91 | ||
| ... | @@ -115,8 +101,7 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths | ... | @@ -115,8 +101,7 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths |
| 115 | } | 101 | } |
| 116 | 102 | ||
| 117 | if (builtin.os.tag != .windows) { | 103 | if (builtin.os.tag != .windows) { |
| 118 | const triple = try native_target.linuxTriple(allocator); | 104 | const triple = try native_target.linuxTriple(arena); |
| 119 | defer allocator.free(triple); | ||
| 120 | 105 | ||
| 121 | const qual = native_target.ptrBitWidth(); | 106 | const qual = native_target.ptrBitWidth(); |
| 122 | 107 | ||
| ... | @@ -172,69 +157,42 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths | ... | @@ -172,69 +157,42 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths |
| 172 | return self; | 157 | return self; |
| 173 | } | 158 | } |
| 174 | 159 | ||
| 175 | pub fn deinit(self: *NativePaths) void { | ||
| 176 | deinitArray(&self.include_dirs); | ||
| 177 | deinitArray(&self.lib_dirs); | ||
| 178 | deinitArray(&self.framework_dirs); | ||
| 179 | deinitArray(&self.rpaths); | ||
| 180 | deinitArray(&self.warnings); | ||
| 181 | self.* = undefined; | ||
| 182 | } | ||
| 183 | |||
| 184 | fn deinitArray(array: *ArrayList([:0]u8)) void { | ||
| 185 | for (array.items) |item| { | ||
| 186 | array.allocator.free(item); | ||
| 187 | } | ||
| 188 | array.deinit(); | ||
| 189 | } | ||
| 190 | |||
| 191 | pub fn addIncludeDir(self: *NativePaths, s: []const u8) !void { | 160 | pub fn addIncludeDir(self: *NativePaths, s: []const u8) !void { |
| 192 | return self.appendArray(&self.include_dirs, s); | 161 | return self.include_dirs.append(self.arena, s); |
| 193 | } | 162 | } |
| 194 | 163 | ||
| 195 | pub fn addIncludeDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { | 164 | pub fn addIncludeDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { |
| 196 | const item = try std.fmt.allocPrintZ(self.include_dirs.allocator, fmt, args); | 165 | const item = try std.fmt.allocPrint(self.arena, fmt, args); |
| 197 | errdefer self.include_dirs.allocator.free(item); | 166 | try self.include_dirs.append(self.arena, item); |
| 198 | try self.include_dirs.append(item); | ||
| 199 | } | 167 | } |
| 200 | 168 | ||
| 201 | pub fn addLibDir(self: *NativePaths, s: []const u8) !void { | 169 | pub fn addLibDir(self: *NativePaths, s: []const u8) !void { |
| 202 | return self.appendArray(&self.lib_dirs, s); | 170 | try self.lib_dirs.append(self.arena, s); |
| 203 | } | 171 | } |
| 204 | 172 | ||
| 205 | pub fn addLibDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { | 173 | pub fn addLibDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { |
| 206 | const item = try std.fmt.allocPrintZ(self.lib_dirs.allocator, fmt, args); | 174 | const item = try std.fmt.allocPrint(self.arena, fmt, args); |
| 207 | errdefer self.lib_dirs.allocator.free(item); | 175 | try self.lib_dirs.append(self.arena, item); |
| 208 | try self.lib_dirs.append(item); | ||
| 209 | } | 176 | } |
| 210 | 177 | ||
| 211 | pub fn addWarning(self: *NativePaths, s: []const u8) !void { | 178 | pub fn addWarning(self: *NativePaths, s: []const u8) !void { |
| 212 | return self.appendArray(&self.warnings, s); | 179 | return self.warnings.append(self.arena, s); |
| 213 | } | 180 | } |
| 214 | 181 | ||
| 215 | pub fn addFrameworkDir(self: *NativePaths, s: []const u8) !void { | 182 | pub fn addFrameworkDir(self: *NativePaths, s: []const u8) !void { |
| 216 | return self.appendArray(&self.framework_dirs, s); | 183 | return self.framework_dirs.append(self.arena, s); |
| 217 | } | 184 | } |
| 218 | 185 | ||
| 219 | pub fn addFrameworkDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { | 186 | pub fn addFrameworkDirFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { |
| 220 | const item = try std.fmt.allocPrintZ(self.framework_dirs.allocator, fmt, args); | 187 | const item = try std.fmt.allocPrint(self.arena, fmt, args); |
| 221 | errdefer self.framework_dirs.allocator.free(item); | 188 | try self.framework_dirs.append(self.arena, item); |
| 222 | try self.framework_dirs.append(item); | ||
| 223 | } | 189 | } |
| 224 | 190 | ||
| 225 | pub fn addWarningFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { | 191 | pub fn addWarningFmt(self: *NativePaths, comptime fmt: []const u8, args: anytype) !void { |
| 226 | const item = try std.fmt.allocPrintZ(self.warnings.allocator, fmt, args); | 192 | const item = try std.fmt.allocPrint(self.arena, fmt, args); |
| 227 | errdefer self.warnings.allocator.free(item); | 193 | try self.warnings.append(self.arena, item); |
| 228 | try self.warnings.append(item); | ||
| 229 | } | 194 | } |
| 230 | 195 | ||
| 231 | pub fn addRPath(self: *NativePaths, s: []const u8) !void { | 196 | pub fn addRPath(self: *NativePaths, s: []const u8) !void { |
| 232 | return self.appendArray(&self.rpaths, s); | 197 | try self.rpaths.append(self.arena, s); |
| 233 | } | ||
| 234 | |||
| 235 | fn appendArray(self: *NativePaths, array: *ArrayList([:0]u8), s: []const u8) !void { | ||
| 236 | _ = self; | ||
| 237 | const item = try array.allocator.dupeZ(u8, s); | ||
| 238 | errdefer array.allocator.free(item); | ||
| 239 | try array.append(item); | ||
| 240 | } | 198 | } |
lib/std/zig/system/darwin.zig+29-25| ... | @@ -8,28 +8,34 @@ pub const macos = @import("darwin/macos.zig"); | ... | @@ -8,28 +8,34 @@ pub const macos = @import("darwin/macos.zig"); |
| 8 | 8 | ||
| 9 | /// Check if SDK is installed on Darwin without triggering CLT installation popup window. | 9 | /// Check if SDK is installed on Darwin without triggering CLT installation popup window. |
| 10 | /// Note: simply invoking `xcrun` will inevitably trigger the CLT installation popup. | 10 | /// Note: simply invoking `xcrun` will inevitably trigger the CLT installation popup. |
| 11 | /// Therefore, we resort to the same tool used by Homebrew, namely, invoking `xcode-select --print-path` | 11 | /// Therefore, we resort to invoking `xcode-select --print-path` and checking |
| 12 | /// and checking if the status is nonzero or the returned string in nonempty. | 12 | /// if the status is nonzero. |
| 13 | /// https://github.com/Homebrew/brew/blob/e119bdc571dcb000305411bc1e26678b132afb98/Library/Homebrew/brew.sh#L630 | 13 | /// stderr from xcode-select is ignored. |
| 14 | pub fn isDarwinSDKInstalled(allocator: Allocator) bool { | 14 | /// If error.OutOfMemory occurs in Allocator, this function returns null. |
| 15 | const argv = &[_][]const u8{ "/usr/bin/xcode-select", "--print-path" }; | 15 | pub fn isSdkInstalled(allocator: Allocator) bool { |
| 16 | const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return false; | 16 | const result = std.process.Child.exec(.{ |
| 17 | .allocator = allocator, | ||
| 18 | .argv = &.{ "/usr/bin/xcode-select", "--print-path" }, | ||
| 19 | }) catch return false; | ||
| 20 | |||
| 17 | defer { | 21 | defer { |
| 18 | allocator.free(result.stderr); | 22 | allocator.free(result.stderr); |
| 19 | allocator.free(result.stdout); | 23 | allocator.free(result.stdout); |
| 20 | } | 24 | } |
| 21 | if (result.stderr.len != 0 or result.term.Exited != 0) { | 25 | |
| 22 | // We don't actually care if there were errors as this is best-effort check anyhow. | 26 | return switch (result.term) { |
| 23 | return false; | 27 | .Exited => |code| if (code == 0) result.stdout.len > 0 else false, |
| 24 | } | 28 | else => false, |
| 25 | return result.stdout.len > 0; | 29 | }; |
| 26 | } | 30 | } |
| 27 | 31 | ||
| 28 | /// Detect SDK on Darwin. | 32 | /// Detect SDK on Darwin. |
| 29 | /// Calls `xcrun --sdk <target_sdk> --show-sdk-path` which fetches the path to the SDK sysroot (if any). | 33 | /// Calls `xcrun --sdk <target_sdk> --show-sdk-path` which fetches the path to the SDK sysroot (if any). |
| 30 | /// Subsequently calls `xcrun --sdk <target_sdk> --show-sdk-version` which fetches version of the SDK. | 34 | /// Subsequently calls `xcrun --sdk <target_sdk> --show-sdk-version` which fetches version of the SDK. |
| 31 | /// The caller needs to deinit the resulting struct. | 35 | /// The caller needs to deinit the resulting struct. |
| 32 | pub fn getDarwinSDK(allocator: Allocator, target: Target) ?DarwinSDK { | 36 | /// stderr from xcrun is ignored. |
| 37 | /// If error.OutOfMemory occurs in Allocator, this function returns null. | ||
| 38 | pub fn getSdk(allocator: Allocator, target: Target) ?Sdk { | ||
| 33 | const is_simulator_abi = target.abi == .simulator; | 39 | const is_simulator_abi = target.abi == .simulator; |
| 34 | const sdk = switch (target.os.tag) { | 40 | const sdk = switch (target.os.tag) { |
| 35 | .macos => "macosx", | 41 | .macos => "macosx", |
| ... | @@ -40,30 +46,28 @@ pub fn getDarwinSDK(allocator: Allocator, target: Target) ?DarwinSDK { | ... | @@ -40,30 +46,28 @@ pub fn getDarwinSDK(allocator: Allocator, target: Target) ?DarwinSDK { |
| 40 | }; | 46 | }; |
| 41 | const path = path: { | 47 | const path = path: { |
| 42 | const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-path" }; | 48 | const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-path" }; |
| 43 | const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null; | 49 | const result = std.process.Child.exec(.{ .allocator = allocator, .argv = argv }) catch return null; |
| 44 | defer { | 50 | defer { |
| 45 | allocator.free(result.stderr); | 51 | allocator.free(result.stderr); |
| 46 | allocator.free(result.stdout); | 52 | allocator.free(result.stdout); |
| 47 | } | 53 | } |
| 48 | if (result.stderr.len != 0 or result.term.Exited != 0) { | 54 | switch (result.term) { |
| 49 | // We don't actually care if there were errors as this is best-effort check anyhow | 55 | .Exited => |code| if (code != 0) return null, |
| 50 | // and in the worst case the user can specify the sysroot manually. | 56 | else => return null, |
| 51 | return null; | ||
| 52 | } | 57 | } |
| 53 | const path = allocator.dupe(u8, mem.trimRight(u8, result.stdout, "\r\n")) catch return null; | 58 | const path = allocator.dupe(u8, mem.trimRight(u8, result.stdout, "\r\n")) catch return null; |
| 54 | break :path path; | 59 | break :path path; |
| 55 | }; | 60 | }; |
| 56 | const version = version: { | 61 | const version = version: { |
| 57 | const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-version" }; | 62 | const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-version" }; |
| 58 | const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null; | 63 | const result = std.process.Child.exec(.{ .allocator = allocator, .argv = argv }) catch return null; |
| 59 | defer { | 64 | defer { |
| 60 | allocator.free(result.stderr); | 65 | allocator.free(result.stderr); |
| 61 | allocator.free(result.stdout); | 66 | allocator.free(result.stdout); |
| 62 | } | 67 | } |
| 63 | if (result.stderr.len != 0 or result.term.Exited != 0) { | 68 | switch (result.term) { |
| 64 | // We don't actually care if there were errors as this is best-effort check anyhow | 69 | .Exited => |code| if (code != 0) return null, |
| 65 | // and in the worst case the user can specify the sysroot manually. | 70 | else => return null, |
| 66 | return null; | ||
| 67 | } | 71 | } |
| 68 | const raw_version = mem.trimRight(u8, result.stdout, "\r\n"); | 72 | const raw_version = mem.trimRight(u8, result.stdout, "\r\n"); |
| 69 | const version = parseSdkVersion(raw_version) orelse Version{ | 73 | const version = parseSdkVersion(raw_version) orelse Version{ |
| ... | @@ -73,7 +77,7 @@ pub fn getDarwinSDK(allocator: Allocator, target: Target) ?DarwinSDK { | ... | @@ -73,7 +77,7 @@ pub fn getDarwinSDK(allocator: Allocator, target: Target) ?DarwinSDK { |
| 73 | }; | 77 | }; |
| 74 | break :version version; | 78 | break :version version; |
| 75 | }; | 79 | }; |
| 76 | return DarwinSDK{ | 80 | return Sdk{ |
| 77 | .path = path, | 81 | .path = path, |
| 78 | .version = version, | 82 | .version = version, |
| 79 | }; | 83 | }; |
| ... | @@ -96,11 +100,11 @@ fn parseSdkVersion(raw: []const u8) ?Version { | ... | @@ -96,11 +100,11 @@ fn parseSdkVersion(raw: []const u8) ?Version { |
| 96 | return Version.parse(buffer[0..len]) catch null; | 100 | return Version.parse(buffer[0..len]) catch null; |
| 97 | } | 101 | } |
| 98 | 102 | ||
| 99 | pub const DarwinSDK = struct { | 103 | pub const Sdk = struct { |
| 100 | path: []const u8, | 104 | path: []const u8, |
| 101 | version: Version, | 105 | version: Version, |
| 102 | 106 | ||
| 103 | pub fn deinit(self: DarwinSDK, allocator: Allocator) void { | 107 | pub fn deinit(self: Sdk, allocator: Allocator) void { |
| 104 | allocator.free(self.path); | 108 | allocator.free(self.path); |
| 105 | } | 109 | } |
| 106 | }; | 110 | }; |
src/Compilation.zig+107-102| ... | @@ -124,6 +124,7 @@ zig_lib_directory: Directory, | ... | @@ -124,6 +124,7 @@ zig_lib_directory: Directory, |
| 124 | local_cache_directory: Directory, | 124 | local_cache_directory: Directory, |
| 125 | global_cache_directory: Directory, | 125 | global_cache_directory: Directory, |
| 126 | libc_include_dir_list: []const []const u8, | 126 | libc_include_dir_list: []const []const u8, |
| 127 | libc_framework_dir_list: []const []const u8, | ||
| 127 | thread_pool: *ThreadPool, | 128 | thread_pool: *ThreadPool, |
| 128 | 129 | ||
| 129 | /// Populated when we build the libc++ static library. A Job to build this is placed in the queue | 130 | /// Populated when we build the libc++ static library. A Job to build this is placed in the queue |
| ... | @@ -448,6 +449,7 @@ pub const ClangPreprocessorMode = enum { | ... | @@ -448,6 +449,7 @@ pub const ClangPreprocessorMode = enum { |
| 448 | stdout, | 449 | stdout, |
| 449 | }; | 450 | }; |
| 450 | 451 | ||
| 452 | pub const Framework = link.Framework; | ||
| 451 | pub const SystemLib = link.SystemLib; | 453 | pub const SystemLib = link.SystemLib; |
| 452 | pub const CacheMode = link.CacheMode; | 454 | pub const CacheMode = link.CacheMode; |
| 453 | 455 | ||
| ... | @@ -505,7 +507,7 @@ pub const InitOptions = struct { | ... | @@ -505,7 +507,7 @@ pub const InitOptions = struct { |
| 505 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, | 507 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, |
| 506 | link_objects: []LinkObject = &[0]LinkObject{}, | 508 | link_objects: []LinkObject = &[0]LinkObject{}, |
| 507 | framework_dirs: []const []const u8 = &[0][]const u8{}, | 509 | framework_dirs: []const []const u8 = &[0][]const u8{}, |
| 508 | frameworks: std.StringArrayHashMapUnmanaged(SystemLib) = .{}, | 510 | frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{}, |
| 509 | system_lib_names: []const []const u8 = &.{}, | 511 | system_lib_names: []const []const u8 = &.{}, |
| 510 | system_lib_infos: []const SystemLib = &.{}, | 512 | system_lib_infos: []const SystemLib = &.{}, |
| 511 | /// These correspond to the WASI libc emulated subcomponents including: | 513 | /// These correspond to the WASI libc emulated subcomponents including: |
| ... | @@ -636,16 +638,12 @@ pub const InitOptions = struct { | ... | @@ -636,16 +638,12 @@ pub const InitOptions = struct { |
| 636 | wasi_exec_model: ?std.builtin.WasiExecModel = null, | 638 | wasi_exec_model: ?std.builtin.WasiExecModel = null, |
| 637 | /// (Zig compiler development) Enable dumping linker's state as JSON. | 639 | /// (Zig compiler development) Enable dumping linker's state as JSON. |
| 638 | enable_link_snapshots: bool = false, | 640 | enable_link_snapshots: bool = false, |
| 639 | /// (Darwin) Path and version of the native SDK if detected. | ||
| 640 | native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null, | ||
| 641 | /// (Darwin) Install name of the dylib | 641 | /// (Darwin) Install name of the dylib |
| 642 | install_name: ?[]const u8 = null, | 642 | install_name: ?[]const u8 = null, |
| 643 | /// (Darwin) Path to entitlements file | 643 | /// (Darwin) Path to entitlements file |
| 644 | entitlements: ?[]const u8 = null, | 644 | entitlements: ?[]const u8 = null, |
| 645 | /// (Darwin) size of the __PAGEZERO segment | 645 | /// (Darwin) size of the __PAGEZERO segment |
| 646 | pagezero_size: ?u64 = null, | 646 | pagezero_size: ?u64 = null, |
| 647 | /// (Darwin) search strategy for system libraries | ||
| 648 | search_strategy: ?link.File.MachO.SearchStrategy = null, | ||
| 649 | /// (Darwin) set minimum space for future expansion of the load commands | 647 | /// (Darwin) set minimum space for future expansion of the load commands |
| 650 | headerpad_size: ?u32 = null, | 648 | headerpad_size: ?u32 = null, |
| 651 | /// (Darwin) set enough space as if all paths were MATPATHLEN | 649 | /// (Darwin) set enough space as if all paths were MATPATHLEN |
| ... | @@ -855,16 +853,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -855,16 +853,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 855 | break :blk false; | 853 | break :blk false; |
| 856 | }; | 854 | }; |
| 857 | 855 | ||
| 858 | const sysroot = blk: { | ||
| 859 | if (options.sysroot) |sysroot| { | ||
| 860 | break :blk sysroot; | ||
| 861 | } else if (options.native_darwin_sdk) |sdk| { | ||
| 862 | break :blk sdk.path; | ||
| 863 | } else { | ||
| 864 | break :blk null; | ||
| 865 | } | ||
| 866 | }; | ||
| 867 | |||
| 868 | const lto = blk: { | 856 | const lto = blk: { |
| 869 | if (options.want_lto) |explicit| { | 857 | if (options.want_lto) |explicit| { |
| 870 | if (!use_lld and !options.target.isDarwin()) | 858 | if (!use_lld and !options.target.isDarwin()) |
| ... | @@ -948,9 +936,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -948,9 +936,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 948 | options.is_native_abi, | 936 | options.is_native_abi, |
| 949 | link_libc, | 937 | link_libc, |
| 950 | options.libc_installation, | 938 | options.libc_installation, |
| 951 | options.native_darwin_sdk != null, | ||
| 952 | ); | 939 | ); |
| 953 | 940 | ||
| 941 | const sysroot = options.sysroot orelse libc_dirs.sysroot; | ||
| 942 | |||
| 954 | const must_pie = target_util.requiresPIE(options.target); | 943 | const must_pie = target_util.requiresPIE(options.target); |
| 955 | const pie: bool = if (options.want_pie) |explicit| pie: { | 944 | const pie: bool = if (options.want_pie) |explicit| pie: { |
| 956 | if (!explicit and must_pie) { | 945 | if (!explicit and must_pie) { |
| ... | @@ -1563,11 +1552,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1563,11 +1552,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1563 | .wasi_exec_model = wasi_exec_model, | 1552 | .wasi_exec_model = wasi_exec_model, |
| 1564 | .hash_style = options.hash_style, | 1553 | .hash_style = options.hash_style, |
| 1565 | .enable_link_snapshots = options.enable_link_snapshots, | 1554 | .enable_link_snapshots = options.enable_link_snapshots, |
| 1566 | .native_darwin_sdk = options.native_darwin_sdk, | ||
| 1567 | .install_name = options.install_name, | 1555 | .install_name = options.install_name, |
| 1568 | .entitlements = options.entitlements, | 1556 | .entitlements = options.entitlements, |
| 1569 | .pagezero_size = options.pagezero_size, | 1557 | .pagezero_size = options.pagezero_size, |
| 1570 | .search_strategy = options.search_strategy, | ||
| 1571 | .headerpad_size = options.headerpad_size, | 1558 | .headerpad_size = options.headerpad_size, |
| 1572 | .headerpad_max_install_names = options.headerpad_max_install_names, | 1559 | .headerpad_max_install_names = options.headerpad_max_install_names, |
| 1573 | .dead_strip_dylibs = options.dead_strip_dylibs, | 1560 | .dead_strip_dylibs = options.dead_strip_dylibs, |
| ... | @@ -1601,6 +1588,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1601,6 +1588,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1601 | .cache_parent = cache, | 1588 | .cache_parent = cache, |
| 1602 | .self_exe_path = options.self_exe_path, | 1589 | .self_exe_path = options.self_exe_path, |
| 1603 | .libc_include_dir_list = libc_dirs.libc_include_dir_list, | 1590 | .libc_include_dir_list = libc_dirs.libc_include_dir_list, |
| 1591 | .libc_framework_dir_list = libc_dirs.libc_framework_dir_list, | ||
| 1604 | .sanitize_c = sanitize_c, | 1592 | .sanitize_c = sanitize_c, |
| 1605 | .thread_pool = options.thread_pool, | 1593 | .thread_pool = options.thread_pool, |
| 1606 | .clang_passthrough_mode = options.clang_passthrough_mode, | 1594 | .clang_passthrough_mode = options.clang_passthrough_mode, |
| ... | @@ -1727,15 +1715,18 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1727,15 +1715,18 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1727 | 1715 | ||
| 1728 | // When linking mingw-w64 there are some import libs we always need. | 1716 | // When linking mingw-w64 there are some import libs we always need. |
| 1729 | for (mingw.always_link_libs) |name| { | 1717 | for (mingw.always_link_libs) |name| { |
| 1730 | try comp.bin_file.options.system_libs.put(comp.gpa, name, .{}); | 1718 | try comp.bin_file.options.system_libs.put(comp.gpa, name, .{ |
| 1719 | .needed = false, | ||
| 1720 | .weak = false, | ||
| 1721 | .path = null, | ||
| 1722 | }); | ||
| 1731 | } | 1723 | } |
| 1732 | } | 1724 | } |
| 1733 | // Generate Windows import libs. | 1725 | // Generate Windows import libs. |
| 1734 | if (target.os.tag == .windows) { | 1726 | if (target.os.tag == .windows) { |
| 1735 | const count = comp.bin_file.options.system_libs.count(); | 1727 | const count = comp.bin_file.options.system_libs.count(); |
| 1736 | try comp.work_queue.ensureUnusedCapacity(count); | 1728 | try comp.work_queue.ensureUnusedCapacity(count); |
| 1737 | var i: usize = 0; | 1729 | for (0..count) |i| { |
| 1738 | while (i < count) : (i += 1) { | ||
| 1739 | comp.work_queue.writeItemAssumeCapacity(.{ .windows_import_lib = i }); | 1730 | comp.work_queue.writeItemAssumeCapacity(.{ .windows_import_lib = i }); |
| 1740 | } | 1731 | } |
| 1741 | } | 1732 | } |
| ... | @@ -2367,17 +2358,17 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2367,17 +2358,17 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2367 | if (comp.bin_file.options.link_libc) { | 2358 | if (comp.bin_file.options.link_libc) { |
| 2368 | man.hash.add(comp.bin_file.options.libc_installation != null); | 2359 | man.hash.add(comp.bin_file.options.libc_installation != null); |
| 2369 | if (comp.bin_file.options.libc_installation) |libc_installation| { | 2360 | if (comp.bin_file.options.libc_installation) |libc_installation| { |
| 2370 | man.hash.addBytes(libc_installation.crt_dir.?); | 2361 | man.hash.addOptionalBytes(libc_installation.crt_dir); |
| 2371 | if (target.abi == .msvc) { | 2362 | if (target.abi == .msvc) { |
| 2372 | man.hash.addBytes(libc_installation.msvc_lib_dir.?); | 2363 | man.hash.addOptionalBytes(libc_installation.msvc_lib_dir); |
| 2373 | man.hash.addBytes(libc_installation.kernel32_lib_dir.?); | 2364 | man.hash.addOptionalBytes(libc_installation.kernel32_lib_dir); |
| 2374 | } | 2365 | } |
| 2375 | } | 2366 | } |
| 2376 | man.hash.addOptionalBytes(comp.bin_file.options.dynamic_linker); | 2367 | man.hash.addOptionalBytes(comp.bin_file.options.dynamic_linker); |
| 2377 | } | 2368 | } |
| 2378 | man.hash.addOptionalBytes(comp.bin_file.options.soname); | 2369 | man.hash.addOptionalBytes(comp.bin_file.options.soname); |
| 2379 | man.hash.addOptional(comp.bin_file.options.version); | 2370 | man.hash.addOptional(comp.bin_file.options.version); |
| 2380 | link.hashAddSystemLibs(&man.hash, comp.bin_file.options.system_libs); | 2371 | try link.hashAddSystemLibs(man, comp.bin_file.options.system_libs); |
| 2381 | man.hash.addListOfBytes(comp.bin_file.options.force_undefined_symbols.keys()); | 2372 | man.hash.addListOfBytes(comp.bin_file.options.force_undefined_symbols.keys()); |
| 2382 | man.hash.addOptional(comp.bin_file.options.allow_shlib_undefined); | 2373 | man.hash.addOptional(comp.bin_file.options.allow_shlib_undefined); |
| 2383 | man.hash.add(comp.bin_file.options.bind_global_refs_locally); | 2374 | man.hash.add(comp.bin_file.options.bind_global_refs_locally); |
| ... | @@ -2395,10 +2386,9 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2395,10 +2386,9 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2395 | 2386 | ||
| 2396 | // Mach-O specific stuff | 2387 | // Mach-O specific stuff |
| 2397 | man.hash.addListOfBytes(comp.bin_file.options.framework_dirs); | 2388 | man.hash.addListOfBytes(comp.bin_file.options.framework_dirs); |
| 2398 | link.hashAddSystemLibs(&man.hash, comp.bin_file.options.frameworks); | 2389 | link.hashAddFrameworks(&man.hash, comp.bin_file.options.frameworks); |
| 2399 | try man.addOptionalFile(comp.bin_file.options.entitlements); | 2390 | try man.addOptionalFile(comp.bin_file.options.entitlements); |
| 2400 | man.hash.addOptional(comp.bin_file.options.pagezero_size); | 2391 | man.hash.addOptional(comp.bin_file.options.pagezero_size); |
| 2401 | man.hash.addOptional(comp.bin_file.options.search_strategy); | ||
| 2402 | man.hash.addOptional(comp.bin_file.options.headerpad_size); | 2392 | man.hash.addOptional(comp.bin_file.options.headerpad_size); |
| 2403 | man.hash.add(comp.bin_file.options.headerpad_max_install_names); | 2393 | man.hash.add(comp.bin_file.options.headerpad_max_install_names); |
| 2404 | man.hash.add(comp.bin_file.options.dead_strip_dylibs); | 2394 | man.hash.add(comp.bin_file.options.dead_strip_dylibs); |
| ... | @@ -4341,6 +4331,14 @@ pub fn addCCArgs( | ... | @@ -4341,6 +4331,14 @@ pub fn addCCArgs( |
| 4341 | try argv.append("-ObjC++"); | 4331 | try argv.append("-ObjC++"); |
| 4342 | } | 4332 | } |
| 4343 | 4333 | ||
| 4334 | for (comp.libc_framework_dir_list) |framework_dir| { | ||
| 4335 | try argv.appendSlice(&.{ "-iframework", framework_dir }); | ||
| 4336 | } | ||
| 4337 | |||
| 4338 | for (comp.bin_file.options.framework_dirs) |framework_dir| { | ||
| 4339 | try argv.appendSlice(&.{ "-F", framework_dir }); | ||
| 4340 | } | ||
| 4341 | |||
| 4344 | // According to Rich Felker libc headers are supposed to go before C language headers. | 4342 | // According to Rich Felker libc headers are supposed to go before C language headers. |
| 4345 | // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics | 4343 | // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics |
| 4346 | // and other compiler specific items. | 4344 | // and other compiler specific items. |
| ... | @@ -4823,6 +4821,8 @@ test "classifyFileExt" { | ... | @@ -4823,6 +4821,8 @@ test "classifyFileExt" { |
| 4823 | const LibCDirs = struct { | 4821 | const LibCDirs = struct { |
| 4824 | libc_include_dir_list: []const []const u8, | 4822 | libc_include_dir_list: []const []const u8, |
| 4825 | libc_installation: ?*const LibCInstallation, | 4823 | libc_installation: ?*const LibCInstallation, |
| 4824 | libc_framework_dir_list: []const []const u8, | ||
| 4825 | sysroot: ?[]const u8, | ||
| 4826 | }; | 4826 | }; |
| 4827 | 4827 | ||
| 4828 | fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8, target: Target) !LibCDirs { | 4828 | fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8, target: Target) !LibCDirs { |
| ... | @@ -4853,6 +4853,8 @@ fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8, | ... | @@ -4853,6 +4853,8 @@ fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8, |
| 4853 | return LibCDirs{ | 4853 | return LibCDirs{ |
| 4854 | .libc_include_dir_list = list, | 4854 | .libc_include_dir_list = list, |
| 4855 | .libc_installation = null, | 4855 | .libc_installation = null, |
| 4856 | .libc_framework_dir_list = &.{}, | ||
| 4857 | .sysroot = null, | ||
| 4856 | }; | 4858 | }; |
| 4857 | } | 4859 | } |
| 4858 | 4860 | ||
| ... | @@ -4863,12 +4865,13 @@ fn detectLibCIncludeDirs( | ... | @@ -4863,12 +4865,13 @@ fn detectLibCIncludeDirs( |
| 4863 | is_native_abi: bool, | 4865 | is_native_abi: bool, |
| 4864 | link_libc: bool, | 4866 | link_libc: bool, |
| 4865 | libc_installation: ?*const LibCInstallation, | 4867 | libc_installation: ?*const LibCInstallation, |
| 4866 | has_macos_sdk: bool, | ||
| 4867 | ) !LibCDirs { | 4868 | ) !LibCDirs { |
| 4868 | if (!link_libc) { | 4869 | if (!link_libc) { |
| 4869 | return LibCDirs{ | 4870 | return LibCDirs{ |
| 4870 | .libc_include_dir_list = &[0][]u8{}, | 4871 | .libc_include_dir_list = &[0][]u8{}, |
| 4871 | .libc_installation = null, | 4872 | .libc_installation = null, |
| 4873 | .libc_framework_dir_list = &.{}, | ||
| 4874 | .sysroot = null, | ||
| 4872 | }; | 4875 | }; |
| 4873 | } | 4876 | } |
| 4874 | 4877 | ||
| ... | @@ -4879,28 +4882,19 @@ fn detectLibCIncludeDirs( | ... | @@ -4879,28 +4882,19 @@ fn detectLibCIncludeDirs( |
| 4879 | // If linking system libraries and targeting the native abi, default to | 4882 | // If linking system libraries and targeting the native abi, default to |
| 4880 | // using the system libc installation. | 4883 | // using the system libc installation. |
| 4881 | if (is_native_abi and !target.isMinGW()) { | 4884 | if (is_native_abi and !target.isMinGW()) { |
| 4882 | if (target.isDarwin()) { | ||
| 4883 | return if (has_macos_sdk) | ||
| 4884 | // For Darwin/macOS, we are all set with getDarwinSDK found earlier. | ||
| 4885 | LibCDirs{ | ||
| 4886 | .libc_include_dir_list = &[0][]u8{}, | ||
| 4887 | .libc_installation = null, | ||
| 4888 | } | ||
| 4889 | else | ||
| 4890 | getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target); | ||
| 4891 | } | ||
| 4892 | const libc = try arena.create(LibCInstallation); | 4885 | const libc = try arena.create(LibCInstallation); |
| 4893 | libc.* = LibCInstallation.findNative(.{ .allocator = arena }) catch |err| switch (err) { | 4886 | libc.* = LibCInstallation.findNative(.{ .allocator = arena, .target = target }) catch |err| switch (err) { |
| 4894 | error.CCompilerExitCode, | 4887 | error.CCompilerExitCode, |
| 4895 | error.CCompilerCrashed, | 4888 | error.CCompilerCrashed, |
| 4896 | error.CCompilerCannotFindHeaders, | 4889 | error.CCompilerCannotFindHeaders, |
| 4897 | error.UnableToSpawnCCompiler, | 4890 | error.UnableToSpawnCCompiler, |
| 4891 | error.DarwinSdkNotFound, | ||
| 4898 | => |e| { | 4892 | => |e| { |
| 4899 | // We tried to integrate with the native system C compiler, | 4893 | // We tried to integrate with the native system C compiler, |
| 4900 | // however, it is not installed. So we must rely on our bundled | 4894 | // however, it is not installed. So we must rely on our bundled |
| 4901 | // libc files. | 4895 | // libc files. |
| 4902 | if (target_util.canBuildLibC(target)) { | 4896 | if (target_util.canBuildLibC(target)) { |
| 4903 | return detectLibCFromBuilding(arena, zig_lib_dir, target, has_macos_sdk); | 4897 | return detectLibCFromBuilding(arena, zig_lib_dir, target); |
| 4904 | } | 4898 | } |
| 4905 | return e; | 4899 | return e; |
| 4906 | }, | 4900 | }, |
| ... | @@ -4912,7 +4906,7 @@ fn detectLibCIncludeDirs( | ... | @@ -4912,7 +4906,7 @@ fn detectLibCIncludeDirs( |
| 4912 | // If not linking system libraries, build and provide our own libc by | 4906 | // If not linking system libraries, build and provide our own libc by |
| 4913 | // default if possible. | 4907 | // default if possible. |
| 4914 | if (target_util.canBuildLibC(target)) { | 4908 | if (target_util.canBuildLibC(target)) { |
| 4915 | return detectLibCFromBuilding(arena, zig_lib_dir, target, has_macos_sdk); | 4909 | return detectLibCFromBuilding(arena, zig_lib_dir, target); |
| 4916 | } | 4910 | } |
| 4917 | 4911 | ||
| 4918 | // If zig can't build the libc for the target and we are targeting the | 4912 | // If zig can't build the libc for the target and we are targeting the |
| ... | @@ -4926,18 +4920,21 @@ fn detectLibCIncludeDirs( | ... | @@ -4926,18 +4920,21 @@ fn detectLibCIncludeDirs( |
| 4926 | 4920 | ||
| 4927 | if (use_system_abi) { | 4921 | if (use_system_abi) { |
| 4928 | const libc = try arena.create(LibCInstallation); | 4922 | const libc = try arena.create(LibCInstallation); |
| 4929 | libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true }); | 4923 | libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true, .target = target }); |
| 4930 | return detectLibCFromLibCInstallation(arena, target, libc); | 4924 | return detectLibCFromLibCInstallation(arena, target, libc); |
| 4931 | } | 4925 | } |
| 4932 | 4926 | ||
| 4933 | return LibCDirs{ | 4927 | return LibCDirs{ |
| 4934 | .libc_include_dir_list = &[0][]u8{}, | 4928 | .libc_include_dir_list = &[0][]u8{}, |
| 4935 | .libc_installation = null, | 4929 | .libc_installation = null, |
| 4930 | .libc_framework_dir_list = &.{}, | ||
| 4931 | .sysroot = null, | ||
| 4936 | }; | 4932 | }; |
| 4937 | } | 4933 | } |
| 4938 | 4934 | ||
| 4939 | fn detectLibCFromLibCInstallation(arena: Allocator, target: Target, lci: *const LibCInstallation) !LibCDirs { | 4935 | fn detectLibCFromLibCInstallation(arena: Allocator, target: Target, lci: *const LibCInstallation) !LibCDirs { |
| 4940 | var list = try std.ArrayList([]const u8).initCapacity(arena, 5); | 4936 | var list = try std.ArrayList([]const u8).initCapacity(arena, 5); |
| 4937 | var framework_list = std.ArrayList([]const u8).init(arena); | ||
| 4941 | 4938 | ||
| 4942 | list.appendAssumeCapacity(lci.include_dir.?); | 4939 | list.appendAssumeCapacity(lci.include_dir.?); |
| 4943 | 4940 | ||
| ... | @@ -4965,9 +4962,20 @@ fn detectLibCFromLibCInstallation(arena: Allocator, target: Target, lci: *const | ... | @@ -4965,9 +4962,20 @@ fn detectLibCFromLibCInstallation(arena: Allocator, target: Target, lci: *const |
| 4965 | list.appendAssumeCapacity(config_dir); | 4962 | list.appendAssumeCapacity(config_dir); |
| 4966 | } | 4963 | } |
| 4967 | 4964 | ||
| 4965 | var sysroot: ?[]const u8 = null; | ||
| 4966 | |||
| 4967 | if (target.isDarwin()) d: { | ||
| 4968 | const down1 = std.fs.path.dirname(lci.sys_include_dir.?) orelse break :d; | ||
| 4969 | const down2 = std.fs.path.dirname(down1) orelse break :d; | ||
| 4970 | try framework_list.append(try std.fs.path.join(arena, &.{ down2, "System", "Library", "Frameworks" })); | ||
| 4971 | sysroot = down2; | ||
| 4972 | } | ||
| 4973 | |||
| 4968 | return LibCDirs{ | 4974 | return LibCDirs{ |
| 4969 | .libc_include_dir_list = list.items, | 4975 | .libc_include_dir_list = list.items, |
| 4970 | .libc_installation = lci, | 4976 | .libc_installation = lci, |
| 4977 | .libc_framework_dir_list = framework_list.items, | ||
| 4978 | .sysroot = sysroot, | ||
| 4971 | }; | 4979 | }; |
| 4972 | } | 4980 | } |
| 4973 | 4981 | ||
| ... | @@ -4975,69 +4983,61 @@ fn detectLibCFromBuilding( | ... | @@ -4975,69 +4983,61 @@ fn detectLibCFromBuilding( |
| 4975 | arena: Allocator, | 4983 | arena: Allocator, |
| 4976 | zig_lib_dir: []const u8, | 4984 | zig_lib_dir: []const u8, |
| 4977 | target: std.Target, | 4985 | target: std.Target, |
| 4978 | has_macos_sdk: bool, | ||
| 4979 | ) !LibCDirs { | 4986 | ) !LibCDirs { |
| 4980 | switch (target.os.tag) { | 4987 | if (target.isDarwin()) |
| 4981 | .macos => return if (has_macos_sdk) | 4988 | return getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target); |
| 4982 | // For Darwin/macOS, we are all set with getDarwinSDK found earlier. | 4989 | |
| 4983 | LibCDirs{ | 4990 | const generic_name = target_util.libCGenericName(target); |
| 4984 | .libc_include_dir_list = &[0][]u8{}, | 4991 | // Some architectures are handled by the same set of headers. |
| 4985 | .libc_installation = null, | 4992 | const arch_name = if (target.abi.isMusl()) |
| 4986 | } | 4993 | musl.archNameHeaders(target.cpu.arch) |
| 4987 | else | 4994 | else if (target.cpu.arch.isThumb()) |
| 4988 | getZigShippedLibCIncludeDirsDarwin(arena, zig_lib_dir, target), | 4995 | // ARM headers are valid for Thumb too. |
| 4989 | else => { | 4996 | switch (target.cpu.arch) { |
| 4990 | const generic_name = target_util.libCGenericName(target); | 4997 | .thumb => "arm", |
| 4991 | // Some architectures are handled by the same set of headers. | 4998 | .thumbeb => "armeb", |
| 4992 | const arch_name = if (target.abi.isMusl()) | 4999 | else => unreachable, |
| 4993 | musl.archNameHeaders(target.cpu.arch) | 5000 | } |
| 4994 | else if (target.cpu.arch.isThumb()) | 5001 | else |
| 4995 | // ARM headers are valid for Thumb too. | 5002 | @tagName(target.cpu.arch); |
| 4996 | switch (target.cpu.arch) { | 5003 | const os_name = @tagName(target.os.tag); |
| 4997 | .thumb => "arm", | 5004 | // Musl's headers are ABI-agnostic and so they all have the "musl" ABI name. |
| 4998 | .thumbeb => "armeb", | 5005 | const abi_name = if (target.abi.isMusl()) "musl" else @tagName(target.abi); |
| 4999 | else => unreachable, | 5006 | const s = std.fs.path.sep_str; |
| 5000 | } | 5007 | const arch_include_dir = try std.fmt.allocPrint( |
| 5001 | else | 5008 | arena, |
| 5002 | @tagName(target.cpu.arch); | 5009 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}", |
| 5003 | const os_name = @tagName(target.os.tag); | 5010 | .{ zig_lib_dir, arch_name, os_name, abi_name }, |
| 5004 | // Musl's headers are ABI-agnostic and so they all have the "musl" ABI name. | 5011 | ); |
| 5005 | const abi_name = if (target.abi.isMusl()) "musl" else @tagName(target.abi); | 5012 | const generic_include_dir = try std.fmt.allocPrint( |
| 5006 | const s = std.fs.path.sep_str; | 5013 | arena, |
| 5007 | const arch_include_dir = try std.fmt.allocPrint( | 5014 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "generic-{s}", |
| 5008 | arena, | 5015 | .{ zig_lib_dir, generic_name }, |
| 5009 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}", | 5016 | ); |
| 5010 | .{ zig_lib_dir, arch_name, os_name, abi_name }, | 5017 | const generic_arch_name = target_util.osArchName(target); |
| 5011 | ); | 5018 | const arch_os_include_dir = try std.fmt.allocPrint( |
| 5012 | const generic_include_dir = try std.fmt.allocPrint( | 5019 | arena, |
| 5013 | arena, | 5020 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-any", |
| 5014 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "generic-{s}", | 5021 | .{ zig_lib_dir, generic_arch_name, os_name }, |
| 5015 | .{ zig_lib_dir, generic_name }, | 5022 | ); |
| 5016 | ); | 5023 | const generic_os_include_dir = try std.fmt.allocPrint( |
| 5017 | const generic_arch_name = target_util.osArchName(target); | 5024 | arena, |
| 5018 | const arch_os_include_dir = try std.fmt.allocPrint( | 5025 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any", |
| 5019 | arena, | 5026 | .{ zig_lib_dir, os_name }, |
| 5020 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-any", | 5027 | ); |
| 5021 | .{ zig_lib_dir, generic_arch_name, os_name }, | ||
| 5022 | ); | ||
| 5023 | const generic_os_include_dir = try std.fmt.allocPrint( | ||
| 5024 | arena, | ||
| 5025 | "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "any-{s}-any", | ||
| 5026 | .{ zig_lib_dir, os_name }, | ||
| 5027 | ); | ||
| 5028 | 5028 | ||
| 5029 | const list = try arena.alloc([]const u8, 4); | 5029 | const list = try arena.alloc([]const u8, 4); |
| 5030 | list[0] = arch_include_dir; | 5030 | list[0] = arch_include_dir; |
| 5031 | list[1] = generic_include_dir; | 5031 | list[1] = generic_include_dir; |
| 5032 | list[2] = arch_os_include_dir; | 5032 | list[2] = arch_os_include_dir; |
| 5033 | list[3] = generic_os_include_dir; | 5033 | list[3] = generic_os_include_dir; |
| 5034 | 5034 | ||
| 5035 | return LibCDirs{ | 5035 | return LibCDirs{ |
| 5036 | .libc_include_dir_list = list, | 5036 | .libc_include_dir_list = list, |
| 5037 | .libc_installation = null, | 5037 | .libc_installation = null, |
| 5038 | }; | 5038 | .libc_framework_dir_list = &.{}, |
| 5039 | }, | 5039 | .sysroot = null, |
| 5040 | } | 5040 | }; |
| 5041 | } | 5041 | } |
| 5042 | 5042 | ||
| 5043 | pub fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 { | 5043 | pub fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 { |
| ... | @@ -5618,6 +5618,11 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -5618,6 +5618,11 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { |
| 5618 | // to queue up a work item to produce the DLL import library for this. | 5618 | // to queue up a work item to produce the DLL import library for this. |
| 5619 | const gop = try comp.bin_file.options.system_libs.getOrPut(comp.gpa, lib_name); | 5619 | const gop = try comp.bin_file.options.system_libs.getOrPut(comp.gpa, lib_name); |
| 5620 | if (!gop.found_existing and comp.getTarget().os.tag == .windows) { | 5620 | if (!gop.found_existing and comp.getTarget().os.tag == .windows) { |
| 5621 | gop.value_ptr.* = .{ | ||
| 5622 | .needed = true, | ||
| 5623 | .weak = false, | ||
| 5624 | .path = null, | ||
| 5625 | }; | ||
| 5621 | try comp.work_queue.writeItem(.{ | 5626 | try comp.work_queue.writeItem(.{ |
| 5622 | .windows_import_lib = comp.bin_file.options.system_libs.count() - 1, | 5627 | .windows_import_lib = comp.bin_file.options.system_libs.count() - 1, |
| 5623 | }); | 5628 | }); |
src/libc_installation.zig+15-1| ... | @@ -33,6 +33,7 @@ pub const LibCInstallation = struct { | ... | @@ -33,6 +33,7 @@ pub const LibCInstallation = struct { |
| 33 | LibCKernel32LibNotFound, | 33 | LibCKernel32LibNotFound, |
| 34 | UnsupportedArchitecture, | 34 | UnsupportedArchitecture, |
| 35 | WindowsSdkNotFound, | 35 | WindowsSdkNotFound, |
| 36 | DarwinSdkNotFound, | ||
| 36 | ZigIsTheCCompiler, | 37 | ZigIsTheCCompiler, |
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| ... | @@ -171,6 +172,7 @@ pub const LibCInstallation = struct { | ... | @@ -171,6 +172,7 @@ pub const LibCInstallation = struct { |
| 171 | 172 | ||
| 172 | pub const FindNativeOptions = struct { | 173 | pub const FindNativeOptions = struct { |
| 173 | allocator: Allocator, | 174 | allocator: Allocator, |
| 175 | target: std.Target, | ||
| 174 | 176 | ||
| 175 | /// If enabled, will print human-friendly errors to stderr. | 177 | /// If enabled, will print human-friendly errors to stderr. |
| 176 | verbose: bool = false, | 178 | verbose: bool = false, |
| ... | @@ -181,7 +183,19 @@ pub const LibCInstallation = struct { | ... | @@ -181,7 +183,19 @@ pub const LibCInstallation = struct { |
| 181 | var self: LibCInstallation = .{}; | 183 | var self: LibCInstallation = .{}; |
| 182 | 184 | ||
| 183 | if (is_darwin) { | 185 | if (is_darwin) { |
| 184 | @panic("Darwin is handled separately via std.zig.system.darwin module"); | 186 | if (!std.zig.system.darwin.isSdkInstalled(args.allocator)) |
| 187 | return error.DarwinSdkNotFound; | ||
| 188 | const sdk = std.zig.system.darwin.getSdk(args.allocator, args.target) orelse | ||
| 189 | return error.DarwinSdkNotFound; | ||
| 190 | defer args.allocator.free(sdk.path); | ||
| 191 | |||
| 192 | self.include_dir = try fs.path.join(args.allocator, &.{ | ||
| 193 | sdk.path, "usr/include", | ||
| 194 | }); | ||
| 195 | self.sys_include_dir = try fs.path.join(args.allocator, &.{ | ||
| 196 | sdk.path, "usr/include", | ||
| 197 | }); | ||
| 198 | return self; | ||
| 185 | } else if (is_windows) { | 199 | } else if (is_windows) { |
| 186 | var sdk: ZigWindowsSDK = ZigWindowsSDK.find(args.allocator) catch |err| switch (err) { | 200 | var sdk: ZigWindowsSDK = ZigWindowsSDK.find(args.allocator) catch |err| switch (err) { |
| 187 | error.NotFound => return error.WindowsSdkNotFound, | 201 | error.NotFound => return error.WindowsSdkNotFound, |
src/link.zig+32-9| ... | @@ -21,7 +21,20 @@ const Type = @import("type.zig").Type; | ... | @@ -21,7 +21,20 @@ const Type = @import("type.zig").Type; |
| 21 | const TypedValue = @import("TypedValue.zig"); | 21 | const TypedValue = @import("TypedValue.zig"); |
| 22 | 22 | ||
| 23 | /// When adding a new field, remember to update `hashAddSystemLibs`. | 23 | /// When adding a new field, remember to update `hashAddSystemLibs`. |
| 24 | /// These are *always* dynamically linked. Static libraries will be | ||
| 25 | /// provided as positional arguments. | ||
| 24 | pub const SystemLib = struct { | 26 | pub const SystemLib = struct { |
| 27 | needed: bool, | ||
| 28 | weak: bool, | ||
| 29 | /// This can be null in two cases right now: | ||
| 30 | /// 1. Windows DLLs that zig ships such as advapi32. | ||
| 31 | /// 2. extern "foo" fn declarations where we find out about libraries too late | ||
| 32 | /// TODO: make this non-optional and resolve those two cases somehow. | ||
| 33 | path: ?[]const u8, | ||
| 34 | }; | ||
| 35 | |||
| 36 | /// When adding a new field, remember to update `hashAddFrameworks`. | ||
| 37 | pub const Framework = struct { | ||
| 25 | needed: bool = false, | 38 | needed: bool = false, |
| 26 | weak: bool = false, | 39 | weak: bool = false, |
| 27 | }; | 40 | }; |
| ... | @@ -31,11 +44,23 @@ pub const SortSection = enum { name, alignment }; | ... | @@ -31,11 +44,23 @@ pub const SortSection = enum { name, alignment }; |
| 31 | pub const CacheMode = enum { incremental, whole }; | 44 | pub const CacheMode = enum { incremental, whole }; |
| 32 | 45 | ||
| 33 | pub fn hashAddSystemLibs( | 46 | pub fn hashAddSystemLibs( |
| 34 | hh: *Cache.HashHelper, | 47 | man: *Cache.Manifest, |
| 35 | hm: std.StringArrayHashMapUnmanaged(SystemLib), | 48 | hm: std.StringArrayHashMapUnmanaged(SystemLib), |
| 49 | ) !void { | ||
| 50 | const keys = hm.keys(); | ||
| 51 | man.hash.addListOfBytes(keys); | ||
| 52 | for (hm.values()) |value| { | ||
| 53 | man.hash.add(value.needed); | ||
| 54 | man.hash.add(value.weak); | ||
| 55 | if (value.path) |p| _ = try man.addFile(p, null); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | pub fn hashAddFrameworks( | ||
| 60 | hh: *Cache.HashHelper, | ||
| 61 | hm: std.StringArrayHashMapUnmanaged(Framework), | ||
| 36 | ) void { | 62 | ) void { |
| 37 | const keys = hm.keys(); | 63 | const keys = hm.keys(); |
| 38 | hh.add(keys.len); | ||
| 39 | hh.addListOfBytes(keys); | 64 | hh.addListOfBytes(keys); |
| 40 | for (hm.values()) |value| { | 65 | for (hm.values()) |value| { |
| 41 | hh.add(value.needed); | 66 | hh.add(value.needed); |
| ... | @@ -183,9 +208,12 @@ pub const Options = struct { | ... | @@ -183,9 +208,12 @@ pub const Options = struct { |
| 183 | 208 | ||
| 184 | objects: []Compilation.LinkObject, | 209 | objects: []Compilation.LinkObject, |
| 185 | framework_dirs: []const []const u8, | 210 | framework_dirs: []const []const u8, |
| 186 | frameworks: std.StringArrayHashMapUnmanaged(SystemLib), | 211 | frameworks: std.StringArrayHashMapUnmanaged(Framework), |
| 212 | /// These are *always* dynamically linked. Static libraries will be | ||
| 213 | /// provided as positional arguments. | ||
| 187 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), | 214 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), |
| 188 | wasi_emulated_libs: []const wasi_libc.CRTFile, | 215 | wasi_emulated_libs: []const wasi_libc.CRTFile, |
| 216 | // TODO: remove this. libraries are resolved by the frontend. | ||
| 189 | lib_dirs: []const []const u8, | 217 | lib_dirs: []const []const u8, |
| 190 | rpath_list: []const []const u8, | 218 | rpath_list: []const []const u8, |
| 191 | 219 | ||
| ... | @@ -203,6 +231,7 @@ pub const Options = struct { | ... | @@ -203,6 +231,7 @@ pub const Options = struct { |
| 203 | 231 | ||
| 204 | version: ?std.SemanticVersion, | 232 | version: ?std.SemanticVersion, |
| 205 | compatibility_version: ?std.SemanticVersion, | 233 | compatibility_version: ?std.SemanticVersion, |
| 234 | darwin_sdk_version: ?std.SemanticVersion = null, | ||
| 206 | libc_installation: ?*const LibCInstallation, | 235 | libc_installation: ?*const LibCInstallation, |
| 207 | 236 | ||
| 208 | dwarf_format: ?std.dwarf.Format, | 237 | dwarf_format: ?std.dwarf.Format, |
| ... | @@ -213,9 +242,6 @@ pub const Options = struct { | ... | @@ -213,9 +242,6 @@ pub const Options = struct { |
| 213 | /// (Zig compiler development) Enable dumping of linker's state as JSON. | 242 | /// (Zig compiler development) Enable dumping of linker's state as JSON. |
| 214 | enable_link_snapshots: bool = false, | 243 | enable_link_snapshots: bool = false, |
| 215 | 244 | ||
| 216 | /// (Darwin) Path and version of the native SDK if detected. | ||
| 217 | native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null, | ||
| 218 | |||
| 219 | /// (Darwin) Install name for the dylib | 245 | /// (Darwin) Install name for the dylib |
| 220 | install_name: ?[]const u8 = null, | 246 | install_name: ?[]const u8 = null, |
| 221 | 247 | ||
| ... | @@ -225,9 +251,6 @@ pub const Options = struct { | ... | @@ -225,9 +251,6 @@ pub const Options = struct { |
| 225 | /// (Darwin) size of the __PAGEZERO segment | 251 | /// (Darwin) size of the __PAGEZERO segment |
| 226 | pagezero_size: ?u64 = null, | 252 | pagezero_size: ?u64 = null, |
| 227 | 253 | ||
| 228 | /// (Darwin) search strategy for system libraries | ||
| 229 | search_strategy: ?File.MachO.SearchStrategy = null, | ||
| 230 | |||
| 231 | /// (Darwin) set minimum space for future expansion of the load commands | 254 | /// (Darwin) set minimum space for future expansion of the load commands |
| 232 | headerpad_size: ?u32 = null, | 255 | headerpad_size: ?u32 = null, |
| 233 | 256 |
src/link/Coff/lld.zig+2-1| ... | @@ -88,7 +88,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -88,7 +88,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 88 | } | 88 | } |
| 89 | } | 89 | } |
| 90 | } | 90 | } |
| 91 | link.hashAddSystemLibs(&man.hash, self.base.options.system_libs); | 91 | try link.hashAddSystemLibs(&man, self.base.options.system_libs); |
| 92 | man.hash.addListOfBytes(self.base.options.force_undefined_symbols.keys()); | 92 | man.hash.addListOfBytes(self.base.options.force_undefined_symbols.keys()); |
| 93 | man.hash.addOptional(self.base.options.subsystem); | 93 | man.hash.addOptional(self.base.options.subsystem); |
| 94 | man.hash.add(self.base.options.is_test); | 94 | man.hash.add(self.base.options.is_test); |
| ... | @@ -405,6 +405,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -405,6 +405,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 405 | try argv.append(try comp.get_libc_crt_file(arena, "mingw32.lib")); | 405 | try argv.append(try comp.get_libc_crt_file(arena, "mingw32.lib")); |
| 406 | try argv.append(try comp.get_libc_crt_file(arena, "mingwex.lib")); | 406 | try argv.append(try comp.get_libc_crt_file(arena, "mingwex.lib")); |
| 407 | try argv.append(try comp.get_libc_crt_file(arena, "msvcrt-os.lib")); | 407 | try argv.append(try comp.get_libc_crt_file(arena, "msvcrt-os.lib")); |
| 408 | try argv.append(try comp.get_libc_crt_file(arena, "uuid.lib")); | ||
| 408 | 409 | ||
| 409 | for (mingw.always_link_libs) |name| { | 410 | for (mingw.always_link_libs) |name| { |
| 410 | if (!self.base.options.system_libs.contains(name)) { | 411 | if (!self.base.options.system_libs.contains(name)) { |
src/link/Elf.zig+4-6| ... | @@ -1428,7 +1428,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -1428,7 +1428,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 1428 | } | 1428 | } |
| 1429 | man.hash.addOptionalBytes(self.base.options.soname); | 1429 | man.hash.addOptionalBytes(self.base.options.soname); |
| 1430 | man.hash.addOptional(self.base.options.version); | 1430 | man.hash.addOptional(self.base.options.version); |
| 1431 | link.hashAddSystemLibs(&man.hash, self.base.options.system_libs); | 1431 | try link.hashAddSystemLibs(&man, self.base.options.system_libs); |
| 1432 | man.hash.addListOfBytes(self.base.options.force_undefined_symbols.keys()); | 1432 | man.hash.addListOfBytes(self.base.options.force_undefined_symbols.keys()); |
| 1433 | man.hash.add(allow_shlib_undefined); | 1433 | man.hash.add(allow_shlib_undefined); |
| 1434 | man.hash.add(self.base.options.bind_global_refs_locally); | 1434 | man.hash.add(self.base.options.bind_global_refs_locally); |
| ... | @@ -1824,8 +1824,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -1824,8 +1824,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 1824 | argv.appendAssumeCapacity("--as-needed"); | 1824 | argv.appendAssumeCapacity("--as-needed"); |
| 1825 | var as_needed = true; | 1825 | var as_needed = true; |
| 1826 | 1826 | ||
| 1827 | for (system_libs, 0..) |link_lib, i| { | 1827 | for (system_libs_values) |lib_info| { |
| 1828 | const lib_as_needed = !system_libs_values[i].needed; | 1828 | const lib_as_needed = !lib_info.needed; |
| 1829 | switch ((@as(u2, @intFromBool(lib_as_needed)) << 1) | @intFromBool(as_needed)) { | 1829 | switch ((@as(u2, @intFromBool(lib_as_needed)) << 1) | @intFromBool(as_needed)) { |
| 1830 | 0b00, 0b11 => {}, | 1830 | 0b00, 0b11 => {}, |
| 1831 | 0b01 => { | 1831 | 0b01 => { |
| ... | @@ -1842,9 +1842,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -1842,9 +1842,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 1842 | // libraries and not static libraries (the check for that needs to be earlier), | 1842 | // libraries and not static libraries (the check for that needs to be earlier), |
| 1843 | // but they could be full paths to .so files, in which case we | 1843 | // but they could be full paths to .so files, in which case we |
| 1844 | // want to avoid prepending "-l". | 1844 | // want to avoid prepending "-l". |
| 1845 | const ext = Compilation.classifyFileExt(link_lib); | 1845 | argv.appendAssumeCapacity(lib_info.path.?); |
| 1846 | const arg = if (ext == .shared_library) link_lib else try std.fmt.allocPrint(arena, "-l{s}", .{link_lib}); | ||
| 1847 | argv.appendAssumeCapacity(arg); | ||
| 1848 | } | 1846 | } |
| 1849 | 1847 | ||
| 1850 | if (!as_needed) { | 1848 | if (!as_needed) { |
src/link/MachO.zig+40-34| ... | @@ -58,11 +58,6 @@ const Rebase = @import("MachO/dyld_info/Rebase.zig"); | ... | @@ -58,11 +58,6 @@ const Rebase = @import("MachO/dyld_info/Rebase.zig"); |
| 58 | 58 | ||
| 59 | pub const base_tag: File.Tag = File.Tag.macho; | 59 | pub const base_tag: File.Tag = File.Tag.macho; |
| 60 | 60 | ||
| 61 | pub const SearchStrategy = enum { | ||
| 62 | paths_first, | ||
| 63 | dylibs_first, | ||
| 64 | }; | ||
| 65 | |||
| 66 | /// Mode of operation of the linker. | 61 | /// Mode of operation of the linker. |
| 67 | pub const Mode = enum { | 62 | pub const Mode = enum { |
| 68 | /// Incremental mode will preallocate segments/sections and is compatible with | 63 | /// Incremental mode will preallocate segments/sections and is compatible with |
| ... | @@ -834,39 +829,50 @@ pub fn resolveLibSystem( | ... | @@ -834,39 +829,50 @@ pub fn resolveLibSystem( |
| 834 | out_libs: anytype, | 829 | out_libs: anytype, |
| 835 | ) !void { | 830 | ) !void { |
| 836 | // If we were given the sysroot, try to look there first for libSystem.B.{dylib, tbd}. | 831 | // If we were given the sysroot, try to look there first for libSystem.B.{dylib, tbd}. |
| 837 | var libsystem_available = false; | 832 | if (syslibroot) |root| { |
| 838 | if (syslibroot != null) blk: { | 833 | const full_dir_path = try std.fs.path.join(arena, &.{ root, "usr", "lib" }); |
| 839 | // Try stub file first. If we hit it, then we're done as the stub file | 834 | if (try resolveLibSystemInDirs(arena, &.{full_dir_path}, out_libs)) return; |
| 840 | // re-exports every single symbol definition. | 835 | } |
| 841 | for (search_dirs) |dir| { | 836 | |
| 842 | if (try resolveLib(arena, dir, "System", ".tbd")) |full_path| { | 837 | // Next, try input search dirs if we are linking on a custom host such as Nix. |
| 843 | try out_libs.put(full_path, .{ .needed = true }); | 838 | if (try resolveLibSystemInDirs(arena, search_dirs, out_libs)) return; |
| 844 | libsystem_available = true; | 839 | |
| 845 | break :blk; | 840 | // As a fallback, try linking against Zig shipped stub. |
| 846 | } | 841 | const libsystem_name = try std.fmt.allocPrint(arena, "libSystem.{d}.tbd", .{ |
| 842 | target.os.version_range.semver.min.major, | ||
| 843 | }); | ||
| 844 | const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 845 | "libc", "darwin", libsystem_name, | ||
| 846 | }); | ||
| 847 | try out_libs.put(full_path, .{ | ||
| 848 | .needed = true, | ||
| 849 | .weak = false, | ||
| 850 | .path = full_path, | ||
| 851 | }); | ||
| 852 | } | ||
| 853 | |||
| 854 | fn resolveLibSystemInDirs(arena: Allocator, dirs: []const []const u8, out_libs: anytype) !bool { | ||
| 855 | // Try stub file first. If we hit it, then we're done as the stub file | ||
| 856 | // re-exports every single symbol definition. | ||
| 857 | for (dirs) |dir| { | ||
| 858 | if (try resolveLib(arena, dir, "System", ".tbd")) |full_path| { | ||
| 859 | try out_libs.put(full_path, .{ .needed = true, .weak = false, .path = full_path }); | ||
| 860 | return true; | ||
| 847 | } | 861 | } |
| 848 | // If we didn't hit the stub file, try .dylib next. However, libSystem.dylib | 862 | } |
| 849 | // doesn't export libc.dylib which we'll need to resolve subsequently also. | 863 | // If we didn't hit the stub file, try .dylib next. However, libSystem.dylib |
| 850 | for (search_dirs) |dir| { | 864 | // doesn't export libc.dylib which we'll need to resolve subsequently also. |
| 851 | if (try resolveLib(arena, dir, "System", ".dylib")) |libsystem_path| { | 865 | for (dirs) |dir| { |
| 852 | if (try resolveLib(arena, dir, "c", ".dylib")) |libc_path| { | 866 | if (try resolveLib(arena, dir, "System", ".dylib")) |libsystem_path| { |
| 853 | try out_libs.put(libsystem_path, .{ .needed = true }); | 867 | if (try resolveLib(arena, dir, "c", ".dylib")) |libc_path| { |
| 854 | try out_libs.put(libc_path, .{ .needed = true }); | 868 | try out_libs.put(libsystem_path, .{ .needed = true, .weak = false, .path = libsystem_path }); |
| 855 | libsystem_available = true; | 869 | try out_libs.put(libc_path, .{ .needed = true, .weak = false, .path = libc_path }); |
| 856 | break :blk; | 870 | return true; |
| 857 | } | ||
| 858 | } | 871 | } |
| 859 | } | 872 | } |
| 860 | } | 873 | } |
| 861 | if (!libsystem_available) { | 874 | |
| 862 | const libsystem_name = try std.fmt.allocPrint(arena, "libSystem.{d}.tbd", .{ | 875 | return false; |
| 863 | target.os.version_range.semver.min.major, | ||
| 864 | }); | ||
| 865 | const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 866 | "libc", "darwin", libsystem_name, | ||
| 867 | }); | ||
| 868 | try out_libs.put(full_path, .{ .needed = true }); | ||
| 869 | } | ||
| 870 | } | 876 | } |
| 871 | 877 | ||
| 872 | pub fn resolveSearchDir( | 878 | pub fn resolveSearchDir( |
src/link/MachO/load_commands.zig+4-5| ... | @@ -278,11 +278,10 @@ pub fn writeBuildVersionLC(options: *const link.Options, lc_writer: anytype) !vo | ... | @@ -278,11 +278,10 @@ pub fn writeBuildVersionLC(options: *const link.Options, lc_writer: anytype) !vo |
| 278 | const platform_version = @as(u32, @intCast(ver.major << 16 | ver.minor << 8)); | 278 | const platform_version = @as(u32, @intCast(ver.major << 16 | ver.minor << 8)); |
| 279 | break :blk platform_version; | 279 | break :blk platform_version; |
| 280 | }; | 280 | }; |
| 281 | const sdk_version = if (options.native_darwin_sdk) |sdk| blk: { | 281 | const sdk_version: u32 = if (options.darwin_sdk_version) |ver| |
| 282 | const ver = sdk.version; | 282 | @intCast(ver.major << 16 | ver.minor << 8) |
| 283 | const sdk_version = @as(u32, @intCast(ver.major << 16 | ver.minor << 8)); | 283 | else |
| 284 | break :blk sdk_version; | 284 | platform_version; |
| 285 | } else platform_version; | ||
| 286 | const is_simulator_abi = options.target.abi == .simulator; | 285 | const is_simulator_abi = options.target.abi == .simulator; |
| 287 | try lc_writer.writeStruct(macho.build_version_command{ | 286 | try lc_writer.writeStruct(macho.build_version_command{ |
| 288 | .cmdsize = cmdsize, | 287 | .cmdsize = cmdsize, |
src/link/MachO/zld.zig+8-82| ... | @@ -3410,7 +3410,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3410,7 +3410,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3410 | // installation sources because they are always a product of the compiler version + target information. | 3410 | // installation sources because they are always a product of the compiler version + target information. |
| 3411 | man.hash.add(stack_size); | 3411 | man.hash.add(stack_size); |
| 3412 | man.hash.addOptional(options.pagezero_size); | 3412 | man.hash.addOptional(options.pagezero_size); |
| 3413 | man.hash.addOptional(options.search_strategy); | ||
| 3414 | man.hash.addOptional(options.headerpad_size); | 3413 | man.hash.addOptional(options.headerpad_size); |
| 3415 | man.hash.add(options.headerpad_max_install_names); | 3414 | man.hash.add(options.headerpad_max_install_names); |
| 3416 | man.hash.add(gc_sections); | 3415 | man.hash.add(gc_sections); |
| ... | @@ -3418,13 +3417,13 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3418,13 +3417,13 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3418 | man.hash.add(options.strip); | 3417 | man.hash.add(options.strip); |
| 3419 | man.hash.addListOfBytes(options.lib_dirs); | 3418 | man.hash.addListOfBytes(options.lib_dirs); |
| 3420 | man.hash.addListOfBytes(options.framework_dirs); | 3419 | man.hash.addListOfBytes(options.framework_dirs); |
| 3421 | link.hashAddSystemLibs(&man.hash, options.frameworks); | 3420 | link.hashAddFrameworks(&man.hash, options.frameworks); |
| 3422 | man.hash.addListOfBytes(options.rpath_list); | 3421 | man.hash.addListOfBytes(options.rpath_list); |
| 3423 | if (is_dyn_lib) { | 3422 | if (is_dyn_lib) { |
| 3424 | man.hash.addOptionalBytes(options.install_name); | 3423 | man.hash.addOptionalBytes(options.install_name); |
| 3425 | man.hash.addOptional(options.version); | 3424 | man.hash.addOptional(options.version); |
| 3426 | } | 3425 | } |
| 3427 | link.hashAddSystemLibs(&man.hash, options.system_libs); | 3426 | try link.hashAddSystemLibs(&man, options.system_libs); |
| 3428 | man.hash.addOptionalBytes(options.sysroot); | 3427 | man.hash.addOptionalBytes(options.sysroot); |
| 3429 | man.hash.addListOfBytes(options.force_undefined_symbols.keys()); | 3428 | man.hash.addListOfBytes(options.force_undefined_symbols.keys()); |
| 3430 | try man.addOptionalFile(options.entitlements); | 3429 | try man.addOptionalFile(options.entitlements); |
| ... | @@ -3550,84 +3549,15 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3550,84 +3549,15 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3550 | try positionals.append(comp.libcxx_static_lib.?.full_object_path); | 3549 | try positionals.append(comp.libcxx_static_lib.?.full_object_path); |
| 3551 | } | 3550 | } |
| 3552 | 3551 | ||
| 3553 | // Shared and static libraries passed via `-l` flag. | ||
| 3554 | var candidate_libs = std.StringArrayHashMap(link.SystemLib).init(arena); | ||
| 3555 | |||
| 3556 | const system_lib_names = options.system_libs.keys(); | ||
| 3557 | for (system_lib_names) |system_lib_name| { | ||
| 3558 | // By this time, we depend on these libs being dynamically linked libraries and not static libraries | ||
| 3559 | // (the check for that needs to be earlier), but they could be full paths to .dylib files, in which | ||
| 3560 | // case we want to avoid prepending "-l". | ||
| 3561 | if (Compilation.classifyFileExt(system_lib_name) == .shared_library) { | ||
| 3562 | try positionals.append(system_lib_name); | ||
| 3563 | continue; | ||
| 3564 | } | ||
| 3565 | |||
| 3566 | const system_lib_info = options.system_libs.get(system_lib_name).?; | ||
| 3567 | try candidate_libs.put(system_lib_name, .{ | ||
| 3568 | .needed = system_lib_info.needed, | ||
| 3569 | .weak = system_lib_info.weak, | ||
| 3570 | }); | ||
| 3571 | } | ||
| 3572 | |||
| 3573 | var lib_dirs = std.ArrayList([]const u8).init(arena); | ||
| 3574 | for (options.lib_dirs) |dir| { | ||
| 3575 | if (try MachO.resolveSearchDir(arena, dir, options.sysroot)) |search_dir| { | ||
| 3576 | try lib_dirs.append(search_dir); | ||
| 3577 | } else { | ||
| 3578 | log.warn("directory not found for '-L{s}'", .{dir}); | ||
| 3579 | } | ||
| 3580 | } | ||
| 3581 | |||
| 3582 | var libs = std.StringArrayHashMap(link.SystemLib).init(arena); | 3552 | var libs = std.StringArrayHashMap(link.SystemLib).init(arena); |
| 3583 | 3553 | ||
| 3584 | // Assume ld64 default -search_paths_first if no strategy specified. | 3554 | { |
| 3585 | const search_strategy = options.search_strategy orelse .paths_first; | 3555 | const vals = options.system_libs.values(); |
| 3586 | outer: for (candidate_libs.keys()) |lib_name| { | 3556 | try libs.ensureUnusedCapacity(vals.len); |
| 3587 | switch (search_strategy) { | 3557 | for (vals) |v| libs.putAssumeCapacity(v.path.?, v); |
| 3588 | .paths_first => { | ||
| 3589 | // Look in each directory for a dylib (stub first), and then for archive | ||
| 3590 | for (lib_dirs.items) |dir| { | ||
| 3591 | for (&[_][]const u8{ ".tbd", ".dylib", ".a" }) |ext| { | ||
| 3592 | if (try MachO.resolveLib(arena, dir, lib_name, ext)) |full_path| { | ||
| 3593 | try libs.put(full_path, candidate_libs.get(lib_name).?); | ||
| 3594 | continue :outer; | ||
| 3595 | } | ||
| 3596 | } | ||
| 3597 | } else { | ||
| 3598 | log.warn("library not found for '-l{s}'", .{lib_name}); | ||
| 3599 | lib_not_found = true; | ||
| 3600 | } | ||
| 3601 | }, | ||
| 3602 | .dylibs_first => { | ||
| 3603 | // First, look for a dylib in each search dir | ||
| 3604 | for (lib_dirs.items) |dir| { | ||
| 3605 | for (&[_][]const u8{ ".tbd", ".dylib" }) |ext| { | ||
| 3606 | if (try MachO.resolveLib(arena, dir, lib_name, ext)) |full_path| { | ||
| 3607 | try libs.put(full_path, candidate_libs.get(lib_name).?); | ||
| 3608 | continue :outer; | ||
| 3609 | } | ||
| 3610 | } | ||
| 3611 | } else for (lib_dirs.items) |dir| { | ||
| 3612 | if (try MachO.resolveLib(arena, dir, lib_name, ".a")) |full_path| { | ||
| 3613 | try libs.put(full_path, candidate_libs.get(lib_name).?); | ||
| 3614 | } else { | ||
| 3615 | log.warn("library not found for '-l{s}'", .{lib_name}); | ||
| 3616 | lib_not_found = true; | ||
| 3617 | } | ||
| 3618 | } | ||
| 3619 | }, | ||
| 3620 | } | ||
| 3621 | } | ||
| 3622 | |||
| 3623 | if (lib_not_found) { | ||
| 3624 | log.warn("Library search paths:", .{}); | ||
| 3625 | for (lib_dirs.items) |dir| { | ||
| 3626 | log.warn(" {s}", .{dir}); | ||
| 3627 | } | ||
| 3628 | } | 3558 | } |
| 3629 | 3559 | ||
| 3630 | try MachO.resolveLibSystem(arena, comp, options.sysroot, target, lib_dirs.items, &libs); | 3560 | try MachO.resolveLibSystem(arena, comp, options.sysroot, target, options.lib_dirs, &libs); |
| 3631 | 3561 | ||
| 3632 | // frameworks | 3562 | // frameworks |
| 3633 | var framework_dirs = std.ArrayList([]const u8).init(arena); | 3563 | var framework_dirs = std.ArrayList([]const u8).init(arena); |
| ... | @@ -3647,6 +3577,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3647,6 +3577,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3647 | try libs.put(full_path, .{ | 3577 | try libs.put(full_path, .{ |
| 3648 | .needed = info.needed, | 3578 | .needed = info.needed, |
| 3649 | .weak = info.weak, | 3579 | .weak = info.weak, |
| 3580 | .path = full_path, | ||
| 3650 | }); | 3581 | }); |
| 3651 | continue :outer; | 3582 | continue :outer; |
| 3652 | } | 3583 | } |
| ... | @@ -3698,11 +3629,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr | ... | @@ -3698,11 +3629,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3698 | try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{pagezero_size})); | 3629 | try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{pagezero_size})); |
| 3699 | } | 3630 | } |
| 3700 | 3631 | ||
| 3701 | if (options.search_strategy) |strat| switch (strat) { | ||
| 3702 | .paths_first => try argv.append("-search_paths_first"), | ||
| 3703 | .dylibs_first => try argv.append("-search_dylibs_first"), | ||
| 3704 | }; | ||
| 3705 | |||
| 3706 | if (options.headerpad_size) |headerpad_size| { | 3632 | if (options.headerpad_size) |headerpad_size| { |
| 3707 | try argv.append("-headerpad_size"); | 3633 | try argv.append("-headerpad_size"); |
| 3708 | try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{headerpad_size})); | 3634 | try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{headerpad_size})); |
src/main.zig+529-281| ... | @@ -28,6 +28,7 @@ const target_util = @import("target.zig"); | ... | @@ -28,6 +28,7 @@ const target_util = @import("target.zig"); |
| 28 | const crash_report = @import("crash_report.zig"); | 28 | const crash_report = @import("crash_report.zig"); |
| 29 | const Module = @import("Module.zig"); | 29 | const Module = @import("Module.zig"); |
| 30 | const AstGen = @import("AstGen.zig"); | 30 | const AstGen = @import("AstGen.zig"); |
| 31 | const mingw = @import("mingw.zig"); | ||
| 31 | const Server = std.zig.Server; | 32 | const Server = std.zig.Server; |
| 32 | 33 | ||
| 33 | pub const std_options = struct { | 34 | pub const std_options = struct { |
| ... | @@ -476,7 +477,19 @@ const usage_build_generic = | ... | @@ -476,7 +477,19 @@ const usage_build_generic = |
| 476 | \\ -l[lib], --library [lib] Link against system library (only if actually used) | 477 | \\ -l[lib], --library [lib] Link against system library (only if actually used) |
| 477 | \\ -needed-l[lib], Link against system library (even if unused) | 478 | \\ -needed-l[lib], Link against system library (even if unused) |
| 478 | \\ --needed-library [lib] | 479 | \\ --needed-library [lib] |
| 480 | \\ -weak-l[lib] link against system library marking it and all | ||
| 481 | \\ -weak_library [lib] referenced symbols as weak | ||
| 479 | \\ -L[d], --library-directory [d] Add a directory to the library search path | 482 | \\ -L[d], --library-directory [d] Add a directory to the library search path |
| 483 | \\ -search_paths_first For each library search path, check for dynamic | ||
| 484 | \\ lib then static lib before proceeding to next path. | ||
| 485 | \\ -search_paths_first_static For each library search path, check for static | ||
| 486 | \\ lib then dynamic lib before proceeding to next path. | ||
| 487 | \\ -search_dylibs_first Search for dynamic libs in all library search | ||
| 488 | \\ paths, then static libs. | ||
| 489 | \\ -search_static_first Search for static libs in all library search | ||
| 490 | \\ paths, then dynamic libs. | ||
| 491 | \\ -search_dylibs_only Only search for dynamic libs. | ||
| 492 | \\ -search_static_only Only search for static libs. | ||
| 480 | \\ -T[script], --script [script] Use a custom linker script | 493 | \\ -T[script], --script [script] Use a custom linker script |
| 481 | \\ --version-script [path] Provide a version .map file | 494 | \\ --version-script [path] Provide a version .map file |
| 482 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) | 495 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) |
| ... | @@ -527,18 +540,14 @@ const usage_build_generic = | ... | @@ -527,18 +540,14 @@ const usage_build_generic = |
| 527 | \\ --subsystem [subsystem] (Windows) /SUBSYSTEM:<subsystem> to the linker | 540 | \\ --subsystem [subsystem] (Windows) /SUBSYSTEM:<subsystem> to the linker |
| 528 | \\ --stack [size] Override default stack size | 541 | \\ --stack [size] Override default stack size |
| 529 | \\ --image-base [addr] Set base address for executable image | 542 | \\ --image-base [addr] Set base address for executable image |
| 530 | \\ -weak-l[lib] (Darwin) link against system library and mark it and all referenced symbols as weak | ||
| 531 | \\ -weak_library [lib] | ||
| 532 | \\ -framework [name] (Darwin) link against framework | 543 | \\ -framework [name] (Darwin) link against framework |
| 533 | \\ -needed_framework [name] (Darwin) link against framework (even if unused) | 544 | \\ -needed_framework [name] (Darwin) link against framework (even if unused) |
| 534 | \\ -needed_library [lib] (Darwin) link against system library (even if unused) | 545 | \\ -needed_library [lib] link against system library (even if unused) |
| 535 | \\ -weak_framework [name] (Darwin) link against framework and mark it and all referenced symbols as weak | 546 | \\ -weak_framework [name] (Darwin) link against framework and mark it and all referenced symbols as weak |
| 536 | \\ -F[dir] (Darwin) add search path for frameworks | 547 | \\ -F[dir] (Darwin) add search path for frameworks |
| 537 | \\ -install_name=[value] (Darwin) add dylib's install name | 548 | \\ -install_name=[value] (Darwin) add dylib's install name |
| 538 | \\ --entitlements [path] (Darwin) add path to entitlements file for embedding in code signature | 549 | \\ --entitlements [path] (Darwin) add path to entitlements file for embedding in code signature |
| 539 | \\ -pagezero_size [value] (Darwin) size of the __PAGEZERO segment in hexadecimal notation | 550 | \\ -pagezero_size [value] (Darwin) size of the __PAGEZERO segment in hexadecimal notation |
| 540 | \\ -search_paths_first (Darwin) search each dir in library search paths for `libx.dylib` then `libx.a` | ||
| 541 | \\ -search_dylibs_first (Darwin) search `libx.dylib` in each dir in library search paths, then `libx.a` | ||
| 542 | \\ -headerpad [value] (Darwin) set minimum space for future expansion of the load commands in hexadecimal notation | 551 | \\ -headerpad [value] (Darwin) set minimum space for future expansion of the load commands in hexadecimal notation |
| 543 | \\ -headerpad_max_install_names (Darwin) set enough space as if all paths were MAXPATHLEN | 552 | \\ -headerpad_max_install_names (Darwin) set enough space as if all paths were MAXPATHLEN |
| 544 | \\ -dead_strip (Darwin) remove functions and data that are unreachable by the entry point or exported symbols | 553 | \\ -dead_strip (Darwin) remove functions and data that are unreachable by the entry point or exported symbols |
| ... | @@ -716,6 +725,39 @@ const ArgsIterator = struct { | ... | @@ -716,6 +725,39 @@ const ArgsIterator = struct { |
| 716 | } | 725 | } |
| 717 | }; | 726 | }; |
| 718 | 727 | ||
| 728 | /// In contrast to `link.SystemLib`, this stores arguments that may need to be | ||
| 729 | /// resolved into static libraries so that we can pass only dynamic libraries | ||
| 730 | /// as system libs to `Compilation`. | ||
| 731 | const SystemLib = struct { | ||
| 732 | needed: bool, | ||
| 733 | weak: bool, | ||
| 734 | |||
| 735 | preferred_mode: std.builtin.LinkMode, | ||
| 736 | search_strategy: SearchStrategy, | ||
| 737 | |||
| 738 | const SearchStrategy = enum { paths_first, mode_first, no_fallback }; | ||
| 739 | |||
| 740 | fn fallbackMode(this: SystemLib) std.builtin.LinkMode { | ||
| 741 | assert(this.search_strategy != .no_fallback); | ||
| 742 | return switch (this.preferred_mode) { | ||
| 743 | .Dynamic => .Static, | ||
| 744 | .Static => .Dynamic, | ||
| 745 | }; | ||
| 746 | } | ||
| 747 | }; | ||
| 748 | |||
| 749 | const CliModule = struct { | ||
| 750 | mod: *Package, | ||
| 751 | /// still in CLI arg format | ||
| 752 | deps_str: []const u8, | ||
| 753 | }; | ||
| 754 | |||
| 755 | fn cleanupModules(modules: *std.StringArrayHashMap(CliModule)) void { | ||
| 756 | var it = modules.iterator(); | ||
| 757 | while (it.next()) |kv| kv.value_ptr.mod.destroy(modules.allocator); | ||
| 758 | modules.deinit(); | ||
| 759 | } | ||
| 760 | |||
| 719 | fn buildOutputType( | 761 | fn buildOutputType( |
| 720 | gpa: Allocator, | 762 | gpa: Allocator, |
| 721 | arena: Allocator, | 763 | arena: Allocator, |
| ... | @@ -849,12 +891,12 @@ fn buildOutputType( | ... | @@ -849,12 +891,12 @@ fn buildOutputType( |
| 849 | var minor_subsystem_version: ?u32 = null; | 891 | var minor_subsystem_version: ?u32 = null; |
| 850 | var wasi_exec_model: ?std.builtin.WasiExecModel = null; | 892 | var wasi_exec_model: ?std.builtin.WasiExecModel = null; |
| 851 | var enable_link_snapshots: bool = false; | 893 | var enable_link_snapshots: bool = false; |
| 852 | var native_darwin_sdk: ?std.zig.system.darwin.DarwinSDK = null; | ||
| 853 | var install_name: ?[]const u8 = null; | 894 | var install_name: ?[]const u8 = null; |
| 854 | var hash_style: link.HashStyle = .both; | 895 | var hash_style: link.HashStyle = .both; |
| 855 | var entitlements: ?[]const u8 = null; | 896 | var entitlements: ?[]const u8 = null; |
| 856 | var pagezero_size: ?u64 = null; | 897 | var pagezero_size: ?u64 = null; |
| 857 | var search_strategy: ?link.File.MachO.SearchStrategy = null; | 898 | var lib_search_strategy: SystemLib.SearchStrategy = .paths_first; |
| 899 | var lib_preferred_mode: std.builtin.LinkMode = .Dynamic; | ||
| 858 | var headerpad_size: ?u32 = null; | 900 | var headerpad_size: ?u32 = null; |
| 859 | var headerpad_max_install_names: bool = false; | 901 | var headerpad_max_install_names: bool = false; |
| 860 | var dead_strip_dylibs: bool = false; | 902 | var dead_strip_dylibs: bool = false; |
| ... | @@ -862,66 +904,30 @@ fn buildOutputType( | ... | @@ -862,66 +904,30 @@ fn buildOutputType( |
| 862 | var error_tracing: ?bool = null; | 904 | var error_tracing: ?bool = null; |
| 863 | var pdb_out_path: ?[]const u8 = null; | 905 | var pdb_out_path: ?[]const u8 = null; |
| 864 | var dwarf_format: ?std.dwarf.Format = null; | 906 | var dwarf_format: ?std.dwarf.Format = null; |
| 865 | |||
| 866 | // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names. | 907 | // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names. |
| 867 | // This array is populated by zig cc frontend and then has to be converted to zig-style | 908 | // This array is populated by zig cc frontend and then has to be converted to zig-style |
| 868 | // CPU features. | 909 | // CPU features. |
| 869 | var llvm_m_args = std.ArrayList([]const u8).init(gpa); | 910 | var llvm_m_args = std.ArrayList([]const u8).init(arena); |
| 870 | defer llvm_m_args.deinit(); | 911 | var system_libs = std.StringArrayHashMap(SystemLib).init(arena); |
| 871 | 912 | var wasi_emulated_libs = std.ArrayList(wasi_libc.CRTFile).init(arena); | |
| 872 | var system_libs = std.StringArrayHashMap(Compilation.SystemLib).init(gpa); | 913 | var clang_argv = std.ArrayList([]const u8).init(arena); |
| 873 | defer system_libs.deinit(); | 914 | var extra_cflags = std.ArrayList([]const u8).init(arena); |
| 874 | 915 | // These are before resolving sysroot. | |
| 875 | var static_libs = std.ArrayList([]const u8).init(gpa); | 916 | var lib_dir_args = std.ArrayList([]const u8).init(arena); |
| 876 | defer static_libs.deinit(); | 917 | var rpath_list = std.ArrayList([]const u8).init(arena); |
| 877 | |||
| 878 | var wasi_emulated_libs = std.ArrayList(wasi_libc.CRTFile).init(gpa); | ||
| 879 | defer wasi_emulated_libs.deinit(); | ||
| 880 | |||
| 881 | var clang_argv = std.ArrayList([]const u8).init(gpa); | ||
| 882 | defer clang_argv.deinit(); | ||
| 883 | |||
| 884 | var extra_cflags = std.ArrayList([]const u8).init(gpa); | ||
| 885 | defer extra_cflags.deinit(); | ||
| 886 | |||
| 887 | var lib_dirs = std.ArrayList([]const u8).init(gpa); | ||
| 888 | defer lib_dirs.deinit(); | ||
| 889 | |||
| 890 | var rpath_list = std.ArrayList([]const u8).init(gpa); | ||
| 891 | defer rpath_list.deinit(); | ||
| 892 | |||
| 893 | var symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{}; | 918 | var symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{}; |
| 894 | 919 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); | |
| 895 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); | 920 | var link_objects = std.ArrayList(Compilation.LinkObject).init(arena); |
| 896 | defer c_source_files.deinit(); | 921 | var framework_dirs = std.ArrayList([]const u8).init(arena); |
| 897 | 922 | var frameworks: std.StringArrayHashMapUnmanaged(Compilation.Framework) = .{}; | |
| 898 | var link_objects = std.ArrayList(Compilation.LinkObject).init(gpa); | ||
| 899 | defer link_objects.deinit(); | ||
| 900 | |||
| 901 | var framework_dirs = std.ArrayList([]const u8).init(gpa); | ||
| 902 | defer framework_dirs.deinit(); | ||
| 903 | |||
| 904 | var frameworks: std.StringArrayHashMapUnmanaged(Compilation.SystemLib) = .{}; | ||
| 905 | |||
| 906 | // null means replace with the test executable binary | 923 | // null means replace with the test executable binary |
| 907 | var test_exec_args = std.ArrayList(?[]const u8).init(gpa); | 924 | var test_exec_args = std.ArrayList(?[]const u8).init(arena); |
| 908 | defer test_exec_args.deinit(); | 925 | var linker_export_symbol_names = std.ArrayList([]const u8).init(arena); |
| 909 | |||
| 910 | var linker_export_symbol_names = std.ArrayList([]const u8).init(gpa); | ||
| 911 | defer linker_export_symbol_names.deinit(); | ||
| 912 | |||
| 913 | // Contains every module specified via --mod. The dependencies are added | 926 | // Contains every module specified via --mod. The dependencies are added |
| 914 | // after argument parsing is completed. We use a StringArrayHashMap to make | 927 | // after argument parsing is completed. We use a StringArrayHashMap to make |
| 915 | // error output consistent. | 928 | // error output consistent. |
| 916 | var modules = std.StringArrayHashMap(struct { | 929 | var modules = std.StringArrayHashMap(CliModule).init(gpa); |
| 917 | mod: *Package, | 930 | defer cleanupModules(&modules); |
| 918 | deps_str: []const u8, // still in CLI arg format | ||
| 919 | }).init(gpa); | ||
| 920 | defer { | ||
| 921 | var it = modules.iterator(); | ||
| 922 | while (it.next()) |kv| kv.value_ptr.mod.destroy(gpa); | ||
| 923 | modules.deinit(); | ||
| 924 | } | ||
| 925 | 931 | ||
| 926 | // The dependency string for the root package | 932 | // The dependency string for the root package |
| 927 | var root_deps_str: ?[]const u8 = null; | 933 | var root_deps_str: ?[]const u8 = null; |
| ... | @@ -1061,7 +1067,7 @@ fn buildOutputType( | ... | @@ -1061,7 +1067,7 @@ fn buildOutputType( |
| 1061 | } else if (mem.eql(u8, arg, "-rpath")) { | 1067 | } else if (mem.eql(u8, arg, "-rpath")) { |
| 1062 | try rpath_list.append(args_iter.nextOrFatal()); | 1068 | try rpath_list.append(args_iter.nextOrFatal()); |
| 1063 | } else if (mem.eql(u8, arg, "--library-directory") or mem.eql(u8, arg, "-L")) { | 1069 | } else if (mem.eql(u8, arg, "--library-directory") or mem.eql(u8, arg, "-L")) { |
| 1064 | try lib_dirs.append(args_iter.nextOrFatal()); | 1070 | try lib_dir_args.append(args_iter.nextOrFatal()); |
| 1065 | } else if (mem.eql(u8, arg, "-F")) { | 1071 | } else if (mem.eql(u8, arg, "-F")) { |
| 1066 | try framework_dirs.append(args_iter.nextOrFatal()); | 1072 | try framework_dirs.append(args_iter.nextOrFatal()); |
| 1067 | } else if (mem.eql(u8, arg, "-framework")) { | 1073 | } else if (mem.eql(u8, arg, "-framework")) { |
| ... | @@ -1085,9 +1091,23 @@ fn buildOutputType( | ... | @@ -1085,9 +1091,23 @@ fn buildOutputType( |
| 1085 | fatal("unable to parse pagezero size'{s}': {s}", .{ next_arg, @errorName(err) }); | 1091 | fatal("unable to parse pagezero size'{s}': {s}", .{ next_arg, @errorName(err) }); |
| 1086 | }; | 1092 | }; |
| 1087 | } else if (mem.eql(u8, arg, "-search_paths_first")) { | 1093 | } else if (mem.eql(u8, arg, "-search_paths_first")) { |
| 1088 | search_strategy = .paths_first; | 1094 | lib_search_strategy = .paths_first; |
| 1095 | lib_preferred_mode = .Dynamic; | ||
| 1096 | } else if (mem.eql(u8, arg, "-search_paths_first_static")) { | ||
| 1097 | lib_search_strategy = .paths_first; | ||
| 1098 | lib_preferred_mode = .Static; | ||
| 1089 | } else if (mem.eql(u8, arg, "-search_dylibs_first")) { | 1099 | } else if (mem.eql(u8, arg, "-search_dylibs_first")) { |
| 1090 | search_strategy = .dylibs_first; | 1100 | lib_search_strategy = .mode_first; |
| 1101 | lib_preferred_mode = .Dynamic; | ||
| 1102 | } else if (mem.eql(u8, arg, "-search_static_first")) { | ||
| 1103 | lib_search_strategy = .mode_first; | ||
| 1104 | lib_preferred_mode = .Static; | ||
| 1105 | } else if (mem.eql(u8, arg, "-search_dylibs_only")) { | ||
| 1106 | lib_search_strategy = .no_fallback; | ||
| 1107 | lib_preferred_mode = .Dynamic; | ||
| 1108 | } else if (mem.eql(u8, arg, "-search_static_only")) { | ||
| 1109 | lib_search_strategy = .no_fallback; | ||
| 1110 | lib_preferred_mode = .Static; | ||
| 1091 | } else if (mem.eql(u8, arg, "-headerpad")) { | 1111 | } else if (mem.eql(u8, arg, "-headerpad")) { |
| 1092 | const next_arg = args_iter.nextOrFatal(); | 1112 | const next_arg = args_iter.nextOrFatal(); |
| 1093 | headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { | 1113 | headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| ... | @@ -1104,17 +1124,33 @@ fn buildOutputType( | ... | @@ -1104,17 +1124,33 @@ fn buildOutputType( |
| 1104 | } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) { | 1124 | } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) { |
| 1105 | version_script = args_iter.nextOrFatal(); | 1125 | version_script = args_iter.nextOrFatal(); |
| 1106 | } else if (mem.eql(u8, arg, "--library") or mem.eql(u8, arg, "-l")) { | 1126 | } else if (mem.eql(u8, arg, "--library") or mem.eql(u8, arg, "-l")) { |
| 1107 | // We don't know whether this library is part of libc or libc++ until | 1127 | // We don't know whether this library is part of libc |
| 1108 | // we resolve the target, so we simply append to the list for now. | 1128 | // or libc++ until we resolve the target, so we append |
| 1109 | try system_libs.put(args_iter.nextOrFatal(), .{}); | 1129 | // to the list for now. |
| 1130 | try system_libs.put(args_iter.nextOrFatal(), .{ | ||
| 1131 | .needed = false, | ||
| 1132 | .weak = false, | ||
| 1133 | .preferred_mode = lib_preferred_mode, | ||
| 1134 | .search_strategy = lib_search_strategy, | ||
| 1135 | }); | ||
| 1110 | } else if (mem.eql(u8, arg, "--needed-library") or | 1136 | } else if (mem.eql(u8, arg, "--needed-library") or |
| 1111 | mem.eql(u8, arg, "-needed-l") or | 1137 | mem.eql(u8, arg, "-needed-l") or |
| 1112 | mem.eql(u8, arg, "-needed_library")) | 1138 | mem.eql(u8, arg, "-needed_library")) |
| 1113 | { | 1139 | { |
| 1114 | const next_arg = args_iter.nextOrFatal(); | 1140 | const next_arg = args_iter.nextOrFatal(); |
| 1115 | try system_libs.put(next_arg, .{ .needed = true }); | 1141 | try system_libs.put(next_arg, .{ |
| 1142 | .needed = true, | ||
| 1143 | .weak = false, | ||
| 1144 | .preferred_mode = lib_preferred_mode, | ||
| 1145 | .search_strategy = lib_search_strategy, | ||
| 1146 | }); | ||
| 1116 | } else if (mem.eql(u8, arg, "-weak_library") or mem.eql(u8, arg, "-weak-l")) { | 1147 | } else if (mem.eql(u8, arg, "-weak_library") or mem.eql(u8, arg, "-weak-l")) { |
| 1117 | try system_libs.put(args_iter.nextOrFatal(), .{ .weak = true }); | 1148 | try system_libs.put(args_iter.nextOrFatal(), .{ |
| 1149 | .needed = false, | ||
| 1150 | .weak = true, | ||
| 1151 | .preferred_mode = lib_preferred_mode, | ||
| 1152 | .search_strategy = lib_search_strategy, | ||
| 1153 | }); | ||
| 1118 | } else if (mem.eql(u8, arg, "-D")) { | 1154 | } else if (mem.eql(u8, arg, "-D")) { |
| 1119 | try clang_argv.append(arg); | 1155 | try clang_argv.append(arg); |
| 1120 | try clang_argv.append(args_iter.nextOrFatal()); | 1156 | try clang_argv.append(args_iter.nextOrFatal()); |
| ... | @@ -1346,8 +1382,12 @@ fn buildOutputType( | ... | @@ -1346,8 +1382,12 @@ fn buildOutputType( |
| 1346 | emit_implib_arg_provided = true; | 1382 | emit_implib_arg_provided = true; |
| 1347 | } else if (mem.eql(u8, arg, "-dynamic")) { | 1383 | } else if (mem.eql(u8, arg, "-dynamic")) { |
| 1348 | link_mode = .Dynamic; | 1384 | link_mode = .Dynamic; |
| 1385 | lib_preferred_mode = .Dynamic; | ||
| 1386 | lib_search_strategy = .mode_first; | ||
| 1349 | } else if (mem.eql(u8, arg, "-static")) { | 1387 | } else if (mem.eql(u8, arg, "-static")) { |
| 1350 | link_mode = .Static; | 1388 | link_mode = .Static; |
| 1389 | lib_preferred_mode = .Static; | ||
| 1390 | lib_search_strategy = .no_fallback; | ||
| 1351 | } else if (mem.eql(u8, arg, "-fdll-export-fns")) { | 1391 | } else if (mem.eql(u8, arg, "-fdll-export-fns")) { |
| 1352 | dll_export_fns = true; | 1392 | dll_export_fns = true; |
| 1353 | } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) { | 1393 | } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) { |
| ... | @@ -1486,17 +1526,33 @@ fn buildOutputType( | ... | @@ -1486,17 +1526,33 @@ fn buildOutputType( |
| 1486 | } else if (mem.startsWith(u8, arg, "-T")) { | 1526 | } else if (mem.startsWith(u8, arg, "-T")) { |
| 1487 | linker_script = arg[2..]; | 1527 | linker_script = arg[2..]; |
| 1488 | } else if (mem.startsWith(u8, arg, "-L")) { | 1528 | } else if (mem.startsWith(u8, arg, "-L")) { |
| 1489 | try lib_dirs.append(arg[2..]); | 1529 | try lib_dir_args.append(arg[2..]); |
| 1490 | } else if (mem.startsWith(u8, arg, "-F")) { | 1530 | } else if (mem.startsWith(u8, arg, "-F")) { |
| 1491 | try framework_dirs.append(arg[2..]); | 1531 | try framework_dirs.append(arg[2..]); |
| 1492 | } else if (mem.startsWith(u8, arg, "-l")) { | 1532 | } else if (mem.startsWith(u8, arg, "-l")) { |
| 1493 | // We don't know whether this library is part of libc or libc++ until | 1533 | // We don't know whether this library is part of libc |
| 1494 | // we resolve the target, so we simply append to the list for now. | 1534 | // or libc++ until we resolve the target, so we append |
| 1495 | try system_libs.put(arg["-l".len..], .{}); | 1535 | // to the list for now. |
| 1536 | try system_libs.put(arg["-l".len..], .{ | ||
| 1537 | .needed = false, | ||
| 1538 | .weak = false, | ||
| 1539 | .preferred_mode = lib_preferred_mode, | ||
| 1540 | .search_strategy = lib_search_strategy, | ||
| 1541 | }); | ||
| 1496 | } else if (mem.startsWith(u8, arg, "-needed-l")) { | 1542 | } else if (mem.startsWith(u8, arg, "-needed-l")) { |
| 1497 | try system_libs.put(arg["-needed-l".len..], .{ .needed = true }); | 1543 | try system_libs.put(arg["-needed-l".len..], .{ |
| 1544 | .needed = true, | ||
| 1545 | .weak = false, | ||
| 1546 | .preferred_mode = lib_preferred_mode, | ||
| 1547 | .search_strategy = lib_search_strategy, | ||
| 1548 | }); | ||
| 1498 | } else if (mem.startsWith(u8, arg, "-weak-l")) { | 1549 | } else if (mem.startsWith(u8, arg, "-weak-l")) { |
| 1499 | try system_libs.put(arg["-weak-l".len..], .{ .weak = true }); | 1550 | try system_libs.put(arg["-weak-l".len..], .{ |
| 1551 | .needed = false, | ||
| 1552 | .weak = true, | ||
| 1553 | .preferred_mode = lib_preferred_mode, | ||
| 1554 | .search_strategy = lib_search_strategy, | ||
| 1555 | }); | ||
| 1500 | } else if (mem.startsWith(u8, arg, "-D")) { | 1556 | } else if (mem.startsWith(u8, arg, "-D")) { |
| 1501 | try clang_argv.append(arg); | 1557 | try clang_argv.append(arg); |
| 1502 | } else if (mem.startsWith(u8, arg, "-I")) { | 1558 | } else if (mem.startsWith(u8, arg, "-I")) { |
| ... | @@ -1571,7 +1627,6 @@ fn buildOutputType( | ... | @@ -1571,7 +1627,6 @@ fn buildOutputType( |
| 1571 | var emit_llvm = false; | 1627 | var emit_llvm = false; |
| 1572 | var needed = false; | 1628 | var needed = false; |
| 1573 | var must_link = false; | 1629 | var must_link = false; |
| 1574 | var force_static_libs = false; | ||
| 1575 | var file_ext: ?Compilation.FileExt = null; | 1630 | var file_ext: ?Compilation.FileExt = null; |
| 1576 | while (it.has_next) { | 1631 | while (it.has_next) { |
| 1577 | it.next() catch |err| { | 1632 | it.next() catch |err| { |
| ... | @@ -1641,10 +1696,13 @@ fn buildOutputType( | ... | @@ -1641,10 +1696,13 @@ fn buildOutputType( |
| 1641 | .must_link = must_link, | 1696 | .must_link = must_link, |
| 1642 | .loption = true, | 1697 | .loption = true, |
| 1643 | }); | 1698 | }); |
| 1644 | } else if (force_static_libs) { | ||
| 1645 | try static_libs.append(it.only_arg); | ||
| 1646 | } else { | 1699 | } else { |
| 1647 | try system_libs.put(it.only_arg, .{ .needed = needed }); | 1700 | try system_libs.put(it.only_arg, .{ |
| 1701 | .needed = needed, | ||
| 1702 | .weak = false, | ||
| 1703 | .preferred_mode = lib_preferred_mode, | ||
| 1704 | .search_strategy = lib_search_strategy, | ||
| 1705 | }); | ||
| 1648 | } | 1706 | } |
| 1649 | }, | 1707 | }, |
| 1650 | .ignore => {}, | 1708 | .ignore => {}, |
| ... | @@ -1740,17 +1798,21 @@ fn buildOutputType( | ... | @@ -1740,17 +1798,21 @@ fn buildOutputType( |
| 1740 | mem.eql(u8, linker_arg, "-dy") or | 1798 | mem.eql(u8, linker_arg, "-dy") or |
| 1741 | mem.eql(u8, linker_arg, "-call_shared")) | 1799 | mem.eql(u8, linker_arg, "-call_shared")) |
| 1742 | { | 1800 | { |
| 1743 | force_static_libs = false; | 1801 | lib_search_strategy = .no_fallback; |
| 1802 | lib_preferred_mode = .Dynamic; | ||
| 1744 | } else if (mem.eql(u8, linker_arg, "-Bstatic") or | 1803 | } else if (mem.eql(u8, linker_arg, "-Bstatic") or |
| 1745 | mem.eql(u8, linker_arg, "-dn") or | 1804 | mem.eql(u8, linker_arg, "-dn") or |
| 1746 | mem.eql(u8, linker_arg, "-non_shared") or | 1805 | mem.eql(u8, linker_arg, "-non_shared") or |
| 1747 | mem.eql(u8, linker_arg, "-static")) | 1806 | mem.eql(u8, linker_arg, "-static")) |
| 1748 | { | 1807 | { |
| 1749 | force_static_libs = true; | 1808 | lib_search_strategy = .no_fallback; |
| 1809 | lib_preferred_mode = .Static; | ||
| 1750 | } else if (mem.eql(u8, linker_arg, "-search_paths_first")) { | 1810 | } else if (mem.eql(u8, linker_arg, "-search_paths_first")) { |
| 1751 | search_strategy = .paths_first; | 1811 | lib_search_strategy = .paths_first; |
| 1812 | lib_preferred_mode = .Dynamic; | ||
| 1752 | } else if (mem.eql(u8, linker_arg, "-search_dylibs_first")) { | 1813 | } else if (mem.eql(u8, linker_arg, "-search_dylibs_first")) { |
| 1753 | search_strategy = .dylibs_first; | 1814 | lib_search_strategy = .mode_first; |
| 1815 | lib_preferred_mode = .Dynamic; | ||
| 1754 | } else { | 1816 | } else { |
| 1755 | try linker_args.append(linker_arg); | 1817 | try linker_args.append(linker_arg); |
| 1756 | } | 1818 | } |
| ... | @@ -1828,7 +1890,7 @@ fn buildOutputType( | ... | @@ -1828,7 +1890,7 @@ fn buildOutputType( |
| 1828 | try linker_args.append("-z"); | 1890 | try linker_args.append("-z"); |
| 1829 | try linker_args.append(it.only_arg); | 1891 | try linker_args.append(it.only_arg); |
| 1830 | }, | 1892 | }, |
| 1831 | .lib_dir => try lib_dirs.append(it.only_arg), | 1893 | .lib_dir => try lib_dir_args.append(it.only_arg), |
| 1832 | .mcpu => target_mcpu = it.only_arg, | 1894 | .mcpu => target_mcpu = it.only_arg, |
| 1833 | .m => try llvm_m_args.append(it.only_arg), | 1895 | .m => try llvm_m_args.append(it.only_arg), |
| 1834 | .dep_file => { | 1896 | .dep_file => { |
| ... | @@ -1860,7 +1922,12 @@ fn buildOutputType( | ... | @@ -1860,7 +1922,12 @@ fn buildOutputType( |
| 1860 | .force_undefined_symbol => { | 1922 | .force_undefined_symbol => { |
| 1861 | try force_undefined_symbols.put(gpa, it.only_arg, {}); | 1923 | try force_undefined_symbols.put(gpa, it.only_arg, {}); |
| 1862 | }, | 1924 | }, |
| 1863 | .weak_library => try system_libs.put(it.only_arg, .{ .weak = true }), | 1925 | .weak_library => try system_libs.put(it.only_arg, .{ |
| 1926 | .needed = false, | ||
| 1927 | .weak = true, | ||
| 1928 | .preferred_mode = lib_preferred_mode, | ||
| 1929 | .search_strategy = lib_search_strategy, | ||
| 1930 | }), | ||
| 1864 | .weak_framework => try frameworks.put(gpa, it.only_arg, .{ .weak = true }), | 1931 | .weak_framework => try frameworks.put(gpa, it.only_arg, .{ .weak = true }), |
| 1865 | .headerpad_max_install_names => headerpad_max_install_names = true, | 1932 | .headerpad_max_install_names => headerpad_max_install_names = true, |
| 1866 | .compress_debug_sections => { | 1933 | .compress_debug_sections => { |
| ... | @@ -2156,11 +2223,26 @@ fn buildOutputType( | ... | @@ -2156,11 +2223,26 @@ fn buildOutputType( |
| 2156 | } else if (mem.eql(u8, arg, "-needed_framework")) { | 2223 | } else if (mem.eql(u8, arg, "-needed_framework")) { |
| 2157 | try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{ .needed = true }); | 2224 | try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{ .needed = true }); |
| 2158 | } else if (mem.eql(u8, arg, "-needed_library")) { | 2225 | } else if (mem.eql(u8, arg, "-needed_library")) { |
| 2159 | try system_libs.put(linker_args_it.nextOrFatal(), .{ .needed = true }); | 2226 | try system_libs.put(linker_args_it.nextOrFatal(), .{ |
| 2227 | .weak = false, | ||
| 2228 | .needed = true, | ||
| 2229 | .preferred_mode = lib_preferred_mode, | ||
| 2230 | .search_strategy = lib_search_strategy, | ||
| 2231 | }); | ||
| 2160 | } else if (mem.startsWith(u8, arg, "-weak-l")) { | 2232 | } else if (mem.startsWith(u8, arg, "-weak-l")) { |
| 2161 | try system_libs.put(arg["-weak-l".len..], .{ .weak = true }); | 2233 | try system_libs.put(arg["-weak-l".len..], .{ |
| 2234 | .weak = true, | ||
| 2235 | .needed = false, | ||
| 2236 | .preferred_mode = lib_preferred_mode, | ||
| 2237 | .search_strategy = lib_search_strategy, | ||
| 2238 | }); | ||
| 2162 | } else if (mem.eql(u8, arg, "-weak_library")) { | 2239 | } else if (mem.eql(u8, arg, "-weak_library")) { |
| 2163 | try system_libs.put(linker_args_it.nextOrFatal(), .{ .weak = true }); | 2240 | try system_libs.put(linker_args_it.nextOrFatal(), .{ |
| 2241 | .weak = true, | ||
| 2242 | .needed = false, | ||
| 2243 | .preferred_mode = lib_preferred_mode, | ||
| 2244 | .search_strategy = lib_search_strategy, | ||
| 2245 | }); | ||
| 2164 | } else if (mem.eql(u8, arg, "-compatibility_version")) { | 2246 | } else if (mem.eql(u8, arg, "-compatibility_version")) { |
| 2165 | const compat_version = linker_args_it.nextOrFatal(); | 2247 | const compat_version = linker_args_it.nextOrFatal(); |
| 2166 | compatibility_version = std.SemanticVersion.parse(compat_version) catch |err| { | 2248 | compatibility_version = std.SemanticVersion.parse(compat_version) catch |err| { |
| ... | @@ -2458,105 +2540,6 @@ fn buildOutputType( | ... | @@ -2458,105 +2540,6 @@ fn buildOutputType( |
| 2458 | } | 2540 | } |
| 2459 | } | 2541 | } |
| 2460 | 2542 | ||
| 2461 | // Now that we have target info, we can find out if any of the system libraries | ||
| 2462 | // are part of libc or libc++. We remove them from the list and communicate their | ||
| 2463 | // existence via flags instead. | ||
| 2464 | { | ||
| 2465 | // Similarly, if any libs in this list are statically provided, we remove | ||
| 2466 | // them from this list and populate the link_objects array instead. | ||
| 2467 | const sep = fs.path.sep_str; | ||
| 2468 | var test_path = std.ArrayList(u8).init(gpa); | ||
| 2469 | defer test_path.deinit(); | ||
| 2470 | |||
| 2471 | var i: usize = 0; | ||
| 2472 | syslib: while (i < system_libs.count()) { | ||
| 2473 | const lib_name = system_libs.keys()[i]; | ||
| 2474 | |||
| 2475 | if (target_util.is_libc_lib_name(target_info.target, lib_name)) { | ||
| 2476 | link_libc = true; | ||
| 2477 | system_libs.orderedRemoveAt(i); | ||
| 2478 | continue; | ||
| 2479 | } | ||
| 2480 | if (target_util.is_libcpp_lib_name(target_info.target, lib_name)) { | ||
| 2481 | link_libcpp = true; | ||
| 2482 | system_libs.orderedRemoveAt(i); | ||
| 2483 | continue; | ||
| 2484 | } | ||
| 2485 | switch (target_util.classifyCompilerRtLibName(target_info.target, lib_name)) { | ||
| 2486 | .none => {}, | ||
| 2487 | .only_libunwind, .both => { | ||
| 2488 | link_libunwind = true; | ||
| 2489 | system_libs.orderedRemoveAt(i); | ||
| 2490 | continue; | ||
| 2491 | }, | ||
| 2492 | .only_compiler_rt => { | ||
| 2493 | std.log.warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name}); | ||
| 2494 | system_libs.orderedRemoveAt(i); | ||
| 2495 | continue; | ||
| 2496 | }, | ||
| 2497 | } | ||
| 2498 | |||
| 2499 | if (fs.path.isAbsolute(lib_name)) { | ||
| 2500 | fatal("cannot use absolute path as a system library: {s}", .{lib_name}); | ||
| 2501 | } | ||
| 2502 | |||
| 2503 | if (target_info.target.os.tag == .wasi) { | ||
| 2504 | if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| { | ||
| 2505 | try wasi_emulated_libs.append(crt_file); | ||
| 2506 | system_libs.orderedRemoveAt(i); | ||
| 2507 | continue; | ||
| 2508 | } | ||
| 2509 | } | ||
| 2510 | |||
| 2511 | for (lib_dirs.items) |lib_dir_path| { | ||
| 2512 | if (cross_target.isDarwin()) break; // Targeting Darwin we let the linker resolve the libraries in the correct order | ||
| 2513 | test_path.clearRetainingCapacity(); | ||
| 2514 | try test_path.writer().print("{s}" ++ sep ++ "{s}{s}{s}", .{ | ||
| 2515 | lib_dir_path, | ||
| 2516 | target_info.target.libPrefix(), | ||
| 2517 | lib_name, | ||
| 2518 | target_info.target.staticLibSuffix(), | ||
| 2519 | }); | ||
| 2520 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { | ||
| 2521 | error.FileNotFound => continue, | ||
| 2522 | else => |e| fatal("unable to search for static library '{s}': {s}", .{ | ||
| 2523 | test_path.items, @errorName(e), | ||
| 2524 | }), | ||
| 2525 | }; | ||
| 2526 | try link_objects.append(.{ .path = try arena.dupe(u8, test_path.items) }); | ||
| 2527 | system_libs.orderedRemoveAt(i); | ||
| 2528 | continue :syslib; | ||
| 2529 | } | ||
| 2530 | |||
| 2531 | // Unfortunately, in the case of MinGW we also need to look for `libfoo.a`. | ||
| 2532 | if (target_info.target.isMinGW()) { | ||
| 2533 | for (lib_dirs.items) |lib_dir_path| { | ||
| 2534 | test_path.clearRetainingCapacity(); | ||
| 2535 | try test_path.writer().print("{s}" ++ sep ++ "lib{s}.a", .{ | ||
| 2536 | lib_dir_path, lib_name, | ||
| 2537 | }); | ||
| 2538 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { | ||
| 2539 | error.FileNotFound => continue, | ||
| 2540 | else => |e| fatal("unable to search for static library '{s}': {s}", .{ | ||
| 2541 | test_path.items, @errorName(e), | ||
| 2542 | }), | ||
| 2543 | }; | ||
| 2544 | try link_objects.append(.{ .path = try arena.dupe(u8, test_path.items) }); | ||
| 2545 | system_libs.orderedRemoveAt(i); | ||
| 2546 | continue :syslib; | ||
| 2547 | } | ||
| 2548 | } | ||
| 2549 | |||
| 2550 | std.log.scoped(.cli).debug("depending on system for -l{s}", .{lib_name}); | ||
| 2551 | |||
| 2552 | i += 1; | ||
| 2553 | } | ||
| 2554 | } | ||
| 2555 | // libc++ depends on libc | ||
| 2556 | if (link_libcpp) { | ||
| 2557 | link_libc = true; | ||
| 2558 | } | ||
| 2559 | |||
| 2560 | if (use_lld) |opt| { | 2543 | if (use_lld) |opt| { |
| 2561 | if (opt and cross_target.isDarwin()) { | 2544 | if (opt and cross_target.isDarwin()) { |
| 2562 | fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{}); | 2545 | fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{}); |
| ... | @@ -2575,8 +2558,124 @@ fn buildOutputType( | ... | @@ -2575,8 +2558,124 @@ fn buildOutputType( |
| 2575 | want_native_include_dirs = true; | 2558 | want_native_include_dirs = true; |
| 2576 | } | 2559 | } |
| 2577 | 2560 | ||
| 2578 | if (sysroot == null and cross_target.isNativeOs() and | 2561 | // Resolve the library path arguments with respect to sysroot. |
| 2579 | (system_libs.count() != 0 or want_native_include_dirs)) | 2562 | var lib_dirs = std.ArrayList([]const u8).init(arena); |
| 2563 | if (sysroot) |root| { | ||
| 2564 | for (lib_dir_args.items) |dir| { | ||
| 2565 | if (fs.path.isAbsolute(dir)) { | ||
| 2566 | const stripped_dir = dir[fs.path.diskDesignator(dir).len..]; | ||
| 2567 | const full_path = try fs.path.join(arena, &[_][]const u8{ root, stripped_dir }); | ||
| 2568 | try lib_dirs.append(full_path); | ||
| 2569 | } | ||
| 2570 | try lib_dirs.append(dir); | ||
| 2571 | } | ||
| 2572 | } else { | ||
| 2573 | lib_dirs = lib_dir_args; | ||
| 2574 | } | ||
| 2575 | lib_dir_args = undefined; // From here we use lib_dirs instead. | ||
| 2576 | |||
| 2577 | const self_exe_path: ?[]const u8 = if (!process.can_spawn) | ||
| 2578 | null | ||
| 2579 | else | ||
| 2580 | introspect.findZigExePath(arena) catch |err| { | ||
| 2581 | fatal("unable to find zig self exe path: {s}", .{@errorName(err)}); | ||
| 2582 | }; | ||
| 2583 | |||
| 2584 | var zig_lib_directory: Compilation.Directory = d: { | ||
| 2585 | if (override_lib_dir) |unresolved_lib_dir| { | ||
| 2586 | const lib_dir = try introspect.resolvePath(arena, unresolved_lib_dir); | ||
| 2587 | break :d .{ | ||
| 2588 | .path = lib_dir, | ||
| 2589 | .handle = fs.cwd().openDir(lib_dir, .{}) catch |err| { | ||
| 2590 | fatal("unable to open zig lib directory '{s}': {s}", .{ lib_dir, @errorName(err) }); | ||
| 2591 | }, | ||
| 2592 | }; | ||
| 2593 | } else if (builtin.os.tag == .wasi) { | ||
| 2594 | break :d getWasiPreopen("/lib"); | ||
| 2595 | } else if (self_exe_path) |p| { | ||
| 2596 | break :d introspect.findZigLibDirFromSelfExe(arena, p) catch |err| { | ||
| 2597 | fatal("unable to find zig installation directory: {s}", .{@errorName(err)}); | ||
| 2598 | }; | ||
| 2599 | } else { | ||
| 2600 | unreachable; | ||
| 2601 | } | ||
| 2602 | }; | ||
| 2603 | defer zig_lib_directory.handle.close(); | ||
| 2604 | |||
| 2605 | // First, remove libc, libc++, and compiler_rt libraries from the system libraries list. | ||
| 2606 | // We need to know whether the set of system libraries contains anything besides these | ||
| 2607 | // to decide whether to trigger native path detection logic. | ||
| 2608 | var external_system_libs: std.MultiArrayList(struct { | ||
| 2609 | name: []const u8, | ||
| 2610 | info: SystemLib, | ||
| 2611 | }) = .{}; | ||
| 2612 | |||
| 2613 | var resolved_system_libs: std.MultiArrayList(struct { | ||
| 2614 | name: []const u8, | ||
| 2615 | lib: Compilation.SystemLib, | ||
| 2616 | }) = .{}; | ||
| 2617 | |||
| 2618 | for (system_libs.keys(), system_libs.values()) |lib_name, info| { | ||
| 2619 | if (target_util.is_libc_lib_name(target_info.target, lib_name)) { | ||
| 2620 | link_libc = true; | ||
| 2621 | continue; | ||
| 2622 | } | ||
| 2623 | if (target_util.is_libcpp_lib_name(target_info.target, lib_name)) { | ||
| 2624 | link_libcpp = true; | ||
| 2625 | continue; | ||
| 2626 | } | ||
| 2627 | switch (target_util.classifyCompilerRtLibName(target_info.target, lib_name)) { | ||
| 2628 | .none => {}, | ||
| 2629 | .only_libunwind, .both => { | ||
| 2630 | link_libunwind = true; | ||
| 2631 | continue; | ||
| 2632 | }, | ||
| 2633 | .only_compiler_rt => { | ||
| 2634 | std.log.warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name}); | ||
| 2635 | continue; | ||
| 2636 | }, | ||
| 2637 | } | ||
| 2638 | |||
| 2639 | if (target_info.target.os.tag == .windows) { | ||
| 2640 | const exists = mingw.libExists(arena, target_info.target, zig_lib_directory, lib_name) catch |err| { | ||
| 2641 | fatal("failed to check zig installation for DLL import libs: {s}", .{ | ||
| 2642 | @errorName(err), | ||
| 2643 | }); | ||
| 2644 | }; | ||
| 2645 | if (exists) { | ||
| 2646 | try resolved_system_libs.append(arena, .{ | ||
| 2647 | .name = lib_name, | ||
| 2648 | .lib = .{ | ||
| 2649 | .needed = true, | ||
| 2650 | .weak = false, | ||
| 2651 | .path = null, | ||
| 2652 | }, | ||
| 2653 | }); | ||
| 2654 | continue; | ||
| 2655 | } | ||
| 2656 | } | ||
| 2657 | |||
| 2658 | if (fs.path.isAbsolute(lib_name)) { | ||
| 2659 | fatal("cannot use absolute path as a system library: {s}", .{lib_name}); | ||
| 2660 | } | ||
| 2661 | |||
| 2662 | if (target_info.target.os.tag == .wasi) { | ||
| 2663 | if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| { | ||
| 2664 | try wasi_emulated_libs.append(crt_file); | ||
| 2665 | continue; | ||
| 2666 | } | ||
| 2667 | } | ||
| 2668 | |||
| 2669 | try external_system_libs.append(arena, .{ | ||
| 2670 | .name = lib_name, | ||
| 2671 | .info = info, | ||
| 2672 | }); | ||
| 2673 | } | ||
| 2674 | // After this point, external_system_libs is used instead of system_libs. | ||
| 2675 | |||
| 2676 | // Trigger native system library path detection if necessary. | ||
| 2677 | if (sysroot == null and cross_target.isNativeOs() and cross_target.isNativeAbi() and | ||
| 2678 | (external_system_libs.len != 0 or want_native_include_dirs)) | ||
| 2580 | { | 2679 | { |
| 2581 | const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| { | 2680 | const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| { |
| 2582 | fatal("unable to detect native system paths: {s}", .{@errorName(err)}); | 2681 | fatal("unable to detect native system paths: {s}", .{@errorName(err)}); |
| ... | @@ -2585,83 +2684,181 @@ fn buildOutputType( | ... | @@ -2585,83 +2684,181 @@ fn buildOutputType( |
| 2585 | warn("{s}", .{warning}); | 2684 | warn("{s}", .{warning}); |
| 2586 | } | 2685 | } |
| 2587 | 2686 | ||
| 2588 | const has_sysroot = if (comptime builtin.target.isDarwin()) outer: { | ||
| 2589 | if (std.zig.system.darwin.isDarwinSDKInstalled(arena)) { | ||
| 2590 | const sdk = std.zig.system.darwin.getDarwinSDK(arena, target_info.target) orelse | ||
| 2591 | break :outer false; | ||
| 2592 | native_darwin_sdk = sdk; | ||
| 2593 | try clang_argv.ensureUnusedCapacity(2); | ||
| 2594 | clang_argv.appendAssumeCapacity("-isysroot"); | ||
| 2595 | clang_argv.appendAssumeCapacity(sdk.path); | ||
| 2596 | break :outer true; | ||
| 2597 | } else break :outer false; | ||
| 2598 | } else false; | ||
| 2599 | |||
| 2600 | try clang_argv.ensureUnusedCapacity(paths.include_dirs.items.len * 2); | 2687 | try clang_argv.ensureUnusedCapacity(paths.include_dirs.items.len * 2); |
| 2601 | const isystem_flag = if (has_sysroot) "-iwithsysroot" else "-isystem"; | ||
| 2602 | for (paths.include_dirs.items) |include_dir| { | 2688 | for (paths.include_dirs.items) |include_dir| { |
| 2603 | clang_argv.appendAssumeCapacity(isystem_flag); | 2689 | clang_argv.appendAssumeCapacity("-isystem"); |
| 2604 | clang_argv.appendAssumeCapacity(include_dir); | 2690 | clang_argv.appendAssumeCapacity(include_dir); |
| 2605 | } | 2691 | } |
| 2606 | 2692 | ||
| 2607 | try clang_argv.ensureUnusedCapacity(paths.framework_dirs.items.len * 2); | 2693 | try framework_dirs.appendSlice(paths.framework_dirs.items); |
| 2608 | try framework_dirs.ensureUnusedCapacity(paths.framework_dirs.items.len); | 2694 | try lib_dirs.appendSlice(paths.lib_dirs.items); |
| 2609 | const iframework_flag = if (has_sysroot) "-iframeworkwithsysroot" else "-iframework"; | 2695 | try rpath_list.appendSlice(paths.rpaths.items); |
| 2610 | for (paths.framework_dirs.items) |framework_dir| { | ||
| 2611 | clang_argv.appendAssumeCapacity(iframework_flag); | ||
| 2612 | clang_argv.appendAssumeCapacity(framework_dir); | ||
| 2613 | framework_dirs.appendAssumeCapacity(framework_dir); | ||
| 2614 | } | ||
| 2615 | |||
| 2616 | for (paths.lib_dirs.items) |lib_dir| { | ||
| 2617 | try lib_dirs.append(lib_dir); | ||
| 2618 | } | ||
| 2619 | for (paths.rpaths.items) |rpath| { | ||
| 2620 | try rpath_list.append(rpath); | ||
| 2621 | } | ||
| 2622 | } | 2696 | } |
| 2623 | 2697 | ||
| 2698 | // If any libs in this list are statically provided, we omit them from the | ||
| 2699 | // resolved list and populate the link_objects array instead. | ||
| 2624 | { | 2700 | { |
| 2625 | // Resolve static libraries into full paths. | ||
| 2626 | const sep = fs.path.sep_str; | ||
| 2627 | |||
| 2628 | var test_path = std.ArrayList(u8).init(gpa); | 2701 | var test_path = std.ArrayList(u8).init(gpa); |
| 2629 | defer test_path.deinit(); | 2702 | defer test_path.deinit(); |
| 2630 | 2703 | ||
| 2631 | for (static_libs.items) |static_lib| { | 2704 | var checked_paths = std.ArrayList(u8).init(gpa); |
| 2632 | for (lib_dirs.items) |lib_dir_path| { | 2705 | defer checked_paths.deinit(); |
| 2633 | test_path.clearRetainingCapacity(); | 2706 | |
| 2634 | try test_path.writer().print("{s}" ++ sep ++ "{s}{s}{s}", .{ | 2707 | var failed_libs = std.ArrayList(struct { |
| 2635 | lib_dir_path, | 2708 | name: []const u8, |
| 2636 | target_info.target.libPrefix(), | 2709 | strategy: SystemLib.SearchStrategy, |
| 2637 | static_lib, | 2710 | checked_paths: []const u8, |
| 2638 | target_info.target.staticLibSuffix(), | 2711 | preferred_mode: std.builtin.LinkMode, |
| 2639 | }); | 2712 | }).init(arena); |
| 2640 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { | 2713 | |
| 2641 | error.FileNotFound => continue, | 2714 | syslib: for (external_system_libs.items(.name), external_system_libs.items(.info)) |lib_name, info| { |
| 2642 | else => |e| fatal("unable to search for static library '{s}': {s}", .{ | 2715 | // Checked in the first pass above while looking for libc libraries. |
| 2643 | test_path.items, @errorName(e), | 2716 | assert(!fs.path.isAbsolute(lib_name)); |
| 2644 | }), | 2717 | |
| 2645 | }; | 2718 | checked_paths.clearRetainingCapacity(); |
| 2646 | try link_objects.append(.{ .path = try arena.dupe(u8, test_path.items) }); | 2719 | |
| 2647 | break; | 2720 | switch (info.search_strategy) { |
| 2648 | } else { | 2721 | .mode_first, .no_fallback => { |
| 2649 | var search_paths = std.ArrayList(u8).init(arena); | 2722 | // check for preferred mode |
| 2650 | for (lib_dirs.items) |lib_dir_path| { | 2723 | for (lib_dirs.items) |lib_dir_path| { |
| 2651 | try search_paths.writer().print("\n {s}" ++ sep ++ "{s}{s}{s}", .{ | 2724 | if (try accessLibPath( |
| 2652 | lib_dir_path, | 2725 | &test_path, |
| 2653 | target_info.target.libPrefix(), | 2726 | &checked_paths, |
| 2654 | static_lib, | 2727 | lib_dir_path, |
| 2655 | target_info.target.staticLibSuffix(), | 2728 | lib_name, |
| 2729 | target_info.target, | ||
| 2730 | info.preferred_mode, | ||
| 2731 | )) { | ||
| 2732 | const path = try arena.dupe(u8, test_path.items); | ||
| 2733 | switch (info.preferred_mode) { | ||
| 2734 | .Static => try link_objects.append(.{ .path = path }), | ||
| 2735 | .Dynamic => try resolved_system_libs.append(arena, .{ | ||
| 2736 | .name = lib_name, | ||
| 2737 | .lib = .{ | ||
| 2738 | .needed = info.needed, | ||
| 2739 | .weak = info.weak, | ||
| 2740 | .path = path, | ||
| 2741 | }, | ||
| 2742 | }), | ||
| 2743 | } | ||
| 2744 | continue :syslib; | ||
| 2745 | } | ||
| 2746 | } | ||
| 2747 | // check for fallback mode | ||
| 2748 | if (info.search_strategy == .no_fallback) { | ||
| 2749 | try failed_libs.append(.{ | ||
| 2750 | .name = lib_name, | ||
| 2751 | .strategy = info.search_strategy, | ||
| 2752 | .checked_paths = try arena.dupe(u8, checked_paths.items), | ||
| 2753 | .preferred_mode = info.preferred_mode, | ||
| 2754 | }); | ||
| 2755 | continue :syslib; | ||
| 2756 | } | ||
| 2757 | for (lib_dirs.items) |lib_dir_path| { | ||
| 2758 | if (try accessLibPath( | ||
| 2759 | &test_path, | ||
| 2760 | &checked_paths, | ||
| 2761 | lib_dir_path, | ||
| 2762 | lib_name, | ||
| 2763 | target_info.target, | ||
| 2764 | info.fallbackMode(), | ||
| 2765 | )) { | ||
| 2766 | const path = try arena.dupe(u8, test_path.items); | ||
| 2767 | switch (info.fallbackMode()) { | ||
| 2768 | .Static => try link_objects.append(.{ .path = path }), | ||
| 2769 | .Dynamic => try resolved_system_libs.append(arena, .{ | ||
| 2770 | .name = lib_name, | ||
| 2771 | .lib = .{ | ||
| 2772 | .needed = info.needed, | ||
| 2773 | .weak = info.weak, | ||
| 2774 | .path = path, | ||
| 2775 | }, | ||
| 2776 | }), | ||
| 2777 | } | ||
| 2778 | continue :syslib; | ||
| 2779 | } | ||
| 2780 | } | ||
| 2781 | try failed_libs.append(.{ | ||
| 2782 | .name = lib_name, | ||
| 2783 | .strategy = info.search_strategy, | ||
| 2784 | .checked_paths = try arena.dupe(u8, checked_paths.items), | ||
| 2785 | .preferred_mode = info.preferred_mode, | ||
| 2656 | }); | 2786 | }); |
| 2657 | } | 2787 | continue :syslib; |
| 2658 | try search_paths.appendSlice("\n suggestion: use full paths to static libraries on the command line rather than using -l and -L arguments"); | 2788 | }, |
| 2659 | fatal("static library '{s}' not found. search paths: {s}", .{ | 2789 | .paths_first => { |
| 2660 | static_lib, search_paths.items, | 2790 | for (lib_dirs.items) |lib_dir_path| { |
| 2791 | // check for preferred mode | ||
| 2792 | if (try accessLibPath( | ||
| 2793 | &test_path, | ||
| 2794 | &checked_paths, | ||
| 2795 | lib_dir_path, | ||
| 2796 | lib_name, | ||
| 2797 | target_info.target, | ||
| 2798 | info.preferred_mode, | ||
| 2799 | )) { | ||
| 2800 | const path = try arena.dupe(u8, test_path.items); | ||
| 2801 | switch (info.preferred_mode) { | ||
| 2802 | .Static => try link_objects.append(.{ .path = path }), | ||
| 2803 | .Dynamic => try resolved_system_libs.append(arena, .{ | ||
| 2804 | .name = lib_name, | ||
| 2805 | .lib = .{ | ||
| 2806 | .needed = info.needed, | ||
| 2807 | .weak = info.weak, | ||
| 2808 | .path = path, | ||
| 2809 | }, | ||
| 2810 | }), | ||
| 2811 | } | ||
| 2812 | continue :syslib; | ||
| 2813 | } | ||
| 2814 | |||
| 2815 | // check for fallback mode | ||
| 2816 | if (try accessLibPath( | ||
| 2817 | &test_path, | ||
| 2818 | &checked_paths, | ||
| 2819 | lib_dir_path, | ||
| 2820 | lib_name, | ||
| 2821 | target_info.target, | ||
| 2822 | info.fallbackMode(), | ||
| 2823 | )) { | ||
| 2824 | const path = try arena.dupe(u8, test_path.items); | ||
| 2825 | switch (info.fallbackMode()) { | ||
| 2826 | .Static => try link_objects.append(.{ .path = path }), | ||
| 2827 | .Dynamic => try resolved_system_libs.append(arena, .{ | ||
| 2828 | .name = lib_name, | ||
| 2829 | .lib = .{ | ||
| 2830 | .needed = info.needed, | ||
| 2831 | .weak = info.weak, | ||
| 2832 | .path = path, | ||
| 2833 | }, | ||
| 2834 | }), | ||
| 2835 | } | ||
| 2836 | continue :syslib; | ||
| 2837 | } | ||
| 2838 | } | ||
| 2839 | try failed_libs.append(.{ | ||
| 2840 | .name = lib_name, | ||
| 2841 | .strategy = info.search_strategy, | ||
| 2842 | .checked_paths = try arena.dupe(u8, checked_paths.items), | ||
| 2843 | .preferred_mode = info.preferred_mode, | ||
| 2844 | }); | ||
| 2845 | continue :syslib; | ||
| 2846 | }, | ||
| 2847 | } | ||
| 2848 | @compileError("unreachable"); | ||
| 2849 | } | ||
| 2850 | |||
| 2851 | if (failed_libs.items.len > 0) { | ||
| 2852 | for (failed_libs.items) |f| { | ||
| 2853 | const searched_paths = if (f.checked_paths.len == 0) " none" else f.checked_paths; | ||
| 2854 | std.log.err("unable to find {s} system library '{s}' using strategy '{s}'. searched paths:{s}", .{ | ||
| 2855 | @tagName(f.preferred_mode), f.name, @tagName(f.strategy), searched_paths, | ||
| 2661 | }); | 2856 | }); |
| 2662 | } | 2857 | } |
| 2858 | process.exit(1); | ||
| 2663 | } | 2859 | } |
| 2664 | } | 2860 | } |
| 2861 | // After this point, resolved_system_libs is used instead of external_system_libs. | ||
| 2665 | 2862 | ||
| 2666 | const object_format = target_info.target.ofmt; | 2863 | const object_format = target_info.target.ofmt; |
| 2667 | 2864 | ||
| ... | @@ -2912,35 +3109,6 @@ fn buildOutputType( | ... | @@ -2912,35 +3109,6 @@ fn buildOutputType( |
| 2912 | } | 3109 | } |
| 2913 | } | 3110 | } |
| 2914 | 3111 | ||
| 2915 | const self_exe_path: ?[]const u8 = if (!process.can_spawn) | ||
| 2916 | null | ||
| 2917 | else | ||
| 2918 | introspect.findZigExePath(arena) catch |err| { | ||
| 2919 | fatal("unable to find zig self exe path: {s}", .{@errorName(err)}); | ||
| 2920 | }; | ||
| 2921 | |||
| 2922 | var zig_lib_directory: Compilation.Directory = d: { | ||
| 2923 | if (override_lib_dir) |unresolved_lib_dir| { | ||
| 2924 | const lib_dir = try introspect.resolvePath(arena, unresolved_lib_dir); | ||
| 2925 | break :d .{ | ||
| 2926 | .path = lib_dir, | ||
| 2927 | .handle = fs.cwd().openDir(lib_dir, .{}) catch |err| { | ||
| 2928 | fatal("unable to open zig lib directory '{s}': {s}", .{ lib_dir, @errorName(err) }); | ||
| 2929 | }, | ||
| 2930 | }; | ||
| 2931 | } else if (builtin.os.tag == .wasi) { | ||
| 2932 | break :d getWasiPreopen("/lib"); | ||
| 2933 | } else if (self_exe_path) |p| { | ||
| 2934 | break :d introspect.findZigLibDirFromSelfExe(arena, p) catch |err| { | ||
| 2935 | fatal("unable to find zig installation directory: {s}", .{@errorName(err)}); | ||
| 2936 | }; | ||
| 2937 | } else { | ||
| 2938 | unreachable; | ||
| 2939 | } | ||
| 2940 | }; | ||
| 2941 | |||
| 2942 | defer zig_lib_directory.handle.close(); | ||
| 2943 | |||
| 2944 | var thread_pool: ThreadPool = undefined; | 3112 | var thread_pool: ThreadPool = undefined; |
| 2945 | try thread_pool.init(.{ .allocator = gpa }); | 3113 | try thread_pool.init(.{ .allocator = gpa }); |
| 2946 | defer thread_pool.deinit(); | 3114 | defer thread_pool.deinit(); |
| ... | @@ -3086,8 +3254,8 @@ fn buildOutputType( | ... | @@ -3086,8 +3254,8 @@ fn buildOutputType( |
| 3086 | .link_objects = link_objects.items, | 3254 | .link_objects = link_objects.items, |
| 3087 | .framework_dirs = framework_dirs.items, | 3255 | .framework_dirs = framework_dirs.items, |
| 3088 | .frameworks = frameworks, | 3256 | .frameworks = frameworks, |
| 3089 | .system_lib_names = system_libs.keys(), | 3257 | .system_lib_names = resolved_system_libs.items(.name), |
| 3090 | .system_lib_infos = system_libs.values(), | 3258 | .system_lib_infos = resolved_system_libs.items(.lib), |
| 3091 | .wasi_emulated_libs = wasi_emulated_libs.items, | 3259 | .wasi_emulated_libs = wasi_emulated_libs.items, |
| 3092 | .link_libc = link_libc, | 3260 | .link_libc = link_libc, |
| 3093 | .link_libcpp = link_libcpp, | 3261 | .link_libcpp = link_libcpp, |
| ... | @@ -3192,11 +3360,9 @@ fn buildOutputType( | ... | @@ -3192,11 +3360,9 @@ fn buildOutputType( |
| 3192 | .wasi_exec_model = wasi_exec_model, | 3360 | .wasi_exec_model = wasi_exec_model, |
| 3193 | .debug_compile_errors = debug_compile_errors, | 3361 | .debug_compile_errors = debug_compile_errors, |
| 3194 | .enable_link_snapshots = enable_link_snapshots, | 3362 | .enable_link_snapshots = enable_link_snapshots, |
| 3195 | .native_darwin_sdk = native_darwin_sdk, | ||
| 3196 | .install_name = install_name, | 3363 | .install_name = install_name, |
| 3197 | .entitlements = entitlements, | 3364 | .entitlements = entitlements, |
| 3198 | .pagezero_size = pagezero_size, | 3365 | .pagezero_size = pagezero_size, |
| 3199 | .search_strategy = search_strategy, | ||
| 3200 | .headerpad_size = headerpad_size, | 3366 | .headerpad_size = headerpad_size, |
| 3201 | .headerpad_max_install_names = headerpad_max_install_names, | 3367 | .headerpad_max_install_names = headerpad_max_install_names, |
| 3202 | .dead_strip_dylibs = dead_strip_dylibs, | 3368 | .dead_strip_dylibs = dead_strip_dylibs, |
| ... | @@ -4069,10 +4235,12 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { | ... | @@ -4069,10 +4235,12 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4069 | if (!cross_target.isNative()) { | 4235 | if (!cross_target.isNative()) { |
| 4070 | fatal("unable to detect libc for non-native target", .{}); | 4236 | fatal("unable to detect libc for non-native target", .{}); |
| 4071 | } | 4237 | } |
| 4238 | const target_info = try detectNativeTargetInfo(cross_target); | ||
| 4072 | 4239 | ||
| 4073 | var libc = LibCInstallation.findNative(.{ | 4240 | var libc = LibCInstallation.findNative(.{ |
| 4074 | .allocator = gpa, | 4241 | .allocator = gpa, |
| 4075 | .verbose = true, | 4242 | .verbose = true, |
| 4243 | .target = target_info.target, | ||
| 4076 | }) catch |err| { | 4244 | }) catch |err| { |
| 4077 | fatal("unable to detect native libc: {s}", .{@errorName(err)}); | 4245 | fatal("unable to detect native libc: {s}", .{@errorName(err)}); |
| 4078 | }; | 4246 | }; |
| ... | @@ -6068,3 +6236,83 @@ fn renderOptions(color: Color) std.zig.ErrorBundle.RenderOptions { | ... | @@ -6068,3 +6236,83 @@ fn renderOptions(color: Color) std.zig.ErrorBundle.RenderOptions { |
| 6068 | .include_reference_trace = ttyconf != .no_color, | 6236 | .include_reference_trace = ttyconf != .no_color, |
| 6069 | }; | 6237 | }; |
| 6070 | } | 6238 | } |
| 6239 | |||
| 6240 | fn accessLibPath( | ||
| 6241 | test_path: *std.ArrayList(u8), | ||
| 6242 | checked_paths: *std.ArrayList(u8), | ||
| 6243 | lib_dir_path: []const u8, | ||
| 6244 | lib_name: []const u8, | ||
| 6245 | target: std.Target, | ||
| 6246 | link_mode: std.builtin.LinkMode, | ||
| 6247 | ) !bool { | ||
| 6248 | const sep = fs.path.sep_str; | ||
| 6249 | |||
| 6250 | if (target.isDarwin() and link_mode == .Dynamic) tbd: { | ||
| 6251 | // Prefer .tbd over .dylib. | ||
| 6252 | test_path.clearRetainingCapacity(); | ||
| 6253 | try test_path.writer().print("{s}" ++ sep ++ "lib{s}.tbd", .{ lib_dir_path, lib_name }); | ||
| 6254 | try checked_paths.writer().print("\n {s}", .{test_path.items}); | ||
| 6255 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { | ||
| 6256 | error.FileNotFound => break :tbd, | ||
| 6257 | else => |e| fatal("unable to search for tbd library '{s}': {s}", .{ | ||
| 6258 | test_path.items, @errorName(e), | ||
| 6259 | }), | ||
| 6260 | }; | ||
| 6261 | return true; | ||
| 6262 | } | ||
| 6263 | |||
| 6264 | main_check: { | ||
| 6265 | test_path.clearRetainingCapacity(); | ||
| 6266 | try test_path.writer().print("{s}" ++ sep ++ "{s}{s}{s}", .{ | ||
| 6267 | lib_dir_path, | ||
| 6268 | target.libPrefix(), | ||
| 6269 | lib_name, | ||
| 6270 | switch (link_mode) { | ||
| 6271 | .Static => target.staticLibSuffix(), | ||
| 6272 | .Dynamic => target.dynamicLibSuffix(), | ||
| 6273 | }, | ||
| 6274 | }); | ||
| 6275 | try checked_paths.writer().print("\n {s}", .{test_path.items}); | ||
| 6276 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { | ||
| 6277 | error.FileNotFound => break :main_check, | ||
| 6278 | else => |e| fatal("unable to search for {s} library '{s}': {s}", .{ | ||
| 6279 | @tagName(link_mode), test_path.items, @errorName(e), | ||
| 6280 | }), | ||
| 6281 | }; | ||
| 6282 | return true; | ||
| 6283 | } | ||
| 6284 | |||
| 6285 | // In the case of Darwin, the main check will be .dylib, so here we | ||
| 6286 | // additionally check for .so files. | ||
| 6287 | if (target.isDarwin() and link_mode == .Dynamic) so: { | ||
| 6288 | test_path.clearRetainingCapacity(); | ||
| 6289 | try test_path.writer().print("{s}" ++ sep ++ "lib{s}.so", .{ lib_dir_path, lib_name }); | ||
| 6290 | try checked_paths.writer().print("\n {s}", .{test_path.items}); | ||
| 6291 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { | ||
| 6292 | error.FileNotFound => break :so, | ||
| 6293 | else => |e| fatal("unable to search for so library '{s}': {s}", .{ | ||
| 6294 | test_path.items, @errorName(e), | ||
| 6295 | }), | ||
| 6296 | }; | ||
| 6297 | return true; | ||
| 6298 | } | ||
| 6299 | |||
| 6300 | // In the case of MinGW, the main check will be .lib but we also need to | ||
| 6301 | // look for `libfoo.a`. | ||
| 6302 | if (target.isMinGW() and link_mode == .Static) mingw: { | ||
| 6303 | test_path.clearRetainingCapacity(); | ||
| 6304 | try test_path.writer().print("{s}" ++ sep ++ "lib{s}.a", .{ | ||
| 6305 | lib_dir_path, lib_name, | ||
| 6306 | }); | ||
| 6307 | try checked_paths.writer().print("\n {s}", .{test_path.items}); | ||
| 6308 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { | ||
| 6309 | error.FileNotFound => break :mingw, | ||
| 6310 | else => |e| fatal("unable to search for static library '{s}': {s}", .{ | ||
| 6311 | test_path.items, @errorName(e), | ||
| 6312 | }), | ||
| 6313 | }; | ||
| 6314 | return true; | ||
| 6315 | } | ||
| 6316 | |||
| 6317 | return false; | ||
| 6318 | } |
src/mingw.zig+25-7| ... | @@ -283,7 +283,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -283,7 +283,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 283 | defer arena_allocator.deinit(); | 283 | defer arena_allocator.deinit(); |
| 284 | const arena = arena_allocator.allocator(); | 284 | const arena = arena_allocator.allocator(); |
| 285 | 285 | ||
| 286 | const def_file_path = findDef(comp, arena, lib_name) catch |err| switch (err) { | 286 | const def_file_path = findDef(arena, comp.getTarget(), comp.zig_lib_directory, lib_name) catch |err| switch (err) { |
| 287 | error.FileNotFound => { | 287 | error.FileNotFound => { |
| 288 | log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name }); | 288 | log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name }); |
| 289 | // In this case we will end up putting foo.lib onto the linker line and letting the linker | 289 | // In this case we will end up putting foo.lib onto the linker line and letting the linker |
| ... | @@ -431,10 +431,28 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -431,10 +431,28 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 431 | }); | 431 | }); |
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | /// This function body is verbose but all it does is test 3 different paths and see if a .def file exists. | 434 | pub fn libExists( |
| 435 | fn findDef(comp: *Compilation, allocator: Allocator, lib_name: []const u8) ![]u8 { | 435 | allocator: Allocator, |
| 436 | const target = comp.getTarget(); | 436 | target: std.Target, |
| 437 | zig_lib_directory: Cache.Directory, | ||
| 438 | lib_name: []const u8, | ||
| 439 | ) !bool { | ||
| 440 | const s = findDef(allocator, target, zig_lib_directory, lib_name) catch |err| switch (err) { | ||
| 441 | error.FileNotFound => return false, | ||
| 442 | else => |e| return e, | ||
| 443 | }; | ||
| 444 | defer allocator.free(s); | ||
| 445 | return true; | ||
| 446 | } | ||
| 437 | 447 | ||
| 448 | /// This function body is verbose but all it does is test 3 different paths and | ||
| 449 | /// see if a .def file exists. | ||
| 450 | fn findDef( | ||
| 451 | allocator: Allocator, | ||
| 452 | target: std.Target, | ||
| 453 | zig_lib_directory: Cache.Directory, | ||
| 454 | lib_name: []const u8, | ||
| 455 | ) ![]u8 { | ||
| 438 | const lib_path = switch (target.cpu.arch) { | 456 | const lib_path = switch (target.cpu.arch) { |
| 439 | .x86 => "lib32", | 457 | .x86 => "lib32", |
| 440 | .x86_64 => "lib64", | 458 | .x86_64 => "lib64", |
| ... | @@ -451,7 +469,7 @@ fn findDef(comp: *Compilation, allocator: Allocator, lib_name: []const u8) ![]u8 | ... | @@ -451,7 +469,7 @@ fn findDef(comp: *Compilation, allocator: Allocator, lib_name: []const u8) ![]u8 |
| 451 | { | 469 | { |
| 452 | // Try the archtecture-specific path first. | 470 | // Try the archtecture-specific path first. |
| 453 | const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "{s}" ++ s ++ "{s}.def"; | 471 | const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "{s}" ++ s ++ "{s}.def"; |
| 454 | if (comp.zig_lib_directory.path) |p| { | 472 | if (zig_lib_directory.path) |p| { |
| 455 | try override_path.writer().print("{s}" ++ s ++ fmt_path, .{ p, lib_path, lib_name }); | 473 | try override_path.writer().print("{s}" ++ s ++ fmt_path, .{ p, lib_path, lib_name }); |
| 456 | } else { | 474 | } else { |
| 457 | try override_path.writer().print(fmt_path, .{ lib_path, lib_name }); | 475 | try override_path.writer().print(fmt_path, .{ lib_path, lib_name }); |
| ... | @@ -468,7 +486,7 @@ fn findDef(comp: *Compilation, allocator: Allocator, lib_name: []const u8) ![]u8 | ... | @@ -468,7 +486,7 @@ fn findDef(comp: *Compilation, allocator: Allocator, lib_name: []const u8) ![]u8 |
| 468 | // Try the generic version. | 486 | // Try the generic version. |
| 469 | override_path.shrinkRetainingCapacity(0); | 487 | override_path.shrinkRetainingCapacity(0); |
| 470 | const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def"; | 488 | const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def"; |
| 471 | if (comp.zig_lib_directory.path) |p| { | 489 | if (zig_lib_directory.path) |p| { |
| 472 | try override_path.writer().print("{s}" ++ s ++ fmt_path, .{ p, lib_name }); | 490 | try override_path.writer().print("{s}" ++ s ++ fmt_path, .{ p, lib_name }); |
| 473 | } else { | 491 | } else { |
| 474 | try override_path.writer().print(fmt_path, .{lib_name}); | 492 | try override_path.writer().print(fmt_path, .{lib_name}); |
| ... | @@ -485,7 +503,7 @@ fn findDef(comp: *Compilation, allocator: Allocator, lib_name: []const u8) ![]u8 | ... | @@ -485,7 +503,7 @@ fn findDef(comp: *Compilation, allocator: Allocator, lib_name: []const u8) ![]u8 |
| 485 | // Try the generic version and preprocess it. | 503 | // Try the generic version and preprocess it. |
| 486 | override_path.shrinkRetainingCapacity(0); | 504 | override_path.shrinkRetainingCapacity(0); |
| 487 | const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def.in"; | 505 | const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def.in"; |
| 488 | if (comp.zig_lib_directory.path) |p| { | 506 | if (zig_lib_directory.path) |p| { |
| 489 | try override_path.writer().print("{s}" ++ s ++ fmt_path, .{ p, lib_name }); | 507 | try override_path.writer().print("{s}" ++ s ++ fmt_path, .{ p, lib_name }); |
| 490 | } else { | 508 | } else { |
| 491 | try override_path.writer().print(fmt_path, .{lib_name}); | 509 | try override_path.writer().print(fmt_path, .{lib_name}); |
src/target.zig+9| ... | @@ -366,6 +366,15 @@ pub fn is_libc_lib_name(target: std.Target, name: []const u8) bool { | ... | @@ -366,6 +366,15 @@ pub fn is_libc_lib_name(target: std.Target, name: []const u8) bool { |
| 366 | if (eqlIgnoreCase(ignore_case, name, "m")) | 366 | if (eqlIgnoreCase(ignore_case, name, "m")) |
| 367 | return true; | 367 | return true; |
| 368 | 368 | ||
| 369 | if (eqlIgnoreCase(ignore_case, name, "uuid")) | ||
| 370 | return true; | ||
| 371 | if (eqlIgnoreCase(ignore_case, name, "mingw32")) | ||
| 372 | return true; | ||
| 373 | if (eqlIgnoreCase(ignore_case, name, "msvcrt-os")) | ||
| 374 | return true; | ||
| 375 | if (eqlIgnoreCase(ignore_case, name, "mingwex")) | ||
| 376 | return true; | ||
| 377 | |||
| 369 | return false; | 378 | return false; |
| 370 | } | 379 | } |
| 371 | 380 |
test/link/macho/bugs/13056/build.zig+1-1| ... | @@ -16,7 +16,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -16,7 +16,7 @@ pub fn build(b: *std.Build) void { |
| 16 | fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { | 16 | fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { |
| 17 | const target: std.zig.CrossTarget = .{ .os_tag = .macos }; | 17 | const target: std.zig.CrossTarget = .{ .os_tag = .macos }; |
| 18 | const target_info = std.zig.system.NativeTargetInfo.detect(target) catch unreachable; | 18 | const target_info = std.zig.system.NativeTargetInfo.detect(target) catch unreachable; |
| 19 | const sdk = std.zig.system.darwin.getDarwinSDK(b.allocator, target_info.target) orelse | 19 | const sdk = std.zig.system.darwin.getSdk(b.allocator, target_info.target) orelse |
| 20 | @panic("macOS SDK is required to run the test"); | 20 | @panic("macOS SDK is required to run the test"); |
| 21 | 21 | ||
| 22 | const exe = b.addExecutable(.{ | 22 | const exe = b.addExecutable(.{ |
test/link/macho/search_strategy/build.zig+7-5| ... | @@ -17,8 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize | ... | @@ -17,8 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 17 | 17 | ||
| 18 | { | 18 | { |
| 19 | // -search_dylibs_first | 19 | // -search_dylibs_first |
| 20 | const exe = createScenario(b, optimize, target, "search_dylibs_first"); | 20 | const exe = createScenario(b, optimize, target, "search_dylibs_first", .mode_first); |
| 21 | exe.search_strategy = .dylibs_first; | ||
| 22 | 21 | ||
| 23 | const check = exe.checkObject(); | 22 | const check = exe.checkObject(); |
| 24 | check.checkStart(); | 23 | check.checkStart(); |
| ... | @@ -34,8 +33,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize | ... | @@ -34,8 +33,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 34 | 33 | ||
| 35 | { | 34 | { |
| 36 | // -search_paths_first | 35 | // -search_paths_first |
| 37 | const exe = createScenario(b, optimize, target, "search_paths_first"); | 36 | const exe = createScenario(b, optimize, target, "search_paths_first", .paths_first); |
| 38 | exe.search_strategy = .paths_first; | ||
| 39 | 37 | ||
| 40 | const run = b.addRunArtifact(exe); | 38 | const run = b.addRunArtifact(exe); |
| 41 | run.skip_foreign_checks = true; | 39 | run.skip_foreign_checks = true; |
| ... | @@ -49,6 +47,7 @@ fn createScenario( | ... | @@ -49,6 +47,7 @@ fn createScenario( |
| 49 | optimize: std.builtin.OptimizeMode, | 47 | optimize: std.builtin.OptimizeMode, |
| 50 | target: std.zig.CrossTarget, | 48 | target: std.zig.CrossTarget, |
| 51 | name: []const u8, | 49 | name: []const u8, |
| 50 | search_strategy: std.Build.Step.Compile.SystemLib.SearchStrategy, | ||
| 52 | ) *std.Build.Step.Compile { | 51 | ) *std.Build.Step.Compile { |
| 53 | const static = b.addStaticLibrary(.{ | 52 | const static = b.addStaticLibrary(.{ |
| 54 | .name = name, | 53 | .name = name, |
| ... | @@ -73,7 +72,10 @@ fn createScenario( | ... | @@ -73,7 +72,10 @@ fn createScenario( |
| 73 | .target = target, | 72 | .target = target, |
| 74 | }); | 73 | }); |
| 75 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); | 74 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); |
| 76 | exe.linkSystemLibraryName(name); | 75 | exe.linkSystemLibrary2(name, .{ |
| 76 | .use_pkg_config = .no, | ||
| 77 | .search_strategy = search_strategy, | ||
| 78 | }); | ||
| 77 | exe.linkLibC(); | 79 | exe.linkLibC(); |
| 78 | exe.addLibraryPath(static.getEmittedBinDirectory()); | 80 | exe.addLibraryPath(static.getEmittedBinDirectory()); |
| 79 | exe.addLibraryPath(dylib.getEmittedBinDirectory()); | 81 | exe.addLibraryPath(dylib.getEmittedBinDirectory()); |