| author | |
| committer | |
| log | 91a73a177bc20fa0219dbb6c3cf3dda1c2a465db |
| tree | 5f391418951620a1f28e8a8fccddbb8e33aed8f6 |
| parent | a9082b4ec51debdbffc20b56e9b37cb82dd04750 |
still TODO is the task of creating import .lib files for DLLs on the fly
both for -lfoo and for e.g. `extern "kernel32"`15 files changed, 1506 insertions(+), 156 deletions(-)
BRANCH_TODO+6-4| ... | @@ -1,14 +1,13 @@ | ... | @@ -1,14 +1,13 @@ |
| 1 | * COFF LLD linking | 1 | * add jobs to build import libs for windows DLLs for explicitly linked libs |
| 2 | * mingw-w64 | 2 | * add jobs to build import libs for windows DLLs for extern "foo" functions used |
| 3 | * MachO LLD linking | 3 | * MachO LLD linking |
| 4 | * WASM LLD linking | 4 | * WASM LLD linking |
| 5 | * audit the CLI options for stage2 | 5 | * audit the CLI options for stage2 |
| 6 | * audit the base cache hash | 6 | * audit the base cache hash |
| 7 | * On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process. | 7 | * On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process. |
| 8 | * windows CUSTOMBUILD : error : unable to build compiler_rt: FileNotFound [D:\a\1\s\build\zig_install_lib_files.vcxproj] | ||
| 9 | * try building some software with zig cc to make sure it didn't regress | ||
| 10 | * `-ftime-report` | 8 | * `-ftime-report` |
| 11 | * -fstack-report print stack size diagnostics\n" | 9 | * -fstack-report print stack size diagnostics\n" |
| 10 | * try building some software with zig cc to make sure it didn't regress | ||
| 12 | 11 | ||
| 13 | * implement proper parsing of clang stderr/stdout and exposing compile errors with the Compilation API | 12 | * implement proper parsing of clang stderr/stdout and exposing compile errors with the Compilation API |
| 14 | * implement proper parsing of LLD stderr/stdout and exposing compile errors with the Compilation API | 13 | * implement proper parsing of LLD stderr/stdout and exposing compile errors with the Compilation API |
| ... | @@ -35,6 +34,7 @@ | ... | @@ -35,6 +34,7 @@ |
| 35 | * integrate target features into building assembly code | 34 | * integrate target features into building assembly code |
| 36 | * libc_installation.zig: make it look for msvc only if msvc abi is chosen | 35 | * libc_installation.zig: make it look for msvc only if msvc abi is chosen |
| 37 | * switch the default C ABI for windows to be mingw-w64 | 36 | * switch the default C ABI for windows to be mingw-w64 |
| 37 | - make it .obj instead of .o always for coff | ||
| 38 | * change glibc log errors to normal exposed compile errors | 38 | * change glibc log errors to normal exposed compile errors |
| 39 | * improve Directory.join to only use 1 allocation in a clean way. | 39 | * improve Directory.join to only use 1 allocation in a clean way. |
| 40 | * tracy builds with lc++ | 40 | * tracy builds with lc++ |
| ... | @@ -48,3 +48,5 @@ | ... | @@ -48,3 +48,5 @@ |
| 48 | * linking hello world with LLD, lld is silently calling exit(1) instead of reporting ok=false. when run standalone the error message is: ld.lld: error: section [index 3] has a sh_offset (0x57000) + sh_size (0x68) that is greater than the file size (0x57060) | 48 | * linking hello world with LLD, lld is silently calling exit(1) instead of reporting ok=false. when run standalone the error message is: ld.lld: error: section [index 3] has a sh_offset (0x57000) + sh_size (0x68) that is greater than the file size (0x57060) |
| 49 | * submit PR to godbolt and update the CLI options (see changes to test/cli.zig) | 49 | * submit PR to godbolt and update the CLI options (see changes to test/cli.zig) |
| 50 | * make proposal about log levels | 50 | * make proposal about log levels |
| 51 | * proposal for changing fs Z/W functions to be native paths and have a way to do native path string literals | ||
| 52 | * proposal for block { break x; } |
lib/std/zig.zig+1-1| ... | @@ -93,7 +93,7 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro | ... | @@ -93,7 +93,7 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro |
| 93 | }; | 93 | }; |
| 94 | return std.fmt.allocPrint(allocator, "{}{}{}", .{ target.libPrefix(), root_name, suffix }); | 94 | return std.fmt.allocPrint(allocator, "{}{}{}", .{ target.libPrefix(), root_name, suffix }); |
| 95 | }, | 95 | }, |
| 96 | .Obj => return std.fmt.allocPrint(allocator, "{}.obj", .{root_name}), | 96 | .Obj => return std.fmt.allocPrint(allocator, "{}{}", .{ root_name, target.abi.oFileExt() }), |
| 97 | }, | 97 | }, |
| 98 | .elf => switch (options.output_mode) { | 98 | .elf => switch (options.output_mode) { |
| 99 | .Exe => return allocator.dupe(u8, root_name), | 99 | .Exe => return allocator.dupe(u8, root_name), |
src/Cache.zig+8| ... | @@ -76,6 +76,14 @@ pub const HashHelper = struct { | ... | @@ -76,6 +76,14 @@ pub const HashHelper = struct { |
| 76 | for (list_of_bytes) |bytes| hh.addBytes(bytes); | 76 | for (list_of_bytes) |bytes| hh.addBytes(bytes); |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | pub fn addStringSet(hh: *HashHelper, hm: std.StringArrayHashMapUnmanaged(void)) void { | ||
| 80 | const entries = hm.items(); | ||
| 81 | hh.add(entries.len); | ||
| 82 | for (entries) |entry| { | ||
| 83 | hh.addBytes(entry.key); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 79 | /// Convert the input value into bytes and record it as a dependency of the process being cached. | 87 | /// Convert the input value into bytes and record it as a dependency of the process being cached. |
| 80 | pub fn add(hh: *HashHelper, x: anytype) void { | 88 | pub fn add(hh: *HashHelper, x: anytype) void { |
| 81 | switch (@TypeOf(x)) { | 89 | switch (@TypeOf(x)) { |
src/Compilation.zig+53-15| ... | @@ -17,6 +17,7 @@ const build_options = @import("build_options"); | ... | @@ -17,6 +17,7 @@ const build_options = @import("build_options"); |
| 17 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; | 17 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; |
| 18 | const glibc = @import("glibc.zig"); | 18 | const glibc = @import("glibc.zig"); |
| 19 | const musl = @import("musl.zig"); | 19 | const musl = @import("musl.zig"); |
| 20 | const mingw = @import("mingw.zig"); | ||
| 20 | const libunwind = @import("libunwind.zig"); | 21 | const libunwind = @import("libunwind.zig"); |
| 21 | const libcxx = @import("libcxx.zig"); | 22 | const libcxx = @import("libcxx.zig"); |
| 22 | const fatal = @import("main.zig").fatal; | 23 | const fatal = @import("main.zig").fatal; |
| ... | @@ -59,7 +60,6 @@ verbose_llvm_ir: bool, | ... | @@ -59,7 +60,6 @@ verbose_llvm_ir: bool, |
| 59 | verbose_cimport: bool, | 60 | verbose_cimport: bool, |
| 60 | verbose_llvm_cpu_features: bool, | 61 | verbose_llvm_cpu_features: bool, |
| 61 | disable_c_depfile: bool, | 62 | disable_c_depfile: bool, |
| 62 | is_test: bool, | ||
| 63 | time_report: bool, | 63 | time_report: bool, |
| 64 | 64 | ||
| 65 | c_source_files: []const CSourceFile, | 65 | c_source_files: []const CSourceFile, |
| ... | @@ -150,8 +150,10 @@ const Job = union(enum) { | ... | @@ -150,8 +150,10 @@ const Job = union(enum) { |
| 150 | glibc_crt_file: glibc.CRTFile, | 150 | glibc_crt_file: glibc.CRTFile, |
| 151 | /// all of the glibc shared objects | 151 | /// all of the glibc shared objects |
| 152 | glibc_shared_objects, | 152 | glibc_shared_objects, |
| 153 | /// one of the glibc static objects | 153 | /// one of the musl static objects |
| 154 | musl_crt_file: musl.CRTFile, | 154 | musl_crt_file: musl.CRTFile, |
| 155 | /// one of the mingw-w64 static objects | ||
| 156 | mingw_crt_file: mingw.CRTFile, | ||
| 155 | /// libunwind.a, usually needed when linking libc | 157 | /// libunwind.a, usually needed when linking libc |
| 156 | libunwind: void, | 158 | libunwind: void, |
| 157 | libcxx: void, | 159 | libcxx: void, |
| ... | @@ -719,6 +721,13 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -719,6 +721,13 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 719 | fatal("TODO implement support for -femit-h in the self-hosted backend", .{}); | 721 | fatal("TODO implement support for -femit-h in the self-hosted backend", .{}); |
| 720 | } | 722 | } |
| 721 | 723 | ||
| 724 | var system_libs: std.StringArrayHashMapUnmanaged(void) = .{}; | ||
| 725 | errdefer system_libs.deinit(gpa); | ||
| 726 | try system_libs.ensureCapacity(gpa, options.system_libs.len); | ||
| 727 | for (options.system_libs) |lib_name| { | ||
| 728 | system_libs.putAssumeCapacity(lib_name, {}); | ||
| 729 | } | ||
| 730 | |||
| 722 | const bin_file = try link.File.openPath(gpa, .{ | 731 | const bin_file = try link.File.openPath(gpa, .{ |
| 723 | .emit = bin_file_emit, | 732 | .emit = bin_file_emit, |
| 724 | .root_name = root_name, | 733 | .root_name = root_name, |
| ... | @@ -736,7 +745,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -736,7 +745,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 736 | .objects = options.link_objects, | 745 | .objects = options.link_objects, |
| 737 | .frameworks = options.frameworks, | 746 | .frameworks = options.frameworks, |
| 738 | .framework_dirs = options.framework_dirs, | 747 | .framework_dirs = options.framework_dirs, |
| 739 | .system_libs = options.system_libs, | 748 | .system_libs = system_libs, |
| 740 | .lib_dirs = options.lib_dirs, | 749 | .lib_dirs = options.lib_dirs, |
| 741 | .rpath_list = options.rpath_list, | 750 | .rpath_list = options.rpath_list, |
| 742 | .strip = options.strip, | 751 | .strip = options.strip, |
| ... | @@ -769,6 +778,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -769,6 +778,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 769 | .each_lib_rpath = options.each_lib_rpath orelse false, | 778 | .each_lib_rpath = options.each_lib_rpath orelse false, |
| 770 | .disable_lld_caching = options.disable_lld_caching, | 779 | .disable_lld_caching = options.disable_lld_caching, |
| 771 | .subsystem = options.subsystem, | 780 | .subsystem = options.subsystem, |
| 781 | .is_test = options.is_test, | ||
| 772 | }); | 782 | }); |
| 773 | errdefer bin_file.destroy(); | 783 | errdefer bin_file.destroy(); |
| 774 | comp.* = .{ | 784 | comp.* = .{ |
| ... | @@ -804,7 +814,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -804,7 +814,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 804 | .verbose_llvm_cpu_features = options.verbose_llvm_cpu_features, | 814 | .verbose_llvm_cpu_features = options.verbose_llvm_cpu_features, |
| 805 | .disable_c_depfile = options.disable_c_depfile, | 815 | .disable_c_depfile = options.disable_c_depfile, |
| 806 | .owned_link_dir = owned_link_dir, | 816 | .owned_link_dir = owned_link_dir, |
| 807 | .is_test = options.is_test, | ||
| 808 | .color = options.color, | 817 | .color = options.color, |
| 809 | .time_report = options.time_report, | 818 | .time_report = options.time_report, |
| 810 | .test_filter = options.test_filter, | 819 | .test_filter = options.test_filter, |
| ... | @@ -847,8 +856,17 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -847,8 +856,17 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 847 | .{ .musl_crt_file = .libc_a }, | 856 | .{ .musl_crt_file = .libc_a }, |
| 848 | }); | 857 | }); |
| 849 | } | 858 | } |
| 850 | if (comp.wantBuildMinGWW64FromSource()) { | 859 | if (comp.wantBuildMinGWFromSource()) { |
| 851 | @panic("TODO"); | 860 | const static_lib_jobs = [_]Job{ |
| 861 | .{ .mingw_crt_file = .mingw32_lib }, | ||
| 862 | .{ .mingw_crt_file = .msvcrt_os_lib }, | ||
| 863 | .{ .mingw_crt_file = .mingwex_lib }, | ||
| 864 | .{ .mingw_crt_file = .uuid_lib }, | ||
| 865 | }; | ||
| 866 | const crt_job: Job = .{ .mingw_crt_file = if (is_dyn_lib) .dllcrt2_o else .crt2_o }; | ||
| 867 | try comp.work_queue.ensureUnusedCapacity(static_lib_jobs.len + 1); | ||
| 868 | comp.work_queue.writeAssumeCapacity(&static_lib_jobs); | ||
| 869 | comp.work_queue.writeItemAssumeCapacity(crt_job); | ||
| 852 | } | 870 | } |
| 853 | if (comp.wantBuildLibUnwindFromSource()) { | 871 | if (comp.wantBuildLibUnwindFromSource()) { |
| 854 | try comp.work_queue.writeItem(.{ .libunwind = {} }); | 872 | try comp.work_queue.writeItem(.{ .libunwind = {} }); |
| ... | @@ -1209,6 +1227,12 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void { | ... | @@ -1209,6 +1227,12 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void { |
| 1209 | fatal("unable to build musl CRT file: {}", .{@errorName(err)}); | 1227 | fatal("unable to build musl CRT file: {}", .{@errorName(err)}); |
| 1210 | }; | 1228 | }; |
| 1211 | }, | 1229 | }, |
| 1230 | .mingw_crt_file => |crt_file| { | ||
| 1231 | mingw.buildCRTFile(self, crt_file) catch |err| { | ||
| 1232 | // TODO Expose this as a normal compile error rather than crashing here. | ||
| 1233 | fatal("unable to build mingw-w64 CRT file: {}", .{@errorName(err)}); | ||
| 1234 | }; | ||
| 1235 | }, | ||
| 1212 | .libunwind => { | 1236 | .libunwind => { |
| 1213 | libunwind.buildStaticLib(self) catch |err| { | 1237 | libunwind.buildStaticLib(self) catch |err| { |
| 1214 | // TODO Expose this as a normal compile error rather than crashing here. | 1238 | // TODO Expose this as a normal compile error rather than crashing here. |
| ... | @@ -2087,7 +2111,7 @@ fn detectLibCFromLibCInstallation(arena: *Allocator, target: Target, lci: *const | ... | @@ -2087,7 +2111,7 @@ fn detectLibCFromLibCInstallation(arena: *Allocator, target: Target, lci: *const |
| 2087 | pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 { | 2111 | pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 { |
| 2088 | if (comp.wantBuildGLibCFromSource() or | 2112 | if (comp.wantBuildGLibCFromSource() or |
| 2089 | comp.wantBuildMuslFromSource() or | 2113 | comp.wantBuildMuslFromSource() or |
| 2090 | comp.wantBuildMinGWW64FromSource()) | 2114 | comp.wantBuildMinGWFromSource()) |
| 2091 | { | 2115 | { |
| 2092 | return comp.crt_files.get(basename).?.full_object_path; | 2116 | return comp.crt_files.get(basename).?.full_object_path; |
| 2093 | } | 2117 | } |
| ... | @@ -2125,7 +2149,7 @@ fn wantBuildMuslFromSource(comp: Compilation) bool { | ... | @@ -2125,7 +2149,7 @@ fn wantBuildMuslFromSource(comp: Compilation) bool { |
| 2125 | return comp.wantBuildLibCFromSource() and comp.getTarget().isMusl(); | 2149 | return comp.wantBuildLibCFromSource() and comp.getTarget().isMusl(); |
| 2126 | } | 2150 | } |
| 2127 | 2151 | ||
| 2128 | fn wantBuildMinGWW64FromSource(comp: Compilation) bool { | 2152 | fn wantBuildMinGWFromSource(comp: Compilation) bool { |
| 2129 | return comp.wantBuildLibCFromSource() and comp.getTarget().isMinGW(); | 2153 | return comp.wantBuildLibCFromSource() and comp.getTarget().isMinGW(); |
| 2130 | } | 2154 | } |
| 2131 | 2155 | ||
| ... | @@ -2186,7 +2210,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 | ... | @@ -2186,7 +2210,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 |
| 2186 | , .{ | 2210 | , .{ |
| 2187 | @tagName(comp.bin_file.options.output_mode), | 2211 | @tagName(comp.bin_file.options.output_mode), |
| 2188 | @tagName(comp.bin_file.options.link_mode), | 2212 | @tagName(comp.bin_file.options.link_mode), |
| 2189 | comp.is_test, | 2213 | comp.bin_file.options.is_test, |
| 2190 | comp.bin_file.options.single_threaded, | 2214 | comp.bin_file.options.single_threaded, |
| 2191 | @tagName(target.abi), | 2215 | @tagName(target.abi), |
| 2192 | @tagName(target.cpu.arch), | 2216 | @tagName(target.cpu.arch), |
| ... | @@ -2214,7 +2238,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 | ... | @@ -2214,7 +2238,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 |
| 2214 | \\pub const os = Os{{ | 2238 | \\pub const os = Os{{ |
| 2215 | \\ .tag = .{}, | 2239 | \\ .tag = .{}, |
| 2216 | \\ .version_range = .{{ | 2240 | \\ .version_range = .{{ |
| 2217 | , | 2241 | , |
| 2218 | .{@tagName(target.os.tag)}, | 2242 | .{@tagName(target.os.tag)}, |
| 2219 | ); | 2243 | ); |
| 2220 | 2244 | ||
| ... | @@ -2283,7 +2307,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 | ... | @@ -2283,7 +2307,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 |
| 2283 | \\ .max = {s}, | 2307 | \\ .max = {s}, |
| 2284 | \\ }}}}, | 2308 | \\ }}}}, |
| 2285 | \\ | 2309 | \\ |
| 2286 | , | 2310 | , |
| 2287 | .{ windows.min, windows.max }, | 2311 | .{ windows.min, windows.max }, |
| 2288 | ), | 2312 | ), |
| 2289 | } | 2313 | } |
| ... | @@ -2311,7 +2335,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 | ... | @@ -2311,7 +2335,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 |
| 2311 | @tagName(comp.bin_file.options.machine_code_model), | 2335 | @tagName(comp.bin_file.options.machine_code_model), |
| 2312 | }); | 2336 | }); |
| 2313 | 2337 | ||
| 2314 | if (comp.is_test) { | 2338 | if (comp.bin_file.options.is_test) { |
| 2315 | try buffer.appendSlice( | 2339 | try buffer.appendSlice( |
| 2316 | \\pub var test_functions: []TestFn = undefined; // overwritten later | 2340 | \\pub var test_functions: []TestFn = undefined; // overwritten later |
| 2317 | \\ | 2341 | \\ |
| ... | @@ -2384,7 +2408,7 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR | ... | @@ -2384,7 +2408,7 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR |
| 2384 | .basename = bin_basename, | 2408 | .basename = bin_basename, |
| 2385 | }; | 2409 | }; |
| 2386 | const optimize_mode: std.builtin.Mode = blk: { | 2410 | const optimize_mode: std.builtin.Mode = blk: { |
| 2387 | if (comp.is_test) | 2411 | if (comp.bin_file.options.is_test) |
| 2388 | break :blk comp.bin_file.options.optimize_mode; | 2412 | break :blk comp.bin_file.options.optimize_mode; |
| 2389 | switch (comp.bin_file.options.optimize_mode) { | 2413 | switch (comp.bin_file.options.optimize_mode) { |
| 2390 | .Debug, .ReleaseFast, .ReleaseSafe => break :blk .ReleaseFast, | 2414 | .Debug, .ReleaseFast, .ReleaseSafe => break :blk .ReleaseFast, |
| ... | @@ -2473,7 +2497,7 @@ fn updateStage1Module(comp: *Compilation) !void { | ... | @@ -2473,7 +2497,7 @@ fn updateStage1Module(comp: *Compilation) !void { |
| 2473 | man.hash.add(target.os.getVersionRange()); | 2497 | man.hash.add(target.os.getVersionRange()); |
| 2474 | man.hash.add(comp.bin_file.options.dll_export_fns); | 2498 | man.hash.add(comp.bin_file.options.dll_export_fns); |
| 2475 | man.hash.add(comp.bin_file.options.function_sections); | 2499 | man.hash.add(comp.bin_file.options.function_sections); |
| 2476 | man.hash.add(comp.is_test); | 2500 | man.hash.add(comp.bin_file.options.is_test); |
| 2477 | man.hash.add(comp.bin_file.options.emit != null); | 2501 | man.hash.add(comp.bin_file.options.emit != null); |
| 2478 | man.hash.add(comp.emit_h != null); | 2502 | man.hash.add(comp.emit_h != null); |
| 2479 | man.hash.add(comp.emit_asm != null); | 2503 | man.hash.add(comp.emit_asm != null); |
| ... | @@ -2537,7 +2561,7 @@ fn updateStage1Module(comp: *Compilation) !void { | ... | @@ -2537,7 +2561,7 @@ fn updateStage1Module(comp: *Compilation) !void { |
| 2537 | zig_lib_dir.ptr, | 2561 | zig_lib_dir.ptr, |
| 2538 | zig_lib_dir.len, | 2562 | zig_lib_dir.len, |
| 2539 | stage2_target, | 2563 | stage2_target, |
| 2540 | comp.is_test, | 2564 | comp.bin_file.options.is_test, |
| 2541 | ) orelse return error.OutOfMemory; | 2565 | ) orelse return error.OutOfMemory; |
| 2542 | 2566 | ||
| 2543 | const emit_bin_path = if (comp.bin_file.options.emit != null) blk: { | 2567 | const emit_bin_path = if (comp.bin_file.options.emit != null) blk: { |
| ... | @@ -2609,8 +2633,22 @@ fn updateStage1Module(comp: *Compilation) !void { | ... | @@ -2609,8 +2633,22 @@ fn updateStage1Module(comp: *Compilation) !void { |
| 2609 | .verbose_cimport = comp.verbose_cimport, | 2633 | .verbose_cimport = comp.verbose_cimport, |
| 2610 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, | 2634 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 2611 | .main_progress_node = main_progress_node, | 2635 | .main_progress_node = main_progress_node, |
| 2636 | .have_c_main = false, | ||
| 2637 | .have_winmain = false, | ||
| 2638 | .have_wwinmain = false, | ||
| 2639 | .have_winmain_crt_startup = false, | ||
| 2640 | .have_wwinmain_crt_startup = false, | ||
| 2641 | .have_dllmain_crt_startup = false, | ||
| 2612 | }; | 2642 | }; |
| 2613 | stage1_module.build_object(); | 2643 | stage1_module.build_object(); |
| 2644 | |||
| 2645 | mod.have_c_main = stage1_module.have_c_main; | ||
| 2646 | mod.have_winmain = stage1_module.have_winmain; | ||
| 2647 | mod.have_wwinmain = stage1_module.have_wwinmain; | ||
| 2648 | mod.have_winmain_crt_startup = stage1_module.have_winmain_crt_startup; | ||
| 2649 | mod.have_wwinmain_crt_startup = stage1_module.have_wwinmain_crt_startup; | ||
| 2650 | mod.have_dllmain_crt_startup = stage1_module.have_dllmain_crt_startup; | ||
| 2651 | |||
| 2614 | stage1_module.destroy(); | 2652 | stage1_module.destroy(); |
| 2615 | 2653 | ||
| 2616 | const digest = man.final(); | 2654 | const digest = man.final(); |
src/Module.zig+8-1| ... | @@ -75,6 +75,13 @@ global_error_set: std.StringHashMapUnmanaged(u16) = .{}, | ... | @@ -75,6 +75,13 @@ global_error_set: std.StringHashMapUnmanaged(u16) = .{}, |
| 75 | /// previous analysis. | 75 | /// previous analysis. |
| 76 | generation: u32 = 0, | 76 | generation: u32 = 0, |
| 77 | 77 | ||
| 78 | have_winmain: bool = false, | ||
| 79 | have_wwinmain: bool = false, | ||
| 80 | have_winmain_crt_startup: bool = false, | ||
| 81 | have_wwinmain_crt_startup: bool = false, | ||
| 82 | have_dllmain_crt_startup: bool = false, | ||
| 83 | have_c_main: bool = false, | ||
| 84 | |||
| 78 | pub const Export = struct { | 85 | pub const Export = struct { |
| 79 | options: std.builtin.ExportOptions, | 86 | options: std.builtin.ExportOptions, |
| 80 | /// Byte offset into the file that contains the export directive. | 87 | /// Byte offset into the file that contains the export directive. |
| ... | @@ -2668,7 +2675,7 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst | ... | @@ -2668,7 +2675,7 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst |
| 2668 | const src_info = inst.ty.intInfo(self.getTarget()); | 2675 | const src_info = inst.ty.intInfo(self.getTarget()); |
| 2669 | const dst_info = dest_type.intInfo(self.getTarget()); | 2676 | const dst_info = dest_type.intInfo(self.getTarget()); |
| 2670 | if ((src_info.signed == dst_info.signed and dst_info.bits >= src_info.bits) or | 2677 | if ((src_info.signed == dst_info.signed and dst_info.bits >= src_info.bits) or |
| 2671 | // small enough unsigned ints can get casted to large enough signed ints | 2678 | // small enough unsigned ints can get casted to large enough signed ints |
| 2672 | (src_info.signed and !dst_info.signed and dst_info.bits > src_info.bits)) | 2679 | (src_info.signed and !dst_info.signed and dst_info.bits > src_info.bits)) |
| 2673 | { | 2680 | { |
| 2674 | const b = try self.requireRuntimeBlock(scope, inst.src); | 2681 | const b = try self.requireRuntimeBlock(scope, inst.src); |
src/link.zig+28-27| ... | @@ -36,7 +36,7 @@ pub const Options = struct { | ... | @@ -36,7 +36,7 @@ pub const Options = struct { |
| 36 | root_name: []const u8, | 36 | root_name: []const u8, |
| 37 | /// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`. | 37 | /// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`. |
| 38 | module: ?*Module, | 38 | module: ?*Module, |
| 39 | dynamic_linker: ?[]const u8 = null, | 39 | dynamic_linker: ?[]const u8, |
| 40 | /// Used for calculating how much space to reserve for symbols in case the binary file | 40 | /// Used for calculating how much space to reserve for symbols in case the binary file |
| 41 | /// does not already have a symbol table. | 41 | /// does not already have a symbol table. |
| 42 | symbol_count_hint: u64 = 32, | 42 | symbol_count_hint: u64 = 32, |
| ... | @@ -44,53 +44,54 @@ pub const Options = struct { | ... | @@ -44,53 +44,54 @@ pub const Options = struct { |
| 44 | /// the binary file does not already have such a section. | 44 | /// the binary file does not already have such a section. |
| 45 | program_code_size_hint: u64 = 256 * 1024, | 45 | program_code_size_hint: u64 = 256 * 1024, |
| 46 | entry_addr: ?u64 = null, | 46 | entry_addr: ?u64 = null, |
| 47 | stack_size_override: ?u64 = null, | 47 | stack_size_override: ?u64, |
| 48 | /// Set to `true` to omit debug info. | 48 | /// Set to `true` to omit debug info. |
| 49 | strip: bool = false, | 49 | strip: bool, |
| 50 | /// If this is true then this link code is responsible for outputting an object | 50 | /// If this is true then this link code is responsible for outputting an object |
| 51 | /// file and then using LLD to link it together with the link options and other objects. | 51 | /// file and then using LLD to link it together with the link options and other objects. |
| 52 | /// Otherwise (depending on `use_llvm`) this link code directly outputs and updates the final binary. | 52 | /// Otherwise (depending on `use_llvm`) this link code directly outputs and updates the final binary. |
| 53 | use_lld: bool = false, | 53 | use_lld: bool, |
| 54 | /// If this is true then this link code is responsible for making an LLVM IR Module, | 54 | /// If this is true then this link code is responsible for making an LLVM IR Module, |
| 55 | /// outputting it to an object file, and then linking that together with link options and | 55 | /// outputting it to an object file, and then linking that together with link options and |
| 56 | /// other objects. | 56 | /// other objects. |
| 57 | /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary. | 57 | /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary. |
| 58 | use_llvm: bool = false, | 58 | use_llvm: bool, |
| 59 | link_libc: bool = false, | 59 | link_libc: bool, |
| 60 | link_libcpp: bool = false, | 60 | link_libcpp: bool, |
| 61 | function_sections: bool = false, | 61 | function_sections: bool, |
| 62 | eh_frame_hdr: bool = false, | 62 | eh_frame_hdr: bool, |
| 63 | rdynamic: bool = false, | 63 | rdynamic: bool, |
| 64 | z_nodelete: bool = false, | 64 | z_nodelete: bool, |
| 65 | z_defs: bool = false, | 65 | z_defs: bool, |
| 66 | bind_global_refs_locally: bool, | 66 | bind_global_refs_locally: bool, |
| 67 | is_native_os: bool, | 67 | is_native_os: bool, |
| 68 | pic: bool, | 68 | pic: bool, |
| 69 | valgrind: bool, | 69 | valgrind: bool, |
| 70 | stack_check: bool, | 70 | stack_check: bool, |
| 71 | single_threaded: bool, | 71 | single_threaded: bool, |
| 72 | verbose_link: bool = false, | 72 | verbose_link: bool, |
| 73 | dll_export_fns: bool, | 73 | dll_export_fns: bool, |
| 74 | error_return_tracing: bool, | 74 | error_return_tracing: bool, |
| 75 | is_compiler_rt_or_libc: bool, | 75 | is_compiler_rt_or_libc: bool, |
| 76 | each_lib_rpath: bool, | 76 | each_lib_rpath: bool, |
| 77 | disable_lld_caching: bool, | 77 | disable_lld_caching: bool, |
| 78 | is_test: bool, | ||
| 78 | gc_sections: ?bool = null, | 79 | gc_sections: ?bool = null, |
| 79 | allow_shlib_undefined: ?bool = null, | 80 | allow_shlib_undefined: ?bool, |
| 80 | subsystem: ?std.Target.SubSystem = null, | 81 | subsystem: ?std.Target.SubSystem, |
| 81 | linker_script: ?[]const u8 = null, | 82 | linker_script: ?[]const u8, |
| 82 | version_script: ?[]const u8 = null, | 83 | version_script: ?[]const u8, |
| 83 | override_soname: ?[]const u8 = null, | 84 | override_soname: ?[]const u8, |
| 84 | llvm_cpu_features: ?[*:0]const u8 = null, | 85 | llvm_cpu_features: ?[*:0]const u8, |
| 85 | /// Extra args passed directly to LLD. Ignored when not linking with LLD. | 86 | /// Extra args passed directly to LLD. Ignored when not linking with LLD. |
| 86 | extra_lld_args: []const []const u8 = &[0][]const u8, | 87 | extra_lld_args: []const []const u8, |
| 87 | 88 | ||
| 88 | objects: []const []const u8 = &[0][]const u8{}, | 89 | objects: []const []const u8, |
| 89 | framework_dirs: []const []const u8 = &[0][]const u8{}, | 90 | framework_dirs: []const []const u8, |
| 90 | frameworks: []const []const u8 = &[0][]const u8{}, | 91 | frameworks: []const []const u8, |
| 91 | system_libs: []const []const u8 = &[0][]const u8{}, | 92 | system_libs: std.StringArrayHashMapUnmanaged(void), |
| 92 | lib_dirs: []const []const u8 = &[0][]const u8{}, | 93 | lib_dirs: []const []const u8, |
| 93 | rpath_list: []const []const u8 = &[0][]const u8{}, | 94 | rpath_list: []const []const u8, |
| 94 | 95 | ||
| 95 | version: ?std.builtin.Version, | 96 | version: ?std.builtin.Version, |
| 96 | libc_installation: ?*const LibCInstallation, | 97 | libc_installation: ?*const LibCInstallation, |
src/link/Coff.zig+497-79| ... | @@ -5,6 +5,8 @@ const log = std.log.scoped(.link); | ... | @@ -5,6 +5,8 @@ const log = std.log.scoped(.link); |
| 5 | const Allocator = std.mem.Allocator; | 5 | const Allocator = std.mem.Allocator; |
| 6 | const assert = std.debug.assert; | 6 | const assert = std.debug.assert; |
| 7 | const fs = std.fs; | 7 | const fs = std.fs; |
| 8 | const allocPrint = std.fmt.allocPrint; | ||
| 9 | const mem = std.mem; | ||
| 8 | 10 | ||
| 9 | const trace = @import("../tracy.zig").trace; | 11 | const trace = @import("../tracy.zig").trace; |
| 10 | const Module = @import("../Module.zig"); | 12 | const Module = @import("../Module.zig"); |
| ... | @@ -12,6 +14,8 @@ const Compilation = @import("../Compilation.zig"); | ... | @@ -12,6 +14,8 @@ const Compilation = @import("../Compilation.zig"); |
| 12 | const codegen = @import("../codegen.zig"); | 14 | const codegen = @import("../codegen.zig"); |
| 13 | const link = @import("../link.zig"); | 15 | const link = @import("../link.zig"); |
| 14 | const build_options = @import("build_options"); | 16 | const build_options = @import("build_options"); |
| 17 | const Cache = @import("../Cache.zig"); | ||
| 18 | const mingw = @import("../mingw.zig"); | ||
| 15 | 19 | ||
| 16 | const allocation_padding = 4 / 3; | 20 | const allocation_padding = 4 / 3; |
| 17 | const minimum_text_block_size = 64 * allocation_padding; | 21 | const minimum_text_block_size = 64 * allocation_padding; |
| ... | @@ -21,7 +25,7 @@ const file_alignment = 512; | ... | @@ -21,7 +25,7 @@ const file_alignment = 512; |
| 21 | const image_base = 0x400_000; | 25 | const image_base = 0x400_000; |
| 22 | const section_table_size = 2 * 40; | 26 | const section_table_size = 2 * 40; |
| 23 | comptime { | 27 | comptime { |
| 24 | assert(std.mem.isAligned(image_base, section_alignment)); | 28 | assert(mem.isAligned(image_base, section_alignment)); |
| 25 | } | 29 | } |
| 26 | 30 | ||
| 27 | pub const base_tag: link.File.Tag = .coff; | 31 | pub const base_tag: link.File.Tag = .coff; |
| ... | @@ -155,14 +159,14 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio | ... | @@ -155,14 +159,14 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 155 | if (machine == .Unknown) { | 159 | if (machine == .Unknown) { |
| 156 | return error.UnsupportedCOFFArchitecture; | 160 | return error.UnsupportedCOFFArchitecture; |
| 157 | } | 161 | } |
| 158 | std.mem.writeIntLittle(u16, hdr_data[0..2], @enumToInt(machine)); | 162 | mem.writeIntLittle(u16, hdr_data[0..2], @enumToInt(machine)); |
| 159 | index += 2; | 163 | index += 2; |
| 160 | 164 | ||
| 161 | // Number of sections (we only use .got, .text) | 165 | // Number of sections (we only use .got, .text) |
| 162 | std.mem.writeIntLittle(u16, hdr_data[index..][0..2], 2); | 166 | mem.writeIntLittle(u16, hdr_data[index..][0..2], 2); |
| 163 | index += 2; | 167 | index += 2; |
| 164 | // TimeDateStamp (u32), PointerToSymbolTable (u32), NumberOfSymbols (u32) | 168 | // TimeDateStamp (u32), PointerToSymbolTable (u32), NumberOfSymbols (u32) |
| 165 | std.mem.set(u8, hdr_data[index..][0..12], 0); | 169 | mem.set(u8, hdr_data[index..][0..12], 0); |
| 166 | index += 12; | 170 | index += 12; |
| 167 | 171 | ||
| 168 | const optional_header_size = switch (options.output_mode) { | 172 | const optional_header_size = switch (options.output_mode) { |
| ... | @@ -177,8 +181,8 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio | ... | @@ -177,8 +181,8 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 177 | const default_offset_table_size = file_alignment; | 181 | const default_offset_table_size = file_alignment; |
| 178 | const default_size_of_code = 0; | 182 | const default_size_of_code = 0; |
| 179 | 183 | ||
| 180 | self.section_data_offset = std.mem.alignForwardGeneric(u32, self.section_table_offset + section_table_size, file_alignment); | 184 | self.section_data_offset = mem.alignForwardGeneric(u32, self.section_table_offset + section_table_size, file_alignment); |
| 181 | const section_data_relative_virtual_address = std.mem.alignForwardGeneric(u32, self.section_table_offset + section_table_size, section_alignment); | 185 | const section_data_relative_virtual_address = mem.alignForwardGeneric(u32, self.section_table_offset + section_table_size, section_alignment); |
| 182 | self.offset_table_virtual_address = image_base + section_data_relative_virtual_address; | 186 | self.offset_table_virtual_address = image_base + section_data_relative_virtual_address; |
| 183 | self.offset_table_size = default_offset_table_size; | 187 | self.offset_table_size = default_offset_table_size; |
| 184 | self.section_table_offset = section_table_offset; | 188 | self.section_table_offset = section_table_offset; |
| ... | @@ -186,9 +190,9 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio | ... | @@ -186,9 +190,9 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 186 | self.text_section_size = default_size_of_code; | 190 | self.text_section_size = default_size_of_code; |
| 187 | 191 | ||
| 188 | // Size of file when loaded in memory | 192 | // Size of file when loaded in memory |
| 189 | const size_of_image = std.mem.alignForwardGeneric(u32, self.text_section_virtual_address - image_base + default_size_of_code, section_alignment); | 193 | const size_of_image = mem.alignForwardGeneric(u32, self.text_section_virtual_address - image_base + default_size_of_code, section_alignment); |
| 190 | 194 | ||
| 191 | std.mem.writeIntLittle(u16, hdr_data[index..][0..2], optional_header_size); | 195 | mem.writeIntLittle(u16, hdr_data[index..][0..2], optional_header_size); |
| 192 | index += 2; | 196 | index += 2; |
| 193 | 197 | ||
| 194 | // Characteristics | 198 | // Characteristics |
| ... | @@ -200,7 +204,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio | ... | @@ -200,7 +204,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 200 | .p32 => characteristics |= std.coff.IMAGE_FILE_32BIT_MACHINE, | 204 | .p32 => characteristics |= std.coff.IMAGE_FILE_32BIT_MACHINE, |
| 201 | .p64 => characteristics |= std.coff.IMAGE_FILE_LARGE_ADDRESS_AWARE, | 205 | .p64 => characteristics |= std.coff.IMAGE_FILE_LARGE_ADDRESS_AWARE, |
| 202 | } | 206 | } |
| 203 | std.mem.writeIntLittle(u16, hdr_data[index..][0..2], characteristics); | 207 | mem.writeIntLittle(u16, hdr_data[index..][0..2], characteristics); |
| 204 | index += 2; | 208 | index += 2; |
| 205 | 209 | ||
| 206 | assert(index == 20); | 210 | assert(index == 20); |
| ... | @@ -210,106 +214,106 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio | ... | @@ -210,106 +214,106 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 210 | self.optional_header_offset = coff_file_header_offset + 20; | 214 | self.optional_header_offset = coff_file_header_offset + 20; |
| 211 | // Optional header | 215 | // Optional header |
| 212 | index = 0; | 216 | index = 0; |
| 213 | std.mem.writeIntLittle(u16, hdr_data[0..2], switch (self.ptr_width) { | 217 | mem.writeIntLittle(u16, hdr_data[0..2], switch (self.ptr_width) { |
| 214 | .p32 => @as(u16, 0x10b), | 218 | .p32 => @as(u16, 0x10b), |
| 215 | .p64 => 0x20b, | 219 | .p64 => 0x20b, |
| 216 | }); | 220 | }); |
| 217 | index += 2; | 221 | index += 2; |
| 218 | 222 | ||
| 219 | // Linker version (u8 + u8) | 223 | // Linker version (u8 + u8) |
| 220 | std.mem.set(u8, hdr_data[index..][0..2], 0); | 224 | mem.set(u8, hdr_data[index..][0..2], 0); |
| 221 | index += 2; | 225 | index += 2; |
| 222 | 226 | ||
| 223 | // SizeOfCode (UNUSED, u32), SizeOfInitializedData (u32), SizeOfUninitializedData (u32), AddressOfEntryPoint (u32), BaseOfCode (UNUSED, u32) | 227 | // SizeOfCode (UNUSED, u32), SizeOfInitializedData (u32), SizeOfUninitializedData (u32), AddressOfEntryPoint (u32), BaseOfCode (UNUSED, u32) |
| 224 | std.mem.set(u8, hdr_data[index..][0..20], 0); | 228 | mem.set(u8, hdr_data[index..][0..20], 0); |
| 225 | index += 20; | 229 | index += 20; |
| 226 | 230 | ||
| 227 | if (self.ptr_width == .p32) { | 231 | if (self.ptr_width == .p32) { |
| 228 | // Base of data relative to the image base (UNUSED) | 232 | // Base of data relative to the image base (UNUSED) |
| 229 | std.mem.set(u8, hdr_data[index..][0..4], 0); | 233 | mem.set(u8, hdr_data[index..][0..4], 0); |
| 230 | index += 4; | 234 | index += 4; |
| 231 | 235 | ||
| 232 | // Image base address | 236 | // Image base address |
| 233 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], image_base); | 237 | mem.writeIntLittle(u32, hdr_data[index..][0..4], image_base); |
| 234 | index += 4; | 238 | index += 4; |
| 235 | } else { | 239 | } else { |
| 236 | // Image base address | 240 | // Image base address |
| 237 | std.mem.writeIntLittle(u64, hdr_data[index..][0..8], image_base); | 241 | mem.writeIntLittle(u64, hdr_data[index..][0..8], image_base); |
| 238 | index += 8; | 242 | index += 8; |
| 239 | } | 243 | } |
| 240 | 244 | ||
| 241 | // Section alignment | 245 | // Section alignment |
| 242 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], section_alignment); | 246 | mem.writeIntLittle(u32, hdr_data[index..][0..4], section_alignment); |
| 243 | index += 4; | 247 | index += 4; |
| 244 | // File alignment | 248 | // File alignment |
| 245 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], file_alignment); | 249 | mem.writeIntLittle(u32, hdr_data[index..][0..4], file_alignment); |
| 246 | index += 4; | 250 | index += 4; |
| 247 | // Required OS version, 6.0 is vista | 251 | // Required OS version, 6.0 is vista |
| 248 | std.mem.writeIntLittle(u16, hdr_data[index..][0..2], 6); | 252 | mem.writeIntLittle(u16, hdr_data[index..][0..2], 6); |
| 249 | index += 2; | 253 | index += 2; |
| 250 | std.mem.writeIntLittle(u16, hdr_data[index..][0..2], 0); | 254 | mem.writeIntLittle(u16, hdr_data[index..][0..2], 0); |
| 251 | index += 2; | 255 | index += 2; |
| 252 | // Image version | 256 | // Image version |
| 253 | std.mem.set(u8, hdr_data[index..][0..4], 0); | 257 | mem.set(u8, hdr_data[index..][0..4], 0); |
| 254 | index += 4; | 258 | index += 4; |
| 255 | // Required subsystem version, same as OS version | 259 | // Required subsystem version, same as OS version |
| 256 | std.mem.writeIntLittle(u16, hdr_data[index..][0..2], 6); | 260 | mem.writeIntLittle(u16, hdr_data[index..][0..2], 6); |
| 257 | index += 2; | 261 | index += 2; |
| 258 | std.mem.writeIntLittle(u16, hdr_data[index..][0..2], 0); | 262 | mem.writeIntLittle(u16, hdr_data[index..][0..2], 0); |
| 259 | index += 2; | 263 | index += 2; |
| 260 | // Reserved zeroes (u32) | 264 | // Reserved zeroes (u32) |
| 261 | std.mem.set(u8, hdr_data[index..][0..4], 0); | 265 | mem.set(u8, hdr_data[index..][0..4], 0); |
| 262 | index += 4; | 266 | index += 4; |
| 263 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], size_of_image); | 267 | mem.writeIntLittle(u32, hdr_data[index..][0..4], size_of_image); |
| 264 | index += 4; | 268 | index += 4; |
| 265 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset); | 269 | mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset); |
| 266 | index += 4; | 270 | index += 4; |
| 267 | // CheckSum (u32) | 271 | // CheckSum (u32) |
| 268 | std.mem.set(u8, hdr_data[index..][0..4], 0); | 272 | mem.set(u8, hdr_data[index..][0..4], 0); |
| 269 | index += 4; | 273 | index += 4; |
| 270 | // Subsystem, TODO: Let users specify the subsystem, always CUI for now | 274 | // Subsystem, TODO: Let users specify the subsystem, always CUI for now |
| 271 | std.mem.writeIntLittle(u16, hdr_data[index..][0..2], 3); | 275 | mem.writeIntLittle(u16, hdr_data[index..][0..2], 3); |
| 272 | index += 2; | 276 | index += 2; |
| 273 | // DLL characteristics | 277 | // DLL characteristics |
| 274 | std.mem.writeIntLittle(u16, hdr_data[index..][0..2], 0x0); | 278 | mem.writeIntLittle(u16, hdr_data[index..][0..2], 0x0); |
| 275 | index += 2; | 279 | index += 2; |
| 276 | 280 | ||
| 277 | switch (self.ptr_width) { | 281 | switch (self.ptr_width) { |
| 278 | .p32 => { | 282 | .p32 => { |
| 279 | // Size of stack reserve + commit | 283 | // Size of stack reserve + commit |
| 280 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000_000); | 284 | mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000_000); |
| 281 | index += 4; | 285 | index += 4; |
| 282 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000); | 286 | mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000); |
| 283 | index += 4; | 287 | index += 4; |
| 284 | // Size of heap reserve + commit | 288 | // Size of heap reserve + commit |
| 285 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x100_000); | 289 | mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x100_000); |
| 286 | index += 4; | 290 | index += 4; |
| 287 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000); | 291 | mem.writeIntLittle(u32, hdr_data[index..][0..4], 0x1_000); |
| 288 | index += 4; | 292 | index += 4; |
| 289 | }, | 293 | }, |
| 290 | .p64 => { | 294 | .p64 => { |
| 291 | // Size of stack reserve + commit | 295 | // Size of stack reserve + commit |
| 292 | std.mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000_000); | 296 | mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000_000); |
| 293 | index += 8; | 297 | index += 8; |
| 294 | std.mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000); | 298 | mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000); |
| 295 | index += 8; | 299 | index += 8; |
| 296 | // Size of heap reserve + commit | 300 | // Size of heap reserve + commit |
| 297 | std.mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x100_000); | 301 | mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x100_000); |
| 298 | index += 8; | 302 | index += 8; |
| 299 | std.mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000); | 303 | mem.writeIntLittle(u64, hdr_data[index..][0..8], 0x1_000); |
| 300 | index += 8; | 304 | index += 8; |
| 301 | }, | 305 | }, |
| 302 | } | 306 | } |
| 303 | 307 | ||
| 304 | // Reserved zeroes | 308 | // Reserved zeroes |
| 305 | std.mem.set(u8, hdr_data[index..][0..4], 0); | 309 | mem.set(u8, hdr_data[index..][0..4], 0); |
| 306 | index += 4; | 310 | index += 4; |
| 307 | 311 | ||
| 308 | // Number of data directories | 312 | // Number of data directories |
| 309 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], data_directory_count); | 313 | mem.writeIntLittle(u32, hdr_data[index..][0..4], data_directory_count); |
| 310 | index += 4; | 314 | index += 4; |
| 311 | // Initialize data directories to zero | 315 | // Initialize data directories to zero |
| 312 | std.mem.set(u8, hdr_data[index..][0 .. data_directory_count * 8], 0); | 316 | mem.set(u8, hdr_data[index..][0 .. data_directory_count * 8], 0); |
| 313 | index += data_directory_count * 8; | 317 | index += data_directory_count * 8; |
| 314 | 318 | ||
| 315 | assert(index == optional_header_size); | 319 | assert(index == optional_header_size); |
| ... | @@ -321,52 +325,52 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio | ... | @@ -321,52 +325,52 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 321 | index += 8; | 325 | index += 8; |
| 322 | if (options.output_mode == .Exe) { | 326 | if (options.output_mode == .Exe) { |
| 323 | // Virtual size (u32) | 327 | // Virtual size (u32) |
| 324 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], default_offset_table_size); | 328 | mem.writeIntLittle(u32, hdr_data[index..][0..4], default_offset_table_size); |
| 325 | index += 4; | 329 | index += 4; |
| 326 | // Virtual address (u32) | 330 | // Virtual address (u32) |
| 327 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], self.offset_table_virtual_address - image_base); | 331 | mem.writeIntLittle(u32, hdr_data[index..][0..4], self.offset_table_virtual_address - image_base); |
| 328 | index += 4; | 332 | index += 4; |
| 329 | } else { | 333 | } else { |
| 330 | std.mem.set(u8, hdr_data[index..][0..8], 0); | 334 | mem.set(u8, hdr_data[index..][0..8], 0); |
| 331 | index += 8; | 335 | index += 8; |
| 332 | } | 336 | } |
| 333 | // Size of raw data (u32) | 337 | // Size of raw data (u32) |
| 334 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], default_offset_table_size); | 338 | mem.writeIntLittle(u32, hdr_data[index..][0..4], default_offset_table_size); |
| 335 | index += 4; | 339 | index += 4; |
| 336 | // File pointer to the start of the section | 340 | // File pointer to the start of the section |
| 337 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset); | 341 | mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset); |
| 338 | index += 4; | 342 | index += 4; |
| 339 | // Pointer to relocations (u32), PointerToLinenumbers (u32), NumberOfRelocations (u16), NumberOfLinenumbers (u16) | 343 | // Pointer to relocations (u32), PointerToLinenumbers (u32), NumberOfRelocations (u16), NumberOfLinenumbers (u16) |
| 340 | std.mem.set(u8, hdr_data[index..][0..12], 0); | 344 | mem.set(u8, hdr_data[index..][0..12], 0); |
| 341 | index += 12; | 345 | index += 12; |
| 342 | // Section flags | 346 | // Section flags |
| 343 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], std.coff.IMAGE_SCN_CNT_INITIALIZED_DATA | std.coff.IMAGE_SCN_MEM_READ); | 347 | mem.writeIntLittle(u32, hdr_data[index..][0..4], std.coff.IMAGE_SCN_CNT_INITIALIZED_DATA | std.coff.IMAGE_SCN_MEM_READ); |
| 344 | index += 4; | 348 | index += 4; |
| 345 | // Then, the .text section | 349 | // Then, the .text section |
| 346 | hdr_data[index..][0..8].* = ".text\x00\x00\x00".*; | 350 | hdr_data[index..][0..8].* = ".text\x00\x00\x00".*; |
| 347 | index += 8; | 351 | index += 8; |
| 348 | if (options.output_mode == .Exe) { | 352 | if (options.output_mode == .Exe) { |
| 349 | // Virtual size (u32) | 353 | // Virtual size (u32) |
| 350 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], default_size_of_code); | 354 | mem.writeIntLittle(u32, hdr_data[index..][0..4], default_size_of_code); |
| 351 | index += 4; | 355 | index += 4; |
| 352 | // Virtual address (u32) | 356 | // Virtual address (u32) |
| 353 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], self.text_section_virtual_address - image_base); | 357 | mem.writeIntLittle(u32, hdr_data[index..][0..4], self.text_section_virtual_address - image_base); |
| 354 | index += 4; | 358 | index += 4; |
| 355 | } else { | 359 | } else { |
| 356 | std.mem.set(u8, hdr_data[index..][0..8], 0); | 360 | mem.set(u8, hdr_data[index..][0..8], 0); |
| 357 | index += 8; | 361 | index += 8; |
| 358 | } | 362 | } |
| 359 | // Size of raw data (u32) | 363 | // Size of raw data (u32) |
| 360 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], default_size_of_code); | 364 | mem.writeIntLittle(u32, hdr_data[index..][0..4], default_size_of_code); |
| 361 | index += 4; | 365 | index += 4; |
| 362 | // File pointer to the start of the section | 366 | // File pointer to the start of the section |
| 363 | std.mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset + default_offset_table_size); | 367 | mem.writeIntLittle(u32, hdr_data[index..][0..4], self.section_data_offset + default_offset_table_size); |
| 364 | index += 4; | 368 | index += 4; |
| 365 | // Pointer to relocations (u32), PointerToLinenumbers (u32), NumberOfRelocations (u16), NumberOfLinenumbers (u16) | 369 | // Pointer to relocations (u32), PointerToLinenumbers (u32), NumberOfRelocations (u16), NumberOfLinenumbers (u16) |
| 366 | std.mem.set(u8, hdr_data[index..][0..12], 0); | 370 | mem.set(u8, hdr_data[index..][0..12], 0); |
| 367 | index += 12; | 371 | index += 12; |
| 368 | // Section flags | 372 | // Section flags |
| 369 | std.mem.writeIntLittle( | 373 | mem.writeIntLittle( |
| 370 | u32, | 374 | u32, |
| 371 | hdr_data[index..][0..4], | 375 | hdr_data[index..][0..4], |
| 372 | std.coff.IMAGE_SCN_CNT_CODE | std.coff.IMAGE_SCN_MEM_EXECUTE | std.coff.IMAGE_SCN_MEM_READ | std.coff.IMAGE_SCN_MEM_WRITE, | 376 | std.coff.IMAGE_SCN_CNT_CODE | std.coff.IMAGE_SCN_MEM_EXECUTE | std.coff.IMAGE_SCN_MEM_READ | std.coff.IMAGE_SCN_MEM_WRITE, |
| ... | @@ -434,7 +438,7 @@ fn allocateTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, a | ... | @@ -434,7 +438,7 @@ fn allocateTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, a |
| 434 | const free_block = self.text_block_free_list.items[i]; | 438 | const free_block = self.text_block_free_list.items[i]; |
| 435 | 439 | ||
| 436 | const next_block_text_offset = free_block.text_offset + free_block.capacity(); | 440 | const next_block_text_offset = free_block.text_offset + free_block.capacity(); |
| 437 | const new_block_text_offset = std.mem.alignForwardGeneric(u64, free_block.getVAddr(self.*) + free_block.size, alignment) - self.text_section_virtual_address; | 441 | const new_block_text_offset = mem.alignForwardGeneric(u64, free_block.getVAddr(self.*) + free_block.size, alignment) - self.text_section_virtual_address; |
| 438 | if (new_block_text_offset < next_block_text_offset and next_block_text_offset - new_block_text_offset >= new_block_min_capacity) { | 442 | if (new_block_text_offset < next_block_text_offset and next_block_text_offset - new_block_text_offset >= new_block_min_capacity) { |
| 439 | block_placement = free_block; | 443 | block_placement = free_block; |
| 440 | 444 | ||
| ... | @@ -453,7 +457,7 @@ fn allocateTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, a | ... | @@ -453,7 +457,7 @@ fn allocateTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, a |
| 453 | continue; | 457 | continue; |
| 454 | } | 458 | } |
| 455 | } else if (self.last_text_block) |last| { | 459 | } else if (self.last_text_block) |last| { |
| 456 | const new_block_vaddr = std.mem.alignForwardGeneric(u64, last.getVAddr(self.*) + last.size, alignment); | 460 | const new_block_vaddr = mem.alignForwardGeneric(u64, last.getVAddr(self.*) + last.size, alignment); |
| 457 | block_placement = last; | 461 | block_placement = last; |
| 458 | break :blk new_block_vaddr; | 462 | break :blk new_block_vaddr; |
| 459 | } else { | 463 | } else { |
| ... | @@ -463,15 +467,15 @@ fn allocateTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, a | ... | @@ -463,15 +467,15 @@ fn allocateTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, a |
| 463 | 467 | ||
| 464 | const expand_text_section = block_placement == null or block_placement.?.next == null; | 468 | const expand_text_section = block_placement == null or block_placement.?.next == null; |
| 465 | if (expand_text_section) { | 469 | if (expand_text_section) { |
| 466 | const needed_size = @intCast(u32, std.mem.alignForwardGeneric(u64, vaddr + new_block_size - self.text_section_virtual_address, file_alignment)); | 470 | const needed_size = @intCast(u32, mem.alignForwardGeneric(u64, vaddr + new_block_size - self.text_section_virtual_address, file_alignment)); |
| 467 | if (needed_size > self.text_section_size) { | 471 | if (needed_size > self.text_section_size) { |
| 468 | const current_text_section_virtual_size = std.mem.alignForwardGeneric(u32, self.text_section_size, section_alignment); | 472 | const current_text_section_virtual_size = mem.alignForwardGeneric(u32, self.text_section_size, section_alignment); |
| 469 | const new_text_section_virtual_size = std.mem.alignForwardGeneric(u32, needed_size, section_alignment); | 473 | const new_text_section_virtual_size = mem.alignForwardGeneric(u32, needed_size, section_alignment); |
| 470 | if (current_text_section_virtual_size != new_text_section_virtual_size) { | 474 | if (current_text_section_virtual_size != new_text_section_virtual_size) { |
| 471 | self.size_of_image_dirty = true; | 475 | self.size_of_image_dirty = true; |
| 472 | // Write new virtual size | 476 | // Write new virtual size |
| 473 | var buf: [4]u8 = undefined; | 477 | var buf: [4]u8 = undefined; |
| 474 | std.mem.writeIntLittle(u32, &buf, new_text_section_virtual_size); | 478 | mem.writeIntLittle(u32, &buf, new_text_section_virtual_size); |
| 475 | try self.base.file.?.pwriteAll(&buf, self.section_table_offset + 40 + 8); | 479 | try self.base.file.?.pwriteAll(&buf, self.section_table_offset + 40 + 8); |
| 476 | } | 480 | } |
| 477 | 481 | ||
| ... | @@ -509,7 +513,7 @@ fn allocateTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, a | ... | @@ -509,7 +513,7 @@ fn allocateTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, a |
| 509 | 513 | ||
| 510 | fn growTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { | 514 | fn growTextBlock(self: *Coff, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { |
| 511 | const block_vaddr = text_block.getVAddr(self.*); | 515 | const block_vaddr = text_block.getVAddr(self.*); |
| 512 | const align_ok = std.mem.alignBackwardGeneric(u64, block_vaddr, alignment) == block_vaddr; | 516 | const align_ok = mem.alignBackwardGeneric(u64, block_vaddr, alignment) == block_vaddr; |
| 513 | const need_realloc = !align_ok or new_block_size > text_block.capacity(); | 517 | const need_realloc = !align_ok or new_block_size > text_block.capacity(); |
| 514 | if (!need_realloc) return @as(u64, block_vaddr); | 518 | if (!need_realloc) return @as(u64, block_vaddr); |
| 515 | return self.allocateTextBlock(text_block, new_block_size, alignment); | 519 | return self.allocateTextBlock(text_block, new_block_size, alignment); |
| ... | @@ -575,14 +579,14 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { | ... | @@ -575,14 +579,14 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 575 | 579 | ||
| 576 | // Write the new raw size in the .got header | 580 | // Write the new raw size in the .got header |
| 577 | var buf: [8]u8 = undefined; | 581 | var buf: [8]u8 = undefined; |
| 578 | std.mem.writeIntLittle(u32, buf[0..4], new_raw_size); | 582 | mem.writeIntLittle(u32, buf[0..4], new_raw_size); |
| 579 | try self.base.file.?.pwriteAll(buf[0..4], self.section_table_offset + 16); | 583 | try self.base.file.?.pwriteAll(buf[0..4], self.section_table_offset + 16); |
| 580 | // Write the new .text section file offset in the .text section header | 584 | // Write the new .text section file offset in the .text section header |
| 581 | std.mem.writeIntLittle(u32, buf[0..4], new_text_section_start); | 585 | mem.writeIntLittle(u32, buf[0..4], new_text_section_start); |
| 582 | try self.base.file.?.pwriteAll(buf[0..4], self.section_table_offset + 40 + 20); | 586 | try self.base.file.?.pwriteAll(buf[0..4], self.section_table_offset + 40 + 20); |
| 583 | 587 | ||
| 584 | const current_virtual_size = std.mem.alignForwardGeneric(u32, self.offset_table_size, section_alignment); | 588 | const current_virtual_size = mem.alignForwardGeneric(u32, self.offset_table_size, section_alignment); |
| 585 | const new_virtual_size = std.mem.alignForwardGeneric(u32, new_raw_size, section_alignment); | 589 | const new_virtual_size = mem.alignForwardGeneric(u32, new_raw_size, section_alignment); |
| 586 | // If we had to move in the virtual address space, we need to fix the VAs in the offset table, as well as the virtual address of the `.text` section | 590 | // If we had to move in the virtual address space, we need to fix the VAs in the offset table, as well as the virtual address of the `.text` section |
| 587 | // and the virutal size of the `.got` section | 591 | // and the virutal size of the `.got` section |
| 588 | 592 | ||
| ... | @@ -592,12 +596,12 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { | ... | @@ -592,12 +596,12 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 592 | const va_offset = new_virtual_size - current_virtual_size; | 596 | const va_offset = new_virtual_size - current_virtual_size; |
| 593 | 597 | ||
| 594 | // Write .got virtual size | 598 | // Write .got virtual size |
| 595 | std.mem.writeIntLittle(u32, buf[0..4], new_virtual_size); | 599 | mem.writeIntLittle(u32, buf[0..4], new_virtual_size); |
| 596 | try self.base.file.?.pwriteAll(buf[0..4], self.section_table_offset + 8); | 600 | try self.base.file.?.pwriteAll(buf[0..4], self.section_table_offset + 8); |
| 597 | 601 | ||
| 598 | // Write .text new virtual address | 602 | // Write .text new virtual address |
| 599 | self.text_section_virtual_address = self.text_section_virtual_address + va_offset; | 603 | self.text_section_virtual_address = self.text_section_virtual_address + va_offset; |
| 600 | std.mem.writeIntLittle(u32, buf[0..4], self.text_section_virtual_address - image_base); | 604 | mem.writeIntLittle(u32, buf[0..4], self.text_section_virtual_address - image_base); |
| 601 | try self.base.file.?.pwriteAll(buf[0..4], self.section_table_offset + 40 + 12); | 605 | try self.base.file.?.pwriteAll(buf[0..4], self.section_table_offset + 40 + 12); |
| 602 | 606 | ||
| 603 | // Fix the VAs in the offset table | 607 | // Fix the VAs in the offset table |
| ... | @@ -607,11 +611,11 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { | ... | @@ -607,11 +611,11 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 607 | 611 | ||
| 608 | switch (entry_size) { | 612 | switch (entry_size) { |
| 609 | 4 => { | 613 | 4 => { |
| 610 | std.mem.writeInt(u32, buf[0..4], @intCast(u32, va.*), endian); | 614 | mem.writeInt(u32, buf[0..4], @intCast(u32, va.*), endian); |
| 611 | try self.base.file.?.pwriteAll(buf[0..4], offset_table_start + idx * entry_size); | 615 | try self.base.file.?.pwriteAll(buf[0..4], offset_table_start + idx * entry_size); |
| 612 | }, | 616 | }, |
| 613 | 8 => { | 617 | 8 => { |
| 614 | std.mem.writeInt(u64, &buf, va.*, endian); | 618 | mem.writeInt(u64, &buf, va.*, endian); |
| 615 | try self.base.file.?.pwriteAll(&buf, offset_table_start + idx * entry_size); | 619 | try self.base.file.?.pwriteAll(&buf, offset_table_start + idx * entry_size); |
| 616 | }, | 620 | }, |
| 617 | else => unreachable, | 621 | else => unreachable, |
| ... | @@ -626,12 +630,12 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { | ... | @@ -626,12 +630,12 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 626 | switch (entry_size) { | 630 | switch (entry_size) { |
| 627 | 4 => { | 631 | 4 => { |
| 628 | var buf: [4]u8 = undefined; | 632 | var buf: [4]u8 = undefined; |
| 629 | std.mem.writeInt(u32, &buf, @intCast(u32, self.offset_table.items[index]), endian); | 633 | mem.writeInt(u32, &buf, @intCast(u32, self.offset_table.items[index]), endian); |
| 630 | try self.base.file.?.pwriteAll(&buf, offset_table_start + index * entry_size); | 634 | try self.base.file.?.pwriteAll(&buf, offset_table_start + index * entry_size); |
| 631 | }, | 635 | }, |
| 632 | 8 => { | 636 | 8 => { |
| 633 | var buf: [8]u8 = undefined; | 637 | var buf: [8]u8 = undefined; |
| 634 | std.mem.writeInt(u64, &buf, self.offset_table.items[index], endian); | 638 | mem.writeInt(u64, &buf, self.offset_table.items[index], endian); |
| 635 | try self.base.file.?.pwriteAll(&buf, offset_table_start + index * entry_size); | 639 | try self.base.file.?.pwriteAll(&buf, offset_table_start + index * entry_size); |
| 636 | }, | 640 | }, |
| 637 | else => unreachable, | 641 | else => unreachable, |
| ... | @@ -664,7 +668,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void { | ... | @@ -664,7 +668,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void { |
| 664 | if (curr_size != 0) { | 668 | if (curr_size != 0) { |
| 665 | const capacity = decl.link.coff.capacity(); | 669 | const capacity = decl.link.coff.capacity(); |
| 666 | const need_realloc = code.len > capacity or | 670 | const need_realloc = code.len > capacity or |
| 667 | !std.mem.isAlignedGeneric(u32, decl.link.coff.text_offset, required_alignment); | 671 | !mem.isAlignedGeneric(u32, decl.link.coff.text_offset, required_alignment); |
| 668 | if (need_realloc) { | 672 | if (need_realloc) { |
| 669 | const curr_vaddr = self.getDeclVAddr(decl); | 673 | const curr_vaddr = self.getDeclVAddr(decl); |
| 670 | const vaddr = try self.growTextBlock(&decl.link.coff, code.len, required_alignment); | 674 | const vaddr = try self.growTextBlock(&decl.link.coff, code.len, required_alignment); |
| ... | @@ -679,7 +683,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void { | ... | @@ -679,7 +683,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void { |
| 679 | } | 683 | } |
| 680 | } else { | 684 | } else { |
| 681 | const vaddr = try self.allocateTextBlock(&decl.link.coff, code.len, required_alignment); | 685 | const vaddr = try self.allocateTextBlock(&decl.link.coff, code.len, required_alignment); |
| 682 | log.debug("allocated text block for {} at 0x{x} (size: {Bi})\n", .{ std.mem.spanZ(decl.name), vaddr, code.len }); | 686 | log.debug("allocated text block for {} at 0x{x} (size: {Bi})\n", .{ mem.spanZ(decl.name), vaddr, code.len }); |
| 683 | errdefer self.freeTextBlock(&decl.link.coff); | 687 | errdefer self.freeTextBlock(&decl.link.coff); |
| 684 | self.offset_table.items[decl.link.coff.offset_table_index] = vaddr; | 688 | self.offset_table.items[decl.link.coff.offset_table_index] = vaddr; |
| 685 | try self.writeOffsetTableEntry(decl.link.coff.offset_table_index); | 689 | try self.writeOffsetTableEntry(decl.link.coff.offset_table_index); |
| ... | @@ -702,7 +706,7 @@ pub fn freeDecl(self: *Coff, decl: *Module.Decl) void { | ... | @@ -702,7 +706,7 @@ pub fn freeDecl(self: *Coff, decl: *Module.Decl) void { |
| 702 | pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, exports: []const *Module.Export) !void { | 706 | pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, exports: []const *Module.Export) !void { |
| 703 | for (exports) |exp| { | 707 | for (exports) |exp| { |
| 704 | if (exp.options.section) |section_name| { | 708 | if (exp.options.section) |section_name| { |
| 705 | if (!std.mem.eql(u8, section_name, ".text")) { | 709 | if (!mem.eql(u8, section_name, ".text")) { |
| 706 | try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); | 710 | try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); |
| 707 | module.failed_exports.putAssumeCapacityNoClobber( | 711 | module.failed_exports.putAssumeCapacityNoClobber( |
| 708 | exp, | 712 | exp, |
| ... | @@ -711,7 +715,7 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, | ... | @@ -711,7 +715,7 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, |
| 711 | continue; | 715 | continue; |
| 712 | } | 716 | } |
| 713 | } | 717 | } |
| 714 | if (std.mem.eql(u8, exp.options.name, "_start")) { | 718 | if (mem.eql(u8, exp.options.name, "_start")) { |
| 715 | self.entry_addr = decl.link.coff.getVAddr(self.*) - image_base; | 719 | self.entry_addr = decl.link.coff.getVAddr(self.*) - image_base; |
| 716 | } else { | 720 | } else { |
| 717 | try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); | 721 | try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); |
| ... | @@ -726,8 +730,12 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, | ... | @@ -726,8 +730,12 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, |
| 726 | 730 | ||
| 727 | pub fn flush(self: *Coff, comp: *Compilation) !void { | 731 | pub fn flush(self: *Coff, comp: *Compilation) !void { |
| 728 | if (build_options.have_llvm and self.base.options.use_lld) { | 732 | if (build_options.have_llvm and self.base.options.use_lld) { |
| 729 | return error.CoffLinkingWithLLDUnimplemented; | 733 | return self.linkWithLLD(comp); |
| 730 | } else { | 734 | } else { |
| 735 | switch (self.base.options.effectiveOutputMode()) { | ||
| 736 | .Exe, .Obj => {}, | ||
| 737 | .Lib => return error.TODOImplementWritingLibFiles, | ||
| 738 | } | ||
| 731 | return self.flushModule(comp); | 739 | return self.flushModule(comp); |
| 732 | } | 740 | } |
| 733 | } | 741 | } |
| ... | @@ -739,16 +747,16 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void { | ... | @@ -739,16 +747,16 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void { |
| 739 | if (self.text_section_size_dirty) { | 747 | if (self.text_section_size_dirty) { |
| 740 | // Write the new raw size in the .text header | 748 | // Write the new raw size in the .text header |
| 741 | var buf: [4]u8 = undefined; | 749 | var buf: [4]u8 = undefined; |
| 742 | std.mem.writeIntLittle(u32, &buf, self.text_section_size); | 750 | mem.writeIntLittle(u32, &buf, self.text_section_size); |
| 743 | try self.base.file.?.pwriteAll(&buf, self.section_table_offset + 40 + 16); | 751 | try self.base.file.?.pwriteAll(&buf, self.section_table_offset + 40 + 16); |
| 744 | try self.base.file.?.setEndPos(self.section_data_offset + self.offset_table_size + self.text_section_size); | 752 | try self.base.file.?.setEndPos(self.section_data_offset + self.offset_table_size + self.text_section_size); |
| 745 | self.text_section_size_dirty = false; | 753 | self.text_section_size_dirty = false; |
| 746 | } | 754 | } |
| 747 | 755 | ||
| 748 | if (self.base.options.output_mode == .Exe and self.size_of_image_dirty) { | 756 | if (self.base.options.output_mode == .Exe and self.size_of_image_dirty) { |
| 749 | const new_size_of_image = std.mem.alignForwardGeneric(u32, self.text_section_virtual_address - image_base + self.text_section_size, section_alignment); | 757 | const new_size_of_image = mem.alignForwardGeneric(u32, self.text_section_virtual_address - image_base + self.text_section_size, section_alignment); |
| 750 | var buf: [4]u8 = undefined; | 758 | var buf: [4]u8 = undefined; |
| 751 | std.mem.writeIntLittle(u32, &buf, new_size_of_image); | 759 | mem.writeIntLittle(u32, &buf, new_size_of_image); |
| 752 | try self.base.file.?.pwriteAll(&buf, self.optional_header_offset + 56); | 760 | try self.base.file.?.pwriteAll(&buf, self.optional_header_offset + 56); |
| 753 | self.size_of_image_dirty = false; | 761 | self.size_of_image_dirty = false; |
| 754 | } | 762 | } |
| ... | @@ -763,12 +771,422 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void { | ... | @@ -763,12 +771,422 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void { |
| 763 | if (self.base.options.output_mode == .Exe) { | 771 | if (self.base.options.output_mode == .Exe) { |
| 764 | // Write AddressOfEntryPoint | 772 | // Write AddressOfEntryPoint |
| 765 | var buf: [4]u8 = undefined; | 773 | var buf: [4]u8 = undefined; |
| 766 | std.mem.writeIntLittle(u32, &buf, self.entry_addr.?); | 774 | mem.writeIntLittle(u32, &buf, self.entry_addr.?); |
| 767 | try self.base.file.?.pwriteAll(&buf, self.optional_header_offset + 16); | 775 | try self.base.file.?.pwriteAll(&buf, self.optional_header_offset + 16); |
| 768 | } | 776 | } |
| 769 | } | 777 | } |
| 770 | } | 778 | } |
| 771 | 779 | ||
| 780 | fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ||
| 781 | const tracy = trace(@src()); | ||
| 782 | defer tracy.end(); | ||
| 783 | |||
| 784 | var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); | ||
| 785 | defer arena_allocator.deinit(); | ||
| 786 | const arena = &arena_allocator.allocator; | ||
| 787 | |||
| 788 | const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type. | ||
| 789 | |||
| 790 | // If there is no Zig code to compile, then we should skip flushing the output file because it | ||
| 791 | // will not be part of the linker line anyway. | ||
| 792 | const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { | ||
| 793 | const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm; | ||
| 794 | if (use_stage1) { | ||
| 795 | const obj_basename = try std.zig.binNameAlloc(arena, .{ | ||
| 796 | .root_name = self.base.options.root_name, | ||
| 797 | .target = self.base.options.target, | ||
| 798 | .output_mode = .Obj, | ||
| 799 | }); | ||
| 800 | const o_directory = self.base.options.module.?.zig_cache_artifact_directory; | ||
| 801 | const full_obj_path = try o_directory.join(arena, &[_][]const u8{obj_basename}); | ||
| 802 | break :blk full_obj_path; | ||
| 803 | } | ||
| 804 | |||
| 805 | try self.flushModule(comp); | ||
| 806 | const obj_basename = self.base.intermediary_basename.?; | ||
| 807 | const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename}); | ||
| 808 | break :blk full_obj_path; | ||
| 809 | } else null; | ||
| 810 | |||
| 811 | const is_lib = self.base.options.output_mode == .Lib; | ||
| 812 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; | ||
| 813 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe; | ||
| 814 | const link_in_crt = self.base.options.link_libc and self.base.options.output_mode == .Exe; | ||
| 815 | const target = self.base.options.target; | ||
| 816 | |||
| 817 | // See link/Elf.zig for comments on how this mechanism works. | ||
| 818 | const id_symlink_basename = "lld.id"; | ||
| 819 | |||
| 820 | var man: Cache.Manifest = undefined; | ||
| 821 | defer if (!self.base.options.disable_lld_caching) man.deinit(); | ||
| 822 | |||
| 823 | var digest: [Cache.hex_digest_len]u8 = undefined; | ||
| 824 | |||
| 825 | if (!self.base.options.disable_lld_caching) { | ||
| 826 | man = comp.cache_parent.obtain(); | ||
| 827 | self.base.releaseLock(); | ||
| 828 | |||
| 829 | try man.addListOfFiles(self.base.options.objects); | ||
| 830 | for (comp.c_object_table.items()) |entry| { | ||
| 831 | _ = try man.addFile(entry.key.status.success.object_path, null); | ||
| 832 | } | ||
| 833 | try man.addOptionalFile(module_obj_path); | ||
| 834 | man.hash.addOptional(self.base.options.stack_size_override); | ||
| 835 | man.hash.addListOfBytes(self.base.options.extra_lld_args); | ||
| 836 | man.hash.addListOfBytes(self.base.options.lib_dirs); | ||
| 837 | man.hash.add(self.base.options.is_compiler_rt_or_libc); | ||
| 838 | if (self.base.options.link_libc) { | ||
| 839 | man.hash.add(self.base.options.libc_installation != null); | ||
| 840 | if (self.base.options.libc_installation) |libc_installation| { | ||
| 841 | man.hash.addBytes(libc_installation.crt_dir.?); | ||
| 842 | if (target.abi == .msvc) { | ||
| 843 | man.hash.addBytes(libc_installation.msvc_lib_dir.?); | ||
| 844 | man.hash.addBytes(libc_installation.kernel32_lib_dir.?); | ||
| 845 | } | ||
| 846 | } | ||
| 847 | } | ||
| 848 | man.hash.addStringSet(self.base.options.system_libs); | ||
| 849 | man.hash.addOptional(self.base.options.subsystem); | ||
| 850 | man.hash.add(self.base.options.is_test); | ||
| 851 | |||
| 852 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. | ||
| 853 | _ = try man.hit(); | ||
| 854 | digest = man.final(); | ||
| 855 | var prev_digest_buf: [digest.len]u8 = undefined; | ||
| 856 | const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| blk: { | ||
| 857 | log.debug("COFF LLD new_digest={} readlink error: {}", .{ digest, @errorName(err) }); | ||
| 858 | // Handle this as a cache miss. | ||
| 859 | break :blk prev_digest_buf[0..0]; | ||
| 860 | }; | ||
| 861 | if (mem.eql(u8, prev_digest, &digest)) { | ||
| 862 | log.debug("COFF LLD digest={} match - skipping invocation", .{digest}); | ||
| 863 | // Hot diggity dog! The output binary is already there. | ||
| 864 | self.base.lock = man.toOwnedLock(); | ||
| 865 | return; | ||
| 866 | } | ||
| 867 | log.debug("COFF LLD prev_digest={} new_digest={}", .{ prev_digest, digest }); | ||
| 868 | |||
| 869 | // We are about to change the output file to be different, so we invalidate the build hash now. | ||
| 870 | directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) { | ||
| 871 | error.FileNotFound => {}, | ||
| 872 | else => |e| return e, | ||
| 873 | }; | ||
| 874 | } | ||
| 875 | |||
| 876 | const is_obj = self.base.options.output_mode == .Obj; | ||
| 877 | |||
| 878 | // Create an LLD command line and invoke it. | ||
| 879 | var argv = std.ArrayList([]const u8).init(self.base.allocator); | ||
| 880 | defer argv.deinit(); | ||
| 881 | // Even though we're calling LLD as a library it thinks the first argument is its own exe name. | ||
| 882 | try argv.append("lld"); | ||
| 883 | if (is_obj) { | ||
| 884 | try argv.append("-r"); | ||
| 885 | } | ||
| 886 | |||
| 887 | try argv.append("-ERRORLIMIT:0"); | ||
| 888 | try argv.append("-NOLOGO"); | ||
| 889 | if (!self.base.options.strip) { | ||
| 890 | try argv.append("-DEBUG"); | ||
| 891 | } | ||
| 892 | if (self.base.options.output_mode == .Exe) { | ||
| 893 | const stack_size = self.base.options.stack_size_override orelse 16777216; | ||
| 894 | try argv.append(try allocPrint(arena, "-STACK:{d}", .{stack_size})); | ||
| 895 | } | ||
| 896 | |||
| 897 | if (target.cpu.arch == .i386) { | ||
| 898 | try argv.append("-MACHINE:X86"); | ||
| 899 | } else if (target.cpu.arch == .x86_64) { | ||
| 900 | try argv.append("-MACHINE:X64"); | ||
| 901 | } else if (target.cpu.arch.isARM()) { | ||
| 902 | if (target.cpu.arch.ptrBitWidth() == 32) { | ||
| 903 | try argv.append("-MACHINE:ARM"); | ||
| 904 | } else { | ||
| 905 | try argv.append("-MACHINE:ARM64"); | ||
| 906 | } | ||
| 907 | } | ||
| 908 | |||
| 909 | if (is_dyn_lib) { | ||
| 910 | try argv.append("-DLL"); | ||
| 911 | } | ||
| 912 | |||
| 913 | const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path}); | ||
| 914 | try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); | ||
| 915 | |||
| 916 | if (self.base.options.link_libc) { | ||
| 917 | if (self.base.options.libc_installation) |libc_installation| { | ||
| 918 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?})); | ||
| 919 | |||
| 920 | if (target.abi == .msvc) { | ||
| 921 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.msvc_lib_dir.?})); | ||
| 922 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.kernel32_lib_dir.?})); | ||
| 923 | } | ||
| 924 | } | ||
| 925 | } | ||
| 926 | |||
| 927 | for (self.base.options.lib_dirs) |lib_dir| { | ||
| 928 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); | ||
| 929 | } | ||
| 930 | |||
| 931 | try argv.appendSlice(self.base.options.objects); | ||
| 932 | |||
| 933 | for (comp.c_object_table.items()) |entry| { | ||
| 934 | try argv.append(entry.key.status.success.object_path); | ||
| 935 | } | ||
| 936 | |||
| 937 | if (module_obj_path) |p| { | ||
| 938 | try argv.append(p); | ||
| 939 | } | ||
| 940 | |||
| 941 | const resolved_subsystem: ?std.Target.SubSystem = blk: { | ||
| 942 | if (self.base.options.subsystem) |explicit| break :blk explicit; | ||
| 943 | switch (target.os.tag) { | ||
| 944 | .windows => { | ||
| 945 | if (self.base.options.module) |module| { | ||
| 946 | if (module.have_dllmain_crt_startup or is_dyn_lib) | ||
| 947 | break :blk null; | ||
| 948 | if (module.have_c_main or self.base.options.is_test or | ||
| 949 | module.have_winmain_crt_startup or module.have_wwinmain_crt_startup) | ||
| 950 | { | ||
| 951 | break :blk .Console; | ||
| 952 | } | ||
| 953 | if (module.have_winmain or module.have_wwinmain) | ||
| 954 | break :blk .Windows; | ||
| 955 | } | ||
| 956 | }, | ||
| 957 | .uefi => break :blk .EfiApplication, | ||
| 958 | else => {}, | ||
| 959 | } | ||
| 960 | break :blk null; | ||
| 961 | }; | ||
| 962 | const Mode = enum { uefi, win32 }; | ||
| 963 | const mode: Mode = mode: { | ||
| 964 | if (resolved_subsystem) |subsystem| switch (subsystem) { | ||
| 965 | .Console => { | ||
| 966 | try argv.append("-SUBSYSTEM:console"); | ||
| 967 | break :mode .win32; | ||
| 968 | }, | ||
| 969 | .EfiApplication => { | ||
| 970 | try argv.append("-SUBSYSTEM:efi_application"); | ||
| 971 | break :mode .uefi; | ||
| 972 | }, | ||
| 973 | .EfiBootServiceDriver => { | ||
| 974 | try argv.append("-SUBSYSTEM:efi_boot_service_driver"); | ||
| 975 | break :mode .uefi; | ||
| 976 | }, | ||
| 977 | .EfiRom => { | ||
| 978 | try argv.append("-SUBSYSTEM:efi_rom"); | ||
| 979 | break :mode .uefi; | ||
| 980 | }, | ||
| 981 | .EfiRuntimeDriver => { | ||
| 982 | try argv.append("-SUBSYSTEM:efi_runtime_driver"); | ||
| 983 | break :mode .uefi; | ||
| 984 | }, | ||
| 985 | .Native => { | ||
| 986 | try argv.append("-SUBSYSTEM:native"); | ||
| 987 | break :mode .win32; | ||
| 988 | }, | ||
| 989 | .Posix => { | ||
| 990 | try argv.append("-SUBSYSTEM:posix"); | ||
| 991 | break :mode .win32; | ||
| 992 | }, | ||
| 993 | .Windows => { | ||
| 994 | try argv.append("-SUBSYSTEM:windows"); | ||
| 995 | break :mode .win32; | ||
| 996 | }, | ||
| 997 | } else if (target.os.tag == .uefi) { | ||
| 998 | break :mode .uefi; | ||
| 999 | } else { | ||
| 1000 | break :mode .win32; | ||
| 1001 | } | ||
| 1002 | }; | ||
| 1003 | |||
| 1004 | switch (mode) { | ||
| 1005 | .uefi => try argv.appendSlice(&[_][]const u8{ | ||
| 1006 | "-BASE:0", | ||
| 1007 | "-ENTRY:EfiMain", | ||
| 1008 | "-OPT:REF", | ||
| 1009 | "-SAFESEH:NO", | ||
| 1010 | "-MERGE:.rdata=.data", | ||
| 1011 | "-ALIGN:32", | ||
| 1012 | "-NODEFAULTLIB", | ||
| 1013 | "-SECTION:.xdata,D", | ||
| 1014 | }), | ||
| 1015 | .win32 => { | ||
| 1016 | if (link_in_crt) { | ||
| 1017 | if (target.abi.isGnu()) { | ||
| 1018 | try argv.append("-lldmingw"); | ||
| 1019 | |||
| 1020 | if (target.cpu.arch == .i386) { | ||
| 1021 | try argv.append("-ALTERNATENAME:__image_base__=___ImageBase"); | ||
| 1022 | } else { | ||
| 1023 | try argv.append("-ALTERNATENAME:__image_base__=__ImageBase"); | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | if (is_dyn_lib) { | ||
| 1027 | try argv.append(try comp.get_libc_crt_file(arena, "dllcrt2.o")); | ||
| 1028 | } else { | ||
| 1029 | try argv.append(try comp.get_libc_crt_file(arena, "crt2.o")); | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | try argv.append(try comp.get_libc_crt_file(arena, "mingw32.lib")); | ||
| 1033 | try argv.append(try comp.get_libc_crt_file(arena, "mingwex.lib")); | ||
| 1034 | try argv.append(try comp.get_libc_crt_file(arena, "msvcrt-os.lib")); | ||
| 1035 | |||
| 1036 | for (mingw.always_link_libs) |name| { | ||
| 1037 | if (!self.base.options.system_libs.contains(name)) { | ||
| 1038 | const lib_basename = try allocPrint(arena, "{s}.lib", .{name}); | ||
| 1039 | try argv.append(try comp.get_libc_crt_file(arena, lib_basename)); | ||
| 1040 | } | ||
| 1041 | } | ||
| 1042 | } else { | ||
| 1043 | const lib_str = switch (self.base.options.link_mode) { | ||
| 1044 | .Dynamic => "", | ||
| 1045 | .Static => "lib", | ||
| 1046 | }; | ||
| 1047 | const d_str = switch (self.base.options.optimize_mode) { | ||
| 1048 | .Debug => "d", | ||
| 1049 | else => "", | ||
| 1050 | }; | ||
| 1051 | switch (self.base.options.link_mode) { | ||
| 1052 | .Static => try argv.append(try allocPrint(arena, "libcmt{s}.lib", .{d_str})), | ||
| 1053 | .Dynamic => try argv.append(try allocPrint(arena, "msvcrt{s}.lib", .{d_str})), | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | try argv.append(try allocPrint(arena, "{s}vcruntime{s}.lib", .{ lib_str, d_str })); | ||
| 1057 | try argv.append(try allocPrint(arena, "{s}ucrt{s}.lib", .{ lib_str, d_str })); | ||
| 1058 | |||
| 1059 | //Visual C++ 2015 Conformance Changes | ||
| 1060 | //https://msdn.microsoft.com/en-us/library/bb531344.aspx | ||
| 1061 | try argv.append("legacy_stdio_definitions.lib"); | ||
| 1062 | |||
| 1063 | // msvcrt depends on kernel32 and ntdll | ||
| 1064 | try argv.append("kernel32.lib"); | ||
| 1065 | try argv.append("ntdll.lib"); | ||
| 1066 | } | ||
| 1067 | } else { | ||
| 1068 | try argv.append("-NODEFAULTLIB"); | ||
| 1069 | if (!is_lib) { | ||
| 1070 | if (self.base.options.module) |module| { | ||
| 1071 | if (module.have_winmain) { | ||
| 1072 | try argv.append("-ENTRY:WinMain"); | ||
| 1073 | } else if (module.have_wwinmain) { | ||
| 1074 | try argv.append("-ENTRY:wWinMain"); | ||
| 1075 | } else if (module.have_wwinmain_crt_startup) { | ||
| 1076 | try argv.append("-ENTRY:wWinMainCRTStartup"); | ||
| 1077 | } else { | ||
| 1078 | try argv.append("-ENTRY:WinMainCRTStartup"); | ||
| 1079 | } | ||
| 1080 | } else { | ||
| 1081 | try argv.append("-ENTRY:WinMainCRTStartup"); | ||
| 1082 | } | ||
| 1083 | } | ||
| 1084 | } | ||
| 1085 | }, | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | if (!is_obj) { | ||
| 1089 | // libc++ dep | ||
| 1090 | if (self.base.options.link_libcpp) { | ||
| 1091 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); | ||
| 1092 | try argv.append(comp.libcxx_static_lib.?.full_object_path); | ||
| 1093 | try argv.append(comp.libunwind_static_lib.?.full_object_path); | ||
| 1094 | } | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | // compiler-rt and libc | ||
| 1098 | if (is_exe_or_dyn_lib and !self.base.options.is_compiler_rt_or_libc) { | ||
| 1099 | if (!self.base.options.link_libc) { | ||
| 1100 | try argv.append(comp.libc_static_lib.?.full_object_path); | ||
| 1101 | } | ||
| 1102 | // MSVC compiler_rt is missing some stuff, so we build it unconditionally but | ||
| 1103 | // and rely on weak linkage to allow MSVC compiler_rt functions to override ours. | ||
| 1104 | try argv.append(comp.compiler_rt_static_lib.?.full_object_path); | ||
| 1105 | } | ||
| 1106 | |||
| 1107 | for (self.base.options.system_libs.items()) |entry| { | ||
| 1108 | const lib_basename = try allocPrint(arena, "{s}.lib", .{entry.key}); | ||
| 1109 | if (comp.crt_files.get(lib_basename)) |crt_file| { | ||
| 1110 | try argv.append(crt_file.full_object_path); | ||
| 1111 | } else { | ||
| 1112 | try argv.append(lib_basename); | ||
| 1113 | } | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | if (self.base.options.verbose_link) { | ||
| 1117 | Compilation.dump_argv(argv.items); | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1); | ||
| 1121 | new_argv_with_sentinel[argv.items.len] = null; | ||
| 1122 | const new_argv = new_argv_with_sentinel[0..argv.items.len :null]; | ||
| 1123 | for (argv.items) |arg, i| { | ||
| 1124 | new_argv[i] = try arena.dupeZ(u8, arg); | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | var stderr_context: LLDContext = .{ | ||
| 1128 | .coff = self, | ||
| 1129 | .data = std.ArrayList(u8).init(self.base.allocator), | ||
| 1130 | }; | ||
| 1131 | defer stderr_context.data.deinit(); | ||
| 1132 | var stdout_context: LLDContext = .{ | ||
| 1133 | .coff = self, | ||
| 1134 | .data = std.ArrayList(u8).init(self.base.allocator), | ||
| 1135 | }; | ||
| 1136 | defer stdout_context.data.deinit(); | ||
| 1137 | const llvm = @import("../llvm.zig"); | ||
| 1138 | const ok = llvm.Link( | ||
| 1139 | .COFF, | ||
| 1140 | new_argv.ptr, | ||
| 1141 | new_argv.len, | ||
| 1142 | append_diagnostic, | ||
| 1143 | @ptrToInt(&stdout_context), | ||
| 1144 | @ptrToInt(&stderr_context), | ||
| 1145 | ); | ||
| 1146 | if (stderr_context.oom or stdout_context.oom) return error.OutOfMemory; | ||
| 1147 | if (stdout_context.data.items.len != 0) { | ||
| 1148 | std.log.warn("unexpected LLD stdout: {}", .{stdout_context.data.items}); | ||
| 1149 | } | ||
| 1150 | if (!ok) { | ||
| 1151 | // TODO parse this output and surface with the Compilation API rather than | ||
| 1152 | // directly outputting to stderr here. | ||
| 1153 | std.debug.print("{}", .{stderr_context.data.items}); | ||
| 1154 | return error.LLDReportedFailure; | ||
| 1155 | } | ||
| 1156 | if (stderr_context.data.items.len != 0) { | ||
| 1157 | std.log.warn("unexpected LLD stderr: {}", .{stderr_context.data.items}); | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | if (!self.base.options.disable_lld_caching) { | ||
| 1161 | // Update the dangling symlink with the digest. If it fails we can continue; it only | ||
| 1162 | // means that the next invocation will have an unnecessary cache miss. | ||
| 1163 | directory.handle.symLink(&digest, id_symlink_basename, .{}) catch |err| { | ||
| 1164 | std.log.warn("failed to save linking hash digest symlink: {}", .{@errorName(err)}); | ||
| 1165 | }; | ||
| 1166 | // Again failure here only means an unnecessary cache miss. | ||
| 1167 | man.writeManifest() catch |err| { | ||
| 1168 | std.log.warn("failed to write cache manifest when linking: {}", .{@errorName(err)}); | ||
| 1169 | }; | ||
| 1170 | // We hang on to this lock so that the output file path can be used without | ||
| 1171 | // other processes clobbering it. | ||
| 1172 | self.base.lock = man.toOwnedLock(); | ||
| 1173 | } | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | const LLDContext = struct { | ||
| 1177 | data: std.ArrayList(u8), | ||
| 1178 | coff: *Coff, | ||
| 1179 | oom: bool = false, | ||
| 1180 | }; | ||
| 1181 | |||
| 1182 | fn append_diagnostic(context: usize, ptr: [*]const u8, len: usize) callconv(.C) void { | ||
| 1183 | const lld_context = @intToPtr(*LLDContext, context); | ||
| 1184 | const msg = ptr[0..len]; | ||
| 1185 | lld_context.data.appendSlice(msg) catch |err| switch (err) { | ||
| 1186 | error.OutOfMemory => lld_context.oom = true, | ||
| 1187 | }; | ||
| 1188 | } | ||
| 1189 | |||
| 772 | pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl) u64 { | 1190 | pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl) u64 { |
| 773 | return self.text_section_virtual_address + decl.link.coff.text_offset; | 1191 | return self.text_section_virtual_address + decl.link.coff.text_offset; |
| 774 | } | 1192 | } |
src/link/Elf.zig+14-11| ... | @@ -1225,7 +1225,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1225,7 +1225,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1225 | const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { | 1225 | const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { |
| 1226 | const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm; | 1226 | const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm; |
| 1227 | if (use_stage1) { | 1227 | if (use_stage1) { |
| 1228 | const obj_basename = try std.fmt.allocPrint(arena, "{}.o", .{self.base.options.root_name}); | 1228 | const obj_basename = try std.zig.binNameAlloc(arena, .{ |
| 1229 | .root_name = self.base.options.root_name, | ||
| 1230 | .target = self.base.options.target, | ||
| 1231 | .output_mode = .Obj, | ||
| 1232 | }); | ||
| 1229 | const o_directory = self.base.options.module.?.zig_cache_artifact_directory; | 1233 | const o_directory = self.base.options.module.?.zig_cache_artifact_directory; |
| 1230 | const full_obj_path = try o_directory.join(arena, &[_][]const u8{obj_basename}); | 1234 | const full_obj_path = try o_directory.join(arena, &[_][]const u8{obj_basename}); |
| 1231 | break :blk full_obj_path; | 1235 | break :blk full_obj_path; |
| ... | @@ -1242,6 +1246,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1242,6 +1246,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1242 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe; | 1246 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe; |
| 1243 | const have_dynamic_linker = self.base.options.link_libc and | 1247 | const have_dynamic_linker = self.base.options.link_libc and |
| 1244 | self.base.options.link_mode == .Dynamic and is_exe_or_dyn_lib; | 1248 | self.base.options.link_mode == .Dynamic and is_exe_or_dyn_lib; |
| 1249 | const link_in_crt = self.base.options.link_libc and self.base.options.output_mode == .Exe; | ||
| 1250 | const target = self.base.options.target; | ||
| 1245 | 1251 | ||
| 1246 | // Here we want to determine whether we can save time by not invoking LLD when the | 1252 | // Here we want to determine whether we can save time by not invoking LLD when the |
| 1247 | // output is unchanged. None of the linker options or the object files that are being | 1253 | // output is unchanged. None of the linker options or the object files that are being |
| ... | @@ -1297,7 +1303,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1297,7 +1303,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1297 | man.hash.addOptionalBytes(self.base.options.override_soname); | 1303 | man.hash.addOptionalBytes(self.base.options.override_soname); |
| 1298 | man.hash.addOptional(self.base.options.version); | 1304 | man.hash.addOptional(self.base.options.version); |
| 1299 | } | 1305 | } |
| 1300 | man.hash.addListOfBytes(self.base.options.system_libs); | 1306 | man.hash.addStringSet(self.base.options.system_libs); |
| 1301 | man.hash.addOptional(self.base.options.allow_shlib_undefined); | 1307 | man.hash.addOptional(self.base.options.allow_shlib_undefined); |
| 1302 | man.hash.add(self.base.options.bind_global_refs_locally); | 1308 | man.hash.add(self.base.options.bind_global_refs_locally); |
| 1303 | 1309 | ||
| ... | @@ -1326,7 +1332,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1326,7 +1332,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1326 | }; | 1332 | }; |
| 1327 | } | 1333 | } |
| 1328 | 1334 | ||
| 1329 | const target = self.base.options.target; | ||
| 1330 | const is_obj = self.base.options.output_mode == .Obj; | 1335 | const is_obj = self.base.options.output_mode == .Obj; |
| 1331 | 1336 | ||
| 1332 | // Create an LLD command line and invoke it. | 1337 | // Create an LLD command line and invoke it. |
| ... | @@ -1337,7 +1342,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1337,7 +1342,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1337 | if (is_obj) { | 1342 | if (is_obj) { |
| 1338 | try argv.append("-r"); | 1343 | try argv.append("-r"); |
| 1339 | } | 1344 | } |
| 1340 | const link_in_crt = self.base.options.link_libc and self.base.options.output_mode == .Exe; | ||
| 1341 | 1345 | ||
| 1342 | try argv.append("-error-limit=0"); | 1346 | try argv.append("-error-limit=0"); |
| 1343 | 1347 | ||
| ... | @@ -1440,7 +1444,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1440,7 +1444,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1440 | var test_path = std.ArrayList(u8).init(self.base.allocator); | 1444 | var test_path = std.ArrayList(u8).init(self.base.allocator); |
| 1441 | defer test_path.deinit(); | 1445 | defer test_path.deinit(); |
| 1442 | for (self.base.options.lib_dirs) |lib_dir_path| { | 1446 | for (self.base.options.lib_dirs) |lib_dir_path| { |
| 1443 | for (self.base.options.system_libs) |link_lib| { | 1447 | for (self.base.options.system_libs.items()) |link_lib| { |
| 1444 | test_path.shrinkRetainingCapacity(0); | 1448 | test_path.shrinkRetainingCapacity(0); |
| 1445 | const sep = fs.path.sep_str; | 1449 | const sep = fs.path.sep_str; |
| 1446 | try test_path.writer().print("{}" ++ sep ++ "lib{}.so", .{ lib_dir_path, link_lib }); | 1450 | try test_path.writer().print("{}" ++ sep ++ "lib{}.so", .{ lib_dir_path, link_lib }); |
| ... | @@ -1509,8 +1513,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1509,8 +1513,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1509 | } | 1513 | } |
| 1510 | 1514 | ||
| 1511 | // Shared libraries. | 1515 | // Shared libraries. |
| 1512 | try argv.ensureCapacity(argv.items.len + self.base.options.system_libs.len); | 1516 | const system_libs = self.base.options.system_libs.items(); |
| 1513 | for (self.base.options.system_libs) |link_lib| { | 1517 | try argv.ensureCapacity(argv.items.len + system_libs.len); |
| 1518 | for (system_libs) |entry| { | ||
| 1519 | const link_lib = entry.key; | ||
| 1514 | // By this time, we depend on these libs being dynamically linked libraries and not static libraries | 1520 | // By this time, we depend on these libs being dynamically linked libraries and not static libraries |
| 1515 | // (the check for that needs to be earlier), but they could be full paths to .so files, in which | 1521 | // (the check for that needs to be earlier), but they could be full paths to .so files, in which |
| 1516 | // case we want to avoid prepending "-l". | 1522 | // case we want to avoid prepending "-l". |
| ... | @@ -1581,10 +1587,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1581,10 +1587,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1581 | } | 1587 | } |
| 1582 | 1588 | ||
| 1583 | if (self.base.options.verbose_link) { | 1589 | if (self.base.options.verbose_link) { |
| 1584 | for (argv.items[0 .. argv.items.len - 1]) |arg| { | 1590 | Compilation.dump_argv(argv.items); |
| 1585 | std.debug.print("{} ", .{arg}); | ||
| 1586 | } | ||
| 1587 | std.debug.print("{}\n", .{argv.items[argv.items.len - 1]}); | ||
| 1588 | } | 1591 | } |
| 1589 | 1592 | ||
| 1590 | // Oh, snapplesauce! We need null terminated argv. | 1593 | // Oh, snapplesauce! We need null terminated argv. |
src/mingw.zig created+866| ... | @@ -0,0 +1,866 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Allocator = std.mem.Allocator; | ||
| 3 | const mem = std.mem; | ||
| 4 | const path = std.fs.path; | ||
| 5 | const assert = std.debug.assert; | ||
| 6 | |||
| 7 | const target_util = @import("target.zig"); | ||
| 8 | const Compilation = @import("Compilation.zig"); | ||
| 9 | const build_options = @import("build_options"); | ||
| 10 | |||
| 11 | pub const CRTFile = enum { | ||
| 12 | crt2_o, | ||
| 13 | dllcrt2_o, | ||
| 14 | mingw32_lib, | ||
| 15 | msvcrt_os_lib, | ||
| 16 | mingwex_lib, | ||
| 17 | uuid_lib, | ||
| 18 | }; | ||
| 19 | |||
| 20 | pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { | ||
| 21 | if (!build_options.have_llvm) { | ||
| 22 | return error.ZigCompilerNotBuiltWithLLVMExtensions; | ||
| 23 | } | ||
| 24 | var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); | ||
| 25 | defer arena_allocator.deinit(); | ||
| 26 | const arena = &arena_allocator.allocator; | ||
| 27 | |||
| 28 | switch (crt_file) { | ||
| 29 | .crt2_o => { | ||
| 30 | var args = std.ArrayList([]const u8).init(arena); | ||
| 31 | try add_cc_args(comp, arena, &args); | ||
| 32 | try args.appendSlice(&[_][]const u8{ | ||
| 33 | "-U__CRTDLL__", | ||
| 34 | "-D__MSVCRT__", | ||
| 35 | // Uncomment these 3 things for crtu | ||
| 36 | //"-DUNICODE", | ||
| 37 | //"-D_UNICODE", | ||
| 38 | //"-DWPRFLAG=1", | ||
| 39 | }); | ||
| 40 | return comp.build_crt_file("crt2", .Obj, &[1]Compilation.CSourceFile{ | ||
| 41 | .{ | ||
| 42 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 43 | "libc", "mingw", "crt", "crtexe.c", | ||
| 44 | }), | ||
| 45 | .extra_flags = args.items, | ||
| 46 | }, | ||
| 47 | }); | ||
| 48 | }, | ||
| 49 | |||
| 50 | .dllcrt2_o => { | ||
| 51 | var args = std.ArrayList([]const u8).init(arena); | ||
| 52 | try add_cc_args(comp, arena, &args); | ||
| 53 | try args.appendSlice(&[_][]const u8{ | ||
| 54 | "-U__CRTDLL__", | ||
| 55 | "-D__MSVCRT__", | ||
| 56 | }); | ||
| 57 | return comp.build_crt_file("dllcrt2", .Obj, &[1]Compilation.CSourceFile{ | ||
| 58 | .{ | ||
| 59 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 60 | "libc", "mingw", "crt", "crtdll.c", | ||
| 61 | }), | ||
| 62 | .extra_flags = args.items, | ||
| 63 | }, | ||
| 64 | }); | ||
| 65 | }, | ||
| 66 | |||
| 67 | .mingw32_lib => { | ||
| 68 | var c_source_files: [mingw32_lib_deps.len]Compilation.CSourceFile = undefined; | ||
| 69 | for (mingw32_lib_deps) |dep, i| { | ||
| 70 | var args = std.ArrayList([]const u8).init(arena); | ||
| 71 | try args.appendSlice(&[_][]const u8{ | ||
| 72 | "-DHAVE_CONFIG_H", | ||
| 73 | "-D_SYSCRT=1", | ||
| 74 | "-DCRTDLL=1", | ||
| 75 | |||
| 76 | "-isystem", | ||
| 77 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 78 | "libc", "include", "any-windows-any", | ||
| 79 | }), | ||
| 80 | |||
| 81 | "-isystem", | ||
| 82 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "include" }), | ||
| 83 | |||
| 84 | "-std=gnu99", | ||
| 85 | "-D_CRTBLD", | ||
| 86 | "-D_WIN32_WINNT=0x0f00", | ||
| 87 | "-D__MSVCRT_VERSION__=0x700", | ||
| 88 | "-g", | ||
| 89 | "-O2", | ||
| 90 | }); | ||
| 91 | c_source_files[i] = .{ | ||
| 92 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 93 | "libc", "mingw", "crt", dep, | ||
| 94 | }), | ||
| 95 | .extra_flags = args.items, | ||
| 96 | }; | ||
| 97 | } | ||
| 98 | return comp.build_crt_file("mingw32", .Lib, &c_source_files); | ||
| 99 | }, | ||
| 100 | |||
| 101 | .msvcrt_os_lib => { | ||
| 102 | const extra_flags = try arena.dupe([]const u8, &[_][]const u8{ | ||
| 103 | "-DHAVE_CONFIG_H", | ||
| 104 | "-D__LIBMSVCRT__", | ||
| 105 | |||
| 106 | "-I", | ||
| 107 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "include" }), | ||
| 108 | |||
| 109 | "-std=gnu99", | ||
| 110 | "-D_CRTBLD", | ||
| 111 | "-D_WIN32_WINNT=0x0f00", | ||
| 112 | "-D__MSVCRT_VERSION__=0x700", | ||
| 113 | |||
| 114 | "-isystem", | ||
| 115 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "any-windows-any" }), | ||
| 116 | |||
| 117 | "-g", | ||
| 118 | "-O2", | ||
| 119 | }); | ||
| 120 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); | ||
| 121 | |||
| 122 | for (msvcrt_common_src) |dep| { | ||
| 123 | (try c_source_files.addOne()).* = .{ | ||
| 124 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", dep }), | ||
| 125 | .extra_flags = extra_flags, | ||
| 126 | }; | ||
| 127 | } | ||
| 128 | if (comp.getTarget().cpu.arch == .i386) { | ||
| 129 | for (msvcrt_i386_src) |dep| { | ||
| 130 | (try c_source_files.addOne()).* = .{ | ||
| 131 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 132 | "libc", "mingw", dep, | ||
| 133 | }), | ||
| 134 | .extra_flags = extra_flags, | ||
| 135 | }; | ||
| 136 | } | ||
| 137 | } else { | ||
| 138 | for (msvcrt_other_src) |dep| { | ||
| 139 | (try c_source_files.addOne()).* = .{ | ||
| 140 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 141 | "libc", "mingw", dep, | ||
| 142 | }), | ||
| 143 | .extra_flags = extra_flags, | ||
| 144 | }; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | return comp.build_crt_file("msvcrt-os", .Lib, c_source_files.items); | ||
| 148 | }, | ||
| 149 | |||
| 150 | .mingwex_lib => { | ||
| 151 | const extra_flags = try arena.dupe([]const u8, &[_][]const u8{ | ||
| 152 | "-DHAVE_CONFIG_H", | ||
| 153 | |||
| 154 | "-I", | ||
| 155 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw" }), | ||
| 156 | |||
| 157 | "-I", | ||
| 158 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "include" }), | ||
| 159 | |||
| 160 | "-std=gnu99", | ||
| 161 | "-D_CRTBLD", | ||
| 162 | "-D_WIN32_WINNT=0x0f00", | ||
| 163 | "-D__MSVCRT_VERSION__=0x700", | ||
| 164 | "-g", | ||
| 165 | "-O2", | ||
| 166 | |||
| 167 | "-isystem", | ||
| 168 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "any-windows-any" }), | ||
| 169 | }); | ||
| 170 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); | ||
| 171 | |||
| 172 | for (mingwex_generic_src) |dep| { | ||
| 173 | (try c_source_files.addOne()).* = .{ | ||
| 174 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 175 | "libc", "mingw", dep, | ||
| 176 | }), | ||
| 177 | .extra_flags = extra_flags, | ||
| 178 | }; | ||
| 179 | } | ||
| 180 | const target = comp.getTarget(); | ||
| 181 | if (target.cpu.arch == .i386 or target.cpu.arch == .x86_64) { | ||
| 182 | for (mingwex_x86_src) |dep| { | ||
| 183 | (try c_source_files.addOne()).* = .{ | ||
| 184 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 185 | "libc", "mingw", dep, | ||
| 186 | }), | ||
| 187 | .extra_flags = extra_flags, | ||
| 188 | }; | ||
| 189 | } | ||
| 190 | } else if (target.cpu.arch.isARM()) { | ||
| 191 | if (target.cpu.arch.ptrBitWidth() == 32) { | ||
| 192 | for (mingwex_arm32_src) |dep| { | ||
| 193 | (try c_source_files.addOne()).* = .{ | ||
| 194 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 195 | "libc", "mingw", dep, | ||
| 196 | }), | ||
| 197 | .extra_flags = extra_flags, | ||
| 198 | }; | ||
| 199 | } | ||
| 200 | } else { | ||
| 201 | for (mingwex_arm64_src) |dep| { | ||
| 202 | (try c_source_files.addOne()).* = .{ | ||
| 203 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 204 | "libc", "mingw", dep, | ||
| 205 | }), | ||
| 206 | .extra_flags = extra_flags, | ||
| 207 | }; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } else { | ||
| 211 | unreachable; | ||
| 212 | } | ||
| 213 | return comp.build_crt_file("mingwex", .Lib, c_source_files.items); | ||
| 214 | }, | ||
| 215 | |||
| 216 | .uuid_lib => { | ||
| 217 | const extra_flags = try arena.dupe([]const u8, &[_][]const u8{ | ||
| 218 | "-DHAVE_CONFIG_H", | ||
| 219 | |||
| 220 | "-I", | ||
| 221 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw" }), | ||
| 222 | |||
| 223 | "-I", | ||
| 224 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "include" }), | ||
| 225 | |||
| 226 | "-std=gnu99", | ||
| 227 | "-D_CRTBLD", | ||
| 228 | "-D_WIN32_WINNT=0x0f00", | ||
| 229 | "-D__MSVCRT_VERSION__=0x700", | ||
| 230 | "-g", | ||
| 231 | "-O2", | ||
| 232 | |||
| 233 | "-isystem", | ||
| 234 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 235 | "libc", "include", "any-windows-any", | ||
| 236 | }), | ||
| 237 | }); | ||
| 238 | var c_source_files: [uuid_src.len]Compilation.CSourceFile = undefined; | ||
| 239 | for (uuid_src) |dep, i| { | ||
| 240 | c_source_files[i] = .{ | ||
| 241 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | ||
| 242 | "libc", "mingw", "libsrc", dep, | ||
| 243 | }), | ||
| 244 | .extra_flags = extra_flags, | ||
| 245 | }; | ||
| 246 | } | ||
| 247 | return comp.build_crt_file("uuid", .Lib, &c_source_files); | ||
| 248 | }, | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | fn add_cc_args( | ||
| 253 | comp: *Compilation, | ||
| 254 | arena: *Allocator, | ||
| 255 | args: *std.ArrayList([]const u8), | ||
| 256 | ) error{OutOfMemory}!void { | ||
| 257 | try args.appendSlice(&[_][]const u8{ | ||
| 258 | "-DHAVE_CONFIG_H", | ||
| 259 | |||
| 260 | "-I", | ||
| 261 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "include" }), | ||
| 262 | |||
| 263 | "-isystem", | ||
| 264 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "any-windows-any" }), | ||
| 265 | }); | ||
| 266 | |||
| 267 | const target = comp.getTarget(); | ||
| 268 | if (target.cpu.arch.isARM() and target.cpu.arch.ptrBitWidth() == 32) { | ||
| 269 | try args.append("-mfpu=vfp"); | ||
| 270 | } | ||
| 271 | |||
| 272 | try args.appendSlice(&[_][]const u8{ | ||
| 273 | "-std=gnu11", | ||
| 274 | "-D_CRTBLD", | ||
| 275 | "-D_WIN32_WINNT=0x0f00", | ||
| 276 | "-D__MSVCRT_VERSION__=0x700", | ||
| 277 | }); | ||
| 278 | } | ||
| 279 | |||
| 280 | const mingw32_lib_deps = [_][]const u8{ | ||
| 281 | "crt0_c.c", | ||
| 282 | "dll_argv.c", | ||
| 283 | "gccmain.c", | ||
| 284 | "natstart.c", | ||
| 285 | "pseudo-reloc-list.c", | ||
| 286 | "wildcard.c", | ||
| 287 | "charmax.c", | ||
| 288 | "crt0_w.c", | ||
| 289 | "dllargv.c", | ||
| 290 | "gs_support.c", | ||
| 291 | "_newmode.c", | ||
| 292 | "tlssup.c", | ||
| 293 | "xncommod.c", | ||
| 294 | "cinitexe.c", | ||
| 295 | "merr.c", | ||
| 296 | "usermatherr.c", | ||
| 297 | "pesect.c", | ||
| 298 | "udllargc.c", | ||
| 299 | "xthdloc.c", | ||
| 300 | "CRT_fp10.c", | ||
| 301 | "mingw_helpers.c", | ||
| 302 | "pseudo-reloc.c", | ||
| 303 | "udll_argv.c", | ||
| 304 | "xtxtmode.c", | ||
| 305 | "crt_handler.c", | ||
| 306 | "tlsthrd.c", | ||
| 307 | "tlsmthread.c", | ||
| 308 | "tlsmcrt.c", | ||
| 309 | "cxa_atexit.c", | ||
| 310 | }; | ||
| 311 | const msvcrt_common_src = [_][]const u8{ | ||
| 312 | "misc" ++ path.sep_str ++ "_create_locale.c", | ||
| 313 | "misc" ++ path.sep_str ++ "_free_locale.c", | ||
| 314 | "misc" ++ path.sep_str ++ "onexit_table.c", | ||
| 315 | "misc" ++ path.sep_str ++ "register_tls_atexit.c", | ||
| 316 | "stdio" ++ path.sep_str ++ "acrt_iob_func.c", | ||
| 317 | "misc" ++ path.sep_str ++ "_configthreadlocale.c", | ||
| 318 | "misc" ++ path.sep_str ++ "_get_current_locale.c", | ||
| 319 | "misc" ++ path.sep_str ++ "invalid_parameter_handler.c", | ||
| 320 | "misc" ++ path.sep_str ++ "output_format.c", | ||
| 321 | "misc" ++ path.sep_str ++ "purecall.c", | ||
| 322 | "secapi" ++ path.sep_str ++ "_access_s.c", | ||
| 323 | "secapi" ++ path.sep_str ++ "_cgets_s.c", | ||
| 324 | "secapi" ++ path.sep_str ++ "_cgetws_s.c", | ||
| 325 | "secapi" ++ path.sep_str ++ "_chsize_s.c", | ||
| 326 | "secapi" ++ path.sep_str ++ "_controlfp_s.c", | ||
| 327 | "secapi" ++ path.sep_str ++ "_cprintf_s.c", | ||
| 328 | "secapi" ++ path.sep_str ++ "_cprintf_s_l.c", | ||
| 329 | "secapi" ++ path.sep_str ++ "_ctime32_s.c", | ||
| 330 | "secapi" ++ path.sep_str ++ "_ctime64_s.c", | ||
| 331 | "secapi" ++ path.sep_str ++ "_cwprintf_s.c", | ||
| 332 | "secapi" ++ path.sep_str ++ "_cwprintf_s_l.c", | ||
| 333 | "secapi" ++ path.sep_str ++ "_gmtime32_s.c", | ||
| 334 | "secapi" ++ path.sep_str ++ "_gmtime64_s.c", | ||
| 335 | "secapi" ++ path.sep_str ++ "_localtime32_s.c", | ||
| 336 | "secapi" ++ path.sep_str ++ "_localtime64_s.c", | ||
| 337 | "secapi" ++ path.sep_str ++ "_mktemp_s.c", | ||
| 338 | "secapi" ++ path.sep_str ++ "_sopen_s.c", | ||
| 339 | "secapi" ++ path.sep_str ++ "_strdate_s.c", | ||
| 340 | "secapi" ++ path.sep_str ++ "_strtime_s.c", | ||
| 341 | "secapi" ++ path.sep_str ++ "_umask_s.c", | ||
| 342 | "secapi" ++ path.sep_str ++ "_vcprintf_s.c", | ||
| 343 | "secapi" ++ path.sep_str ++ "_vcprintf_s_l.c", | ||
| 344 | "secapi" ++ path.sep_str ++ "_vcwprintf_s.c", | ||
| 345 | "secapi" ++ path.sep_str ++ "_vcwprintf_s_l.c", | ||
| 346 | "secapi" ++ path.sep_str ++ "_vscprintf_p.c", | ||
| 347 | "secapi" ++ path.sep_str ++ "_vscwprintf_p.c", | ||
| 348 | "secapi" ++ path.sep_str ++ "_vswprintf_p.c", | ||
| 349 | "secapi" ++ path.sep_str ++ "_waccess_s.c", | ||
| 350 | "secapi" ++ path.sep_str ++ "_wasctime_s.c", | ||
| 351 | "secapi" ++ path.sep_str ++ "_wctime32_s.c", | ||
| 352 | "secapi" ++ path.sep_str ++ "_wctime64_s.c", | ||
| 353 | "secapi" ++ path.sep_str ++ "_wstrtime_s.c", | ||
| 354 | "secapi" ++ path.sep_str ++ "_wmktemp_s.c", | ||
| 355 | "secapi" ++ path.sep_str ++ "_wstrdate_s.c", | ||
| 356 | "secapi" ++ path.sep_str ++ "asctime_s.c", | ||
| 357 | "secapi" ++ path.sep_str ++ "memcpy_s.c", | ||
| 358 | "secapi" ++ path.sep_str ++ "memmove_s.c", | ||
| 359 | "secapi" ++ path.sep_str ++ "rand_s.c", | ||
| 360 | "secapi" ++ path.sep_str ++ "sprintf_s.c", | ||
| 361 | "secapi" ++ path.sep_str ++ "strerror_s.c", | ||
| 362 | "secapi" ++ path.sep_str ++ "vsprintf_s.c", | ||
| 363 | "secapi" ++ path.sep_str ++ "wmemcpy_s.c", | ||
| 364 | "secapi" ++ path.sep_str ++ "wmemmove_s.c", | ||
| 365 | "stdio" ++ path.sep_str ++ "mingw_lock.c", | ||
| 366 | }; | ||
| 367 | const msvcrt_i386_src = [_][]const u8{ | ||
| 368 | "misc" ++ path.sep_str ++ "lc_locale_func.c", | ||
| 369 | "misc" ++ path.sep_str ++ "___mb_cur_max_func.c", | ||
| 370 | }; | ||
| 371 | |||
| 372 | const msvcrt_other_src = [_][]const u8{ | ||
| 373 | "misc" ++ path.sep_str ++ "__p___argv.c", | ||
| 374 | "misc" ++ path.sep_str ++ "__p__acmdln.c", | ||
| 375 | "misc" ++ path.sep_str ++ "__p__fmode.c", | ||
| 376 | "misc" ++ path.sep_str ++ "__p__wcmdln.c", | ||
| 377 | }; | ||
| 378 | const mingwex_generic_src = [_][]const u8{ | ||
| 379 | "complex" ++ path.sep_str ++ "_cabs.c", | ||
| 380 | "complex" ++ path.sep_str ++ "cabs.c", | ||
| 381 | "complex" ++ path.sep_str ++ "cabsf.c", | ||
| 382 | "complex" ++ path.sep_str ++ "cabsl.c", | ||
| 383 | "complex" ++ path.sep_str ++ "cacos.c", | ||
| 384 | "complex" ++ path.sep_str ++ "cacosf.c", | ||
| 385 | "complex" ++ path.sep_str ++ "cacosl.c", | ||
| 386 | "complex" ++ path.sep_str ++ "carg.c", | ||
| 387 | "complex" ++ path.sep_str ++ "cargf.c", | ||
| 388 | "complex" ++ path.sep_str ++ "cargl.c", | ||
| 389 | "complex" ++ path.sep_str ++ "casin.c", | ||
| 390 | "complex" ++ path.sep_str ++ "casinf.c", | ||
| 391 | "complex" ++ path.sep_str ++ "casinl.c", | ||
| 392 | "complex" ++ path.sep_str ++ "catan.c", | ||
| 393 | "complex" ++ path.sep_str ++ "catanf.c", | ||
| 394 | "complex" ++ path.sep_str ++ "catanl.c", | ||
| 395 | "complex" ++ path.sep_str ++ "ccos.c", | ||
| 396 | "complex" ++ path.sep_str ++ "ccosf.c", | ||
| 397 | "complex" ++ path.sep_str ++ "ccosl.c", | ||
| 398 | "complex" ++ path.sep_str ++ "cexp.c", | ||
| 399 | "complex" ++ path.sep_str ++ "cexpf.c", | ||
| 400 | "complex" ++ path.sep_str ++ "cexpl.c", | ||
| 401 | "complex" ++ path.sep_str ++ "cimag.c", | ||
| 402 | "complex" ++ path.sep_str ++ "cimagf.c", | ||
| 403 | "complex" ++ path.sep_str ++ "cimagl.c", | ||
| 404 | "complex" ++ path.sep_str ++ "clog.c", | ||
| 405 | "complex" ++ path.sep_str ++ "clog10.c", | ||
| 406 | "complex" ++ path.sep_str ++ "clog10f.c", | ||
| 407 | "complex" ++ path.sep_str ++ "clog10l.c", | ||
| 408 | "complex" ++ path.sep_str ++ "clogf.c", | ||
| 409 | "complex" ++ path.sep_str ++ "clogl.c", | ||
| 410 | "complex" ++ path.sep_str ++ "conj.c", | ||
| 411 | "complex" ++ path.sep_str ++ "conjf.c", | ||
| 412 | "complex" ++ path.sep_str ++ "conjl.c", | ||
| 413 | "complex" ++ path.sep_str ++ "cpow.c", | ||
| 414 | "complex" ++ path.sep_str ++ "cpowf.c", | ||
| 415 | "complex" ++ path.sep_str ++ "cpowl.c", | ||
| 416 | "complex" ++ path.sep_str ++ "cproj.c", | ||
| 417 | "complex" ++ path.sep_str ++ "cprojf.c", | ||
| 418 | "complex" ++ path.sep_str ++ "cprojl.c", | ||
| 419 | "complex" ++ path.sep_str ++ "creal.c", | ||
| 420 | "complex" ++ path.sep_str ++ "crealf.c", | ||
| 421 | "complex" ++ path.sep_str ++ "creall.c", | ||
| 422 | "complex" ++ path.sep_str ++ "csin.c", | ||
| 423 | "complex" ++ path.sep_str ++ "csinf.c", | ||
| 424 | "complex" ++ path.sep_str ++ "csinl.c", | ||
| 425 | "complex" ++ path.sep_str ++ "csqrt.c", | ||
| 426 | "complex" ++ path.sep_str ++ "csqrtf.c", | ||
| 427 | "complex" ++ path.sep_str ++ "csqrtl.c", | ||
| 428 | "complex" ++ path.sep_str ++ "ctan.c", | ||
| 429 | "complex" ++ path.sep_str ++ "ctanf.c", | ||
| 430 | "complex" ++ path.sep_str ++ "ctanl.c", | ||
| 431 | "crt" ++ path.sep_str ++ "dllentry.c", | ||
| 432 | "crt" ++ path.sep_str ++ "dllmain.c", | ||
| 433 | "gdtoa" ++ path.sep_str ++ "arithchk.c", | ||
| 434 | "gdtoa" ++ path.sep_str ++ "dmisc.c", | ||
| 435 | "gdtoa" ++ path.sep_str ++ "dtoa.c", | ||
| 436 | "gdtoa" ++ path.sep_str ++ "g__fmt.c", | ||
| 437 | "gdtoa" ++ path.sep_str ++ "g_dfmt.c", | ||
| 438 | "gdtoa" ++ path.sep_str ++ "g_ffmt.c", | ||
| 439 | "gdtoa" ++ path.sep_str ++ "g_xfmt.c", | ||
| 440 | "gdtoa" ++ path.sep_str ++ "gdtoa.c", | ||
| 441 | "gdtoa" ++ path.sep_str ++ "gethex.c", | ||
| 442 | "gdtoa" ++ path.sep_str ++ "gmisc.c", | ||
| 443 | "gdtoa" ++ path.sep_str ++ "hd_init.c", | ||
| 444 | "gdtoa" ++ path.sep_str ++ "hexnan.c", | ||
| 445 | "gdtoa" ++ path.sep_str ++ "misc.c", | ||
| 446 | "gdtoa" ++ path.sep_str ++ "qnan.c", | ||
| 447 | "gdtoa" ++ path.sep_str ++ "smisc.c", | ||
| 448 | "gdtoa" ++ path.sep_str ++ "strtodg.c", | ||
| 449 | "gdtoa" ++ path.sep_str ++ "strtodnrp.c", | ||
| 450 | "gdtoa" ++ path.sep_str ++ "strtof.c", | ||
| 451 | "gdtoa" ++ path.sep_str ++ "strtopx.c", | ||
| 452 | "gdtoa" ++ path.sep_str ++ "sum.c", | ||
| 453 | "gdtoa" ++ path.sep_str ++ "ulp.c", | ||
| 454 | "math" ++ path.sep_str ++ "abs64.c", | ||
| 455 | "math" ++ path.sep_str ++ "cbrt.c", | ||
| 456 | "math" ++ path.sep_str ++ "cbrtf.c", | ||
| 457 | "math" ++ path.sep_str ++ "cbrtl.c", | ||
| 458 | "math" ++ path.sep_str ++ "cephes_emath.c", | ||
| 459 | "math" ++ path.sep_str ++ "copysign.c", | ||
| 460 | "math" ++ path.sep_str ++ "copysignf.c", | ||
| 461 | "math" ++ path.sep_str ++ "coshf.c", | ||
| 462 | "math" ++ path.sep_str ++ "coshl.c", | ||
| 463 | "math" ++ path.sep_str ++ "erfl.c", | ||
| 464 | "math" ++ path.sep_str ++ "expf.c", | ||
| 465 | "math" ++ path.sep_str ++ "fabs.c", | ||
| 466 | "math" ++ path.sep_str ++ "fabsf.c", | ||
| 467 | "math" ++ path.sep_str ++ "fabsl.c", | ||
| 468 | "math" ++ path.sep_str ++ "fdim.c", | ||
| 469 | "math" ++ path.sep_str ++ "fdimf.c", | ||
| 470 | "math" ++ path.sep_str ++ "fdiml.c", | ||
| 471 | "math" ++ path.sep_str ++ "fma.c", | ||
| 472 | "math" ++ path.sep_str ++ "fmaf.c", | ||
| 473 | "math" ++ path.sep_str ++ "fmal.c", | ||
| 474 | "math" ++ path.sep_str ++ "fmax.c", | ||
| 475 | "math" ++ path.sep_str ++ "fmaxf.c", | ||
| 476 | "math" ++ path.sep_str ++ "fmaxl.c", | ||
| 477 | "math" ++ path.sep_str ++ "fmin.c", | ||
| 478 | "math" ++ path.sep_str ++ "fminf.c", | ||
| 479 | "math" ++ path.sep_str ++ "fminl.c", | ||
| 480 | "math" ++ path.sep_str ++ "fp_consts.c", | ||
| 481 | "math" ++ path.sep_str ++ "fp_constsf.c", | ||
| 482 | "math" ++ path.sep_str ++ "fp_constsl.c", | ||
| 483 | "math" ++ path.sep_str ++ "fpclassify.c", | ||
| 484 | "math" ++ path.sep_str ++ "fpclassifyf.c", | ||
| 485 | "math" ++ path.sep_str ++ "fpclassifyl.c", | ||
| 486 | "math" ++ path.sep_str ++ "frexpf.c", | ||
| 487 | "math" ++ path.sep_str ++ "hypot.c", | ||
| 488 | "math" ++ path.sep_str ++ "hypotf.c", | ||
| 489 | "math" ++ path.sep_str ++ "hypotl.c", | ||
| 490 | "math" ++ path.sep_str ++ "isnan.c", | ||
| 491 | "math" ++ path.sep_str ++ "isnanf.c", | ||
| 492 | "math" ++ path.sep_str ++ "isnanl.c", | ||
| 493 | "math" ++ path.sep_str ++ "ldexpf.c", | ||
| 494 | "math" ++ path.sep_str ++ "lgamma.c", | ||
| 495 | "math" ++ path.sep_str ++ "lgammaf.c", | ||
| 496 | "math" ++ path.sep_str ++ "lgammal.c", | ||
| 497 | "math" ++ path.sep_str ++ "llrint.c", | ||
| 498 | "math" ++ path.sep_str ++ "llrintf.c", | ||
| 499 | "math" ++ path.sep_str ++ "llrintl.c", | ||
| 500 | "math" ++ path.sep_str ++ "llround.c", | ||
| 501 | "math" ++ path.sep_str ++ "llroundf.c", | ||
| 502 | "math" ++ path.sep_str ++ "llroundl.c", | ||
| 503 | "math" ++ path.sep_str ++ "log10f.c", | ||
| 504 | "math" ++ path.sep_str ++ "logf.c", | ||
| 505 | "math" ++ path.sep_str ++ "lrint.c", | ||
| 506 | "math" ++ path.sep_str ++ "lrintf.c", | ||
| 507 | "math" ++ path.sep_str ++ "lrintl.c", | ||
| 508 | "math" ++ path.sep_str ++ "lround.c", | ||
| 509 | "math" ++ path.sep_str ++ "lroundf.c", | ||
| 510 | "math" ++ path.sep_str ++ "lroundl.c", | ||
| 511 | "math" ++ path.sep_str ++ "modf.c", | ||
| 512 | "math" ++ path.sep_str ++ "modff.c", | ||
| 513 | "math" ++ path.sep_str ++ "modfl.c", | ||
| 514 | "math" ++ path.sep_str ++ "nextafterf.c", | ||
| 515 | "math" ++ path.sep_str ++ "nextafterl.c", | ||
| 516 | "math" ++ path.sep_str ++ "nexttoward.c", | ||
| 517 | "math" ++ path.sep_str ++ "nexttowardf.c", | ||
| 518 | "math" ++ path.sep_str ++ "powf.c", | ||
| 519 | "math" ++ path.sep_str ++ "powi.c", | ||
| 520 | "math" ++ path.sep_str ++ "powif.c", | ||
| 521 | "math" ++ path.sep_str ++ "powil.c", | ||
| 522 | "math" ++ path.sep_str ++ "rint.c", | ||
| 523 | "math" ++ path.sep_str ++ "rintf.c", | ||
| 524 | "math" ++ path.sep_str ++ "rintl.c", | ||
| 525 | "math" ++ path.sep_str ++ "round.c", | ||
| 526 | "math" ++ path.sep_str ++ "roundf.c", | ||
| 527 | "math" ++ path.sep_str ++ "roundl.c", | ||
| 528 | "math" ++ path.sep_str ++ "s_erf.c", | ||
| 529 | "math" ++ path.sep_str ++ "sf_erf.c", | ||
| 530 | "math" ++ path.sep_str ++ "signbit.c", | ||
| 531 | "math" ++ path.sep_str ++ "signbitf.c", | ||
| 532 | "math" ++ path.sep_str ++ "signbitl.c", | ||
| 533 | "math" ++ path.sep_str ++ "signgam.c", | ||
| 534 | "math" ++ path.sep_str ++ "sinhf.c", | ||
| 535 | "math" ++ path.sep_str ++ "sinhl.c", | ||
| 536 | "math" ++ path.sep_str ++ "sqrt.c", | ||
| 537 | "math" ++ path.sep_str ++ "sqrtf.c", | ||
| 538 | "math" ++ path.sep_str ++ "sqrtl.c", | ||
| 539 | "math" ++ path.sep_str ++ "tanhf.c", | ||
| 540 | "math" ++ path.sep_str ++ "tanhl.c", | ||
| 541 | "math" ++ path.sep_str ++ "tgamma.c", | ||
| 542 | "math" ++ path.sep_str ++ "tgammaf.c", | ||
| 543 | "math" ++ path.sep_str ++ "tgammal.c", | ||
| 544 | "math" ++ path.sep_str ++ "truncl.c", | ||
| 545 | "misc" ++ path.sep_str ++ "alarm.c", | ||
| 546 | "misc" ++ path.sep_str ++ "basename.c", | ||
| 547 | "misc" ++ path.sep_str ++ "btowc.c", | ||
| 548 | "misc" ++ path.sep_str ++ "delay-f.c", | ||
| 549 | "misc" ++ path.sep_str ++ "delay-n.c", | ||
| 550 | "misc" ++ path.sep_str ++ "delayimp.c", | ||
| 551 | "misc" ++ path.sep_str ++ "dirent.c", | ||
| 552 | "misc" ++ path.sep_str ++ "dirname.c", | ||
| 553 | "misc" ++ path.sep_str ++ "feclearexcept.c", | ||
| 554 | "misc" ++ path.sep_str ++ "fegetenv.c", | ||
| 555 | "misc" ++ path.sep_str ++ "fegetexceptflag.c", | ||
| 556 | "misc" ++ path.sep_str ++ "fegetround.c", | ||
| 557 | "misc" ++ path.sep_str ++ "feholdexcept.c", | ||
| 558 | "misc" ++ path.sep_str ++ "feraiseexcept.c", | ||
| 559 | "misc" ++ path.sep_str ++ "fesetenv.c", | ||
| 560 | "misc" ++ path.sep_str ++ "fesetexceptflag.c", | ||
| 561 | "misc" ++ path.sep_str ++ "fesetround.c", | ||
| 562 | "misc" ++ path.sep_str ++ "fetestexcept.c", | ||
| 563 | "misc" ++ path.sep_str ++ "feupdateenv.c", | ||
| 564 | "misc" ++ path.sep_str ++ "ftruncate.c", | ||
| 565 | "misc" ++ path.sep_str ++ "ftw.c", | ||
| 566 | "misc" ++ path.sep_str ++ "ftw64.c", | ||
| 567 | "misc" ++ path.sep_str ++ "fwide.c", | ||
| 568 | "misc" ++ path.sep_str ++ "getlogin.c", | ||
| 569 | "misc" ++ path.sep_str ++ "getopt.c", | ||
| 570 | "misc" ++ path.sep_str ++ "gettimeofday.c", | ||
| 571 | "misc" ++ path.sep_str ++ "imaxabs.c", | ||
| 572 | "misc" ++ path.sep_str ++ "imaxdiv.c", | ||
| 573 | "misc" ++ path.sep_str ++ "isblank.c", | ||
| 574 | "misc" ++ path.sep_str ++ "iswblank.c", | ||
| 575 | "misc" ++ path.sep_str ++ "mbrtowc.c", | ||
| 576 | "misc" ++ path.sep_str ++ "mbsinit.c", | ||
| 577 | "misc" ++ path.sep_str ++ "mempcpy.c", | ||
| 578 | "misc" ++ path.sep_str ++ "mingw-aligned-malloc.c", | ||
| 579 | "misc" ++ path.sep_str ++ "mingw-fseek.c", | ||
| 580 | "misc" ++ path.sep_str ++ "mingw_getsp.S", | ||
| 581 | "misc" ++ path.sep_str ++ "mingw_matherr.c", | ||
| 582 | "misc" ++ path.sep_str ++ "mingw_mbwc_convert.c", | ||
| 583 | "misc" ++ path.sep_str ++ "mingw_usleep.c", | ||
| 584 | "misc" ++ path.sep_str ++ "mingw_wcstod.c", | ||
| 585 | "misc" ++ path.sep_str ++ "mingw_wcstof.c", | ||
| 586 | "misc" ++ path.sep_str ++ "mingw_wcstold.c", | ||
| 587 | "misc" ++ path.sep_str ++ "mkstemp.c", | ||
| 588 | "misc" ++ path.sep_str ++ "seterrno.c", | ||
| 589 | "misc" ++ path.sep_str ++ "sleep.c", | ||
| 590 | "misc" ++ path.sep_str ++ "strnlen.c", | ||
| 591 | "misc" ++ path.sep_str ++ "strsafe.c", | ||
| 592 | "misc" ++ path.sep_str ++ "strtoimax.c", | ||
| 593 | "misc" ++ path.sep_str ++ "strtold.c", | ||
| 594 | "misc" ++ path.sep_str ++ "strtoumax.c", | ||
| 595 | "misc" ++ path.sep_str ++ "tdelete.c", | ||
| 596 | "misc" ++ path.sep_str ++ "tfind.c", | ||
| 597 | "misc" ++ path.sep_str ++ "tsearch.c", | ||
| 598 | "misc" ++ path.sep_str ++ "twalk.c", | ||
| 599 | "misc" ++ path.sep_str ++ "uchar_c16rtomb.c", | ||
| 600 | "misc" ++ path.sep_str ++ "uchar_c32rtomb.c", | ||
| 601 | "misc" ++ path.sep_str ++ "uchar_mbrtoc16.c", | ||
| 602 | "misc" ++ path.sep_str ++ "uchar_mbrtoc32.c", | ||
| 603 | "misc" ++ path.sep_str ++ "wassert.c", | ||
| 604 | "misc" ++ path.sep_str ++ "wcrtomb.c", | ||
| 605 | "misc" ++ path.sep_str ++ "wcsnlen.c", | ||
| 606 | "misc" ++ path.sep_str ++ "wcstof.c", | ||
| 607 | "misc" ++ path.sep_str ++ "wcstoimax.c", | ||
| 608 | "misc" ++ path.sep_str ++ "wcstold.c", | ||
| 609 | "misc" ++ path.sep_str ++ "wcstoumax.c", | ||
| 610 | "misc" ++ path.sep_str ++ "wctob.c", | ||
| 611 | "misc" ++ path.sep_str ++ "wctrans.c", | ||
| 612 | "misc" ++ path.sep_str ++ "wctype.c", | ||
| 613 | "misc" ++ path.sep_str ++ "wdirent.c", | ||
| 614 | "misc" ++ path.sep_str ++ "winbs_uint64.c", | ||
| 615 | "misc" ++ path.sep_str ++ "winbs_ulong.c", | ||
| 616 | "misc" ++ path.sep_str ++ "winbs_ushort.c", | ||
| 617 | "misc" ++ path.sep_str ++ "wmemchr.c", | ||
| 618 | "misc" ++ path.sep_str ++ "wmemcmp.c", | ||
| 619 | "misc" ++ path.sep_str ++ "wmemcpy.c", | ||
| 620 | "misc" ++ path.sep_str ++ "wmemmove.c", | ||
| 621 | "misc" ++ path.sep_str ++ "wmempcpy.c", | ||
| 622 | "misc" ++ path.sep_str ++ "wmemset.c", | ||
| 623 | "stdio" ++ path.sep_str ++ "_Exit.c", | ||
| 624 | "stdio" ++ path.sep_str ++ "_findfirst64i32.c", | ||
| 625 | "stdio" ++ path.sep_str ++ "_findnext64i32.c", | ||
| 626 | "stdio" ++ path.sep_str ++ "_fstat.c", | ||
| 627 | "stdio" ++ path.sep_str ++ "_fstat64i32.c", | ||
| 628 | "stdio" ++ path.sep_str ++ "_ftime.c", | ||
| 629 | "stdio" ++ path.sep_str ++ "_getc_nolock.c", | ||
| 630 | "stdio" ++ path.sep_str ++ "_getwc_nolock.c", | ||
| 631 | "stdio" ++ path.sep_str ++ "_putc_nolock.c", | ||
| 632 | "stdio" ++ path.sep_str ++ "_putwc_nolock.c", | ||
| 633 | "stdio" ++ path.sep_str ++ "_stat.c", | ||
| 634 | "stdio" ++ path.sep_str ++ "_stat64i32.c", | ||
| 635 | "stdio" ++ path.sep_str ++ "_wfindfirst64i32.c", | ||
| 636 | "stdio" ++ path.sep_str ++ "_wfindnext64i32.c", | ||
| 637 | "stdio" ++ path.sep_str ++ "_wstat.c", | ||
| 638 | "stdio" ++ path.sep_str ++ "_wstat64i32.c", | ||
| 639 | "stdio" ++ path.sep_str ++ "asprintf.c", | ||
| 640 | "stdio" ++ path.sep_str ++ "atoll.c", | ||
| 641 | "stdio" ++ path.sep_str ++ "fgetpos64.c", | ||
| 642 | "stdio" ++ path.sep_str ++ "fopen64.c", | ||
| 643 | "stdio" ++ path.sep_str ++ "fseeko32.c", | ||
| 644 | "stdio" ++ path.sep_str ++ "fseeko64.c", | ||
| 645 | "stdio" ++ path.sep_str ++ "fsetpos64.c", | ||
| 646 | "stdio" ++ path.sep_str ++ "ftello.c", | ||
| 647 | "stdio" ++ path.sep_str ++ "ftello64.c", | ||
| 648 | "stdio" ++ path.sep_str ++ "ftruncate64.c", | ||
| 649 | "stdio" ++ path.sep_str ++ "lltoa.c", | ||
| 650 | "stdio" ++ path.sep_str ++ "lltow.c", | ||
| 651 | "stdio" ++ path.sep_str ++ "lseek64.c", | ||
| 652 | "stdio" ++ path.sep_str ++ "mingw_asprintf.c", | ||
| 653 | "stdio" ++ path.sep_str ++ "mingw_fprintf.c", | ||
| 654 | "stdio" ++ path.sep_str ++ "mingw_fprintfw.c", | ||
| 655 | "stdio" ++ path.sep_str ++ "mingw_fscanf.c", | ||
| 656 | "stdio" ++ path.sep_str ++ "mingw_fwscanf.c", | ||
| 657 | "stdio" ++ path.sep_str ++ "mingw_pformat.c", | ||
| 658 | "stdio" ++ path.sep_str ++ "mingw_pformatw.c", | ||
| 659 | "stdio" ++ path.sep_str ++ "mingw_printf.c", | ||
| 660 | "stdio" ++ path.sep_str ++ "mingw_printfw.c", | ||
| 661 | "stdio" ++ path.sep_str ++ "mingw_scanf.c", | ||
| 662 | "stdio" ++ path.sep_str ++ "mingw_snprintf.c", | ||
| 663 | "stdio" ++ path.sep_str ++ "mingw_snprintfw.c", | ||
| 664 | "stdio" ++ path.sep_str ++ "mingw_sprintf.c", | ||
| 665 | "stdio" ++ path.sep_str ++ "mingw_sprintfw.c", | ||
| 666 | "stdio" ++ path.sep_str ++ "mingw_sscanf.c", | ||
| 667 | "stdio" ++ path.sep_str ++ "mingw_swscanf.c", | ||
| 668 | "stdio" ++ path.sep_str ++ "mingw_vasprintf.c", | ||
| 669 | "stdio" ++ path.sep_str ++ "mingw_vfprintf.c", | ||
| 670 | "stdio" ++ path.sep_str ++ "mingw_vfprintfw.c", | ||
| 671 | "stdio" ++ path.sep_str ++ "mingw_vfscanf.c", | ||
| 672 | "stdio" ++ path.sep_str ++ "mingw_vprintf.c", | ||
| 673 | "stdio" ++ path.sep_str ++ "mingw_vprintfw.c", | ||
| 674 | "stdio" ++ path.sep_str ++ "mingw_vsnprintf.c", | ||
| 675 | "stdio" ++ path.sep_str ++ "mingw_vsnprintfw.c", | ||
| 676 | "stdio" ++ path.sep_str ++ "mingw_vsprintf.c", | ||
| 677 | "stdio" ++ path.sep_str ++ "mingw_vsprintfw.c", | ||
| 678 | "stdio" ++ path.sep_str ++ "mingw_wscanf.c", | ||
| 679 | "stdio" ++ path.sep_str ++ "mingw_wvfscanf.c", | ||
| 680 | "stdio" ++ path.sep_str ++ "scanf.S", | ||
| 681 | "stdio" ++ path.sep_str ++ "snprintf.c", | ||
| 682 | "stdio" ++ path.sep_str ++ "snwprintf.c", | ||
| 683 | "stdio" ++ path.sep_str ++ "strtof.c", | ||
| 684 | "stdio" ++ path.sep_str ++ "strtok_r.c", | ||
| 685 | "stdio" ++ path.sep_str ++ "truncate.c", | ||
| 686 | "stdio" ++ path.sep_str ++ "ulltoa.c", | ||
| 687 | "stdio" ++ path.sep_str ++ "ulltow.c", | ||
| 688 | "stdio" ++ path.sep_str ++ "vasprintf.c", | ||
| 689 | "stdio" ++ path.sep_str ++ "vfscanf.c", | ||
| 690 | "stdio" ++ path.sep_str ++ "vfscanf2.S", | ||
| 691 | "stdio" ++ path.sep_str ++ "vfwscanf.c", | ||
| 692 | "stdio" ++ path.sep_str ++ "vfwscanf2.S", | ||
| 693 | "stdio" ++ path.sep_str ++ "vscanf.c", | ||
| 694 | "stdio" ++ path.sep_str ++ "vscanf2.S", | ||
| 695 | "stdio" ++ path.sep_str ++ "vsnprintf.c", | ||
| 696 | "stdio" ++ path.sep_str ++ "vsnwprintf.c", | ||
| 697 | "stdio" ++ path.sep_str ++ "vsscanf.c", | ||
| 698 | "stdio" ++ path.sep_str ++ "vsscanf2.S", | ||
| 699 | "stdio" ++ path.sep_str ++ "vswscanf.c", | ||
| 700 | "stdio" ++ path.sep_str ++ "vswscanf2.S", | ||
| 701 | "stdio" ++ path.sep_str ++ "vwscanf.c", | ||
| 702 | "stdio" ++ path.sep_str ++ "vwscanf2.S", | ||
| 703 | "stdio" ++ path.sep_str ++ "wtoll.c", | ||
| 704 | }; | ||
| 705 | |||
| 706 | const mingwex_x86_src = [_][]const u8{ | ||
| 707 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "acosf.c", | ||
| 708 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "acosh.c", | ||
| 709 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "acoshf.c", | ||
| 710 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "acoshl.c", | ||
| 711 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "acosl.c", | ||
| 712 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "asinf.c", | ||
| 713 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "asinh.c", | ||
| 714 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "asinhf.c", | ||
| 715 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "asinhl.c", | ||
| 716 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "asinl.c", | ||
| 717 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atan2.c", | ||
| 718 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atan2f.c", | ||
| 719 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atan2l.c", | ||
| 720 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atanf.c", | ||
| 721 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atanh.c", | ||
| 722 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atanhf.c", | ||
| 723 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atanhl.c", | ||
| 724 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atanl.c", | ||
| 725 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "ceilf.S", | ||
| 726 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "ceill.S", | ||
| 727 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "ceil.S", | ||
| 728 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "_chgsignl.S", | ||
| 729 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "copysignl.S", | ||
| 730 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cos.c", | ||
| 731 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cosf.c", | ||
| 732 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cosl.c", | ||
| 733 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cosl_internal.S", | ||
| 734 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cossin.c", | ||
| 735 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "exp2f.S", | ||
| 736 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "exp2l.S", | ||
| 737 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "exp2.S", | ||
| 738 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "exp.c", | ||
| 739 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "expl.c", | ||
| 740 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "expm1.c", | ||
| 741 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "expm1f.c", | ||
| 742 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "expm1l.c", | ||
| 743 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "floorf.S", | ||
| 744 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "floorl.S", | ||
| 745 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "floor.S", | ||
| 746 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "fmod.c", | ||
| 747 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "fmodf.c", | ||
| 748 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "fmodl.c", | ||
| 749 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "fucom.c", | ||
| 750 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "ilogbf.S", | ||
| 751 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "ilogbl.S", | ||
| 752 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "ilogb.S", | ||
| 753 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "internal_logl.S", | ||
| 754 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "ldexp.c", | ||
| 755 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "ldexpl.c", | ||
| 756 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "log10l.S", | ||
| 757 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "log1pf.S", | ||
| 758 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "log1pl.S", | ||
| 759 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "log1p.S", | ||
| 760 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "log2f.S", | ||
| 761 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "log2l.S", | ||
| 762 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "log2.S", | ||
| 763 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "logb.c", | ||
| 764 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "logbf.c", | ||
| 765 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "logbl.c", | ||
| 766 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "log.c", | ||
| 767 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "logl.c", | ||
| 768 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "nearbyintf.S", | ||
| 769 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "nearbyintl.S", | ||
| 770 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "nearbyint.S", | ||
| 771 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "pow.c", | ||
| 772 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "powl.c", | ||
| 773 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "remainderf.S", | ||
| 774 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "remainderl.S", | ||
| 775 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "remainder.S", | ||
| 776 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "remquof.S", | ||
| 777 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "remquol.S", | ||
| 778 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "remquo.S", | ||
| 779 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "scalbnf.S", | ||
| 780 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "scalbnl.S", | ||
| 781 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "scalbn.S", | ||
| 782 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "sin.c", | ||
| 783 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "sinf.c", | ||
| 784 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "sinl.c", | ||
| 785 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "sinl_internal.S", | ||
| 786 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "tanf.c", | ||
| 787 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "tanl.S", | ||
| 788 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "truncf.S", | ||
| 789 | "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "trunc.S", | ||
| 790 | }; | ||
| 791 | |||
| 792 | const mingwex_arm32_src = [_][]const u8{ | ||
| 793 | "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "_chgsignl.S", | ||
| 794 | "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "exp2.c", | ||
| 795 | "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "nearbyint.S", | ||
| 796 | "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "nearbyintf.S", | ||
| 797 | "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "nearbyintl.S", | ||
| 798 | "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "trunc.S", | ||
| 799 | "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "truncf.S", | ||
| 800 | }; | ||
| 801 | |||
| 802 | const mingwex_arm64_src = [_][]const u8{ | ||
| 803 | "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "_chgsignl.S", | ||
| 804 | "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "exp2f.S", | ||
| 805 | "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "exp2.S", | ||
| 806 | "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "nearbyintf.S", | ||
| 807 | "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "nearbyintl.S", | ||
| 808 | "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "nearbyint.S", | ||
| 809 | "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "truncf.S", | ||
| 810 | "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "trunc.S", | ||
| 811 | }; | ||
| 812 | |||
| 813 | const uuid_src = [_][]const u8{ | ||
| 814 | "ativscp-uuid.c", | ||
| 815 | "atsmedia-uuid.c", | ||
| 816 | "bth-uuid.c", | ||
| 817 | "cguid-uuid.c", | ||
| 818 | "comcat-uuid.c", | ||
| 819 | "devguid.c", | ||
| 820 | "docobj-uuid.c", | ||
| 821 | "dxva-uuid.c", | ||
| 822 | "exdisp-uuid.c", | ||
| 823 | "extras-uuid.c", | ||
| 824 | "fwp-uuid.c", | ||
| 825 | "guid_nul.c", | ||
| 826 | "hlguids-uuid.c", | ||
| 827 | "hlink-uuid.c", | ||
| 828 | "mlang-uuid.c", | ||
| 829 | "msctf-uuid.c", | ||
| 830 | "mshtmhst-uuid.c", | ||
| 831 | "mshtml-uuid.c", | ||
| 832 | "msxml-uuid.c", | ||
| 833 | "netcon-uuid.c", | ||
| 834 | "ntddkbd-uuid.c", | ||
| 835 | "ntddmou-uuid.c", | ||
| 836 | "ntddpar-uuid.c", | ||
| 837 | "ntddscsi-uuid.c", | ||
| 838 | "ntddser-uuid.c", | ||
| 839 | "ntddstor-uuid.c", | ||
| 840 | "ntddvdeo-uuid.c", | ||
| 841 | "oaidl-uuid.c", | ||
| 842 | "objidl-uuid.c", | ||
| 843 | "objsafe-uuid.c", | ||
| 844 | "ocidl-uuid.c", | ||
| 845 | "oleacc-uuid.c", | ||
| 846 | "olectlid-uuid.c", | ||
| 847 | "oleidl-uuid.c", | ||
| 848 | "power-uuid.c", | ||
| 849 | "powrprof-uuid.c", | ||
| 850 | "uianimation-uuid.c", | ||
| 851 | "usbcamdi-uuid.c", | ||
| 852 | "usbiodef-uuid.c", | ||
| 853 | "uuid.c", | ||
| 854 | "vds-uuid.c", | ||
| 855 | "virtdisk-uuid.c", | ||
| 856 | "wia-uuid.c", | ||
| 857 | }; | ||
| 858 | |||
| 859 | pub const always_link_libs = [_][]const u8{ | ||
| 860 | "advapi32", | ||
| 861 | "kernel32", | ||
| 862 | "msvcrt", | ||
| 863 | "ntdll", | ||
| 864 | "shell32", | ||
| 865 | "user32", | ||
| 866 | }; | ||
src/musl.zig-3| ... | @@ -7,9 +7,6 @@ const assert = std.debug.assert; | ... | @@ -7,9 +7,6 @@ const assert = std.debug.assert; |
| 7 | const target_util = @import("target.zig"); | 7 | const target_util = @import("target.zig"); |
| 8 | const Compilation = @import("Compilation.zig"); | 8 | const Compilation = @import("Compilation.zig"); |
| 9 | const build_options = @import("build_options"); | 9 | const build_options = @import("build_options"); |
| 10 | const trace = @import("tracy.zig").trace; | ||
| 11 | const Cache = @import("Cache.zig"); | ||
| 12 | const Package = @import("Package.zig"); | ||
| 13 | 10 | ||
| 14 | pub const CRTFile = enum { | 11 | pub const CRTFile = enum { |
| 15 | crti_o, | 12 | crti_o, |
src/stage1.zig+8| ... | @@ -121,6 +121,14 @@ pub const Module = extern struct { | ... | @@ -121,6 +121,14 @@ pub const Module = extern struct { |
| 121 | verbose_cimport: bool, | 121 | verbose_cimport: bool, |
| 122 | verbose_llvm_cpu_features: bool, | 122 | verbose_llvm_cpu_features: bool, |
| 123 | 123 | ||
| 124 | // Set by stage1 | ||
| 125 | have_c_main: bool, | ||
| 126 | have_winmain: bool, | ||
| 127 | have_wwinmain: bool, | ||
| 128 | have_winmain_crt_startup: bool, | ||
| 129 | have_wwinmain_crt_startup: bool, | ||
| 130 | have_dllmain_crt_startup: bool, | ||
| 131 | |||
| 124 | pub fn build_object(mod: *Module) void { | 132 | pub fn build_object(mod: *Module) void { |
| 125 | zig_stage1_build_object(mod); | 133 | zig_stage1_build_object(mod); |
| 126 | } | 134 | } |
src/stage1/all_types.hpp-6| ... | @@ -2152,12 +2152,6 @@ struct CodeGen { | ... | @@ -2152,12 +2152,6 @@ struct CodeGen { |
| 2152 | uint32_t next_unresolved_index; | 2152 | uint32_t next_unresolved_index; |
| 2153 | unsigned pointer_size_bytes; | 2153 | unsigned pointer_size_bytes; |
| 2154 | bool is_big_endian; | 2154 | bool is_big_endian; |
| 2155 | bool have_c_main; | ||
| 2156 | bool have_winmain; | ||
| 2157 | bool have_wwinmain; | ||
| 2158 | bool have_winmain_crt_startup; | ||
| 2159 | bool have_wwinmain_crt_startup; | ||
| 2160 | bool have_dllmain_crt_startup; | ||
| 2161 | bool have_err_ret_tracing; | 2155 | bool have_err_ret_tracing; |
| 2162 | bool verbose_tokenize; | 2156 | bool verbose_tokenize; |
| 2163 | bool verbose_ast; | 2157 | bool verbose_ast; |
src/stage1/analyze.cpp+6-6| ... | @@ -3496,18 +3496,18 @@ void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLink | ... | @@ -3496,18 +3496,18 @@ void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLink |
| 3496 | 3496 | ||
| 3497 | void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, CallingConvention cc) { | 3497 | void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, CallingConvention cc) { |
| 3498 | if (cc == CallingConventionC && strcmp(symbol_name, "main") == 0 && g->link_libc) { | 3498 | if (cc == CallingConventionC && strcmp(symbol_name, "main") == 0 && g->link_libc) { |
| 3499 | g->have_c_main = true; | 3499 | g->stage1.have_c_main = true; |
| 3500 | } else if (cc == CallingConventionStdcall && g->zig_target->os == OsWindows) { | 3500 | } else if (cc == CallingConventionStdcall && g->zig_target->os == OsWindows) { |
| 3501 | if (strcmp(symbol_name, "WinMain") == 0) { | 3501 | if (strcmp(symbol_name, "WinMain") == 0) { |
| 3502 | g->have_winmain = true; | 3502 | g->stage1.have_winmain = true; |
| 3503 | } else if (strcmp(symbol_name, "wWinMain") == 0) { | 3503 | } else if (strcmp(symbol_name, "wWinMain") == 0) { |
| 3504 | g->have_wwinmain = true; | 3504 | g->stage1.have_wwinmain = true; |
| 3505 | } else if (strcmp(symbol_name, "WinMainCRTStartup") == 0) { | 3505 | } else if (strcmp(symbol_name, "WinMainCRTStartup") == 0) { |
| 3506 | g->have_winmain_crt_startup = true; | 3506 | g->stage1.have_winmain_crt_startup = true; |
| 3507 | } else if (strcmp(symbol_name, "wWinMainCRTStartup") == 0) { | 3507 | } else if (strcmp(symbol_name, "wWinMainCRTStartup") == 0) { |
| 3508 | g->have_wwinmain_crt_startup = true; | 3508 | g->stage1.have_wwinmain_crt_startup = true; |
| 3509 | } else if (strcmp(symbol_name, "DllMainCRTStartup") == 0) { | 3509 | } else if (strcmp(symbol_name, "DllMainCRTStartup") == 0) { |
| 3510 | g->have_dllmain_crt_startup = true; | 3510 | g->stage1.have_dllmain_crt_startup = true; |
| 3511 | } | 3511 | } |
| 3512 | } | 3512 | } |
| 3513 | 3513 |
src/stage1/codegen.cpp+3-3| ... | @@ -8666,11 +8666,11 @@ TargetSubsystem detect_subsystem(CodeGen *g) { | ... | @@ -8666,11 +8666,11 @@ TargetSubsystem detect_subsystem(CodeGen *g) { |
| 8666 | if (g->subsystem != TargetSubsystemAuto) | 8666 | if (g->subsystem != TargetSubsystemAuto) |
| 8667 | return g->subsystem; | 8667 | return g->subsystem; |
| 8668 | if (g->zig_target->os == OsWindows) { | 8668 | if (g->zig_target->os == OsWindows) { |
| 8669 | if (g->have_dllmain_crt_startup) | 8669 | if (g->stage1.have_dllmain_crt_startup) |
| 8670 | return TargetSubsystemAuto; | 8670 | return TargetSubsystemAuto; |
| 8671 | if (g->have_c_main || g->is_test_build || g->have_winmain_crt_startup || g->have_wwinmain_crt_startup) | 8671 | if (g->stage1.have_c_main || g->is_test_build || g->stage1.have_winmain_crt_startup || g->stage1.have_wwinmain_crt_startup) |
| 8672 | return TargetSubsystemConsole; | 8672 | return TargetSubsystemConsole; |
| 8673 | if (g->have_winmain || g->have_wwinmain) | 8673 | if (g->stage1.have_winmain || g->stage1.have_wwinmain) |
| 8674 | return TargetSubsystemWindows; | 8674 | return TargetSubsystemWindows; |
| 8675 | } else if (g->zig_target->os == OsUefi) { | 8675 | } else if (g->zig_target->os == OsUefi) { |
| 8676 | return TargetSubsystemEfiApplication; | 8676 | return TargetSubsystemEfiApplication; |
src/stage1/stage1.h+8| ... | @@ -195,6 +195,14 @@ struct ZigStage1 { | ... | @@ -195,6 +195,14 @@ struct ZigStage1 { |
| 195 | bool verbose_llvm_ir; | 195 | bool verbose_llvm_ir; |
| 196 | bool verbose_cimport; | 196 | bool verbose_cimport; |
| 197 | bool verbose_llvm_cpu_features; | 197 | bool verbose_llvm_cpu_features; |
| 198 | |||
| 199 | // Set by stage1 | ||
| 200 | bool have_c_main; | ||
| 201 | bool have_winmain; | ||
| 202 | bool have_wwinmain; | ||
| 203 | bool have_winmain_crt_startup; | ||
| 204 | bool have_wwinmain_crt_startup; | ||
| 205 | bool have_dllmain_crt_startup; | ||
| 198 | }; | 206 | }; |
| 199 | 207 | ||
| 200 | ZIG_EXTERN_C void zig_stage1_os_init(void); | 208 | ZIG_EXTERN_C void zig_stage1_os_init(void); |