| ... | @@ -53,6 +53,9 @@ c_object_work_queue: std.fifo.LinearFifo(*CObject, .Dynamic), | ... | @@ -53,6 +53,9 @@ c_object_work_queue: std.fifo.LinearFifo(*CObject, .Dynamic), |
| 53 | /// This data is accessed by multiple threads and is protected by `mutex`. | 53 | /// This data is accessed by multiple threads and is protected by `mutex`. |
| 54 | failed_c_objects: std.AutoArrayHashMapUnmanaged(*CObject, *CObject.ErrorMsg) = .{}, | 54 | failed_c_objects: std.AutoArrayHashMapUnmanaged(*CObject, *CObject.ErrorMsg) = .{}, |
| 55 | | 55 | |
| | 56 | /// Miscellaneous things that can fail. |
| | 57 | misc_failures: std.AutoArrayHashMapUnmanaged(MiscTask, MiscError) = .{}, |
| | 58 | |
| 56 | keep_source_files_loaded: bool, | 59 | keep_source_files_loaded: bool, |
| 57 | use_clang: bool, | 60 | use_clang: bool, |
| 58 | sanitize_c: bool, | 61 | sanitize_c: bool, |
| ... | @@ -256,6 +259,36 @@ pub const CObject = struct { | ... | @@ -256,6 +259,36 @@ pub const CObject = struct { |
| 256 | } | 259 | } |
| 257 | }; | 260 | }; |
| 258 | | 261 | |
| | 262 | pub const MiscTask = enum { |
| | 263 | write_builtin_zig, |
| | 264 | glibc_crt_file, |
| | 265 | glibc_shared_objects, |
| | 266 | musl_crt_file, |
| | 267 | mingw_crt_file, |
| | 268 | windows_import_lib, |
| | 269 | libunwind, |
| | 270 | libcxx, |
| | 271 | libcxxabi, |
| | 272 | libtsan, |
| | 273 | compiler_rt, |
| | 274 | libssp, |
| | 275 | zig_libc, |
| | 276 | }; |
| | 277 | |
| | 278 | pub const MiscError = struct { |
| | 279 | /// Allocated with gpa. |
| | 280 | msg: []u8, |
| | 281 | children: ?AllErrors = null, |
| | 282 | |
| | 283 | pub fn deinit(misc_err: *MiscError, gpa: *Allocator) void { |
| | 284 | gpa.free(misc_err.msg); |
| | 285 | if (misc_err.children) |*children| { |
| | 286 | children.deinit(gpa); |
| | 287 | } |
| | 288 | misc_err.* = undefined; |
| | 289 | } |
| | 290 | }; |
| | 291 | |
| 259 | /// To support incremental compilation, errors are stored in various places | 292 | /// To support incremental compilation, errors are stored in various places |
| 260 | /// so that they can be created and destroyed appropriately. This structure | 293 | /// so that they can be created and destroyed appropriately. This structure |
| 261 | /// is used to collect all the errors from the various places into one | 294 | /// is used to collect all the errors from the various places into one |
| ... | @@ -278,6 +311,7 @@ pub const AllErrors = struct { | ... | @@ -278,6 +311,7 @@ pub const AllErrors = struct { |
| 278 | }, | 311 | }, |
| 279 | plain: struct { | 312 | plain: struct { |
| 280 | msg: []const u8, | 313 | msg: []const u8, |
| | 314 | notes: []Message = &.{}, |
| 281 | }, | 315 | }, |
| 282 | | 316 | |
| 283 | pub fn renderToStdErr(msg: Message, ttyconf: std.debug.TTY.Config) void { | 317 | pub fn renderToStdErr(msg: Message, ttyconf: std.debug.TTY.Config) void { |
| ... | @@ -285,7 +319,7 @@ pub const AllErrors = struct { | ... | @@ -285,7 +319,7 @@ pub const AllErrors = struct { |
| 285 | const held = std.debug.getStderrMutex().acquire(); | 319 | const held = std.debug.getStderrMutex().acquire(); |
| 286 | defer held.release(); | 320 | defer held.release(); |
| 287 | const stderr = std.io.getStdErr(); | 321 | const stderr = std.io.getStdErr(); |
| 288 | return msg.renderToStdErrInner(ttyconf, stderr, "error:", .Red) catch return; | 322 | return msg.renderToStdErrInner(ttyconf, stderr, "error:", .Red, 0) catch return; |
| 289 | } | 323 | } |
| 290 | | 324 | |
| 291 | fn renderToStdErrInner( | 325 | fn renderToStdErrInner( |
| ... | @@ -294,6 +328,7 @@ pub const AllErrors = struct { | ... | @@ -294,6 +328,7 @@ pub const AllErrors = struct { |
| 294 | stderr_file: std.fs.File, | 328 | stderr_file: std.fs.File, |
| 295 | kind: []const u8, | 329 | kind: []const u8, |
| 296 | color: std.debug.TTY.Color, | 330 | color: std.debug.TTY.Color, |
| | 331 | indent: usize, |
| 297 | ) anyerror!void { | 332 | ) anyerror!void { |
| 298 | const stderr = stderr_file.writer(); | 333 | const stderr = stderr_file.writer(); |
| 299 | switch (msg) { | 334 | switch (msg) { |
| ... | @@ -305,6 +340,7 @@ pub const AllErrors = struct { | ... | @@ -305,6 +340,7 @@ pub const AllErrors = struct { |
| 305 | src.column + 1, | 340 | src.column + 1, |
| 306 | }); | 341 | }); |
| 307 | ttyconf.setColor(stderr, color); | 342 | ttyconf.setColor(stderr, color); |
| | 343 | try stderr.writeByteNTimes(' ', indent); |
| 308 | try stderr.writeAll(kind); | 344 | try stderr.writeAll(kind); |
| 309 | ttyconf.setColor(stderr, .Bold); | 345 | ttyconf.setColor(stderr, .Bold); |
| 310 | try stderr.print(" {s}\n", .{src.msg}); | 346 | try stderr.print(" {s}\n", .{src.msg}); |
| ... | @@ -318,11 +354,19 @@ pub const AllErrors = struct { | ... | @@ -318,11 +354,19 @@ pub const AllErrors = struct { |
| 318 | ttyconf.setColor(stderr, .Reset); | 354 | ttyconf.setColor(stderr, .Reset); |
| 319 | } | 355 | } |
| 320 | for (src.notes) |note| { | 356 | for (src.notes) |note| { |
| 321 | try note.renderToStdErrInner(ttyconf, stderr_file, "note:", .Cyan); | 357 | try note.renderToStdErrInner(ttyconf, stderr_file, "note:", .Cyan, indent); |
| 322 | } | 358 | } |
| 323 | }, | 359 | }, |
| 324 | .plain => |plain| { | 360 | .plain => |plain| { |
| 325 | try stderr.print("{s}: {s}\n", .{ kind, plain.msg }); | 361 | ttyconf.setColor(stderr, color); |
| | 362 | try stderr.writeByteNTimes(' ', indent); |
| | 363 | try stderr.writeAll(kind); |
| | 364 | ttyconf.setColor(stderr, .Reset); |
| | 365 | try stderr.print(" {s}\n", .{plain.msg}); |
| | 366 | ttyconf.setColor(stderr, .Reset); |
| | 367 | for (plain.notes) |note| { |
| | 368 | try note.renderToStdErrInner(ttyconf, stderr_file, "error:", .Red, indent + 4); |
| | 369 | } |
| 326 | }, | 370 | }, |
| 327 | } | 371 | } |
| 328 | } | 372 | } |
| ... | @@ -380,6 +424,45 @@ pub const AllErrors = struct { | ... | @@ -380,6 +424,45 @@ pub const AllErrors = struct { |
| 380 | ) !void { | 424 | ) !void { |
| 381 | try errors.append(.{ .plain = .{ .msg = msg } }); | 425 | try errors.append(.{ .plain = .{ .msg = msg } }); |
| 382 | } | 426 | } |
| | 427 | |
| | 428 | fn addPlainWithChildren( |
| | 429 | arena: *std.heap.ArenaAllocator, |
| | 430 | errors: *std.ArrayList(Message), |
| | 431 | msg: []const u8, |
| | 432 | optional_children: ?AllErrors, |
| | 433 | ) !void { |
| | 434 | const duped_msg = try arena.allocator.dupe(u8, msg); |
| | 435 | if (optional_children) |*children| { |
| | 436 | try errors.append(.{ .plain = .{ |
| | 437 | .msg = duped_msg, |
| | 438 | .notes = try dupeList(children.list, &arena.allocator), |
| | 439 | } }); |
| | 440 | } else { |
| | 441 | try errors.append(.{ .plain = .{ .msg = duped_msg } }); |
| | 442 | } |
| | 443 | } |
| | 444 | |
| | 445 | fn dupeList(list: []const Message, arena: *Allocator) Allocator.Error![]Message { |
| | 446 | const duped_list = try arena.alloc(Message, list.len); |
| | 447 | for (list) |item, i| { |
| | 448 | duped_list[i] = switch (item) { |
| | 449 | .src => |src| .{ .src = .{ |
| | 450 | .msg = try arena.dupe(u8, src.msg), |
| | 451 | .src_path = try arena.dupe(u8, src.src_path), |
| | 452 | .line = src.line, |
| | 453 | .column = src.column, |
| | 454 | .byte_offset = src.byte_offset, |
| | 455 | .source_line = if (src.source_line) |s| try arena.dupe(u8, s) else null, |
| | 456 | .notes = try dupeList(src.notes, arena), |
| | 457 | } }, |
| | 458 | .plain => |plain| .{ .plain = .{ |
| | 459 | .msg = try arena.dupe(u8, plain.msg), |
| | 460 | .notes = try dupeList(plain.notes, arena), |
| | 461 | } }, |
| | 462 | }; |
| | 463 | } |
| | 464 | return duped_list; |
| | 465 | } |
| 383 | }; | 466 | }; |
| 384 | | 467 | |
| 385 | pub const Directory = struct { | 468 | pub const Directory = struct { |
| ... | @@ -1357,6 +1440,8 @@ pub fn destroy(self: *Compilation) void { | ... | @@ -1357,6 +1440,8 @@ pub fn destroy(self: *Compilation) void { |
| 1357 | } | 1440 | } |
| 1358 | self.failed_c_objects.deinit(gpa); | 1441 | self.failed_c_objects.deinit(gpa); |
| 1359 | | 1442 | |
| | 1443 | self.clearMiscFailures(); |
| | 1444 | |
| 1360 | self.cache_parent.manifest_dir.close(); | 1445 | self.cache_parent.manifest_dir.close(); |
| 1361 | if (self.owned_link_dir) |*dir| dir.close(); | 1446 | if (self.owned_link_dir) |*dir| dir.close(); |
| 1362 | | 1447 | |
| ... | @@ -1366,6 +1451,14 @@ pub fn destroy(self: *Compilation) void { | ... | @@ -1366,6 +1451,14 @@ pub fn destroy(self: *Compilation) void { |
| 1366 | self.arena_state.promote(gpa).deinit(); | 1451 | self.arena_state.promote(gpa).deinit(); |
| 1367 | } | 1452 | } |
| 1368 | | 1453 | |
| | 1454 | pub fn clearMiscFailures(comp: *Compilation) void { |
| | 1455 | for (comp.misc_failures.items()) |*entry| { |
| | 1456 | entry.value.deinit(comp.gpa); |
| | 1457 | } |
| | 1458 | comp.misc_failures.deinit(comp.gpa); |
| | 1459 | comp.misc_failures = .{}; |
| | 1460 | } |
| | 1461 | |
| 1369 | pub fn getTarget(self: Compilation) Target { | 1462 | pub fn getTarget(self: Compilation) Target { |
| 1370 | return self.bin_file.options.target; | 1463 | return self.bin_file.options.target; |
| 1371 | } | 1464 | } |
| ... | @@ -1375,6 +1468,7 @@ pub fn update(self: *Compilation) !void { | ... | @@ -1375,6 +1468,7 @@ pub fn update(self: *Compilation) !void { |
| 1375 | const tracy = trace(@src()); | 1468 | const tracy = trace(@src()); |
| 1376 | defer tracy.end(); | 1469 | defer tracy.end(); |
| 1377 | | 1470 | |
| | 1471 | self.clearMiscFailures(); |
| 1378 | self.c_object_cache_digest_set.clearRetainingCapacity(); | 1472 | self.c_object_cache_digest_set.clearRetainingCapacity(); |
| 1379 | | 1473 | |
| 1380 | // For compiling C objects, we rely on the cache hash system to avoid duplicating work. | 1474 | // For compiling C objects, we rely on the cache hash system to avoid duplicating work. |
| ... | @@ -1475,7 +1569,7 @@ pub fn makeBinFileWritable(self: *Compilation) !void { | ... | @@ -1475,7 +1569,7 @@ pub fn makeBinFileWritable(self: *Compilation) !void { |
| 1475 | } | 1569 | } |
| 1476 | | 1570 | |
| 1477 | pub fn totalErrorCount(self: *Compilation) usize { | 1571 | pub fn totalErrorCount(self: *Compilation) usize { |
| 1478 | var total: usize = self.failed_c_objects.items().len; | 1572 | var total: usize = self.failed_c_objects.count() + self.misc_failures.count(); |
| 1479 | | 1573 | |
| 1480 | if (self.bin_file.options.module) |module| { | 1574 | if (self.bin_file.options.module) |module| { |
| 1481 | total += module.failed_exports.items().len + | 1575 | total += module.failed_exports.items().len + |
| ... | @@ -1539,6 +1633,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { | ... | @@ -1539,6 +1633,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { |
| 1539 | }, | 1633 | }, |
| 1540 | }); | 1634 | }); |
| 1541 | } | 1635 | } |
| | 1636 | for (self.misc_failures.items()) |entry| { |
| | 1637 | try AllErrors.addPlainWithChildren(&arena, &errors, entry.value.msg, entry.value.children); |
| | 1638 | } |
| 1542 | if (self.bin_file.options.module) |module| { | 1639 | if (self.bin_file.options.module) |module| { |
| 1543 | for (module.failed_files.items()) |entry| { | 1640 | for (module.failed_files.items()) |entry| { |
| 1544 | try AllErrors.add(module, &arena, &errors, entry.value.*); | 1641 | try AllErrors.add(module, &arena, &errors, entry.value.*); |
| ... | @@ -1775,89 +1872,160 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor | ... | @@ -1775,89 +1872,160 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor |
| 1775 | }, | 1872 | }, |
| 1776 | .glibc_crt_file => |crt_file| { | 1873 | .glibc_crt_file => |crt_file| { |
| 1777 | glibc.buildCRTFile(self, crt_file) catch |err| { | 1874 | glibc.buildCRTFile(self, crt_file) catch |err| { |
| 1778 | // TODO Expose this as a normal compile error rather than crashing here. | 1875 | // TODO Surface more error details. |
| 1779 | fatal("unable to build glibc CRT file: {s}", .{@errorName(err)}); | 1876 | try self.setMiscFailure(.glibc_crt_file, "unable to build glibc CRT file: {s}", .{ |
| | 1877 | @errorName(err), |
| | 1878 | }); |
| 1780 | }; | 1879 | }; |
| 1781 | }, | 1880 | }, |
| 1782 | .glibc_shared_objects => { | 1881 | .glibc_shared_objects => { |
| 1783 | glibc.buildSharedObjects(self) catch |err| { | 1882 | glibc.buildSharedObjects(self) catch |err| { |
| 1784 | // TODO Expose this as a normal compile error rather than crashing here. | 1883 | // TODO Surface more error details. |
| 1785 | fatal("unable to build glibc shared objects: {s}", .{@errorName(err)}); | 1884 | try self.setMiscFailure( |
| | 1885 | .glibc_shared_objects, |
| | 1886 | "unable to build glibc shared objects: {s}", |
| | 1887 | .{@errorName(err)}, |
| | 1888 | ); |
| 1786 | }; | 1889 | }; |
| 1787 | }, | 1890 | }, |
| 1788 | .musl_crt_file => |crt_file| { | 1891 | .musl_crt_file => |crt_file| { |
| 1789 | musl.buildCRTFile(self, crt_file) catch |err| { | 1892 | musl.buildCRTFile(self, crt_file) catch |err| { |
| 1790 | // TODO Expose this as a normal compile error rather than crashing here. | 1893 | // TODO Surface more error details. |
| 1791 | fatal("unable to build musl CRT file: {s}", .{@errorName(err)}); | 1894 | try self.setMiscFailure( |
| | 1895 | .musl_crt_file, |
| | 1896 | "unable to build musl CRT file: {s}", |
| | 1897 | .{@errorName(err)}, |
| | 1898 | ); |
| 1792 | }; | 1899 | }; |
| 1793 | }, | 1900 | }, |
| 1794 | .mingw_crt_file => |crt_file| { | 1901 | .mingw_crt_file => |crt_file| { |
| 1795 | mingw.buildCRTFile(self, crt_file) catch |err| { | 1902 | mingw.buildCRTFile(self, crt_file) catch |err| { |
| 1796 | // TODO Expose this as a normal compile error rather than crashing here. | 1903 | // TODO Surface more error details. |
| 1797 | fatal("unable to build mingw-w64 CRT file: {s}", .{@errorName(err)}); | 1904 | try self.setMiscFailure( |
| | 1905 | .mingw_crt_file, |
| | 1906 | "unable to build mingw-w64 CRT file: {s}", |
| | 1907 | .{@errorName(err)}, |
| | 1908 | ); |
| 1798 | }; | 1909 | }; |
| 1799 | }, | 1910 | }, |
| 1800 | .windows_import_lib => |index| { | 1911 | .windows_import_lib => |index| { |
| 1801 | const link_lib = self.bin_file.options.system_libs.items()[index].key; | 1912 | const link_lib = self.bin_file.options.system_libs.items()[index].key; |
| 1802 | mingw.buildImportLib(self, link_lib) catch |err| { | 1913 | mingw.buildImportLib(self, link_lib) catch |err| { |
| 1803 | // TODO Expose this as a normal compile error rather than crashing here. | 1914 | // TODO Surface more error details. |
| 1804 | fatal("unable to generate DLL import .lib file: {s}", .{@errorName(err)}); | 1915 | try self.setMiscFailure( |
| | 1916 | .windows_import_lib, |
| | 1917 | "unable to generate DLL import .lib file: {s}", |
| | 1918 | .{@errorName(err)}, |
| | 1919 | ); |
| 1805 | }; | 1920 | }; |
| 1806 | }, | 1921 | }, |
| 1807 | .libunwind => { | 1922 | .libunwind => { |
| 1808 | libunwind.buildStaticLib(self) catch |err| { | 1923 | libunwind.buildStaticLib(self) catch |err| { |
| 1809 | // TODO Expose this as a normal compile error rather than crashing here. | 1924 | // TODO Surface more error details. |
| 1810 | fatal("unable to build libunwind: {s}", .{@errorName(err)}); | 1925 | try self.setMiscFailure( |
| | 1926 | .libunwind, |
| | 1927 | "unable to build libunwind: {s}", |
| | 1928 | .{@errorName(err)}, |
| | 1929 | ); |
| 1811 | }; | 1930 | }; |
| 1812 | }, | 1931 | }, |
| 1813 | .libcxx => { | 1932 | .libcxx => { |
| 1814 | libcxx.buildLibCXX(self) catch |err| { | 1933 | libcxx.buildLibCXX(self) catch |err| { |
| 1815 | // TODO Expose this as a normal compile error rather than crashing here. | 1934 | // TODO Surface more error details. |
| 1816 | fatal("unable to build libcxx: {s}", .{@errorName(err)}); | 1935 | try self.setMiscFailure( |
| | 1936 | .libcxx, |
| | 1937 | "unable to build libcxx: {s}", |
| | 1938 | .{@errorName(err)}, |
| | 1939 | ); |
| 1817 | }; | 1940 | }; |
| 1818 | }, | 1941 | }, |
| 1819 | .libcxxabi => { | 1942 | .libcxxabi => { |
| 1820 | libcxx.buildLibCXXABI(self) catch |err| { | 1943 | libcxx.buildLibCXXABI(self) catch |err| { |
| 1821 | // TODO Expose this as a normal compile error rather than crashing here. | 1944 | // TODO Surface more error details. |
| 1822 | fatal("unable to build libcxxabi: {s}", .{@errorName(err)}); | 1945 | try self.setMiscFailure( |
| | 1946 | .libcxxabi, |
| | 1947 | "unable to build libcxxabi: {s}", |
| | 1948 | .{@errorName(err)}, |
| | 1949 | ); |
| 1823 | }; | 1950 | }; |
| 1824 | }, | 1951 | }, |
| 1825 | .libtsan => { | 1952 | .libtsan => { |
| 1826 | libtsan.buildTsan(self) catch |err| { | 1953 | libtsan.buildTsan(self) catch |err| { |
| 1827 | // TODO Expose this as a normal compile error rather than crashing here. | 1954 | // TODO Surface more error details. |
| 1828 | fatal("unable to build TSAN library: {s}", .{@errorName(err)}); | 1955 | try self.setMiscFailure( |
| | 1956 | .libtsan, |
| | 1957 | "unable to build TSAN library: {s}", |
| | 1958 | .{@errorName(err)}, |
| | 1959 | ); |
| 1829 | }; | 1960 | }; |
| 1830 | }, | 1961 | }, |
| 1831 | .compiler_rt_lib => { | 1962 | .compiler_rt_lib => { |
| 1832 | self.buildOutputFromZig("compiler_rt.zig", .Lib, &self.compiler_rt_static_lib) catch |err| { | 1963 | self.buildOutputFromZig( |
| 1833 | // TODO Expose this as a normal compile error rather than crashing here. | 1964 | "compiler_rt.zig", |
| 1834 | fatal("unable to build compiler_rt: {s}", .{@errorName(err)}); | 1965 | .Lib, |
| | 1966 | &self.compiler_rt_static_lib, |
| | 1967 | .compiler_rt, |
| | 1968 | ) catch |err| switch (err) { |
| | 1969 | error.OutOfMemory => return error.OutOfMemory, |
| | 1970 | error.SubCompilationFailed => continue, // error reported already |
| | 1971 | else => try self.setMiscFailure( |
| | 1972 | .compiler_rt, |
| | 1973 | "unable to build compiler_rt: {s}", |
| | 1974 | .{@errorName(err)}, |
| | 1975 | ), |
| 1835 | }; | 1976 | }; |
| 1836 | }, | 1977 | }, |
| 1837 | .compiler_rt_obj => { | 1978 | .compiler_rt_obj => { |
| 1838 | self.buildOutputFromZig("compiler_rt.zig", .Obj, &self.compiler_rt_obj) catch |err| { | 1979 | self.buildOutputFromZig( |
| 1839 | // TODO Expose this as a normal compile error rather than crashing here. | 1980 | "compiler_rt.zig", |
| 1840 | fatal("unable to build compiler_rt: {s}", .{@errorName(err)}); | 1981 | .Obj, |
| | 1982 | &self.compiler_rt_obj, |
| | 1983 | .compiler_rt, |
| | 1984 | ) catch |err| switch (err) { |
| | 1985 | error.OutOfMemory => return error.OutOfMemory, |
| | 1986 | error.SubCompilationFailed => continue, // error reported already |
| | 1987 | else => try self.setMiscFailure( |
| | 1988 | .compiler_rt, |
| | 1989 | "unable to build compiler_rt: {s}", |
| | 1990 | .{@errorName(err)}, |
| | 1991 | ), |
| 1841 | }; | 1992 | }; |
| 1842 | }, | 1993 | }, |
| 1843 | .libssp => { | 1994 | .libssp => { |
| 1844 | self.buildOutputFromZig("ssp.zig", .Lib, &self.libssp_static_lib) catch |err| { | 1995 | self.buildOutputFromZig( |
| 1845 | // TODO Expose this as a normal compile error rather than crashing here. | 1996 | "ssp.zig", |
| 1846 | fatal("unable to build libssp: {s}", .{@errorName(err)}); | 1997 | .Lib, |
| | 1998 | &self.libssp_static_lib, |
| | 1999 | .libssp, |
| | 2000 | ) catch |err| switch (err) { |
| | 2001 | error.OutOfMemory => return error.OutOfMemory, |
| | 2002 | error.SubCompilationFailed => continue, // error reported already |
| | 2003 | else => try self.setMiscFailure( |
| | 2004 | .libssp, |
| | 2005 | "unable to build libssp: {s}", |
| | 2006 | .{@errorName(err)}, |
| | 2007 | ), |
| 1847 | }; | 2008 | }; |
| 1848 | }, | 2009 | }, |
| 1849 | .zig_libc => { | 2010 | .zig_libc => { |
| 1850 | self.buildOutputFromZig("c.zig", .Lib, &self.libc_static_lib) catch |err| { | 2011 | self.buildOutputFromZig( |
| 1851 | // TODO Expose this as a normal compile error rather than crashing here. | 2012 | "c.zig", |
| 1852 | fatal("unable to build zig's multitarget libc: {s}", .{@errorName(err)}); | 2013 | .Lib, |
| | 2014 | &self.libc_static_lib, |
| | 2015 | .zig_libc, |
| | 2016 | ) catch |err| switch (err) { |
| | 2017 | error.OutOfMemory => return error.OutOfMemory, |
| | 2018 | error.SubCompilationFailed => continue, // error reported already |
| | 2019 | else => try self.setMiscFailure( |
| | 2020 | .zig_libc, |
| | 2021 | "unable to build zig's multitarget libc: {s}", |
| | 2022 | .{@errorName(err)}, |
| | 2023 | ), |
| 1853 | }; | 2024 | }; |
| 1854 | }, | 2025 | }, |
| 1855 | .generate_builtin_zig => { | 2026 | .generate_builtin_zig => { |
| 1856 | // This Job is only queued up if there is a zig module. | 2027 | // This Job is only queued up if there is a zig module. |
| 1857 | self.updateBuiltinZigFile(self.bin_file.options.module.?) catch |err| { | 2028 | try self.updateBuiltinZigFile(self.bin_file.options.module.?); |
| 1858 | // TODO Expose this as a normal compile error rather than crashing here. | | |
| 1859 | fatal("unable to update builtin.zig file: {s}", .{@errorName(err)}); | | |
| 1860 | }; | | |
| 1861 | }, | 2029 | }, |
| 1862 | .stage1_module => { | 2030 | .stage1_module => { |
| 1863 | if (!build_options.is_stage1) | 2031 | if (!build_options.is_stage1) |
| ... | @@ -2858,13 +3026,31 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool { | ... | @@ -2858,13 +3026,31 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool { |
| 2858 | target_util.libcNeedsLibUnwind(comp.getTarget()); | 3026 | target_util.libcNeedsLibUnwind(comp.getTarget()); |
| 2859 | } | 3027 | } |
| 2860 | | 3028 | |
| 2861 | fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) !void { | 3029 | fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) Allocator.Error!void { |
| 2862 | const tracy = trace(@src()); | 3030 | const tracy = trace(@src()); |
| 2863 | defer tracy.end(); | 3031 | defer tracy.end(); |
| 2864 | | 3032 | |
| 2865 | const source = try comp.generateBuiltinZigSource(comp.gpa); | 3033 | const source = try comp.generateBuiltinZigSource(comp.gpa); |
| 2866 | defer comp.gpa.free(source); | 3034 | defer comp.gpa.free(source); |
| 2867 | try mod.zig_cache_artifact_directory.handle.writeFile("builtin.zig", source); | 3035 | |
| | 3036 | mod.zig_cache_artifact_directory.handle.writeFile("builtin.zig", source) catch |err| { |
| | 3037 | const dir_path: []const u8 = mod.zig_cache_artifact_directory.path orelse "."; |
| | 3038 | try comp.setMiscFailure(.write_builtin_zig, "unable to write builtin.zig to {s}: {s}", .{ |
| | 3039 | dir_path, |
| | 3040 | @errorName(err), |
| | 3041 | }); |
| | 3042 | }; |
| | 3043 | } |
| | 3044 | |
| | 3045 | fn setMiscFailure( |
| | 3046 | comp: *Compilation, |
| | 3047 | tag: MiscTask, |
| | 3048 | comptime format: []const u8, |
| | 3049 | args: anytype, |
| | 3050 | ) Allocator.Error!void { |
| | 3051 | try comp.misc_failures.ensureCapacity(comp.gpa, comp.misc_failures.count() + 1); |
| | 3052 | const msg = try std.fmt.allocPrint(comp.gpa, format, args); |
| | 3053 | comp.misc_failures.putAssumeCapacityNoClobber(tag, .{ .msg = msg }); |
| 2868 | } | 3054 | } |
| 2869 | | 3055 | |
| 2870 | pub fn dump_argv(argv: []const []const u8) void { | 3056 | pub fn dump_argv(argv: []const []const u8) void { |
| ... | @@ -2874,7 +3060,7 @@ pub fn dump_argv(argv: []const []const u8) void { | ... | @@ -2874,7 +3060,7 @@ pub fn dump_argv(argv: []const []const u8) void { |
| 2874 | std.debug.print("{s}\n", .{argv[argv.len - 1]}); | 3060 | std.debug.print("{s}\n", .{argv[argv.len - 1]}); |
| 2875 | } | 3061 | } |
| 2876 | | 3062 | |
| 2877 | pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 { | 3063 | pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Allocator.Error![]u8 { |
| 2878 | const tracy = trace(@src()); | 3064 | const tracy = trace(@src()); |
| 2879 | defer tracy.end(); | 3065 | defer tracy.end(); |
| 2880 | | 3066 | |
| ... | @@ -3071,6 +3257,10 @@ pub fn updateSubCompilation(sub_compilation: *Compilation) !void { | ... | @@ -3071,6 +3257,10 @@ pub fn updateSubCompilation(sub_compilation: *Compilation) !void { |
| 3071 | try sub_compilation.update(); | 3257 | try sub_compilation.update(); |
| 3072 | | 3258 | |
| 3073 | // Look for compilation errors in this sub_compilation | 3259 | // Look for compilation errors in this sub_compilation |
| | 3260 | // TODO instead of logging these errors, handle them in the callsites |
| | 3261 | // of updateSubCompilation and attach them as sub-errors, properly |
| | 3262 | // surfacing the errors. You can see an example of this already |
| | 3263 | // done inside buildOutputFromZig. |
| 3074 | var errors = try sub_compilation.getAllErrorsAlloc(); | 3264 | var errors = try sub_compilation.getAllErrorsAlloc(); |
| 3075 | defer errors.deinit(sub_compilation.gpa); | 3265 | defer errors.deinit(sub_compilation.gpa); |
| 3076 | | 3266 | |
| ... | @@ -3099,6 +3289,7 @@ fn buildOutputFromZig( | ... | @@ -3099,6 +3289,7 @@ fn buildOutputFromZig( |
| 3099 | src_basename: []const u8, | 3289 | src_basename: []const u8, |
| 3100 | output_mode: std.builtin.OutputMode, | 3290 | output_mode: std.builtin.OutputMode, |
| 3101 | out: *?CRTFile, | 3291 | out: *?CRTFile, |
| | 3292 | misc_task_tag: MiscTask, |
| 3102 | ) !void { | 3293 | ) !void { |
| 3103 | const tracy = trace(@src()); | 3294 | const tracy = trace(@src()); |
| 3104 | defer tracy.end(); | 3295 | defer tracy.end(); |
| ... | @@ -3173,7 +3364,23 @@ fn buildOutputFromZig( | ... | @@ -3173,7 +3364,23 @@ fn buildOutputFromZig( |
| 3173 | }); | 3364 | }); |
| 3174 | defer sub_compilation.destroy(); | 3365 | defer sub_compilation.destroy(); |
| 3175 | | 3366 | |
| 3176 | try sub_compilation.updateSubCompilation(); | 3367 | try sub_compilation.update(); |
| | 3368 | // Look for compilation errors in this sub_compilation. |
| | 3369 | var keep_errors = false; |
| | 3370 | var errors = try sub_compilation.getAllErrorsAlloc(); |
| | 3371 | defer if (!keep_errors) errors.deinit(sub_compilation.gpa); |
| | 3372 | |
| | 3373 | if (errors.list.len != 0) { |
| | 3374 | try comp.misc_failures.ensureCapacity(comp.gpa, comp.misc_failures.count() + 1); |
| | 3375 | comp.misc_failures.putAssumeCapacityNoClobber(misc_task_tag, .{ |
| | 3376 | .msg = try std.fmt.allocPrint(comp.gpa, "sub-compilation of {s} failed", .{ |
| | 3377 | @tagName(misc_task_tag), |
| | 3378 | }), |
| | 3379 | .children = errors, |
| | 3380 | }); |
| | 3381 | keep_errors = true; |
| | 3382 | return error.SubCompilationFailed; |
| | 3383 | } |
| 3177 | | 3384 | |
| 3178 | assert(out.* == null); | 3385 | assert(out.* == null); |
| 3179 | out.* = Compilation.CRTFile{ | 3386 | out.* = Compilation.CRTFile{ |