authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-19 15:03:55-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:20-07:00
log8944dea23fb554290a4b54ca40b0594f6e3f77a9
tree9ce6e53249296cac235346f7e26fbc0f6a87fc11
parentdb2ca2ca0005b73e1a7df42de77a06c5506f3aaf

CLI: fix regressed logic for any_dyn_libs

This value needs access to the fully resolved set of system libraries, which required restructuring a bunch of CLI logic.

2 files changed, 329 insertions(+), 303 deletions(-)

src/Compilation.zig+11
...@@ -86,6 +86,7 @@ skip_linker_dependencies: bool,...@@ -86,6 +86,7 @@ skip_linker_dependencies: bool,
86no_builtin: bool,86no_builtin: bool,
87function_sections: bool,87function_sections: bool,
88data_sections: bool,88data_sections: bool,
89native_system_include_paths: []const []const u8,
8990
90c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},91c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
91win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) =92win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) =
...@@ -1065,6 +1066,7 @@ pub const InitOptions = struct {...@@ -1065,6 +1066,7 @@ pub const InitOptions = struct {
1065 version: ?std.SemanticVersion = null,1066 version: ?std.SemanticVersion = null,
1066 compatibility_version: ?std.SemanticVersion = null,1067 compatibility_version: ?std.SemanticVersion = null,
1067 libc_installation: ?*const LibCInstallation = null,1068 libc_installation: ?*const LibCInstallation = null,
1069 native_system_include_paths: []const []const u8 = &.{},
1068 clang_preprocessor_mode: ClangPreprocessorMode = .no,1070 clang_preprocessor_mode: ClangPreprocessorMode = .no,
1069 /// This is for stage1 and should be deleted upon completion of self-hosting.1071 /// This is for stage1 and should be deleted upon completion of self-hosting.
1070 color: Color = .auto,1072 color: Color = .auto,
...@@ -1508,6 +1510,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1508,6 +1510,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1508 .job_queued_update_builtin_zig = have_zcu,1510 .job_queued_update_builtin_zig = have_zcu,
1509 .function_sections = options.function_sections,1511 .function_sections = options.function_sections,
1510 .data_sections = options.data_sections,1512 .data_sections = options.data_sections,
1513 .native_system_include_paths = options.native_system_include_paths,
1511 };1514 };
15121515
1513 const lf_open_opts: link.File.OpenOptions = .{1516 const lf_open_opts: link.File.OpenOptions = .{
...@@ -5296,6 +5299,14 @@ pub fn addCCArgs(...@@ -5296,6 +5299,14 @@ pub fn addCCArgs(
5296 try argv.append("-ffreestanding");5299 try argv.append("-ffreestanding");
5297 }5300 }
52985301
5302 if (mod.resolved_target.is_native_os and mod.resolved_target.is_native_abi) {
5303 try argv.ensureUnusedCapacity(comp.native_system_include_paths.len * 2);
5304 for (comp.native_system_include_paths) |include_path| {
5305 argv.appendAssumeCapacity("-isystem");
5306 argv.appendAssumeCapacity(include_path);
5307 }
5308 }
5309
5299 try argv.appendSlice(mod.cc_argv);5310 try argv.appendSlice(mod.cc_argv);
5300}5311}
53015312
src/main.zig+318-303
...@@ -821,7 +821,6 @@ fn buildOutputType(...@@ -821,7 +821,6 @@ fn buildOutputType(
821 var target_mcpu: ?[]const u8 = null;821 var target_mcpu: ?[]const u8 = null;
822 var emit_h: Emit = .no;822 var emit_h: Emit = .no;
823 var soname: SOName = undefined;823 var soname: SOName = undefined;
824 var want_native_include_dirs = false;
825 var want_compiler_rt: ?bool = null;824 var want_compiler_rt: ?bool = null;
826 var linker_script: ?[]const u8 = null;825 var linker_script: ?[]const u8 = null;
827 var version_script: ?[]const u8 = null;826 var version_script: ?[]const u8 = null;
...@@ -863,8 +862,6 @@ fn buildOutputType(...@@ -863,8 +862,6 @@ fn buildOutputType(
863 var link_emit_relocs = false;862 var link_emit_relocs = false;
864 var each_lib_rpath: ?bool = null;863 var each_lib_rpath: ?bool = null;
865 var build_id: ?std.zig.BuildId = null;864 var build_id: ?std.zig.BuildId = null;
866 var sysroot: ?[]const u8 = null;
867 var libc_paths_file: ?[]const u8 = try EnvVar.ZIG_LIBC.get(arena);
868 var runtime_args_start: ?usize = null;865 var runtime_args_start: ?usize = null;
869 var test_filter: ?[]const u8 = null;866 var test_filter: ?[]const u8 = null;
870 var test_name_prefix: ?[]const u8 = null;867 var test_name_prefix: ?[]const u8 = null;
...@@ -892,16 +889,11 @@ fn buildOutputType(...@@ -892,16 +889,11 @@ fn buildOutputType(
892 var pdb_out_path: ?[]const u8 = null;889 var pdb_out_path: ?[]const u8 = null;
893 var error_limit: ?Module.ErrorInt = null;890 var error_limit: ?Module.ErrorInt = null;
894 // These are before resolving sysroot.891 // These are before resolving sysroot.
895 var lib_dir_args: std.ArrayListUnmanaged([]const u8) = .{};
896 var extra_cflags: std.ArrayListUnmanaged([]const u8) = .{};892 var extra_cflags: std.ArrayListUnmanaged([]const u8) = .{};
897 var extra_rcflags: std.ArrayListUnmanaged([]const u8) = .{};893 var extra_rcflags: std.ArrayListUnmanaged([]const u8) = .{};
898 var symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{};894 var symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{};
899 var rpath_list: std.ArrayListUnmanaged([]const u8) = .{};
900 var rc_includes: Compilation.RcIncludes = .any;895 var rc_includes: Compilation.RcIncludes = .any;
901 var manifest_file: ?[]const u8 = null;896 var manifest_file: ?[]const u8 = null;
902 var link_objects: std.ArrayListUnmanaged(Compilation.LinkObject) = .{};
903 var framework_dirs: std.ArrayListUnmanaged([]const u8) = .{};
904 var frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{};
905 var linker_export_symbol_names: std.ArrayListUnmanaged([]const u8) = .{};897 var linker_export_symbol_names: std.ArrayListUnmanaged([]const u8) = .{};
906898
907 // Tracks the position in c_source_files which have already their owner populated.899 // Tracks the position in c_source_files which have already their owner populated.
...@@ -951,7 +943,6 @@ fn buildOutputType(...@@ -951,7 +943,6 @@ fn buildOutputType(
951 .resolved_options = undefined,943 .resolved_options = undefined,
952944
953 .system_libs = .{},945 .system_libs = .{},
954 .external_system_libs = .{},
955 .resolved_system_libs = .{},946 .resolved_system_libs = .{},
956 .wasi_emulated_libs = .{},947 .wasi_emulated_libs = .{},
957948
...@@ -959,6 +950,17 @@ fn buildOutputType(...@@ -959,6 +950,17 @@ fn buildOutputType(
959 .rc_source_files = .{},950 .rc_source_files = .{},
960951
961 .llvm_m_args = .{},952 .llvm_m_args = .{},
953 .sysroot = null,
954 .lib_dirs = .{}, // populated by createModule()
955 .lib_dir_args = .{}, // populated from CLI arg parsing
956 .libc_installation = null,
957 .want_native_include_dirs = false,
958 .frameworks = .{},
959 .framework_dirs = .{},
960 .rpath_list = .{},
961 .libc_paths_file = try EnvVar.ZIG_LIBC.get(arena),
962 .link_objects = .{},
963 .native_system_include_paths = &.{},
962 };964 };
963965
964 // before arg parsing, check for the NO_COLOR environment variable966 // before arg parsing, check for the NO_COLOR environment variable
...@@ -1137,17 +1139,17 @@ fn buildOutputType(...@@ -1137,17 +1139,17 @@ fn buildOutputType(
1137 if (!mem.eql(u8, provided_name.?, fs.path.basename(provided_name.?)))1139 if (!mem.eql(u8, provided_name.?, fs.path.basename(provided_name.?)))
1138 fatal("invalid package name '{s}': cannot contain folder separators", .{provided_name.?});1140 fatal("invalid package name '{s}': cannot contain folder separators", .{provided_name.?});
1139 } else if (mem.eql(u8, arg, "-rpath")) {1141 } else if (mem.eql(u8, arg, "-rpath")) {
1140 try rpath_list.append(arena, args_iter.nextOrFatal());1142 try create_module.rpath_list.append(arena, args_iter.nextOrFatal());
1141 } else if (mem.eql(u8, arg, "--library-directory") or mem.eql(u8, arg, "-L")) {1143 } else if (mem.eql(u8, arg, "--library-directory") or mem.eql(u8, arg, "-L")) {
1142 try lib_dir_args.append(arena, args_iter.nextOrFatal());1144 try create_module.lib_dir_args.append(arena, args_iter.nextOrFatal());
1143 } else if (mem.eql(u8, arg, "-F")) {1145 } else if (mem.eql(u8, arg, "-F")) {
1144 try framework_dirs.append(arena, args_iter.nextOrFatal());1146 try create_module.framework_dirs.append(arena, args_iter.nextOrFatal());
1145 } else if (mem.eql(u8, arg, "-framework")) {1147 } else if (mem.eql(u8, arg, "-framework")) {
1146 try frameworks.put(arena, args_iter.nextOrFatal(), .{});1148 try create_module.frameworks.put(arena, args_iter.nextOrFatal(), .{});
1147 } else if (mem.eql(u8, arg, "-weak_framework")) {1149 } else if (mem.eql(u8, arg, "-weak_framework")) {
1148 try frameworks.put(arena, args_iter.nextOrFatal(), .{ .weak = true });1150 try create_module.frameworks.put(arena, args_iter.nextOrFatal(), .{ .weak = true });
1149 } else if (mem.eql(u8, arg, "-needed_framework")) {1151 } else if (mem.eql(u8, arg, "-needed_framework")) {
1150 try frameworks.put(arena, args_iter.nextOrFatal(), .{ .needed = true });1152 try create_module.frameworks.put(arena, args_iter.nextOrFatal(), .{ .needed = true });
1151 } else if (mem.eql(u8, arg, "-install_name")) {1153 } else if (mem.eql(u8, arg, "-install_name")) {
1152 install_name = args_iter.nextOrFatal();1154 install_name = args_iter.nextOrFatal();
1153 } else if (mem.startsWith(u8, arg, "--compress-debug-sections=")) {1155 } else if (mem.startsWith(u8, arg, "--compress-debug-sections=")) {
...@@ -1236,11 +1238,11 @@ fn buildOutputType(...@@ -1236,11 +1238,11 @@ fn buildOutputType(
1236 } else if (mem.eql(u8, arg, "-iframework")) {1238 } else if (mem.eql(u8, arg, "-iframework")) {
1237 const path = args_iter.nextOrFatal();1239 const path = args_iter.nextOrFatal();
1238 try cssan.addIncludePath(arena, &clang_argv, .iframework, arg, path, false);1240 try cssan.addIncludePath(arena, &clang_argv, .iframework, arg, path, false);
1239 try framework_dirs.append(arena, path); // Forward to the backend as -F1241 try create_module.framework_dirs.append(arena, path); // Forward to the backend as -F
1240 } else if (mem.eql(u8, arg, "-iframeworkwithsysroot")) {1242 } else if (mem.eql(u8, arg, "-iframeworkwithsysroot")) {
1241 const path = args_iter.nextOrFatal();1243 const path = args_iter.nextOrFatal();
1242 try cssan.addIncludePath(arena, &clang_argv, .iframeworkwithsysroot, arg, path, false);1244 try cssan.addIncludePath(arena, &clang_argv, .iframeworkwithsysroot, arg, path, false);
1243 try framework_dirs.append(arena, path); // Forward to the backend as -F1245 try create_module.framework_dirs.append(arena, path); // Forward to the backend as -F
1244 } else if (mem.eql(u8, arg, "--version")) {1246 } else if (mem.eql(u8, arg, "--version")) {
1245 const next_arg = args_iter.nextOrFatal();1247 const next_arg = args_iter.nextOrFatal();
1246 version = std.SemanticVersion.parse(next_arg) catch |err| {1248 version = std.SemanticVersion.parse(next_arg) catch |err| {
...@@ -1265,10 +1267,10 @@ fn buildOutputType(...@@ -1265,10 +1267,10 @@ fn buildOutputType(
1265 create_module.dynamic_linker = args_iter.nextOrFatal();1267 create_module.dynamic_linker = args_iter.nextOrFatal();
1266 } else if (mem.eql(u8, arg, "--sysroot")) {1268 } else if (mem.eql(u8, arg, "--sysroot")) {
1267 const next_arg = args_iter.nextOrFatal();1269 const next_arg = args_iter.nextOrFatal();
1268 sysroot = next_arg;1270 create_module.sysroot = next_arg;
1269 try clang_argv.appendSlice(arena, &.{ "-isysroot", next_arg });1271 try clang_argv.appendSlice(arena, &.{ "-isysroot", next_arg });
1270 } else if (mem.eql(u8, arg, "--libc")) {1272 } else if (mem.eql(u8, arg, "--libc")) {
1271 libc_paths_file = args_iter.nextOrFatal();1273 create_module.libc_paths_file = args_iter.nextOrFatal();
1272 } else if (mem.eql(u8, arg, "--test-filter")) {1274 } else if (mem.eql(u8, arg, "--test-filter")) {
1273 test_filter = args_iter.nextOrFatal();1275 test_filter = args_iter.nextOrFatal();
1274 } else if (mem.eql(u8, arg, "--test-name-prefix")) {1276 } else if (mem.eql(u8, arg, "--test-name-prefix")) {
...@@ -1620,9 +1622,9 @@ fn buildOutputType(...@@ -1620,9 +1622,9 @@ fn buildOutputType(
1620 } else if (mem.startsWith(u8, arg, "-T")) {1622 } else if (mem.startsWith(u8, arg, "-T")) {
1621 linker_script = arg[2..];1623 linker_script = arg[2..];
1622 } else if (mem.startsWith(u8, arg, "-L")) {1624 } else if (mem.startsWith(u8, arg, "-L")) {
1623 try lib_dir_args.append(arena, arg[2..]);1625 try create_module.lib_dir_args.append(arena, arg[2..]);
1624 } else if (mem.startsWith(u8, arg, "-F")) {1626 } else if (mem.startsWith(u8, arg, "-F")) {
1625 try framework_dirs.append(arena, arg[2..]);1627 try create_module.framework_dirs.append(arena, arg[2..]);
1626 } else if (mem.startsWith(u8, arg, "-l")) {1628 } else if (mem.startsWith(u8, arg, "-l")) {
1627 // We don't know whether this library is part of libc1629 // We don't know whether this library is part of libc
1628 // or libc++ until we resolve the target, so we append1630 // or libc++ until we resolve the target, so we append
...@@ -1667,14 +1669,14 @@ fn buildOutputType(...@@ -1667,14 +1669,14 @@ fn buildOutputType(
1667 }1669 }
1668 } else switch (file_ext orelse Compilation.classifyFileExt(arg)) {1670 } else switch (file_ext orelse Compilation.classifyFileExt(arg)) {
1669 .shared_library => {1671 .shared_library => {
1670 try link_objects.append(arena, .{ .path = arg });1672 try create_module.link_objects.append(arena, .{ .path = arg });
1671 create_module.opts.any_dyn_libs = true;1673 create_module.opts.any_dyn_libs = true;
1672 },1674 },
1673 .object, .static_library => {1675 .object, .static_library => {
1674 try link_objects.append(arena, .{ .path = arg });1676 try create_module.link_objects.append(arena, .{ .path = arg });
1675 },1677 },
1676 .res => {1678 .res => {
1677 try link_objects.append(arena, .{ .path = arg });1679 try create_module.link_objects.append(arena, .{ .path = arg });
1678 contains_res_file = true;1680 contains_res_file = true;
1679 },1681 },
1680 .manifest => {1682 .manifest => {
...@@ -1721,7 +1723,7 @@ fn buildOutputType(...@@ -1721,7 +1723,7 @@ fn buildOutputType(
1721 soname = .no;1723 soname = .no;
1722 create_module.opts.ensure_libc_on_non_freestanding = true;1724 create_module.opts.ensure_libc_on_non_freestanding = true;
1723 create_module.opts.ensure_libcpp_on_non_freestanding = arg_mode == .cpp;1725 create_module.opts.ensure_libcpp_on_non_freestanding = arg_mode == .cpp;
1724 want_native_include_dirs = true;1726 create_module.want_native_include_dirs = true;
1725 // Clang's driver enables this switch unconditionally.1727 // Clang's driver enables this switch unconditionally.
1726 // Disabling the emission of .eh_frame_hdr can unexpectedly break1728 // Disabling the emission of .eh_frame_hdr can unexpectedly break
1727 // some functionality that depend on it, such as C++ exceptions and1729 // some functionality that depend on it, such as C++ exceptions and
...@@ -1786,20 +1788,20 @@ fn buildOutputType(...@@ -1786,20 +1788,20 @@ fn buildOutputType(
1786 });1788 });
1787 },1789 },
1788 .shared_library => {1790 .shared_library => {
1789 try link_objects.append(arena, .{1791 try create_module.link_objects.append(arena, .{
1790 .path = it.only_arg,1792 .path = it.only_arg,
1791 .must_link = must_link,1793 .must_link = must_link,
1792 });1794 });
1793 create_module.opts.any_dyn_libs = true;1795 create_module.opts.any_dyn_libs = true;
1794 },1796 },
1795 .unknown, .object, .static_library => {1797 .unknown, .object, .static_library => {
1796 try link_objects.append(arena, .{1798 try create_module.link_objects.append(arena, .{
1797 .path = it.only_arg,1799 .path = it.only_arg,
1798 .must_link = must_link,1800 .must_link = must_link,
1799 });1801 });
1800 },1802 },
1801 .res => {1803 .res => {
1802 try link_objects.append(arena, .{1804 try create_module.link_objects.append(arena, .{
1803 .path = it.only_arg,1805 .path = it.only_arg,
1804 .must_link = must_link,1806 .must_link = must_link,
1805 });1807 });
...@@ -1835,7 +1837,7 @@ fn buildOutputType(...@@ -1835,7 +1837,7 @@ fn buildOutputType(
1835 // more control over what's in the resulting1837 // more control over what's in the resulting
1836 // binary: no extra rpaths and DSO filename exactly1838 // binary: no extra rpaths and DSO filename exactly
1837 // as provided. Hello, Go.1839 // as provided. Hello, Go.
1838 try link_objects.append(arena, .{1840 try create_module.link_objects.append(arena, .{
1839 .path = it.only_arg,1841 .path = it.only_arg,
1840 .must_link = must_link,1842 .must_link = must_link,
1841 .loption = true,1843 .loption = true,
...@@ -2036,7 +2038,7 @@ fn buildOutputType(...@@ -2036,7 +2038,7 @@ fn buildOutputType(
2036 try linker_args.append("-z");2038 try linker_args.append("-z");
2037 try linker_args.append(it.only_arg);2039 try linker_args.append(it.only_arg);
2038 },2040 },
2039 .lib_dir => try lib_dir_args.append(arena, it.only_arg),2041 .lib_dir => try create_module.lib_dir_args.append(arena, it.only_arg),
2040 .mcpu => target_mcpu = it.only_arg,2042 .mcpu => target_mcpu = it.only_arg,
2041 .m => try create_module.llvm_m_args.append(arena, it.only_arg),2043 .m => try create_module.llvm_m_args.append(arena, it.only_arg),
2042 .dep_file => {2044 .dep_file => {
...@@ -2050,15 +2052,15 @@ fn buildOutputType(...@@ -2050,15 +2052,15 @@ fn buildOutputType(
2050 disable_c_depfile = true;2052 disable_c_depfile = true;
2051 try clang_argv.appendSlice(arena, it.other_args);2053 try clang_argv.appendSlice(arena, it.other_args);
2052 },2054 },
2053 .framework_dir => try framework_dirs.append(arena, it.only_arg),2055 .framework_dir => try create_module.framework_dirs.append(arena, it.only_arg),
2054 .framework => try frameworks.put(arena, it.only_arg, .{}),2056 .framework => try create_module.frameworks.put(arena, it.only_arg, .{}),
2055 .nostdlibinc => want_native_include_dirs = false,2057 .nostdlibinc => create_module.want_native_include_dirs = false,
2056 .strip => mod_opts.strip = true,2058 .strip => mod_opts.strip = true,
2057 .exec_model => {2059 .exec_model => {
2058 create_module.opts.wasi_exec_model = parseWasiExecModel(it.only_arg);2060 create_module.opts.wasi_exec_model = parseWasiExecModel(it.only_arg);
2059 },2061 },
2060 .sysroot => {2062 .sysroot => {
2061 sysroot = it.only_arg;2063 create_module.sysroot = it.only_arg;
2062 },2064 },
2063 .entry => {2065 .entry => {
2064 create_module.opts.entry = .{ .named = it.only_arg };2066 create_module.opts.entry = .{ .named = it.only_arg };
...@@ -2072,7 +2074,7 @@ fn buildOutputType(...@@ -2072,7 +2074,7 @@ fn buildOutputType(
2072 .preferred_mode = lib_preferred_mode,2074 .preferred_mode = lib_preferred_mode,
2073 .search_strategy = lib_search_strategy,2075 .search_strategy = lib_search_strategy,
2074 }),2076 }),
2075 .weak_framework => try frameworks.put(arena, it.only_arg, .{ .weak = true }),2077 .weak_framework => try create_module.frameworks.put(arena, it.only_arg, .{ .weak = true }),
2076 .headerpad_max_install_names => headerpad_max_install_names = true,2078 .headerpad_max_install_names => headerpad_max_install_names = true,
2077 .compress_debug_sections => {2079 .compress_debug_sections => {
2078 if (it.only_arg.len == 0) {2080 if (it.only_arg.len == 0) {
...@@ -2133,7 +2135,7 @@ fn buildOutputType(...@@ -2133,7 +2135,7 @@ fn buildOutputType(
2133 }2135 }
2134 provided_name = name[prefix..end];2136 provided_name = name[prefix..end];
2135 } else if (mem.eql(u8, arg, "-rpath")) {2137 } else if (mem.eql(u8, arg, "-rpath")) {
2136 try rpath_list.append(arena, linker_args_it.nextOrFatal());2138 try create_module.rpath_list.append(arena, linker_args_it.nextOrFatal());
2137 } else if (mem.eql(u8, arg, "--subsystem")) {2139 } else if (mem.eql(u8, arg, "--subsystem")) {
2138 subsystem = try parseSubSystem(linker_args_it.nextOrFatal());2140 subsystem = try parseSubSystem(linker_args_it.nextOrFatal());
2139 } else if (mem.eql(u8, arg, "-I") or2141 } else if (mem.eql(u8, arg, "-I") or
...@@ -2345,11 +2347,11 @@ fn buildOutputType(...@@ -2345,11 +2347,11 @@ fn buildOutputType(
2345 });2347 });
2346 };2348 };
2347 } else if (mem.eql(u8, arg, "-framework")) {2349 } else if (mem.eql(u8, arg, "-framework")) {
2348 try frameworks.put(arena, linker_args_it.nextOrFatal(), .{});2350 try create_module.frameworks.put(arena, linker_args_it.nextOrFatal(), .{});
2349 } else if (mem.eql(u8, arg, "-weak_framework")) {2351 } else if (mem.eql(u8, arg, "-weak_framework")) {
2350 try frameworks.put(arena, linker_args_it.nextOrFatal(), .{ .weak = true });2352 try create_module.frameworks.put(arena, linker_args_it.nextOrFatal(), .{ .weak = true });
2351 } else if (mem.eql(u8, arg, "-needed_framework")) {2353 } else if (mem.eql(u8, arg, "-needed_framework")) {
2352 try frameworks.put(arena, linker_args_it.nextOrFatal(), .{ .needed = true });2354 try create_module.frameworks.put(arena, linker_args_it.nextOrFatal(), .{ .needed = true });
2353 } else if (mem.eql(u8, arg, "-needed_library")) {2355 } else if (mem.eql(u8, arg, "-needed_library")) {
2354 try create_module.system_libs.put(arena, linker_args_it.nextOrFatal(), .{2356 try create_module.system_libs.put(arena, linker_args_it.nextOrFatal(), .{
2355 .weak = false,2357 .weak = false,
...@@ -2399,7 +2401,7 @@ fn buildOutputType(...@@ -2399,7 +2401,7 @@ fn buildOutputType(
2399 } else if (mem.eql(u8, arg, "-install_name")) {2401 } else if (mem.eql(u8, arg, "-install_name")) {
2400 install_name = linker_args_it.nextOrFatal();2402 install_name = linker_args_it.nextOrFatal();
2401 } else if (mem.eql(u8, arg, "-force_load")) {2403 } else if (mem.eql(u8, arg, "-force_load")) {
2402 try link_objects.append(arena, .{2404 try create_module.link_objects.append(arena, .{
2403 .path = linker_args_it.nextOrFatal(),2405 .path = linker_args_it.nextOrFatal(),
2404 .must_link = true,2406 .must_link = true,
2405 });2407 });
...@@ -2504,7 +2506,7 @@ fn buildOutputType(...@@ -2504,7 +2506,7 @@ fn buildOutputType(
2504 },2506 },
2505 }2507 }
2506 if (create_module.c_source_files.items.len == 0 and2508 if (create_module.c_source_files.items.len == 0 and
2507 link_objects.items.len == 0 and2509 create_module.link_objects.items.len == 0 and
2508 root_src_file == null)2510 root_src_file == null)
2509 {2511 {
2510 // For example `zig cc` and no args should print the "no input files" message.2512 // For example `zig cc` and no args should print the "no input files" message.
...@@ -2550,8 +2552,8 @@ fn buildOutputType(...@@ -2550,8 +2552,8 @@ fn buildOutputType(
2550 if (create_module.c_source_files.items.len >= 1)2552 if (create_module.c_source_files.items.len >= 1)
2551 break :b create_module.c_source_files.items[0].src_path;2553 break :b create_module.c_source_files.items[0].src_path;
25522554
2553 if (link_objects.items.len >= 1)2555 if (create_module.link_objects.items.len >= 1)
2554 break :b link_objects.items[0].path;2556 break :b create_module.link_objects.items[0].path;
25552557
2556 if (emit_bin == .yes)2558 if (emit_bin == .yes)
2557 break :b emit_bin.yes;2559 break :b emit_bin.yes;
...@@ -2761,250 +2763,10 @@ fn buildOutputType(...@@ -2761,250 +2763,10 @@ fn buildOutputType(
2761 }2763 }
2762 }2764 }
27632765
2764 const root_name = if (provided_name) |n| n else main_mod.fully_qualified_name;
2765
2766 // Resolve the library path arguments with respect to sysroot.
2767 var lib_dirs: std.ArrayListUnmanaged([]const u8) = .{};
2768 if (sysroot) |root| {
2769 try lib_dirs.ensureUnusedCapacity(arena, lib_dir_args.items.len * 2);
2770 for (lib_dir_args.items) |dir| {
2771 if (fs.path.isAbsolute(dir)) {
2772 const stripped_dir = dir[fs.path.diskDesignator(dir).len..];
2773 const full_path = try fs.path.join(arena, &[_][]const u8{ root, stripped_dir });
2774 lib_dirs.appendAssumeCapacity(full_path);
2775 }
2776 lib_dirs.appendAssumeCapacity(dir);
2777 }
2778 } else {
2779 lib_dirs = lib_dir_args;
2780 }
2781 lib_dir_args = undefined; // From here we use lib_dirs instead.
2782
2783 if (main_mod.resolved_target.is_native_os and target.isDarwin()) {
2784 // If we want to link against frameworks, we need system headers.
2785 if (framework_dirs.items.len > 0 or frameworks.count() > 0)
2786 want_native_include_dirs = true;
2787 }
2788
2789 // Trigger native system library path detection if necessary.
2790 if (sysroot == null and
2791 main_mod.resolved_target.is_native_os and
2792 main_mod.resolved_target.is_native_abi and
2793 (create_module.external_system_libs.len != 0 or want_native_include_dirs))
2794 {
2795 const paths = std.zig.system.NativePaths.detect(arena, target) catch |err| {
2796 fatal("unable to detect native system paths: {s}", .{@errorName(err)});
2797 };
2798 for (paths.warnings.items) |warning| {
2799 warn("{s}", .{warning});
2800 }
2801
2802 try clang_argv.ensureUnusedCapacity(arena, paths.include_dirs.items.len * 2);
2803 for (paths.include_dirs.items) |include_dir| {
2804 clang_argv.appendAssumeCapacity("-isystem");
2805 clang_argv.appendAssumeCapacity(include_dir);
2806 }
2807
2808 try framework_dirs.appendSlice(arena, paths.framework_dirs.items);
2809 try lib_dirs.appendSlice(arena, paths.lib_dirs.items);
2810 try rpath_list.appendSlice(arena, paths.rpaths.items);
2811 }
2812
2813 var libc_installation: ?LibCInstallation = null;
2814 if (libc_paths_file) |paths_file| {
2815 libc_installation = LibCInstallation.parse(arena, paths_file, target) catch |err| {
2816 fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });
2817 };
2818 }
2819
2820 if (builtin.target.os.tag == .windows and
2821 target.abi == .msvc and
2822 create_module.external_system_libs.len != 0)
2823 {
2824 if (libc_installation == null) {
2825 libc_installation = try LibCInstallation.findNative(.{
2826 .allocator = arena,
2827 .verbose = true,
2828 .target = target,
2829 });
2830
2831 try lib_dirs.appendSlice(arena, &.{
2832 libc_installation.?.msvc_lib_dir.?,
2833 libc_installation.?.kernel32_lib_dir.?,
2834 });
2835 }
2836 }
2837
2838 // If any libs in this list are statically provided, we omit them from the
2839 // resolved list and populate the link_objects array instead.
2840 {
2841 var test_path = std.ArrayList(u8).init(gpa);
2842 defer test_path.deinit();
2843
2844 var checked_paths = std.ArrayList(u8).init(gpa);
2845 defer checked_paths.deinit();
2846
2847 var failed_libs = std.ArrayList(struct {
2848 name: []const u8,
2849 strategy: SystemLib.SearchStrategy,
2850 checked_paths: []const u8,
2851 preferred_mode: std.builtin.LinkMode,
2852 }).init(arena);
2853
2854 syslib: for (create_module.external_system_libs.items(.name), create_module.external_system_libs.items(.info)) |lib_name, info| {
2855 // Checked in the first pass above while looking for libc libraries.
2856 assert(!fs.path.isAbsolute(lib_name));
2857
2858 checked_paths.clearRetainingCapacity();
2859
2860 switch (info.search_strategy) {
2861 .mode_first, .no_fallback => {
2862 // check for preferred mode
2863 for (lib_dirs.items) |lib_dir_path| {
2864 if (try accessLibPath(
2865 &test_path,
2866 &checked_paths,
2867 lib_dir_path,
2868 lib_name,
2869 target,
2870 info.preferred_mode,
2871 )) {
2872 const path = try arena.dupe(u8, test_path.items);
2873 switch (info.preferred_mode) {
2874 .Static => try link_objects.append(arena, .{ .path = path }),
2875 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
2876 .name = lib_name,
2877 .lib = .{
2878 .needed = info.needed,
2879 .weak = info.weak,
2880 .path = path,
2881 },
2882 }),
2883 }
2884 continue :syslib;
2885 }
2886 }
2887 // check for fallback mode
2888 if (info.search_strategy == .no_fallback) {
2889 try failed_libs.append(.{
2890 .name = lib_name,
2891 .strategy = info.search_strategy,
2892 .checked_paths = try arena.dupe(u8, checked_paths.items),
2893 .preferred_mode = info.preferred_mode,
2894 });
2895 continue :syslib;
2896 }
2897 for (lib_dirs.items) |lib_dir_path| {
2898 if (try accessLibPath(
2899 &test_path,
2900 &checked_paths,
2901 lib_dir_path,
2902 lib_name,
2903 target,
2904 info.fallbackMode(),
2905 )) {
2906 const path = try arena.dupe(u8, test_path.items);
2907 switch (info.fallbackMode()) {
2908 .Static => try link_objects.append(arena, .{ .path = path }),
2909 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
2910 .name = lib_name,
2911 .lib = .{
2912 .needed = info.needed,
2913 .weak = info.weak,
2914 .path = path,
2915 },
2916 }),
2917 }
2918 continue :syslib;
2919 }
2920 }
2921 try failed_libs.append(.{
2922 .name = lib_name,
2923 .strategy = info.search_strategy,
2924 .checked_paths = try arena.dupe(u8, checked_paths.items),
2925 .preferred_mode = info.preferred_mode,
2926 });
2927 continue :syslib;
2928 },
2929 .paths_first => {
2930 for (lib_dirs.items) |lib_dir_path| {
2931 // check for preferred mode
2932 if (try accessLibPath(
2933 &test_path,
2934 &checked_paths,
2935 lib_dir_path,
2936 lib_name,
2937 target,
2938 info.preferred_mode,
2939 )) {
2940 const path = try arena.dupe(u8, test_path.items);
2941 switch (info.preferred_mode) {
2942 .Static => try link_objects.append(arena, .{ .path = path }),
2943 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
2944 .name = lib_name,
2945 .lib = .{
2946 .needed = info.needed,
2947 .weak = info.weak,
2948 .path = path,
2949 },
2950 }),
2951 }
2952 continue :syslib;
2953 }
2954
2955 // check for fallback mode
2956 if (try accessLibPath(
2957 &test_path,
2958 &checked_paths,
2959 lib_dir_path,
2960 lib_name,
2961 target,
2962 info.fallbackMode(),
2963 )) {
2964 const path = try arena.dupe(u8, test_path.items);
2965 switch (info.fallbackMode()) {
2966 .Static => try link_objects.append(arena, .{ .path = path }),
2967 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
2968 .name = lib_name,
2969 .lib = .{
2970 .needed = info.needed,
2971 .weak = info.weak,
2972 .path = path,
2973 },
2974 }),
2975 }
2976 continue :syslib;
2977 }
2978 }
2979 try failed_libs.append(.{
2980 .name = lib_name,
2981 .strategy = info.search_strategy,
2982 .checked_paths = try arena.dupe(u8, checked_paths.items),
2983 .preferred_mode = info.preferred_mode,
2984 });
2985 continue :syslib;
2986 },
2987 }
2988 @compileError("unreachable");
2989 }
2990
2991 if (failed_libs.items.len > 0) {
2992 for (failed_libs.items) |f| {
2993 const searched_paths = if (f.checked_paths.len == 0) " none" else f.checked_paths;
2994 std.log.err("unable to find {s} system library '{s}' using strategy '{s}'. searched paths:{s}", .{
2995 @tagName(f.preferred_mode), f.name, @tagName(f.strategy), searched_paths,
2996 });
2997 }
2998 process.exit(1);
2999 }
3000 }
3001 // After this point, create_module.resolved_system_libs is used instead of
3002 // create_module.external_system_libs.
3003
3004 // We now repeat part of the process for frameworks.2766 // We now repeat part of the process for frameworks.
3005 var resolved_frameworks = std.ArrayList(Compilation.Framework).init(arena);2767 var resolved_frameworks = std.ArrayList(Compilation.Framework).init(arena);
30062768
3007 if (frameworks.keys().len > 0) {2769 if (create_module.frameworks.keys().len > 0) {
3008 var test_path = std.ArrayList(u8).init(gpa);2770 var test_path = std.ArrayList(u8).init(gpa);
3009 defer test_path.deinit();2771 defer test_path.deinit();
30102772
...@@ -3016,10 +2778,10 @@ fn buildOutputType(...@@ -3016,10 +2778,10 @@ fn buildOutputType(
3016 checked_paths: []const u8,2778 checked_paths: []const u8,
3017 }).init(arena);2779 }).init(arena);
30182780
3019 framework: for (frameworks.keys(), frameworks.values()) |framework_name, info| {2781 framework: for (create_module.frameworks.keys(), create_module.frameworks.values()) |framework_name, info| {
3020 checked_paths.clearRetainingCapacity();2782 checked_paths.clearRetainingCapacity();
30212783
3022 for (framework_dirs.items) |framework_dir_path| {2784 for (create_module.framework_dirs.items) |framework_dir_path| {
3023 if (try accessFrameworkPath(2785 if (try accessFrameworkPath(
3024 &test_path,2786 &test_path,
3025 &checked_paths,2787 &checked_paths,
...@@ -3054,11 +2816,13 @@ fn buildOutputType(...@@ -3054,11 +2816,13 @@ fn buildOutputType(
3054 }2816 }
3055 // After this point, resolved_frameworks is used instead of frameworks.2817 // After this point, resolved_frameworks is used instead of frameworks.
30562818
3057 if (create_module.opts.output_mode == .Obj and (target.ofmt == .coff or target.ofmt == .macho)) {2819 if (create_module.resolved_options.output_mode == .Obj and
2820 (target.ofmt == .coff or target.ofmt == .macho))
2821 {
3058 const total_obj_count = create_module.c_source_files.items.len +2822 const total_obj_count = create_module.c_source_files.items.len +
3059 @intFromBool(root_src_file != null) +2823 @intFromBool(root_src_file != null) +
3060 create_module.rc_source_files.items.len +2824 create_module.rc_source_files.items.len +
3061 link_objects.items.len;2825 create_module.link_objects.items.len;
3062 if (total_obj_count > 1) {2826 if (total_obj_count > 1) {
3063 fatal("{s} does not support linking multiple objects into one", .{@tagName(target.ofmt)});2827 fatal("{s} does not support linking multiple objects into one", .{@tagName(target.ofmt)});
3064 }2828 }
...@@ -3070,6 +2834,8 @@ fn buildOutputType(...@@ -3070,6 +2834,8 @@ fn buildOutputType(
3070 const output_to_cache = listen != .none;2834 const output_to_cache = listen != .none;
3071 const optional_version = if (have_version) version else null;2835 const optional_version = if (have_version) version else null;
30722836
2837 const root_name = if (provided_name) |n| n else main_mod.fully_qualified_name;
2838
3073 const resolved_soname: ?[]const u8 = switch (soname) {2839 const resolved_soname: ?[]const u8 = switch (soname) {
3074 .yes => |explicit| explicit,2840 .yes => |explicit| explicit,
3075 .no => null,2841 .no => null,
...@@ -3105,8 +2871,8 @@ fn buildOutputType(...@@ -3105,8 +2871,8 @@ fn buildOutputType(
3105 .basename = try std.zig.binNameAlloc(arena, .{2871 .basename = try std.zig.binNameAlloc(arena, .{
3106 .root_name = root_name,2872 .root_name = root_name,
3107 .target = target,2873 .target = target,
3108 .output_mode = create_module.opts.output_mode,2874 .output_mode = create_module.resolved_options.output_mode,
3109 .link_mode = create_module.opts.link_mode,2875 .link_mode = create_module.resolved_options.link_mode,
3110 .version = optional_version,2876 .version = optional_version,
3111 }),2877 }),
3112 },2878 },
...@@ -3224,9 +2990,9 @@ fn buildOutputType(...@@ -3224,9 +2990,9 @@ fn buildOutputType(
3224 };2990 };
3225 defer emit_docs_resolved.deinit();2991 defer emit_docs_resolved.deinit();
32262992
3227 const is_exe_or_dyn_lib = switch (create_module.opts.output_mode) {2993 const is_exe_or_dyn_lib = switch (create_module.resolved_options.output_mode) {
3228 .Obj => false,2994 .Obj => false,
3229 .Lib => (create_module.opts.link_mode orelse .Static) == .Dynamic,2995 .Lib => create_module.resolved_options.link_mode == .Dynamic,
3230 .Exe => true,2996 .Exe => true,
3231 };2997 };
3232 // Note that cmake when targeting Windows will try to execute2998 // Note that cmake when targeting Windows will try to execute
...@@ -3354,7 +3120,7 @@ fn buildOutputType(...@@ -3354,7 +3120,7 @@ fn buildOutputType(
3354 .self_exe_path = self_exe_path,3120 .self_exe_path = self_exe_path,
3355 .config = create_module.resolved_options,3121 .config = create_module.resolved_options,
3356 .root_name = root_name,3122 .root_name = root_name,
3357 .sysroot = sysroot,3123 .sysroot = create_module.sysroot,
3358 .main_mod = main_mod,3124 .main_mod = main_mod,
3359 .root_mod = root_mod,3125 .root_mod = root_mod,
3360 .std_mod = std_mod,3126 .std_mod = std_mod,
...@@ -3365,15 +3131,15 @@ fn buildOutputType(...@@ -3365,15 +3131,15 @@ fn buildOutputType(
3365 .emit_llvm_bc = emit_llvm_bc_resolved.data,3131 .emit_llvm_bc = emit_llvm_bc_resolved.data,
3366 .emit_docs = emit_docs_resolved.data,3132 .emit_docs = emit_docs_resolved.data,
3367 .emit_implib = emit_implib_resolved.data,3133 .emit_implib = emit_implib_resolved.data,
3368 .lib_dirs = lib_dirs.items,3134 .lib_dirs = create_module.lib_dirs.items,
3369 .rpath_list = rpath_list.items,3135 .rpath_list = create_module.rpath_list.items,
3370 .symbol_wrap_set = symbol_wrap_set,3136 .symbol_wrap_set = symbol_wrap_set,
3371 .c_source_files = create_module.c_source_files.items,3137 .c_source_files = create_module.c_source_files.items,
3372 .rc_source_files = create_module.rc_source_files.items,3138 .rc_source_files = create_module.rc_source_files.items,
3373 .manifest_file = manifest_file,3139 .manifest_file = manifest_file,
3374 .rc_includes = rc_includes,3140 .rc_includes = rc_includes,
3375 .link_objects = link_objects.items,3141 .link_objects = create_module.link_objects.items,
3376 .framework_dirs = framework_dirs.items,3142 .framework_dirs = create_module.framework_dirs.items,
3377 .frameworks = resolved_frameworks.items,3143 .frameworks = resolved_frameworks.items,
3378 .system_lib_names = create_module.resolved_system_libs.items(.name),3144 .system_lib_names = create_module.resolved_system_libs.items(.name),
3379 .system_lib_infos = create_module.resolved_system_libs.items(.lib),3145 .system_lib_infos = create_module.resolved_system_libs.items(.lib),
...@@ -3427,7 +3193,7 @@ fn buildOutputType(...@@ -3427,7 +3193,7 @@ fn buildOutputType(
3427 .clang_passthrough_mode = clang_passthrough_mode,3193 .clang_passthrough_mode = clang_passthrough_mode,
3428 .clang_preprocessor_mode = clang_preprocessor_mode,3194 .clang_preprocessor_mode = clang_preprocessor_mode,
3429 .version = optional_version,3195 .version = optional_version,
3430 .libc_installation = if (libc_installation) |*lci| lci else null,3196 .libc_installation = if (create_module.libc_installation) |*lci| lci else null,
3431 .verbose_cc = verbose_cc,3197 .verbose_cc = verbose_cc,
3432 .verbose_link = verbose_link,3198 .verbose_link = verbose_link,
3433 .verbose_air = verbose_air,3199 .verbose_air = verbose_air,
...@@ -3458,6 +3224,7 @@ fn buildOutputType(...@@ -3458,6 +3224,7 @@ fn buildOutputType(
3458 .reference_trace = reference_trace,3224 .reference_trace = reference_trace,
3459 .pdb_out_path = pdb_out_path,3225 .pdb_out_path = pdb_out_path,
3460 .error_limit = error_limit,3226 .error_limit = error_limit,
3227 .native_system_include_paths = create_module.native_system_include_paths,
3461 }) catch |err| switch (err) {3228 }) catch |err| switch (err) {
3462 error.LibCUnavailable => {3229 error.LibCUnavailable => {
3463 const triple_name = try target.zigTriple(arena);3230 const triple_name = try target.zigTriple(arena);
...@@ -3626,10 +3393,6 @@ const CreateModule = struct {...@@ -3626,10 +3393,6 @@ const CreateModule = struct {
3626 /// link_libcpp, and then the libraries are filtered into3393 /// link_libcpp, and then the libraries are filtered into
3627 /// `external_system_libs` and `resolved_system_libs`.3394 /// `external_system_libs` and `resolved_system_libs`.
3628 system_libs: std.StringArrayHashMapUnmanaged(SystemLib),3395 system_libs: std.StringArrayHashMapUnmanaged(SystemLib),
3629 external_system_libs: std.MultiArrayList(struct {
3630 name: []const u8,
3631 info: SystemLib,
3632 }),
3633 resolved_system_libs: std.MultiArrayList(struct {3396 resolved_system_libs: std.MultiArrayList(struct {
3634 name: []const u8,3397 name: []const u8,
3635 lib: Compilation.SystemLib,3398 lib: Compilation.SystemLib,
...@@ -3643,6 +3406,17 @@ const CreateModule = struct {...@@ -3643,6 +3406,17 @@ const CreateModule = struct {
3643 // This array is populated by zig cc frontend and then has to be converted to zig-style3406 // This array is populated by zig cc frontend and then has to be converted to zig-style
3644 // CPU features.3407 // CPU features.
3645 llvm_m_args: std.ArrayListUnmanaged([]const u8),3408 llvm_m_args: std.ArrayListUnmanaged([]const u8),
3409 sysroot: ?[]const u8,
3410 lib_dirs: std.ArrayListUnmanaged([]const u8),
3411 lib_dir_args: std.ArrayListUnmanaged([]const u8),
3412 libc_installation: ?LibCInstallation,
3413 want_native_include_dirs: bool,
3414 frameworks: std.StringArrayHashMapUnmanaged(Framework),
3415 native_system_include_paths: []const []const u8,
3416 framework_dirs: std.ArrayListUnmanaged([]const u8),
3417 rpath_list: std.ArrayListUnmanaged([]const u8),
3418 libc_paths_file: ?[]const u8,
3419 link_objects: std.ArrayListUnmanaged(Compilation.LinkObject),
3646};3420};
36473421
3648fn createModule(3422fn createModule(
...@@ -3749,6 +3523,10 @@ fn createModule(...@@ -3749,6 +3523,10 @@ fn createModule(
3749 // First, remove libc, libc++, and compiler_rt libraries from the system libraries list.3523 // First, remove libc, libc++, and compiler_rt libraries from the system libraries list.
3750 // We need to know whether the set of system libraries contains anything besides these3524 // We need to know whether the set of system libraries contains anything besides these
3751 // to decide whether to trigger native path detection logic.3525 // to decide whether to trigger native path detection logic.
3526 var external_system_libs: std.MultiArrayList(struct {
3527 name: []const u8,
3528 info: SystemLib,
3529 }) = .{};
3752 for (create_module.system_libs.keys(), create_module.system_libs.values()) |lib_name, info| {3530 for (create_module.system_libs.keys(), create_module.system_libs.values()) |lib_name, info| {
3753 if (target.is_libc_lib_name(lib_name)) {3531 if (target.is_libc_lib_name(lib_name)) {
3754 create_module.opts.link_libc = true;3532 create_module.opts.link_libc = true;
...@@ -3800,12 +3578,249 @@ fn createModule(...@@ -3800,12 +3578,249 @@ fn createModule(
3800 }3578 }
3801 }3579 }
38023580
3803 try create_module.external_system_libs.append(arena, .{3581 try external_system_libs.append(arena, .{
3804 .name = lib_name,3582 .name = lib_name,
3805 .info = info,3583 .info = info,
3806 });3584 });
3807 }3585 }
3808 // After this point, external_system_libs is used instead of system_libs.3586 // After this point, external_system_libs is used instead of system_libs.
3587 if (external_system_libs.len != 0)
3588 create_module.want_native_include_dirs = true;
3589
3590 // Resolve the library path arguments with respect to sysroot.
3591 if (create_module.sysroot) |root| {
3592 try create_module.lib_dirs.ensureUnusedCapacity(arena, create_module.lib_dir_args.items.len * 2);
3593 for (create_module.lib_dir_args.items) |dir| {
3594 if (fs.path.isAbsolute(dir)) {
3595 const stripped_dir = dir[fs.path.diskDesignator(dir).len..];
3596 const full_path = try fs.path.join(arena, &[_][]const u8{ root, stripped_dir });
3597 create_module.lib_dirs.appendAssumeCapacity(full_path);
3598 }
3599 create_module.lib_dirs.appendAssumeCapacity(dir);
3600 }
3601 } else {
3602 create_module.lib_dirs = create_module.lib_dir_args;
3603 }
3604 create_module.lib_dir_args = undefined; // From here we use lib_dirs instead.
3605
3606 if (resolved_target.is_native_os and target.isDarwin()) {
3607 // If we want to link against frameworks, we need system headers.
3608 if (create_module.frameworks.count() > 0)
3609 create_module.want_native_include_dirs = true;
3610 }
3611
3612 // Trigger native system library path detection if necessary.
3613 if (create_module.sysroot == null and
3614 resolved_target.is_native_os and resolved_target.is_native_abi and
3615 create_module.want_native_include_dirs)
3616 {
3617 var paths = std.zig.system.NativePaths.detect(arena, target) catch |err| {
3618 fatal("unable to detect native system paths: {s}", .{@errorName(err)});
3619 };
3620 for (paths.warnings.items) |warning| {
3621 warn("{s}", .{warning});
3622 }
3623
3624 create_module.native_system_include_paths = try paths.include_dirs.toOwnedSlice(arena);
3625
3626 try create_module.framework_dirs.appendSlice(arena, paths.framework_dirs.items);
3627 try create_module.lib_dirs.appendSlice(arena, paths.lib_dirs.items);
3628 try create_module.rpath_list.appendSlice(arena, paths.rpaths.items);
3629 }
3630
3631 if (create_module.libc_paths_file) |paths_file| {
3632 create_module.libc_installation = LibCInstallation.parse(arena, paths_file, target) catch |err| {
3633 fatal("unable to parse libc paths file at path {s}: {s}", .{
3634 paths_file, @errorName(err),
3635 });
3636 };
3637 }
3638
3639 if (builtin.target.os.tag == .windows and target.abi == .msvc and
3640 external_system_libs.len != 0)
3641 {
3642 if (create_module.libc_installation == null) {
3643 create_module.libc_installation = try LibCInstallation.findNative(.{
3644 .allocator = arena,
3645 .verbose = true,
3646 .target = target,
3647 });
3648
3649 try create_module.lib_dirs.appendSlice(arena, &.{
3650 create_module.libc_installation.?.msvc_lib_dir.?,
3651 create_module.libc_installation.?.kernel32_lib_dir.?,
3652 });
3653 }
3654 }
3655
3656 // If any libs in this list are statically provided, we omit them from the
3657 // resolved list and populate the link_objects array instead.
3658 {
3659 var test_path = std.ArrayList(u8).init(gpa);
3660 defer test_path.deinit();
3661
3662 var checked_paths = std.ArrayList(u8).init(gpa);
3663 defer checked_paths.deinit();
3664
3665 var failed_libs = std.ArrayList(struct {
3666 name: []const u8,
3667 strategy: SystemLib.SearchStrategy,
3668 checked_paths: []const u8,
3669 preferred_mode: std.builtin.LinkMode,
3670 }).init(arena);
3671
3672 syslib: for (external_system_libs.items(.name), external_system_libs.items(.info)) |lib_name, info| {
3673 // Checked in the first pass above while looking for libc libraries.
3674 assert(!fs.path.isAbsolute(lib_name));
3675
3676 checked_paths.clearRetainingCapacity();
3677
3678 switch (info.search_strategy) {
3679 .mode_first, .no_fallback => {
3680 // check for preferred mode
3681 for (create_module.lib_dirs.items) |lib_dir_path| {
3682 if (try accessLibPath(
3683 &test_path,
3684 &checked_paths,
3685 lib_dir_path,
3686 lib_name,
3687 target,
3688 info.preferred_mode,
3689 )) {
3690 const path = try arena.dupe(u8, test_path.items);
3691 switch (info.preferred_mode) {
3692 .Static => try create_module.link_objects.append(arena, .{ .path = path }),
3693 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
3694 .name = lib_name,
3695 .lib = .{
3696 .needed = info.needed,
3697 .weak = info.weak,
3698 .path = path,
3699 },
3700 }),
3701 }
3702 continue :syslib;
3703 }
3704 }
3705 // check for fallback mode
3706 if (info.search_strategy == .no_fallback) {
3707 try failed_libs.append(.{
3708 .name = lib_name,
3709 .strategy = info.search_strategy,
3710 .checked_paths = try arena.dupe(u8, checked_paths.items),
3711 .preferred_mode = info.preferred_mode,
3712 });
3713 continue :syslib;
3714 }
3715 for (create_module.lib_dirs.items) |lib_dir_path| {
3716 if (try accessLibPath(
3717 &test_path,
3718 &checked_paths,
3719 lib_dir_path,
3720 lib_name,
3721 target,
3722 info.fallbackMode(),
3723 )) {
3724 const path = try arena.dupe(u8, test_path.items);
3725 switch (info.fallbackMode()) {
3726 .Static => try create_module.link_objects.append(arena, .{ .path = path }),
3727 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
3728 .name = lib_name,
3729 .lib = .{
3730 .needed = info.needed,
3731 .weak = info.weak,
3732 .path = path,
3733 },
3734 }),
3735 }
3736 continue :syslib;
3737 }
3738 }
3739 try failed_libs.append(.{
3740 .name = lib_name,
3741 .strategy = info.search_strategy,
3742 .checked_paths = try arena.dupe(u8, checked_paths.items),
3743 .preferred_mode = info.preferred_mode,
3744 });
3745 continue :syslib;
3746 },
3747 .paths_first => {
3748 for (create_module.lib_dirs.items) |lib_dir_path| {
3749 // check for preferred mode
3750 if (try accessLibPath(
3751 &test_path,
3752 &checked_paths,
3753 lib_dir_path,
3754 lib_name,
3755 target,
3756 info.preferred_mode,
3757 )) {
3758 const path = try arena.dupe(u8, test_path.items);
3759 switch (info.preferred_mode) {
3760 .Static => try create_module.link_objects.append(arena, .{ .path = path }),
3761 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
3762 .name = lib_name,
3763 .lib = .{
3764 .needed = info.needed,
3765 .weak = info.weak,
3766 .path = path,
3767 },
3768 }),
3769 }
3770 continue :syslib;
3771 }
3772
3773 // check for fallback mode
3774 if (try accessLibPath(
3775 &test_path,
3776 &checked_paths,
3777 lib_dir_path,
3778 lib_name,
3779 target,
3780 info.fallbackMode(),
3781 )) {
3782 const path = try arena.dupe(u8, test_path.items);
3783 switch (info.fallbackMode()) {
3784 .Static => try create_module.link_objects.append(arena, .{ .path = path }),
3785 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
3786 .name = lib_name,
3787 .lib = .{
3788 .needed = info.needed,
3789 .weak = info.weak,
3790 .path = path,
3791 },
3792 }),
3793 }
3794 continue :syslib;
3795 }
3796 }
3797 try failed_libs.append(.{
3798 .name = lib_name,
3799 .strategy = info.search_strategy,
3800 .checked_paths = try arena.dupe(u8, checked_paths.items),
3801 .preferred_mode = info.preferred_mode,
3802 });
3803 continue :syslib;
3804 },
3805 }
3806 @compileError("unreachable");
3807 }
3808
3809 if (failed_libs.items.len > 0) {
3810 for (failed_libs.items) |f| {
3811 const searched_paths = if (f.checked_paths.len == 0) " none" else f.checked_paths;
3812 std.log.err("unable to find {s} system library '{s}' using strategy '{s}'. searched paths:{s}", .{
3813 @tagName(f.preferred_mode), f.name, @tagName(f.strategy), searched_paths,
3814 });
3815 }
3816 process.exit(1);
3817 }
3818 }
3819 // After this point, create_module.resolved_system_libs is used instead of
3820 // create_module.external_system_libs.
3821
3822 if (create_module.resolved_system_libs.len != 0)
3823 create_module.opts.any_dyn_libs = true;
38093824
3810 create_module.resolved_options = Compilation.Config.resolve(create_module.opts) catch |err| switch (err) {3825 create_module.resolved_options = Compilation.Config.resolve(create_module.opts) catch |err| switch (err) {
3811 else => fatal("unable to resolve compilation options: {s}", .{@errorName(err)}),3826 else => fatal("unable to resolve compilation options: {s}", .{@errorName(err)}),