authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-17 23:27:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-17 23:27:24-07:00
loga9b18023a4c33a0563fca2aa20a239e3ee38927a
tree88a968afb4e2f56c0fff6757eb059d36c435d23b
parentdc478687d95ee0d495cd26182edae78a01db59af

stage2: implement --show-builtin

This takes the place of `zig builtin`. This is an improvement over the command because now the generated source will correctly show LinkMode and OutputMode, whereas before it was always stuck as Static and Obj, respectively.

11 files changed, 247 insertions(+), 64 deletions(-)

BRANCH_TODO+8-6
...@@ -1,9 +1,5 @@...@@ -1,9 +1,5 @@
1 * `zig builtin`
2 * `zig translate-c`1 * `zig translate-c`
3 * `zig test`2 * `zig test`
4 * `zig run`
5 * `zig init-lib`
6 * `zig init-exe`
7 * `zig build`3 * `zig build`
8 * `-ftime-report`4 * `-ftime-report`
9 * -fstack-report print stack size diagnostics\n"5 * -fstack-report print stack size diagnostics\n"
...@@ -15,14 +11,14 @@...@@ -15,14 +11,14 @@
15 * -femit-llvm-ir produce a .ll file with LLVM IR\n"11 * -femit-llvm-ir produce a .ll file with LLVM IR\n"
16 * -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"12 * -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"
17 * --cache-dir [path] override the local cache directory\n"13 * --cache-dir [path] override the local cache directory\n"
18 * move main.cpp to stage2
19 * make sure zig cc works14 * make sure zig cc works
20 - using it as a preprocessor (-E)15 - using it as a preprocessor (-E)
21 - try building some software16 - try building some software
22 * support rpaths in ELF linker code17 * support rpaths in ELF linker code
23 * build & link against compiler-rt18 * build & link against compiler-rt
24 - stage1 C++ code integration19 - stage1 C++ code integration
25 * build & link againstn freestanding libc20 * repair @cImport
21 * build & link against freestanding libc
26 * add CLI support for a way to pass extra flags to c source files22 * add CLI support for a way to pass extra flags to c source files
27 * capture lld stdout/stderr better23 * capture lld stdout/stderr better
28 * musl24 * musl
...@@ -41,6 +37,9 @@...@@ -41,6 +37,9 @@
41 * implement -fno-emit-bin37 * implement -fno-emit-bin
42 * audit the base cache hash38 * audit the base cache hash
43 * audit the CLI options for stage239 * audit the CLI options for stage2
40 * `zig init-lib`
41 * `zig init-exe`
42 * `zig run`
4443
45 * implement serialization/deserialization of incremental compilation metadata44 * implement serialization/deserialization of incremental compilation metadata
46 * incremental compilation - implement detection of which source files changed45 * incremental compilation - implement detection of which source files changed
...@@ -69,3 +68,6 @@...@@ -69,3 +68,6 @@
69 * rename src-self-hosted/ to src/68 * rename src-self-hosted/ to src/
70 * improve Directory.join to only use 1 allocation in a clean way.69 * improve Directory.join to only use 1 allocation in a clean way.
71 * tracy builds with lc++70 * tracy builds with lc++
71 * some kind of "zig identifier escape" function rather than unconditionally using @"" syntax
72 in builtin.zig
73 * rename Mode to OptimizeMode
src-self-hosted/Compilation.zig+201-18
...@@ -29,7 +29,7 @@ c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},...@@ -29,7 +29,7 @@ c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
2929
30link_error_flags: link.File.ErrorFlags = .{},30link_error_flags: link.File.ErrorFlags = .{},
3131
32work_queue: std.fifo.LinearFifo(WorkItem, .Dynamic),32work_queue: std.fifo.LinearFifo(Job, .Dynamic),
3333
34/// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator.34/// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator.
35failed_c_objects: std.AutoArrayHashMapUnmanaged(*CObject, *ErrorMsg) = .{},35failed_c_objects: std.AutoArrayHashMapUnmanaged(*CObject, *ErrorMsg) = .{},
...@@ -43,8 +43,9 @@ sanitize_c: bool,...@@ -43,8 +43,9 @@ sanitize_c: bool,
43/// This is `true` for `zig cc`, `zig c++`, and `zig translate-c`.43/// This is `true` for `zig cc`, `zig c++`, and `zig translate-c`.
44clang_passthrough_mode: bool,44clang_passthrough_mode: bool,
45/// Whether to print clang argvs to stdout.45/// Whether to print clang argvs to stdout.
46debug_cc: bool,46verbose_cc: bool,
47disable_c_depfile: bool,47disable_c_depfile: bool,
48is_test: bool,
4849
49c_source_files: []const CSourceFile,50c_source_files: []const CSourceFile,
50clang_argv: []const []const u8,51clang_argv: []const []const u8,
...@@ -56,16 +57,16 @@ zig_cache_directory: Directory,...@@ -56,16 +57,16 @@ zig_cache_directory: Directory,
56libc_include_dir_list: []const []const u8,57libc_include_dir_list: []const []const u8,
57rand: *std.rand.Random,58rand: *std.rand.Random,
5859
59/// Populated when we build libc++.a. A WorkItem to build this is placed in the queue60/// Populated when we build libc++.a. A Job to build this is placed in the queue
60/// and resolved before calling linker.flush().61/// and resolved before calling linker.flush().
61libcxx_static_lib: ?[]const u8 = null,62libcxx_static_lib: ?[]const u8 = null,
62/// Populated when we build libc++abi.a. A WorkItem to build this is placed in the queue63/// Populated when we build libc++abi.a. A Job to build this is placed in the queue
63/// and resolved before calling linker.flush().64/// and resolved before calling linker.flush().
64libcxxabi_static_lib: ?[]const u8 = null,65libcxxabi_static_lib: ?[]const u8 = null,
65/// Populated when we build libunwind.a. A WorkItem to build this is placed in the queue66/// Populated when we build libunwind.a. A Job to build this is placed in the queue
66/// and resolved before calling linker.flush().67/// and resolved before calling linker.flush().
67libunwind_static_lib: ?CRTFile = null,68libunwind_static_lib: ?CRTFile = null,
68/// Populated when we build c.a. A WorkItem to build this is placed in the queue69/// Populated when we build c.a. A Job to build this is placed in the queue
69/// and resolved before calling linker.flush().70/// and resolved before calling linker.flush().
70libc_static_lib: ?[]const u8 = null,71libc_static_lib: ?[]const u8 = null,
7172
...@@ -98,7 +99,7 @@ pub const CSourceFile = struct {...@@ -98,7 +99,7 @@ pub const CSourceFile = struct {
98 extra_flags: []const []const u8 = &[0][]const u8{},99 extra_flags: []const []const u8 = &[0][]const u8{},
99};100};
100101
101const WorkItem = union(enum) {102const Job = union(enum) {
102 /// Write the machine code for a Decl to the output file.103 /// Write the machine code for a Decl to the output file.
103 codegen_decl: *Module.Decl,104 codegen_decl: *Module.Decl,
104 /// The Decl needs to be analyzed and possibly export itself.105 /// The Decl needs to be analyzed and possibly export itself.
...@@ -116,8 +117,11 @@ const WorkItem = union(enum) {...@@ -116,8 +117,11 @@ const WorkItem = union(enum) {
116 glibc_crt_file: glibc.CRTFile,117 glibc_crt_file: glibc.CRTFile,
117 /// all of the glibc shared objects118 /// all of the glibc shared objects
118 glibc_shared_objects,119 glibc_shared_objects,
119120 /// libunwind.a, usually needed when linking libc
120 libunwind: void,121 libunwind: void,
122
123 /// Generate builtin.zig source code and write it into the correct place.
124 generate_builtin_zig: void,
121};125};
122126
123pub const CObject = struct {127pub const CObject = struct {
...@@ -282,8 +286,9 @@ pub const InitOptions = struct {...@@ -282,8 +286,9 @@ pub const InitOptions = struct {
282 linker_z_nodelete: bool = false,286 linker_z_nodelete: bool = false,
283 linker_z_defs: bool = false,287 linker_z_defs: bool = false,
284 clang_passthrough_mode: bool = false,288 clang_passthrough_mode: bool = false,
285 debug_cc: bool = false,289 verbose_cc: bool = false,
286 debug_link: bool = false,290 verbose_link: bool = false,
291 is_test: bool = false,
287 stack_size_override: ?u64 = null,292 stack_size_override: ?u64 = null,
288 self_exe_path: ?[]const u8 = null,293 self_exe_path: ?[]const u8 = null,
289 version: ?std.builtin.Version = null,294 version: ?std.builtin.Version = null,
...@@ -570,6 +575,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -570,6 +575,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
570 break :blk link_artifact_directory;575 break :blk link_artifact_directory;
571 };576 };
572577
578 const error_return_tracing = !options.strip and switch (options.optimize_mode) {
579 .Debug, .ReleaseSafe => true,
580 .ReleaseFast, .ReleaseSmall => false,
581 };
582
573 const bin_file = try link.File.openPath(gpa, .{583 const bin_file = try link.File.openPath(gpa, .{
574 .directory = bin_directory,584 .directory = bin_directory,
575 .sub_path = emit_bin.basename,585 .sub_path = emit_bin.basename,
...@@ -612,9 +622,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -612,9 +622,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
612 .valgrind = valgrind,622 .valgrind = valgrind,
613 .stack_check = stack_check,623 .stack_check = stack_check,
614 .single_threaded = single_threaded,624 .single_threaded = single_threaded,
615 .debug_link = options.debug_link,625 .verbose_link = options.verbose_link,
616 .machine_code_model = options.machine_code_model,626 .machine_code_model = options.machine_code_model,
617 .dll_export_fns = dll_export_fns,627 .dll_export_fns = dll_export_fns,
628 .error_return_tracing = error_return_tracing,
618 });629 });
619 errdefer bin_file.destroy();630 errdefer bin_file.destroy();
620631
...@@ -624,7 +635,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -624,7 +635,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
624 .zig_lib_directory = options.zig_lib_directory,635 .zig_lib_directory = options.zig_lib_directory,
625 .zig_cache_directory = options.zig_cache_directory,636 .zig_cache_directory = options.zig_cache_directory,
626 .bin_file = bin_file,637 .bin_file = bin_file,
627 .work_queue = std.fifo.LinearFifo(WorkItem, .Dynamic).init(gpa),638 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
628 .keep_source_files_loaded = options.keep_source_files_loaded,639 .keep_source_files_loaded = options.keep_source_files_loaded,
629 .use_clang = use_clang,640 .use_clang = use_clang,
630 .clang_argv = options.clang_argv,641 .clang_argv = options.clang_argv,
...@@ -635,14 +646,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -635,14 +646,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
635 .sanitize_c = sanitize_c,646 .sanitize_c = sanitize_c,
636 .rand = options.rand,647 .rand = options.rand,
637 .clang_passthrough_mode = options.clang_passthrough_mode,648 .clang_passthrough_mode = options.clang_passthrough_mode,
638 .debug_cc = options.debug_cc,649 .verbose_cc = options.verbose_cc,
639 .disable_c_depfile = options.disable_c_depfile,650 .disable_c_depfile = options.disable_c_depfile,
640 .owned_link_dir = owned_link_dir,651 .owned_link_dir = owned_link_dir,
652 .is_test = options.is_test,
641 };653 };
642 break :comp comp;654 break :comp comp;
643 };655 };
644 errdefer comp.destroy();656 errdefer comp.destroy();
645657
658 if (comp.bin_file.options.module) |mod| {
659 try comp.work_queue.writeItem(.{ .generate_builtin_zig = {} });
660 }
661
646 // Add a `CObject` for each `c_source_files`.662 // Add a `CObject` for each `c_source_files`.
647 try comp.c_object_table.ensureCapacity(gpa, options.c_source_files.len);663 try comp.c_object_table.ensureCapacity(gpa, options.c_source_files.len);
648 for (options.c_source_files) |c_source_file| {664 for (options.c_source_files) |c_source_file| {
...@@ -659,7 +675,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -659,7 +675,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
659 // If we need to build glibc for the target, add work items for it.675 // If we need to build glibc for the target, add work items for it.
660 // We go through the work queue so that building can be done in parallel.676 // We go through the work queue so that building can be done in parallel.
661 if (comp.wantBuildGLibCFromSource()) {677 if (comp.wantBuildGLibCFromSource()) {
662 try comp.addBuildingGLibCWorkItems();678 try comp.addBuildingGLibCJobs();
663 }679 }
664 if (comp.wantBuildLibUnwindFromSource()) {680 if (comp.wantBuildLibUnwindFromSource()) {
665 try comp.work_queue.writeItem(.{ .libunwind = {} });681 try comp.work_queue.writeItem(.{ .libunwind = {} });
...@@ -715,7 +731,7 @@ pub fn update(self: *Compilation) !void {...@@ -715,7 +731,7 @@ pub fn update(self: *Compilation) !void {
715 defer tracy.end();731 defer tracy.end();
716732
717 // For compiling C objects, we rely on the cache hash system to avoid duplicating work.733 // For compiling C objects, we rely on the cache hash system to avoid duplicating work.
718 // Add a WorkItem for each C object.734 // Add a Job for each C object.
719 try self.work_queue.ensureUnusedCapacity(self.c_object_table.items().len);735 try self.work_queue.ensureUnusedCapacity(self.c_object_table.items().len);
720 for (self.c_object_table.items()) |entry| {736 for (self.c_object_table.items()) |entry| {
721 self.work_queue.writeItemAssumeCapacity(.{ .c_object = entry.key });737 self.work_queue.writeItemAssumeCapacity(.{ .c_object = entry.key });
...@@ -974,6 +990,13 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void {...@@ -974,6 +990,13 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void {
974 fatal("unable to build libunwind: {}", .{@errorName(err)});990 fatal("unable to build libunwind: {}", .{@errorName(err)});
975 };991 };
976 },992 },
993 .generate_builtin_zig => {
994 // This Job is only queued up if there is a zig module.
995 self.updateBuiltinZigFile(self.bin_file.options.module.?) catch |err| {
996 // TODO Expose this as a normal compile error rather than crashing here.
997 fatal("unable to update builtin.zig file: {}", .{@errorName(err)});
998 };
999 },
977 };1000 };
978}1001}
9791002
...@@ -1057,7 +1080,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {...@@ -1057,7 +1080,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
1057 try argv.append(c_object.src.src_path);1080 try argv.append(c_object.src.src_path);
1058 try argv.appendSlice(c_object.src.extra_flags);1081 try argv.appendSlice(c_object.src.extra_flags);
10591082
1060 if (comp.debug_cc) {1083 if (comp.verbose_cc) {
1061 for (argv.items[0 .. argv.items.len - 1]) |arg| {1084 for (argv.items[0 .. argv.items.len - 1]) |arg| {
1062 std.debug.print("{} ", .{arg});1085 std.debug.print("{} ", .{arg});
1063 }1086 }
...@@ -1616,8 +1639,8 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []cons...@@ -1616,8 +1639,8 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []cons
1616 return full_path;1639 return full_path;
1617}1640}
16181641
1619fn addBuildingGLibCWorkItems(comp: *Compilation) !void {1642fn addBuildingGLibCJobs(comp: *Compilation) !void {
1620 try comp.work_queue.write(&[_]WorkItem{1643 try comp.work_queue.write(&[_]Job{
1621 .{ .glibc_crt_file = .crti_o },1644 .{ .glibc_crt_file = .crti_o },
1622 .{ .glibc_crt_file = .crtn_o },1645 .{ .glibc_crt_file = .crtn_o },
1623 .{ .glibc_crt_file = .scrt1_o },1646 .{ .glibc_crt_file = .scrt1_o },
...@@ -1646,3 +1669,163 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {...@@ -1646,3 +1669,163 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
1646 return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and1669 return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and
1647 comp.bin_file.options.libc_installation == null;1670 comp.bin_file.options.libc_installation == null;
1648}1671}
1672
1673fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) !void {
1674 const source = try comp.generateBuiltinZigSource();
1675 defer comp.gpa.free(source);
1676 try mod.zig_cache_artifact_directory.handle.writeFile("builtin.zig", source);
1677}
1678
1679pub fn generateBuiltinZigSource(comp: *Compilation) ![]u8 {
1680 var buffer = std.ArrayList(u8).init(comp.gpa);
1681 defer buffer.deinit();
1682
1683 const target = comp.getTarget();
1684 const generic_arch_name = target.cpu.arch.genericName();
1685
1686 @setEvalBranchQuota(4000);
1687 try buffer.writer().print(
1688 \\usingnamespace @import("std").builtin;
1689 \\/// Deprecated
1690 \\pub const arch = std.Target.current.cpu.arch;
1691 \\/// Deprecated
1692 \\pub const endian = std.Target.current.cpu.arch.endian();
1693 \\pub const output_mode = OutputMode.{};
1694 \\pub const link_mode = LinkMode.{};
1695 \\pub const is_test = {};
1696 \\pub const single_threaded = {};
1697 \\pub const abi = Abi.{};
1698 \\pub const cpu: Cpu = Cpu{{
1699 \\ .arch = .{},
1700 \\ .model = &Target.{}.cpu.{},
1701 \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{
1702 \\
1703 , .{
1704 @tagName(comp.bin_file.options.output_mode),
1705 @tagName(comp.bin_file.options.link_mode),
1706 comp.is_test,
1707 comp.bin_file.options.single_threaded,
1708 @tagName(target.abi),
1709 @tagName(target.cpu.arch),
1710 generic_arch_name,
1711 target.cpu.model.name,
1712 generic_arch_name,
1713 generic_arch_name,
1714 });
1715
1716 for (target.cpu.arch.allFeaturesList()) |feature, index_usize| {
1717 const index = @intCast(std.Target.Cpu.Feature.Set.Index, index_usize);
1718 const is_enabled = target.cpu.features.isEnabled(index);
1719 if (is_enabled) {
1720 // TODO some kind of "zig identifier escape" function rather than
1721 // unconditionally using @"" syntax
1722 try buffer.appendSlice(" .@\"");
1723 try buffer.appendSlice(feature.name);
1724 try buffer.appendSlice("\",\n");
1725 }
1726 }
1727
1728 try buffer.writer().print(
1729 \\ }}),
1730 \\}};
1731 \\pub const os = Os{{
1732 \\ .tag = .{},
1733 \\ .version_range = .{{
1734 ,
1735 .{@tagName(target.os.tag)},
1736 );
1737
1738 switch (target.os.getVersionRange()) {
1739 .none => try buffer.appendSlice(" .none = {} }\n"),
1740 .semver => |semver| try buffer.outStream().print(
1741 \\ .semver = .{{
1742 \\ .min = .{{
1743 \\ .major = {},
1744 \\ .minor = {},
1745 \\ .patch = {},
1746 \\ }},
1747 \\ .max = .{{
1748 \\ .major = {},
1749 \\ .minor = {},
1750 \\ .patch = {},
1751 \\ }},
1752 \\ }}}},
1753 \\
1754 , .{
1755 semver.min.major,
1756 semver.min.minor,
1757 semver.min.patch,
1758
1759 semver.max.major,
1760 semver.max.minor,
1761 semver.max.patch,
1762 }),
1763 .linux => |linux| try buffer.outStream().print(
1764 \\ .linux = .{{
1765 \\ .range = .{{
1766 \\ .min = .{{
1767 \\ .major = {},
1768 \\ .minor = {},
1769 \\ .patch = {},
1770 \\ }},
1771 \\ .max = .{{
1772 \\ .major = {},
1773 \\ .minor = {},
1774 \\ .patch = {},
1775 \\ }},
1776 \\ }},
1777 \\ .glibc = .{{
1778 \\ .major = {},
1779 \\ .minor = {},
1780 \\ .patch = {},
1781 \\ }},
1782 \\ }}}},
1783 \\
1784 , .{
1785 linux.range.min.major,
1786 linux.range.min.minor,
1787 linux.range.min.patch,
1788
1789 linux.range.max.major,
1790 linux.range.max.minor,
1791 linux.range.max.patch,
1792
1793 linux.glibc.major,
1794 linux.glibc.minor,
1795 linux.glibc.patch,
1796 }),
1797 .windows => |windows| try buffer.outStream().print(
1798 \\ .windows = .{{
1799 \\ .min = {s},
1800 \\ .max = {s},
1801 \\ }}}},
1802 \\
1803 ,
1804 .{ windows.min, windows.max },
1805 ),
1806 }
1807 try buffer.appendSlice("};\n");
1808 try buffer.writer().print(
1809 \\pub const object_format = ObjectFormat.{};
1810 \\pub const mode = Mode.{};
1811 \\pub const link_libc = {};
1812 \\pub const link_libcpp = {};
1813 \\pub const have_error_return_tracing = {};
1814 \\pub const valgrind_support = {};
1815 \\pub const position_independent_code = {};
1816 \\pub const strip_debug_info = {};
1817 \\pub const code_model = CodeModel.{};
1818 \\
1819 , .{
1820 @tagName(comp.bin_file.options.object_format),
1821 @tagName(comp.bin_file.options.optimize_mode),
1822 comp.bin_file.options.link_libc,
1823 comp.bin_file.options.link_libcpp,
1824 comp.bin_file.options.error_return_tracing,
1825 comp.bin_file.options.valgrind,
1826 comp.bin_file.options.pic,
1827 comp.bin_file.options.strip,
1828 @tagName(comp.bin_file.options.machine_code_model),
1829 });
1830 return buffer.toOwnedSlice();
1831}
src-self-hosted/glibc.zig+4-4
...@@ -711,8 +711,8 @@ fn build_crt_file(...@@ -711,8 +711,8 @@ fn build_crt_file(
711 .is_native_os = comp.bin_file.options.is_native_os,711 .is_native_os = comp.bin_file.options.is_native_os,
712 .self_exe_path = comp.self_exe_path,712 .self_exe_path = comp.self_exe_path,
713 .c_source_files = c_source_files,713 .c_source_files = c_source_files,
714 .debug_cc = comp.debug_cc,714 .verbose_cc = comp.verbose_cc,
715 .debug_link = comp.bin_file.options.debug_link,715 .verbose_link = comp.bin_file.options.verbose_link,
716 .clang_passthrough_mode = comp.clang_passthrough_mode,716 .clang_passthrough_mode = comp.clang_passthrough_mode,
717 });717 });
718 defer sub_compilation.destroy();718 defer sub_compilation.destroy();
...@@ -987,8 +987,8 @@ fn buildSharedLib(...@@ -987,8 +987,8 @@ fn buildSharedLib(
987 .strip = comp.bin_file.options.strip,987 .strip = comp.bin_file.options.strip,
988 .is_native_os = false,988 .is_native_os = false,
989 .self_exe_path = comp.self_exe_path,989 .self_exe_path = comp.self_exe_path,
990 .debug_cc = comp.debug_cc,990 .verbose_cc = comp.verbose_cc,
991 .debug_link = comp.bin_file.options.debug_link,991 .verbose_link = comp.bin_file.options.verbose_link,
992 .clang_passthrough_mode = comp.clang_passthrough_mode,992 .clang_passthrough_mode = comp.clang_passthrough_mode,
993 .version = version,993 .version = version,
994 .version_script = map_file_path,994 .version_script = map_file_path,
src-self-hosted/libunwind.zig+2-2
...@@ -107,8 +107,8 @@ pub fn buildStaticLib(comp: *Compilation) !void {...@@ -107,8 +107,8 @@ pub fn buildStaticLib(comp: *Compilation) !void {
107 .is_native_os = comp.bin_file.options.is_native_os,107 .is_native_os = comp.bin_file.options.is_native_os,
108 .self_exe_path = comp.self_exe_path,108 .self_exe_path = comp.self_exe_path,
109 .c_source_files = &c_source_files,109 .c_source_files = &c_source_files,
110 .debug_cc = comp.debug_cc,110 .verbose_cc = comp.verbose_cc,
111 .debug_link = comp.bin_file.options.debug_link,111 .verbose_link = comp.bin_file.options.verbose_link,
112 .clang_passthrough_mode = comp.clang_passthrough_mode,112 .clang_passthrough_mode = comp.clang_passthrough_mode,
113 .link_libc = true,113 .link_libc = true,
114 });114 });
src-self-hosted/link.zig+3-2
...@@ -61,8 +61,9 @@ pub const Options = struct {...@@ -61,8 +61,9 @@ pub const Options = struct {
61 valgrind: bool,61 valgrind: bool,
62 stack_check: bool,62 stack_check: bool,
63 single_threaded: bool,63 single_threaded: bool,
64 debug_link: bool = false,64 verbose_link: bool = false,
65 dll_export_fns: bool,65 dll_export_fns: bool,
66 error_return_tracing: bool,
66 gc_sections: ?bool = null,67 gc_sections: ?bool = null,
67 allow_shlib_undefined: ?bool = null,68 allow_shlib_undefined: ?bool = null,
68 linker_script: ?[]const u8 = null,69 linker_script: ?[]const u8 = null,
...@@ -441,7 +442,7 @@ pub const File = struct {...@@ -441,7 +442,7 @@ pub const File = struct {
441 base.options.sub_path;442 base.options.sub_path;
442 const full_out_path_z = try arena.dupeZ(u8, full_out_path);443 const full_out_path_z = try arena.dupeZ(u8, full_out_path);
443444
444 if (base.options.debug_link) {445 if (base.options.verbose_link) {
445 std.debug.print("ar rcs {}", .{full_out_path_z});446 std.debug.print("ar rcs {}", .{full_out_path_z});
446 for (object_files.items) |arg| {447 for (object_files.items) |arg| {
447 std.debug.print(" {}", .{arg});448 std.debug.print(" {}", .{arg});
src-self-hosted/link/Elf.zig+1-1
...@@ -1569,7 +1569,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1569,7 +1569,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1569 try argv.append("-Bsymbolic");1569 try argv.append("-Bsymbolic");
1570 }1570 }
15711571
1572 if (self.base.options.debug_link) {1572 if (self.base.options.verbose_link) {
1573 for (argv.items[0 .. argv.items.len - 1]) |arg| {1573 for (argv.items[0 .. argv.items.len - 1]) |arg| {
1574 std.debug.print("{} ", .{arg});1574 std.debug.print("{} ", .{arg});
1575 }1575 }
src-self-hosted/main.zig+28-15
...@@ -179,6 +179,7 @@ const usage_build_generic =...@@ -179,6 +179,7 @@ const usage_build_generic =
179 \\ --color [auto|off|on] Enable or disable colored error messages179 \\ --color [auto|off|on] Enable or disable colored error messages
180 \\ -femit-bin[=path] (default) output machine code180 \\ -femit-bin[=path] (default) output machine code
181 \\ -fno-emit-bin Do not output machine code181 \\ -fno-emit-bin Do not output machine code
182 \\ --show-builtin Output the source of @import("builtin") then exit
182 \\183 \\
183 \\Compile Options:184 \\Compile Options:
184 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command185 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command
...@@ -233,8 +234,8 @@ const usage_build_generic =...@@ -233,8 +234,8 @@ const usage_build_generic =
233 \\234 \\
234 \\Debug Options (Zig Compiler Development):235 \\Debug Options (Zig Compiler Development):
235 \\ -ftime-report Print timing diagnostics236 \\ -ftime-report Print timing diagnostics
236 \\ --debug-link Verbose linker invocation237 \\ --verbose-link Display linker invocations
237 \\ --debug-cc Verbose C compiler invocation238 \\ --verbose-cc Display C compiler invocations
238 \\239 \\
239;240;
240241
...@@ -274,9 +275,10 @@ pub fn buildOutputType(...@@ -274,9 +275,10 @@ pub fn buildOutputType(
274 var strip = false;275 var strip = false;
275 var single_threaded = false;276 var single_threaded = false;
276 var watch = false;277 var watch = false;
277 var debug_link = false;278 var verbose_link = false;
278 var debug_cc = false;279 var verbose_cc = false;
279 var time_report = false;280 var time_report = false;
281 var show_builtin = false;
280 var emit_bin: Emit = .yes_default_path;282 var emit_bin: Emit = .yes_default_path;
281 var emit_zir: Emit = .no;283 var emit_zir: Emit = .no;
282 var target_arch_os_abi: []const u8 = "native";284 var target_arch_os_abi: []const u8 = "native";
...@@ -531,6 +533,8 @@ pub fn buildOutputType(...@@ -531,6 +533,8 @@ pub fn buildOutputType(
531 dll_export_fns = true;533 dll_export_fns = true;
532 } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) {534 } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) {
533 dll_export_fns = false;535 dll_export_fns = false;
536 } else if (mem.eql(u8, arg, "--show-builtin")) {
537 show_builtin = true;
534 } else if (mem.eql(u8, arg, "--strip")) {538 } else if (mem.eql(u8, arg, "--strip")) {
535 strip = true;539 strip = true;
536 } else if (mem.eql(u8, arg, "--single-threaded")) {540 } else if (mem.eql(u8, arg, "--single-threaded")) {
...@@ -539,10 +543,10 @@ pub fn buildOutputType(...@@ -539,10 +543,10 @@ pub fn buildOutputType(
539 link_eh_frame_hdr = true;543 link_eh_frame_hdr = true;
540 } else if (mem.eql(u8, arg, "-Bsymbolic")) {544 } else if (mem.eql(u8, arg, "-Bsymbolic")) {
541 linker_bind_global_refs_locally = true;545 linker_bind_global_refs_locally = true;
542 } else if (mem.eql(u8, arg, "--debug-link")) {546 } else if (mem.eql(u8, arg, "--verbose-link")) {
543 debug_link = true;547 verbose_link = true;
544 } else if (mem.eql(u8, arg, "--debug-cc")) {548 } else if (mem.eql(u8, arg, "--verbose-cc")) {
545 debug_cc = true;549 verbose_cc = true;
546 } else if (mem.startsWith(u8, arg, "-T")) {550 } else if (mem.startsWith(u8, arg, "-T")) {
547 linker_script = arg[2..];551 linker_script = arg[2..];
548 } else if (mem.startsWith(u8, arg, "-L")) {552 } else if (mem.startsWith(u8, arg, "-L")) {
...@@ -680,8 +684,8 @@ pub fn buildOutputType(...@@ -680,8 +684,8 @@ pub fn buildOutputType(
680 },684 },
681 .linker_script => linker_script = it.only_arg,685 .linker_script => linker_script = it.only_arg,
682 .verbose_cmds => {686 .verbose_cmds => {
683 debug_cc = true;687 verbose_cc = true;
684 debug_link = true;688 verbose_link = true;
685 },689 },
686 .for_linker => try linker_args.append(it.only_arg),690 .for_linker => try linker_args.append(it.only_arg),
687 .linker_input_z => {691 .linker_input_z => {
...@@ -873,6 +877,8 @@ pub fn buildOutputType(...@@ -873,6 +877,8 @@ pub fn buildOutputType(
873 } else if (emit_bin == .yes) {877 } else if (emit_bin == .yes) {
874 const basename = fs.path.basename(emit_bin.yes);878 const basename = fs.path.basename(emit_bin.yes);
875 break :blk mem.split(basename, ".").next().?;879 break :blk mem.split(basename, ".").next().?;
880 } else if (show_builtin) {
881 break :blk "builtin";
876 } else {882 } else {
877 fatal("--name [name] not provided and unable to infer", .{});883 fatal("--name [name] not provided and unable to infer", .{});
878 }884 }
...@@ -1160,17 +1166,20 @@ pub fn buildOutputType(...@@ -1160,17 +1166,20 @@ pub fn buildOutputType(
1160 .clang_passthrough_mode = arg_mode != .build,1166 .clang_passthrough_mode = arg_mode != .build,
1161 .version = if (have_version) version else null,1167 .version = if (have_version) version else null,
1162 .libc_installation = if (libc_installation) |*lci| lci else null,1168 .libc_installation = if (libc_installation) |*lci| lci else null,
1163 .debug_cc = debug_cc,1169 .verbose_cc = verbose_cc,
1164 .debug_link = debug_link,1170 .verbose_link = verbose_link,
1165 .machine_code_model = machine_code_model,1171 .machine_code_model = machine_code_model,
1166 }) catch |err| {1172 }) catch |err| {
1167 fatal("unable to create compilation: {}", .{@errorName(err)});1173 fatal("unable to create compilation: {}", .{@errorName(err)});
1168 };1174 };
1169 defer comp.destroy();1175 defer comp.destroy();
11701176
1171 const stdin = std.io.getStdIn().inStream();1177 if (show_builtin) {
1172 const stderr = std.io.getStdErr().outStream();1178 const source = try comp.generateBuiltinZigSource();
1173 var repl_buf: [1024]u8 = undefined;1179 defer comp.gpa.free(source);
1180 try std.io.getStdOut().writeAll(source);
1181 return;
1182 }
11741183
1175 try updateModule(gpa, comp, zir_out_path);1184 try updateModule(gpa, comp, zir_out_path);
11761185
...@@ -1179,6 +1188,10 @@ pub fn buildOutputType(...@@ -1179,6 +1188,10 @@ pub fn buildOutputType(
1179 fatal("TODO: implement `zig cc` when using it as a preprocessor", .{});1188 fatal("TODO: implement `zig cc` when using it as a preprocessor", .{});
1180 }1189 }
11811190
1191 const stdin = std.io.getStdIn().inStream();
1192 const stderr = std.io.getStdErr().outStream();
1193 var repl_buf: [1024]u8 = undefined;
1194
1182 while (watch) {1195 while (watch) {
1183 try stderr.print("🦎 ", .{});1196 try stderr.print("🦎 ", .{});
1184 if (output_mode == .Exe) {1197 if (output_mode == .Exe) {
src/all_types.hpp-2
...@@ -2161,11 +2161,9 @@ struct CodeGen {...@@ -2161,11 +2161,9 @@ struct CodeGen {
2161 bool have_err_ret_tracing;2161 bool have_err_ret_tracing;
2162 bool verbose_tokenize;2162 bool verbose_tokenize;
2163 bool verbose_ast;2163 bool verbose_ast;
2164 bool verbose_link;
2165 bool verbose_ir;2164 bool verbose_ir;
2166 bool verbose_llvm_ir;2165 bool verbose_llvm_ir;
2167 bool verbose_cimport;2166 bool verbose_cimport;
2168 bool verbose_cc;
2169 bool verbose_llvm_cpu_features;2167 bool verbose_llvm_cpu_features;
2170 bool error_during_imports;2168 bool error_during_imports;
2171 bool generate_error_name_table;2169 bool generate_error_name_table;
src/stage1.cpp-2
...@@ -104,11 +104,9 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {...@@ -104,11 +104,9 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {
104104
105 g->verbose_tokenize = stage1->verbose_tokenize;105 g->verbose_tokenize = stage1->verbose_tokenize;
106 g->verbose_ast = stage1->verbose_ast;106 g->verbose_ast = stage1->verbose_ast;
107 g->verbose_link = stage1->verbose_link;
108 g->verbose_ir = stage1->verbose_ir;107 g->verbose_ir = stage1->verbose_ir;
109 g->verbose_llvm_ir = stage1->verbose_llvm_ir;108 g->verbose_llvm_ir = stage1->verbose_llvm_ir;
110 g->verbose_cimport = stage1->verbose_cimport;109 g->verbose_cimport = stage1->verbose_cimport;
111 g->verbose_cc = stage1->verbose_cc;
112 g->verbose_llvm_cpu_features = stage1->verbose_llvm_cpu_features;110 g->verbose_llvm_cpu_features = stage1->verbose_llvm_cpu_features;
113111
114 g->err_color = stage1->err_color;112 g->err_color = stage1->err_color;
src/stage1.h-2
...@@ -194,11 +194,9 @@ struct ZigStage1 {...@@ -194,11 +194,9 @@ struct ZigStage1 {
194 bool test_is_evented;194 bool test_is_evented;
195 bool verbose_tokenize;195 bool verbose_tokenize;
196 bool verbose_ast;196 bool verbose_ast;
197 bool verbose_link;
198 bool verbose_ir;197 bool verbose_ir;
199 bool verbose_llvm_ir;198 bool verbose_llvm_ir;
200 bool verbose_cimport;199 bool verbose_cimport;
201 bool verbose_cc;
202 bool verbose_llvm_cpu_features;200 bool verbose_llvm_cpu_features;
203};201};
204202
src/zig0.cpp-10
...@@ -44,11 +44,9 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -44,11 +44,9 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
44 " -mcpu [cpu] specify target CPU and feature set\n"44 " -mcpu [cpu] specify target CPU and feature set\n"
45 " --verbose-tokenize enable compiler debug output for tokenization\n"45 " --verbose-tokenize enable compiler debug output for tokenization\n"
46 " --verbose-ast enable compiler debug output for AST parsing\n"46 " --verbose-ast enable compiler debug output for AST parsing\n"
47 " --verbose-link enable compiler debug output for linking\n"
48 " --verbose-ir enable compiler debug output for Zig IR\n"47 " --verbose-ir enable compiler debug output for Zig IR\n"
49 " --verbose-llvm-ir enable compiler debug output for LLVM IR\n"48 " --verbose-llvm-ir enable compiler debug output for LLVM IR\n"
50 " --verbose-cimport enable compiler debug output for C imports\n"49 " --verbose-cimport enable compiler debug output for C imports\n"
51 " --verbose-cc enable compiler debug output for C compilation\n"
52 " --verbose-llvm-cpu-features enable compiler debug output for LLVM CPU features\n"50 " --verbose-llvm-cpu-features enable compiler debug output for LLVM CPU features\n"
53 "\n"51 "\n"
54 , arg0);52 , arg0);
...@@ -82,11 +80,9 @@ int main(int argc, char **argv) {...@@ -82,11 +80,9 @@ int main(int argc, char **argv) {
82 const char *out_name = nullptr;80 const char *out_name = nullptr;
83 bool verbose_tokenize = false;81 bool verbose_tokenize = false;
84 bool verbose_ast = false;82 bool verbose_ast = false;
85 bool verbose_link = false;
86 bool verbose_ir = false;83 bool verbose_ir = false;
87 bool verbose_llvm_ir = false;84 bool verbose_llvm_ir = false;
88 bool verbose_cimport = false;85 bool verbose_cimport = false;
89 bool verbose_cc = false;
90 bool verbose_llvm_cpu_features = false;86 bool verbose_llvm_cpu_features = false;
91 ErrColor color = ErrColorAuto;87 ErrColor color = ErrColorAuto;
92 const char *dynamic_linker = nullptr;88 const char *dynamic_linker = nullptr;
...@@ -120,16 +116,12 @@ int main(int argc, char **argv) {...@@ -120,16 +116,12 @@ int main(int argc, char **argv) {
120 verbose_tokenize = true;116 verbose_tokenize = true;
121 } else if (strcmp(arg, "--verbose-ast") == 0) {117 } else if (strcmp(arg, "--verbose-ast") == 0) {
122 verbose_ast = true;118 verbose_ast = true;
123 } else if (strcmp(arg, "--verbose-link") == 0) {
124 verbose_link = true;
125 } else if (strcmp(arg, "--verbose-ir") == 0) {119 } else if (strcmp(arg, "--verbose-ir") == 0) {
126 verbose_ir = true;120 verbose_ir = true;
127 } else if (strcmp(arg, "--verbose-llvm-ir") == 0) {121 } else if (strcmp(arg, "--verbose-llvm-ir") == 0) {
128 verbose_llvm_ir = true;122 verbose_llvm_ir = true;
129 } else if (strcmp(arg, "--verbose-cimport") == 0) {123 } else if (strcmp(arg, "--verbose-cimport") == 0) {
130 verbose_cimport = true;124 verbose_cimport = true;
131 } else if (strcmp(arg, "--verbose-cc") == 0) {
132 verbose_cc = true;
133 } else if (strcmp(arg, "--verbose-llvm-cpu-features") == 0) {125 } else if (strcmp(arg, "--verbose-llvm-cpu-features") == 0) {
134 verbose_llvm_cpu_features = true;126 verbose_llvm_cpu_features = true;
135 } else if (arg[1] == 'l' && arg[2] != 0) {127 } else if (arg[1] == 'l' && arg[2] != 0) {
...@@ -283,11 +275,9 @@ int main(int argc, char **argv) {...@@ -283,11 +275,9 @@ int main(int argc, char **argv) {
283 stage1->strip = strip;275 stage1->strip = strip;
284 stage1->verbose_tokenize = verbose_tokenize;276 stage1->verbose_tokenize = verbose_tokenize;
285 stage1->verbose_ast = verbose_ast;277 stage1->verbose_ast = verbose_ast;
286 stage1->verbose_link = verbose_link;
287 stage1->verbose_ir = verbose_ir;278 stage1->verbose_ir = verbose_ir;
288 stage1->verbose_llvm_ir = verbose_llvm_ir;279 stage1->verbose_llvm_ir = verbose_llvm_ir;
289 stage1->verbose_cimport = verbose_cimport;280 stage1->verbose_cimport = verbose_cimport;
290 stage1->verbose_cc = verbose_cc;
291 stage1->verbose_llvm_cpu_features = verbose_llvm_cpu_features;281 stage1->verbose_llvm_cpu_features = verbose_llvm_cpu_features;
292 stage1->output_dir_ptr = output_dir;282 stage1->output_dir_ptr = output_dir;
293 stage1->output_dir_len = strlen(output_dir);283 stage1->output_dir_len = strlen(output_dir);