| ... | ... | @@ -478,6 +478,7 @@ const usage_build_generic = |
| 478 | 478 | \\ --sysroot [path] Set the system root directory (usually /) |
| 479 | 479 | \\ --version [ver] Dynamic library semver |
| 480 | 480 | \\ --entry [name] Set the entrypoint symbol name |
| 481 | \\ --force_undefined [name] Specify the symbol must be defined for the link to succeed |
| 481 | 482 | \\ -fsoname[=name] Override the default SONAME value |
| 482 | 483 | \\ -fno-soname Disable emitting a SONAME |
| 483 | 484 | \\ -fLLD Force using LLD as the linker |
| ... | ... | @@ -680,6 +681,28 @@ const Listen = union(enum) { |
| 680 | 681 | stdio, |
| 681 | 682 | }; |
| 682 | 683 | |
| 684 | const ArgsIterator = struct { |
| 685 | resp_file: ?ArgIteratorResponseFile = null, |
| 686 | args: []const []const u8, |
| 687 | i: usize = 0, |
| 688 | fn next(it: *@This()) ?[]const u8 { |
| 689 | if (it.i >= it.args.len) { |
| 690 | if (it.resp_file) |*resp| return resp.next(); |
| 691 | return null; |
| 692 | } |
| 693 | defer it.i += 1; |
| 694 | return it.args[it.i]; |
| 695 | } |
| 696 | fn nextOrFatal(it: *@This()) []const u8 { |
| 697 | if (it.i >= it.args.len) { |
| 698 | if (it.resp_file) |*resp| if (resp.next()) |ret| return ret; |
| 699 | fatal("expected parameter after {s}", .{it.args[it.i - 1]}); |
| 700 | } |
| 701 | defer it.i += 1; |
| 702 | return it.args[it.i]; |
| 703 | } |
| 704 | }; |
| 705 | |
| 683 | 706 | fn buildOutputType( |
| 684 | 707 | gpa: Allocator, |
| 685 | 708 | arena: Allocator, |
| ... | ... | @@ -784,6 +807,7 @@ fn buildOutputType( |
| 784 | 807 | var test_evented_io = false; |
| 785 | 808 | var test_no_exec = false; |
| 786 | 809 | var entry: ?[]const u8 = null; |
| 810 | var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}; |
| 787 | 811 | var stack_size_override: ?u64 = null; |
| 788 | 812 | var image_base_override: ?u64 = null; |
| 789 | 813 | var use_llvm: ?bool = null; |
| ... | ... | @@ -917,28 +941,7 @@ fn buildOutputType( |
| 917 | 941 | |
| 918 | 942 | soname = .yes_default_value; |
| 919 | 943 | |
| 920 | | const Iterator = struct { |
| 921 | | resp_file: ?ArgIteratorResponseFile = null, |
| 922 | | args: []const []const u8, |
| 923 | | i: usize = 0, |
| 924 | | fn next(it: *@This()) ?[]const u8 { |
| 925 | | if (it.i >= it.args.len) { |
| 926 | | if (it.resp_file) |*resp| return resp.next(); |
| 927 | | return null; |
| 928 | | } |
| 929 | | defer it.i += 1; |
| 930 | | return it.args[it.i]; |
| 931 | | } |
| 932 | | fn nextOrFatal(it: *@This()) []const u8 { |
| 933 | | if (it.i >= it.args.len) { |
| 934 | | if (it.resp_file) |*resp| if (resp.next()) |ret| return ret; |
| 935 | | fatal("expected parameter after {s}", .{it.args[it.i - 1]}); |
| 936 | | } |
| 937 | | defer it.i += 1; |
| 938 | | return it.args[it.i]; |
| 939 | | } |
| 940 | | }; |
| 941 | | var args_iter = Iterator{ |
| 944 | var args_iter = ArgsIterator{ |
| 942 | 945 | .args = all_args[2..], |
| 943 | 946 | }; |
| 944 | 947 | |
| ... | ... | @@ -1029,6 +1032,8 @@ fn buildOutputType( |
| 1029 | 1032 | optimize_mode_string = args_iter.nextOrFatal(); |
| 1030 | 1033 | } else if (mem.eql(u8, arg, "--entry")) { |
| 1031 | 1034 | entry = args_iter.nextOrFatal(); |
| 1035 | } else if (mem.eql(u8, arg, "--force_undefined")) { |
| 1036 | try force_undefined_symbols.put(gpa, args_iter.nextOrFatal(), {}); |
| 1032 | 1037 | } else if (mem.eql(u8, arg, "--stack")) { |
| 1033 | 1038 | const next_arg = args_iter.nextOrFatal(); |
| 1034 | 1039 | stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| { |
| ... | ... | @@ -1816,6 +1821,9 @@ fn buildOutputType( |
| 1816 | 1821 | .entry => { |
| 1817 | 1822 | entry = it.only_arg; |
| 1818 | 1823 | }, |
| 1824 | .force_undefined_symbol => { |
| 1825 | try force_undefined_symbols.put(gpa, it.only_arg, {}); |
| 1826 | }, |
| 1819 | 1827 | .weak_library => try system_libs.put(it.only_arg, .{ .weak = true }), |
| 1820 | 1828 | .weak_framework => try frameworks.put(gpa, it.only_arg, .{ .weak = true }), |
| 1821 | 1829 | .headerpad_max_install_names => headerpad_max_install_names = true, |
| ... | ... | @@ -1843,17 +1851,14 @@ fn buildOutputType( |
| 1843 | 1851 | } |
| 1844 | 1852 | } |
| 1845 | 1853 | // Parse linker args. |
| 1846 | | var i: usize = 0; |
| 1847 | | while (i < linker_args.items.len) : (i += 1) { |
| 1848 | | const arg = linker_args.items[i]; |
| 1854 | var linker_args_it = ArgsIterator{ |
| 1855 | .args = linker_args.items, |
| 1856 | }; |
| 1857 | while (linker_args_it.next()) |arg| { |
| 1849 | 1858 | if (mem.eql(u8, arg, "-soname") or |
| 1850 | 1859 | mem.eql(u8, arg, "--soname")) |
| 1851 | 1860 | { |
| 1852 | | i += 1; |
| 1853 | | if (i >= linker_args.items.len) { |
| 1854 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 1855 | | } |
| 1856 | | const name = linker_args.items[i]; |
| 1861 | const name = linker_args_it.nextOrFatal(); |
| 1857 | 1862 | soname = .{ .yes = name }; |
| 1858 | 1863 | // Use it as --name. |
| 1859 | 1864 | // Example: libsoundio.so.2 |
| ... | ... | @@ -1881,64 +1886,37 @@ fn buildOutputType( |
| 1881 | 1886 | } |
| 1882 | 1887 | provided_name = name[prefix..end]; |
| 1883 | 1888 | } else if (mem.eql(u8, arg, "-rpath")) { |
| 1884 | | i += 1; |
| 1885 | | if (i >= linker_args.items.len) { |
| 1886 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 1887 | | } |
| 1888 | | try rpath_list.append(linker_args.items[i]); |
| 1889 | try rpath_list.append(linker_args_it.nextOrFatal()); |
| 1889 | 1890 | } else if (mem.eql(u8, arg, "--subsystem")) { |
| 1890 | | i += 1; |
| 1891 | | if (i >= linker_args.items.len) { |
| 1892 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 1893 | | } |
| 1894 | | subsystem = try parseSubSystem(linker_args.items[i]); |
| 1891 | subsystem = try parseSubSystem(linker_args_it.nextOrFatal()); |
| 1895 | 1892 | } else if (mem.eql(u8, arg, "-I") or |
| 1896 | 1893 | mem.eql(u8, arg, "--dynamic-linker") or |
| 1897 | 1894 | mem.eql(u8, arg, "-dynamic-linker")) |
| 1898 | 1895 | { |
| 1899 | | i += 1; |
| 1900 | | if (i >= linker_args.items.len) { |
| 1901 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 1902 | | } |
| 1903 | | target_dynamic_linker = linker_args.items[i]; |
| 1896 | target_dynamic_linker = linker_args_it.nextOrFatal(); |
| 1904 | 1897 | } else if (mem.eql(u8, arg, "-E") or |
| 1905 | 1898 | mem.eql(u8, arg, "--export-dynamic") or |
| 1906 | 1899 | mem.eql(u8, arg, "-export-dynamic")) |
| 1907 | 1900 | { |
| 1908 | 1901 | rdynamic = true; |
| 1909 | 1902 | } else if (mem.eql(u8, arg, "--version-script")) { |
| 1910 | | i += 1; |
| 1911 | | if (i >= linker_args.items.len) { |
| 1912 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 1913 | | } |
| 1914 | | version_script = linker_args.items[i]; |
| 1903 | version_script = linker_args_it.nextOrFatal(); |
| 1915 | 1904 | } else if (mem.eql(u8, arg, "-O")) { |
| 1916 | | i += 1; |
| 1917 | | if (i >= linker_args.items.len) { |
| 1918 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 1919 | | } |
| 1920 | | linker_optimization = std.fmt.parseUnsigned(u8, linker_args.items[i], 10) catch |err| { |
| 1921 | | fatal("unable to parse optimization level '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 1905 | const opt = linker_args_it.nextOrFatal(); |
| 1906 | linker_optimization = std.fmt.parseUnsigned(u8, opt, 10) catch |err| { |
| 1907 | fatal("unable to parse optimization level '{s}': {s}", .{ opt, @errorName(err) }); |
| 1922 | 1908 | }; |
| 1923 | 1909 | } else if (mem.startsWith(u8, arg, "-O")) { |
| 1924 | 1910 | linker_optimization = std.fmt.parseUnsigned(u8, arg["-O".len..], 10) catch |err| { |
| 1925 | 1911 | fatal("unable to parse optimization level '{s}': {s}", .{ arg, @errorName(err) }); |
| 1926 | 1912 | }; |
| 1927 | 1913 | } else if (mem.eql(u8, arg, "-pagezero_size")) { |
| 1928 | | i += 1; |
| 1929 | | if (i >= linker_args.items.len) { |
| 1930 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 1931 | | } |
| 1932 | | const next_arg = linker_args.items[i]; |
| 1914 | const next_arg = linker_args_it.nextOrFatal(); |
| 1933 | 1915 | pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| 1934 | 1916 | fatal("unable to parse pagezero size '{s}': {s}", .{ next_arg, @errorName(err) }); |
| 1935 | 1917 | }; |
| 1936 | 1918 | } else if (mem.eql(u8, arg, "-headerpad")) { |
| 1937 | | i += 1; |
| 1938 | | if (i >= linker_args.items.len) { |
| 1939 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 1940 | | } |
| 1941 | | const next_arg = linker_args.items[i]; |
| 1919 | const next_arg = linker_args_it.nextOrFatal(); |
| 1942 | 1920 | headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| 1943 | 1921 | fatal("unable to parse headerpad size '{s}': {s}", .{ next_arg, @errorName(err) }); |
| 1944 | 1922 | }; |
| ... | ... | @@ -1961,11 +1939,7 @@ fn buildOutputType( |
| 1961 | 1939 | } else if (mem.eql(u8, arg, "--print-map")) { |
| 1962 | 1940 | linker_print_map = true; |
| 1963 | 1941 | } else if (mem.eql(u8, arg, "--sort-section")) { |
| 1964 | | i += 1; |
| 1965 | | if (i >= linker_args.items.len) { |
| 1966 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 1967 | | } |
| 1968 | | const arg1 = linker_args.items[i]; |
| 1942 | const arg1 = linker_args_it.nextOrFatal(); |
| 1969 | 1943 | linker_sort_section = std.meta.stringToEnum(link.SortSection, arg1) orelse { |
| 1970 | 1944 | fatal("expected [name|alignment] after --sort-section, found '{s}'", .{arg1}); |
| 1971 | 1945 | }; |
| ... | ... | @@ -1998,28 +1972,16 @@ fn buildOutputType( |
| 1998 | 1972 | } else if (mem.startsWith(u8, arg, "--export=")) { |
| 1999 | 1973 | try linker_export_symbol_names.append(arg["--export=".len..]); |
| 2000 | 1974 | } else if (mem.eql(u8, arg, "--export")) { |
| 2001 | | i += 1; |
| 2002 | | if (i >= linker_args.items.len) { |
| 2003 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2004 | | } |
| 2005 | | try linker_export_symbol_names.append(linker_args.items[i]); |
| 1975 | try linker_export_symbol_names.append(linker_args_it.nextOrFatal()); |
| 2006 | 1976 | } else if (mem.eql(u8, arg, "--compress-debug-sections")) { |
| 2007 | | i += 1; |
| 2008 | | if (i >= linker_args.items.len) { |
| 2009 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2010 | | } |
| 2011 | | const arg1 = linker_args.items[i]; |
| 1977 | const arg1 = linker_args_it.nextOrFatal(); |
| 2012 | 1978 | linker_compress_debug_sections = std.meta.stringToEnum(link.CompressDebugSections, arg1) orelse { |
| 2013 | 1979 | fatal("expected [none|zlib] after --compress-debug-sections, found '{s}'", .{arg1}); |
| 2014 | 1980 | }; |
| 2015 | 1981 | } else if (mem.startsWith(u8, arg, "-z")) { |
| 2016 | 1982 | var z_arg = arg[2..]; |
| 2017 | 1983 | if (z_arg.len == 0) { |
| 2018 | | i += 1; |
| 2019 | | if (i >= linker_args.items.len) { |
| 2020 | | fatal("expected linker extension flag after '{s}'", .{arg}); |
| 2021 | | } |
| 2022 | | z_arg = linker_args.items[i]; |
| 1984 | z_arg = linker_args_it.nextOrFatal(); |
| 2023 | 1985 | } |
| 2024 | 1986 | if (mem.eql(u8, z_arg, "nodelete")) { |
| 2025 | 1987 | linker_z_nodelete = true; |
| ... | ... | @@ -2056,51 +2018,33 @@ fn buildOutputType( |
| 2056 | 2018 | fatal("unsupported linker extension flag: -z {s}", .{z_arg}); |
| 2057 | 2019 | } |
| 2058 | 2020 | } else if (mem.eql(u8, arg, "--major-image-version")) { |
| 2059 | | i += 1; |
| 2060 | | if (i >= linker_args.items.len) { |
| 2061 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2062 | | } |
| 2063 | | version.major = std.fmt.parseUnsigned(u32, linker_args.items[i], 10) catch |err| { |
| 2064 | | fatal("unable to parse major image version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 2021 | const major = linker_args_it.nextOrFatal(); |
| 2022 | version.major = std.fmt.parseUnsigned(u32, major, 10) catch |err| { |
| 2023 | fatal("unable to parse major image version '{s}': {s}", .{ major, @errorName(err) }); |
| 2065 | 2024 | }; |
| 2066 | 2025 | have_version = true; |
| 2067 | 2026 | } else if (mem.eql(u8, arg, "--minor-image-version")) { |
| 2068 | | i += 1; |
| 2069 | | if (i >= linker_args.items.len) { |
| 2070 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2071 | | } |
| 2072 | | version.minor = std.fmt.parseUnsigned(u32, linker_args.items[i], 10) catch |err| { |
| 2073 | | fatal("unable to parse minor image version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 2027 | const minor = linker_args_it.nextOrFatal(); |
| 2028 | version.minor = std.fmt.parseUnsigned(u32, minor, 10) catch |err| { |
| 2029 | fatal("unable to parse minor image version '{s}': {s}", .{ minor, @errorName(err) }); |
| 2074 | 2030 | }; |
| 2075 | 2031 | have_version = true; |
| 2076 | 2032 | } else if (mem.eql(u8, arg, "-e") or mem.eql(u8, arg, "--entry")) { |
| 2077 | | i += 1; |
| 2078 | | if (i >= linker_args.items.len) { |
| 2079 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2080 | | } |
| 2081 | | entry = linker_args.items[i]; |
| 2033 | entry = linker_args_it.nextOrFatal(); |
| 2034 | } else if (mem.eql(u8, arg, "-u")) { |
| 2035 | try force_undefined_symbols.put(gpa, linker_args_it.nextOrFatal(), {}); |
| 2082 | 2036 | } else if (mem.eql(u8, arg, "--stack") or mem.eql(u8, arg, "-stack_size")) { |
| 2083 | | i += 1; |
| 2084 | | if (i >= linker_args.items.len) { |
| 2085 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2086 | | } |
| 2087 | | stack_size_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| { |
| 2088 | | fatal("unable to parse stack size override '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 2037 | const stack_size = linker_args_it.nextOrFatal(); |
| 2038 | stack_size_override = std.fmt.parseUnsigned(u64, stack_size, 0) catch |err| { |
| 2039 | fatal("unable to parse stack size override '{s}': {s}", .{ stack_size, @errorName(err) }); |
| 2089 | 2040 | }; |
| 2090 | 2041 | } else if (mem.eql(u8, arg, "--image-base")) { |
| 2091 | | i += 1; |
| 2092 | | if (i >= linker_args.items.len) { |
| 2093 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2094 | | } |
| 2095 | | image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| { |
| 2096 | | fatal("unable to parse image base override '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 2042 | const image_base = linker_args_it.nextOrFatal(); |
| 2043 | image_base_override = std.fmt.parseUnsigned(u64, image_base, 0) catch |err| { |
| 2044 | fatal("unable to parse image base override '{s}': {s}", .{ image_base, @errorName(err) }); |
| 2097 | 2045 | }; |
| 2098 | 2046 | } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) { |
| 2099 | | i += 1; |
| 2100 | | if (i >= linker_args.items.len) { |
| 2101 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2102 | | } |
| 2103 | | linker_script = linker_args.items[i]; |
| 2047 | linker_script = linker_args_it.nextOrFatal(); |
| 2104 | 2048 | } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { |
| 2105 | 2049 | link_eh_frame_hdr = true; |
| 2106 | 2050 | } else if (mem.eql(u8, arg, "--no-eh-frame-hdr")) { |
| ... | ... | @@ -2138,130 +2082,74 @@ fn buildOutputType( |
| 2138 | 2082 | } else if (mem.eql(u8, arg, "--major-os-version") or |
| 2139 | 2083 | mem.eql(u8, arg, "--minor-os-version")) |
| 2140 | 2084 | { |
| 2141 | | i += 1; |
| 2142 | | if (i >= linker_args.items.len) { |
| 2143 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2144 | | } |
| 2145 | 2085 | // This option does not do anything. |
| 2086 | _ = linker_args_it.nextOrFatal(); |
| 2146 | 2087 | } else if (mem.eql(u8, arg, "--major-subsystem-version")) { |
| 2147 | | i += 1; |
| 2148 | | if (i >= linker_args.items.len) { |
| 2149 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2150 | | } |
| 2151 | | |
| 2088 | const major = linker_args_it.nextOrFatal(); |
| 2152 | 2089 | major_subsystem_version = std.fmt.parseUnsigned( |
| 2153 | 2090 | u32, |
| 2154 | | linker_args.items[i], |
| 2091 | major, |
| 2155 | 2092 | 10, |
| 2156 | 2093 | ) catch |err| { |
| 2157 | | fatal("unable to parse major subsystem version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 2094 | fatal("unable to parse major subsystem version '{s}': {s}", .{ major, @errorName(err) }); |
| 2158 | 2095 | }; |
| 2159 | 2096 | } else if (mem.eql(u8, arg, "--minor-subsystem-version")) { |
| 2160 | | i += 1; |
| 2161 | | if (i >= linker_args.items.len) { |
| 2162 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2163 | | } |
| 2164 | | |
| 2097 | const minor = linker_args_it.nextOrFatal(); |
| 2165 | 2098 | minor_subsystem_version = std.fmt.parseUnsigned( |
| 2166 | 2099 | u32, |
| 2167 | | linker_args.items[i], |
| 2100 | minor, |
| 2168 | 2101 | 10, |
| 2169 | 2102 | ) catch |err| { |
| 2170 | | fatal("unable to parse minor subsystem version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 2103 | fatal("unable to parse minor subsystem version '{s}': {s}", .{ minor, @errorName(err) }); |
| 2171 | 2104 | }; |
| 2172 | 2105 | } else if (mem.eql(u8, arg, "-framework")) { |
| 2173 | | i += 1; |
| 2174 | | if (i >= linker_args.items.len) { |
| 2175 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2176 | | } |
| 2177 | | try frameworks.put(gpa, linker_args.items[i], .{}); |
| 2106 | try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{}); |
| 2178 | 2107 | } else if (mem.eql(u8, arg, "-weak_framework")) { |
| 2179 | | i += 1; |
| 2180 | | if (i >= linker_args.items.len) { |
| 2181 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2182 | | } |
| 2183 | | try frameworks.put(gpa, linker_args.items[i], .{ .weak = true }); |
| 2108 | try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{ .weak = true }); |
| 2184 | 2109 | } else if (mem.eql(u8, arg, "-needed_framework")) { |
| 2185 | | i += 1; |
| 2186 | | if (i >= linker_args.items.len) { |
| 2187 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2188 | | } |
| 2189 | | try frameworks.put(gpa, linker_args.items[i], .{ .needed = true }); |
| 2110 | try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{ .needed = true }); |
| 2190 | 2111 | } else if (mem.eql(u8, arg, "-needed_library")) { |
| 2191 | | i += 1; |
| 2192 | | if (i >= linker_args.items.len) { |
| 2193 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2194 | | } |
| 2195 | | try system_libs.put(linker_args.items[i], .{ .needed = true }); |
| 2112 | try system_libs.put(linker_args_it.nextOrFatal(), .{ .needed = true }); |
| 2196 | 2113 | } else if (mem.startsWith(u8, arg, "-weak-l")) { |
| 2197 | 2114 | try system_libs.put(arg["-weak-l".len..], .{ .weak = true }); |
| 2198 | 2115 | } else if (mem.eql(u8, arg, "-weak_library")) { |
| 2199 | | i += 1; |
| 2200 | | if (i >= linker_args.items.len) { |
| 2201 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2202 | | } |
| 2203 | | try system_libs.put(linker_args.items[i], .{ .weak = true }); |
| 2116 | try system_libs.put(linker_args_it.nextOrFatal(), .{ .weak = true }); |
| 2204 | 2117 | } else if (mem.eql(u8, arg, "-compatibility_version")) { |
| 2205 | | i += 1; |
| 2206 | | if (i >= linker_args.items.len) { |
| 2207 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2208 | | } |
| 2209 | | compatibility_version = std.builtin.Version.parse(linker_args.items[i]) catch |err| { |
| 2210 | | fatal("unable to parse -compatibility_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 2118 | const compat_version = linker_args_it.nextOrFatal(); |
| 2119 | compatibility_version = std.builtin.Version.parse(compat_version) catch |err| { |
| 2120 | fatal("unable to parse -compatibility_version '{s}': {s}", .{ compat_version, @errorName(err) }); |
| 2211 | 2121 | }; |
| 2212 | 2122 | } else if (mem.eql(u8, arg, "-current_version")) { |
| 2213 | | i += 1; |
| 2214 | | if (i >= linker_args.items.len) { |
| 2215 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2216 | | } |
| 2217 | | version = std.builtin.Version.parse(linker_args.items[i]) catch |err| { |
| 2218 | | fatal("unable to parse -current_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 2123 | const curr_version = linker_args_it.nextOrFatal(); |
| 2124 | version = std.builtin.Version.parse(curr_version) catch |err| { |
| 2125 | fatal("unable to parse -current_version '{s}': {s}", .{ curr_version, @errorName(err) }); |
| 2219 | 2126 | }; |
| 2220 | 2127 | have_version = true; |
| 2221 | 2128 | } else if (mem.eql(u8, arg, "--out-implib") or |
| 2222 | 2129 | mem.eql(u8, arg, "-implib")) |
| 2223 | 2130 | { |
| 2224 | | i += 1; |
| 2225 | | if (i >= linker_args.items.len) { |
| 2226 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2227 | | } |
| 2228 | | emit_implib = .{ .yes = linker_args.items[i] }; |
| 2131 | emit_implib = .{ .yes = linker_args_it.nextOrFatal() }; |
| 2229 | 2132 | emit_implib_arg_provided = true; |
| 2230 | 2133 | } else if (mem.eql(u8, arg, "-undefined")) { |
| 2231 | | i += 1; |
| 2232 | | if (i >= linker_args.items.len) { |
| 2233 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2234 | | } |
| 2235 | | if (mem.eql(u8, "dynamic_lookup", linker_args.items[i])) { |
| 2134 | const lookup_type = linker_args_it.nextOrFatal(); |
| 2135 | if (mem.eql(u8, "dynamic_lookup", lookup_type)) { |
| 2236 | 2136 | linker_allow_shlib_undefined = true; |
| 2237 | | } else if (mem.eql(u8, "error", linker_args.items[i])) { |
| 2137 | } else if (mem.eql(u8, "error", lookup_type)) { |
| 2238 | 2138 | linker_allow_shlib_undefined = false; |
| 2239 | 2139 | } else { |
| 2240 | | fatal("unsupported -undefined option '{s}'", .{linker_args.items[i]}); |
| 2140 | fatal("unsupported -undefined option '{s}'", .{lookup_type}); |
| 2241 | 2141 | } |
| 2242 | 2142 | } else if (mem.eql(u8, arg, "-install_name")) { |
| 2243 | | i += 1; |
| 2244 | | if (i >= linker_args.items.len) { |
| 2245 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2246 | | } |
| 2247 | | install_name = linker_args.items[i]; |
| 2143 | install_name = linker_args_it.nextOrFatal(); |
| 2248 | 2144 | } else if (mem.eql(u8, arg, "-force_load")) { |
| 2249 | | i += 1; |
| 2250 | | if (i >= linker_args.items.len) { |
| 2251 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2252 | | } |
| 2253 | 2145 | try link_objects.append(.{ |
| 2254 | | .path = linker_args.items[i], |
| 2146 | .path = linker_args_it.nextOrFatal(), |
| 2255 | 2147 | .must_link = true, |
| 2256 | 2148 | }); |
| 2257 | 2149 | } else if (mem.eql(u8, arg, "-hash-style") or |
| 2258 | 2150 | mem.eql(u8, arg, "--hash-style")) |
| 2259 | 2151 | { |
| 2260 | | i += 1; |
| 2261 | | if (i >= linker_args.items.len) { |
| 2262 | | fatal("expected linker arg after '{s}'", .{arg}); |
| 2263 | | } |
| 2264 | | const next_arg = linker_args.items[i]; |
| 2152 | const next_arg = linker_args_it.nextOrFatal(); |
| 2265 | 2153 | hash_style = std.meta.stringToEnum(link.HashStyle, next_arg) orelse { |
| 2266 | 2154 | fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{ |
| 2267 | 2155 | next_arg, |
| ... | ... | @@ -3219,6 +3107,7 @@ fn buildOutputType( |
| 3219 | 3107 | .link_eh_frame_hdr = link_eh_frame_hdr, |
| 3220 | 3108 | .link_emit_relocs = link_emit_relocs, |
| 3221 | 3109 | .entry = entry, |
| 3110 | .force_undefined_symbols = force_undefined_symbols, |
| 3222 | 3111 | .stack_size_override = stack_size_override, |
| 3223 | 3112 | .image_base_override = image_base_override, |
| 3224 | 3113 | .strip = strip, |
| ... | ... | @@ -5295,6 +5184,7 @@ pub const ClangArgIterator = struct { |
| 5295 | 5184 | emit_llvm, |
| 5296 | 5185 | sysroot, |
| 5297 | 5186 | entry, |
| 5187 | force_undefined_symbol, |
| 5298 | 5188 | weak_library, |
| 5299 | 5189 | weak_framework, |
| 5300 | 5190 | headerpad_max_install_names, |