authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-01 19:37:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-03 09:52:14-07:00
logc65a06188173a4f1c911bfd44084a9dea57fe330
tree54c52dcd5ed1e57a7bb3f2fb86f152c4acb913cd
parent256074428fc987c16fe5e1b862c6e5fc8c2123a6

CLI: adjust order of operations of system libraries

First, system_libs are collected into a list. This is the same as before. Next, system_libs are filtered into external_system_libs, which is the same list but without any libc, compiler_rt, etc. At this point, if there are any external system libs, native library directory paths are detected and added to lib_dirs. Finally, extern_system_libs are filtered into resolved_system_libs, which has full paths to all of the libraries. This is the list passed into Compilation. This makes the required changes noted by @ifreund in the code review for this branch.

1 files changed, 116 insertions(+), 95 deletions(-)

src/main.zig+116-95
......@@ -2554,6 +2554,24 @@ fn buildOutputType(
25542554 }
25552555 }
25562556
2557 if (use_lld) |opt| {
2558 if (opt and cross_target.isDarwin()) {
2559 fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{});
2560 }
2561 }
2562
2563 if (want_lto) |opt| {
2564 if (opt and cross_target.isDarwin()) {
2565 fatal("LTO is not yet supported with the Mach-O object format. More details: https://github.com/ziglang/zig/issues/8680", .{});
2566 }
2567 }
2568
2569 if (comptime builtin.target.isDarwin()) {
2570 // If we want to link against frameworks, we need system headers.
2571 if (framework_dirs.items.len > 0 or frameworks.count() > 0)
2572 want_native_include_dirs = true;
2573 }
2574
25572575 // Resolve the library path arguments with respect to sysroot.
25582576 var lib_dirs = std.ArrayList([]const u8).init(arena);
25592577 if (sysroot) |root| {
......@@ -2598,6 +2616,100 @@ fn buildOutputType(
25982616 };
25992617 defer zig_lib_directory.handle.close();
26002618
2619 // First, remove libc, libc++, and compiler_rt libraries from the system libraries list.
2620 // We need to know whether the set of system libraries contains anything besides these
2621 // to decide whether to trigger native path detection logic.
2622 var external_system_libs: std.MultiArrayList(struct {
2623 name: []const u8,
2624 info: SystemLib,
2625 }) = .{};
2626 for (system_libs.keys(), system_libs.values()) |lib_name, info| {
2627 if (target_util.is_libc_lib_name(target_info.target, lib_name)) {
2628 link_libc = true;
2629 continue;
2630 }
2631 if (target_util.is_libcpp_lib_name(target_info.target, lib_name)) {
2632 link_libcpp = true;
2633 continue;
2634 }
2635 switch (target_util.classifyCompilerRtLibName(target_info.target, lib_name)) {
2636 .none => {},
2637 .only_libunwind, .both => {
2638 link_libunwind = true;
2639 continue;
2640 },
2641 .only_compiler_rt => {
2642 std.log.warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name});
2643 continue;
2644 },
2645 }
2646
2647 if (fs.path.isAbsolute(lib_name)) {
2648 fatal("cannot use absolute path as a system library: {s}", .{lib_name});
2649 }
2650
2651 if (target_info.target.os.tag == .wasi) {
2652 if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| {
2653 try wasi_emulated_libs.append(crt_file);
2654 continue;
2655 }
2656 }
2657
2658 try external_system_libs.append(arena, .{
2659 .name = lib_name,
2660 .info = info,
2661 });
2662 }
2663 // After this point, external_system_libs is used instead of system_libs.
2664
2665 // libc++ depends on libc
2666 if (link_libcpp) {
2667 link_libc = true;
2668 }
2669
2670 // Trigger native system library path detection if necessary.
2671 if (sysroot == null and cross_target.isNativeOs() and
2672 (external_system_libs.len != 0 or want_native_include_dirs))
2673 {
2674 const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| {
2675 fatal("unable to detect native system paths: {s}", .{@errorName(err)});
2676 };
2677 for (paths.warnings.items) |warning| {
2678 warn("{s}", .{warning});
2679 }
2680
2681 const has_sysroot = if (comptime builtin.target.isDarwin()) outer: {
2682 if (std.zig.system.darwin.isDarwinSDKInstalled(arena)) {
2683 const sdk = std.zig.system.darwin.getDarwinSDK(arena, target_info.target) orelse
2684 break :outer false;
2685 native_darwin_sdk = sdk;
2686 try clang_argv.ensureUnusedCapacity(2);
2687 clang_argv.appendAssumeCapacity("-isysroot");
2688 clang_argv.appendAssumeCapacity(sdk.path);
2689 break :outer true;
2690 } else break :outer false;
2691 } else false;
2692
2693 try clang_argv.ensureUnusedCapacity(paths.include_dirs.items.len * 2);
2694 const isystem_flag = if (has_sysroot) "-iwithsysroot" else "-isystem";
2695 for (paths.include_dirs.items) |include_dir| {
2696 clang_argv.appendAssumeCapacity(isystem_flag);
2697 clang_argv.appendAssumeCapacity(include_dir);
2698 }
2699
2700 try clang_argv.ensureUnusedCapacity(paths.framework_dirs.items.len * 2);
2701 try framework_dirs.ensureUnusedCapacity(paths.framework_dirs.items.len);
2702 const iframework_flag = if (has_sysroot) "-iframeworkwithsysroot" else "-iframework";
2703 for (paths.framework_dirs.items) |framework_dir| {
2704 clang_argv.appendAssumeCapacity(iframework_flag);
2705 clang_argv.appendAssumeCapacity(framework_dir);
2706 framework_dirs.appendAssumeCapacity(framework_dir);
2707 }
2708
2709 try lib_dirs.appendSlice(paths.lib_dirs.items);
2710 try rpath_list.appendSlice(paths.rpaths.items);
2711 }
2712
26012713 // Now that we have target info, we can find out if any of the system libraries
26022714 // are part of libc or libc++. We remove them from the list and communicate their
26032715 // existence via flags instead.
......@@ -2622,27 +2734,7 @@ fn buildOutputType(
26222734 preferred_mode: std.builtin.LinkMode,
26232735 }).init(arena);
26242736
2625 syslib: for (system_libs.keys(), system_libs.values()) |lib_name, info| {
2626 if (target_util.is_libc_lib_name(target_info.target, lib_name)) {
2627 link_libc = true;
2628 continue;
2629 }
2630 if (target_util.is_libcpp_lib_name(target_info.target, lib_name)) {
2631 link_libcpp = true;
2632 continue;
2633 }
2634 switch (target_util.classifyCompilerRtLibName(target_info.target, lib_name)) {
2635 .none => {},
2636 .only_libunwind, .both => {
2637 link_libunwind = true;
2638 continue;
2639 },
2640 .only_compiler_rt => {
2641 std.log.warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name});
2642 continue;
2643 },
2644 }
2645
2737 syslib: for (external_system_libs.items(.name), external_system_libs.items(.info)) |lib_name, info| {
26462738 if (target_info.target.os.tag == .windows) {
26472739 const exists = mingw.libExists(arena, target_info.target, zig_lib_directory, lib_name) catch |err| {
26482740 fatal("failed to check zig installation for DLL import libs: {s}", .{
......@@ -2662,16 +2754,8 @@ fn buildOutputType(
26622754 }
26632755 }
26642756
2665 if (fs.path.isAbsolute(lib_name)) {
2666 fatal("cannot use absolute path as a system library: {s}", .{lib_name});
2667 }
2668
2669 if (target_info.target.os.tag == .wasi) {
2670 if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| {
2671 try wasi_emulated_libs.append(crt_file);
2672 continue;
2673 }
2674 }
2757 // Checked in the first pass above while looking for libc libraries.
2758 assert(!fs.path.isAbsolute(lib_name));
26752759
26762760 checked_paths.clearRetainingCapacity();
26772761
......@@ -2819,70 +2903,7 @@ fn buildOutputType(
28192903 process.exit(1);
28202904 }
28212905 }
2822 // libc++ depends on libc
2823 if (link_libcpp) {
2824 link_libc = true;
2825 }
2826
2827 if (use_lld) |opt| {
2828 if (opt and cross_target.isDarwin()) {
2829 fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{});
2830 }
2831 }
2832
2833 if (want_lto) |opt| {
2834 if (opt and cross_target.isDarwin()) {
2835 fatal("LTO is not yet supported with the Mach-O object format. More details: https://github.com/ziglang/zig/issues/8680", .{});
2836 }
2837 }
2838
2839 if (comptime builtin.target.isDarwin()) {
2840 // If we want to link against frameworks, we need system headers.
2841 if (framework_dirs.items.len > 0 or frameworks.count() > 0)
2842 want_native_include_dirs = true;
2843 }
2844
2845 if (sysroot == null and cross_target.isNativeOs() and
2846 (resolved_system_libs.len != 0 or want_native_include_dirs))
2847 {
2848 const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| {
2849 fatal("unable to detect native system paths: {s}", .{@errorName(err)});
2850 };
2851 for (paths.warnings.items) |warning| {
2852 warn("{s}", .{warning});
2853 }
2854
2855 const has_sysroot = if (comptime builtin.target.isDarwin()) outer: {
2856 if (std.zig.system.darwin.isDarwinSDKInstalled(arena)) {
2857 const sdk = std.zig.system.darwin.getDarwinSDK(arena, target_info.target) orelse
2858 break :outer false;
2859 native_darwin_sdk = sdk;
2860 try clang_argv.ensureUnusedCapacity(2);
2861 clang_argv.appendAssumeCapacity("-isysroot");
2862 clang_argv.appendAssumeCapacity(sdk.path);
2863 break :outer true;
2864 } else break :outer false;
2865 } else false;
2866
2867 try clang_argv.ensureUnusedCapacity(paths.include_dirs.items.len * 2);
2868 const isystem_flag = if (has_sysroot) "-iwithsysroot" else "-isystem";
2869 for (paths.include_dirs.items) |include_dir| {
2870 clang_argv.appendAssumeCapacity(isystem_flag);
2871 clang_argv.appendAssumeCapacity(include_dir);
2872 }
2873
2874 try clang_argv.ensureUnusedCapacity(paths.framework_dirs.items.len * 2);
2875 try framework_dirs.ensureUnusedCapacity(paths.framework_dirs.items.len);
2876 const iframework_flag = if (has_sysroot) "-iframeworkwithsysroot" else "-iframework";
2877 for (paths.framework_dirs.items) |framework_dir| {
2878 clang_argv.appendAssumeCapacity(iframework_flag);
2879 clang_argv.appendAssumeCapacity(framework_dir);
2880 framework_dirs.appendAssumeCapacity(framework_dir);
2881 }
2882
2883 try lib_dirs.appendSlice(paths.lib_dirs.items);
2884 try rpath_list.appendSlice(paths.rpaths.items);
2885 }
2906 // After this point, resolved_system_libs is used instead of external_system_libs.
28862907
28872908 const object_format = target_info.target.ofmt;
28882909