aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BRANCH_TODO28
-rw-r--r--src-self-hosted/Compilation.zig290
-rw-r--r--src-self-hosted/Package.zig34
-rw-r--r--src-self-hosted/glibc.zig36
-rw-r--r--src-self-hosted/libunwind.zig28
-rw-r--r--src-self-hosted/link.zig12
-rw-r--r--src-self-hosted/link/Elf.zig22
-rw-r--r--src-self-hosted/main.zig10
8 files changed, 295 insertions, 165 deletions
diff --git a/BRANCH_TODO b/BRANCH_TODO
index bee98d6d2b..35972cb3e2 100644
--- a/BRANCH_TODO
+++ b/BRANCH_TODO
@@ -1,6 +1,8 @@
+ * Cache integration for stage1 zig code compilation
* build & link against compiler-rt
* build & link against freestanding libc
- * Cache integration for stage1 zig code compilation
+ * resolve builtin.zig not working on windows & macos; try os_path_real
+ * build & link against libcxx and libcxxabi
* `zig test`
* `zig build`
* `-ftime-report`
@@ -16,32 +18,33 @@
* make sure zig cc works
- using it as a preprocessor (-E)
- try building some software
+ * implement proper parsing of LLD stderr/stdout and exposing compile errors
+ * implement proper parsing of clang stderr/stdout and exposing compile errors
* support rpaths in ELF linker code
* repair @cImport
* add CLI support for a way to pass extra flags to c source files
- * capture lld stdout/stderr better
* musl
* mingw-w64
* use global zig-cache dir for crt files
* MachO LLD linking
* COFF LLD linking
* WASM LLD linking
- * implement proper parsing of LLD stderr/stdout and exposing compile errors
- * implement proper parsing of clang stderr/stdout and exposing compile errors
- * implement proper compile errors for failing to build glibc crt files and shared libs
- * improve the stage2 tests to support testing with LLVM extensions enabled
- * multi-thread building C objects
* support cross compiling stage2 with `zig build`
- * implement emit-h in stage2
- * implement -fno-emit-bin
- * audit the base cache hash
* --main-pkg-path
* audit the CLI options for stage2
* `zig init-lib`
* `zig init-exe`
* `zig run`
* restore error messages for stage2_add_link_lib
+ * audit the base cache hash
+ * implement proper compile errors for failing to build glibc crt files and shared libs
+ * implement -fno-emit-bin
+ * improve the stage2 tests to support testing with LLVM extensions enabled
+ * rename src/ to src/stage1/
+ * rename src-self-hosted/ to src/
+ * implement emit-h in stage2
+ * multi-thread building C objects
* implement serialization/deserialization of incremental compilation metadata
* incremental compilation - implement detection of which source files changed
* improve the cache hash logic for c objects with respect to extra flags and file parameters
@@ -59,16 +62,13 @@
* integrate target features into building assembly code
* libc_installation.zig: make it look for msvc only if msvc abi is chosen
* switch the default C ABI for windows to be mingw-w64
- * port windows_sdk.cpp to zig
* change glibc log errors to normal exposed compile errors
* update Package to use Compilation.Directory in create()
- skip LLD caching when bin directory is not in the cache (so we don't put `id.txt` into the cwd)
(maybe make it an explicit option and have main.zig disable it)
- make it possible for Package to not openDir and reference already existing resources.
- * rename src/ to src/stage1/
- * rename src-self-hosted/ to src/
* improve Directory.join to only use 1 allocation in a clean way.
* tracy builds with lc++
* some kind of "zig identifier escape" function rather than unconditionally using @"" syntax
in builtin.zig
- * rename Mode to OptimizeMode
+ * rename std.builtin.Mode to std.builtin.OptimizeMode
diff --git a/src-self-hosted/Compilation.zig b/src-self-hosted/Compilation.zig
index f08c5ef82f..32edc92718 100644
--- a/src-self-hosted/Compilation.zig
+++ b/src-self-hosted/Compilation.zig
@@ -46,6 +46,12 @@ sanitize_c: bool,
clang_passthrough_mode: bool,
/// Whether to print clang argvs to stdout.
verbose_cc: bool,
+verbose_tokenize: bool,
+verbose_ast: bool,
+verbose_ir: bool,
+verbose_llvm_ir: bool,
+verbose_cimport: bool,
+verbose_llvm_cpu_features: bool,
disable_c_depfile: bool,
is_test: bool,
@@ -59,18 +65,21 @@ zig_cache_directory: Directory,
libc_include_dir_list: []const []const u8,
rand: *std.rand.Random,
-/// Populated when we build libc++.a. A Job to build this is placed in the queue
+/// Populated when we build the libc++ static library. A Job to build this is placed in the queue
/// and resolved before calling linker.flush().
libcxx_static_lib: ?[]const u8 = null,
-/// Populated when we build libc++abi.a. A Job to build this is placed in the queue
+/// Populated when we build the libc++abi static library. A Job to build this is placed in the queue
/// and resolved before calling linker.flush().
libcxxabi_static_lib: ?[]const u8 = null,
-/// Populated when we build libunwind.a. A Job to build this is placed in the queue
+/// Populated when we build the libunwind static library. A Job to build this is placed in the queue
/// and resolved before calling linker.flush().
libunwind_static_lib: ?CRTFile = null,
-/// Populated when we build c.a. A Job to build this is placed in the queue
+/// Populated when we build the libc static library. A Job to build this is placed in the queue
/// and resolved before calling linker.flush().
-libc_static_lib: ?[]const u8 = null,
+libc_static_lib: ?CRTFile = null,
+/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue
+/// and resolved before calling linker.flush().
+compiler_rt_static_lib: ?CRTFile = null,
glibc_so_files: ?glibc.BuiltSharedObjects = null,
@@ -121,6 +130,11 @@ const Job = union(enum) {
glibc_shared_objects,
/// libunwind.a, usually needed when linking libc
libunwind: void,
+ /// needed when producing a dynamic library or executable
+ libcompiler_rt: void,
+ /// needed when not linking libc and using LLVM for code generation because it generates
+ /// calls to, for example, memcpy and memset.
+ zig_libc: void,
/// Generate builtin.zig source code and write it into the correct place.
generate_builtin_zig: void,
@@ -310,6 +324,15 @@ pub const InitOptions = struct {
};
pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
+ const is_dyn_lib = switch (options.output_mode) {
+ .Obj, .Exe => false,
+ .Lib => (options.link_mode orelse .Static) == .Dynamic,
+ };
+ const is_exe_or_dyn_lib = switch (options.output_mode) {
+ .Obj => false,
+ .Lib => is_dyn_lib,
+ .Exe => true,
+ };
const comp: *Compilation = comp: {
// For allocations that have the same lifetime as Compilation. This arena is used only during this
// initialization and then is freed in deinit().
@@ -375,15 +398,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
return error.MachineCodeModelNotSupported;
}
- const is_dyn_lib = switch (options.output_mode) {
- .Obj, .Exe => false,
- .Lib => (options.link_mode orelse .Static) == .Dynamic,
- };
- const is_exe_or_dyn_lib = switch (options.output_mode) {
- .Obj => false,
- .Lib => is_dyn_lib,
- .Exe => true,
- };
const must_dynamic_link = dl: {
if (target_util.cannotDynamicLink(options.target))
break :dl false;
@@ -461,6 +475,27 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
};
const single_threaded = options.single_threaded or target_util.isSingleThreaded(options.target);
+ const function_sections = options.function_sections orelse false;
+
+ const llvm_cpu_features: ?[*:0]const u8 = if (build_options.have_llvm and use_llvm) blk: {
+ var buf = std.ArrayList(u8).init(arena);
+ for (options.target.cpu.arch.allFeaturesList()) |feature, index_usize| {
+ const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
+ const is_enabled = options.target.cpu.features.isEnabled(index);
+
+ if (feature.llvm_name) |llvm_name| {
+ const plus_or_minus = "-+"[@boolToInt(is_enabled)];
+ try buf.ensureCapacity(buf.items.len + 2 + llvm_name.len);
+ buf.appendAssumeCapacity(plus_or_minus);
+ buf.appendSliceAssumeCapacity(llvm_name);
+ buf.appendSliceAssumeCapacity(",");
+ }
+ }
+ assert(mem.endsWith(u8, buf.items, ","));
+ buf.items[buf.items.len - 1] = 0;
+ buf.shrink(buf.items.len);
+ break :blk buf.items[0 .. buf.items.len - 1 :0].ptr;
+ } else null;
// We put everything into the cache hash that *cannot be modified during an incremental update*.
// For example, one cannot change the target between updates, but one can change source files,
@@ -489,8 +524,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
cache.hash.add(pic);
cache.hash.add(stack_check);
cache.hash.add(link_mode);
+ cache.hash.add(function_sections);
cache.hash.add(options.strip);
cache.hash.add(options.link_libc);
+ cache.hash.add(options.link_libcpp);
cache.hash.add(options.output_mode);
cache.hash.add(options.machine_code_model);
// TODO audit this and make sure everything is in it
@@ -596,10 +633,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
owned_link_dir = artifact_dir;
const link_artifact_directory: Directory = .{
.handle = artifact_dir,
- .path = if (options.zig_cache_directory.path) |p|
- try std.fs.path.join(arena, &[_][]const u8{ p, artifact_sub_dir })
- else
- artifact_sub_dir,
+ .path = try options.zig_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}),
};
break :blk link_artifact_directory;
};
@@ -609,26 +643,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.ReleaseFast, .ReleaseSmall => false,
};
- const llvm_cpu_features: ?[*:0]const u8 = if (build_options.have_llvm and use_llvm) blk: {
- var buf = std.ArrayList(u8).init(arena);
- for (options.target.cpu.arch.allFeaturesList()) |feature, index_usize| {
- const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
- const is_enabled = options.target.cpu.features.isEnabled(index);
-
- if (feature.llvm_name) |llvm_name| {
- const plus_or_minus = "-+"[@boolToInt(is_enabled)];
- try buf.ensureCapacity(buf.items.len + 2 + llvm_name.len);
- buf.appendAssumeCapacity(plus_or_minus);
- buf.appendSliceAssumeCapacity(llvm_name);
- buf.appendSliceAssumeCapacity(",");
- }
- }
- assert(mem.endsWith(u8, buf.items, ","));
- buf.items[buf.items.len - 1] = 0;
- buf.shrink(buf.items.len);
- break :blk buf.items[0 .. buf.items.len - 1 :0].ptr;
- } else null;
-
const stage1_module: ?*stage1.Module = if (build_options.is_stage1 and use_llvm) blk: {
// Here we use the legacy stage1 C++ compiler to compile Zig code.
const stage2_target = try arena.create(stage1.Stage2Target);
@@ -646,7 +660,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
if (options.color == .Off) progress.terminal = null;
const mod = module.?;
- const main_zig_file = mod.root_pkg.root_src_path;
+ const main_zig_file = try mod.root_pkg.root_src_directory.join(arena, &[_][]const u8{
+ mod.root_pkg.root_src_path,
+ });
const zig_lib_dir = options.zig_lib_directory.path.?;
const builtin_sub = &[_][]const u8{"builtin.zig"};
const builtin_zig_path = try mod.zig_cache_artifact_directory.join(arena, builtin_sub);
@@ -700,7 +716,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.dll_export_fns = dll_export_fns,
.link_mode_dynamic = link_mode == .Dynamic,
.valgrind_enabled = valgrind,
- .function_sections = options.function_sections orelse false,
+ .function_sections = function_sections,
.enable_stack_probing = stack_check,
.enable_time_report = options.time_report,
.enable_stack_report = false,
@@ -790,6 +806,12 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.rand = options.rand,
.clang_passthrough_mode = options.clang_passthrough_mode,
.verbose_cc = options.verbose_cc,
+ .verbose_tokenize = options.verbose_tokenize,
+ .verbose_ast = options.verbose_ast,
+ .verbose_ir = options.verbose_ir,
+ .verbose_llvm_ir = options.verbose_llvm_ir,
+ .verbose_cimport = options.verbose_cimport,
+ .verbose_llvm_cpu_features = options.verbose_llvm_cpu_features,
.disable_c_depfile = options.disable_c_depfile,
.owned_link_dir = owned_link_dir,
.is_test = options.is_test,
@@ -823,10 +845,15 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
if (comp.wantBuildLibUnwindFromSource()) {
try comp.work_queue.writeItem(.{ .libunwind = {} });
}
-
if (comp.stage1_module) |module| {
try comp.work_queue.writeItem(.{ .stage1_module = {} });
}
+ if (is_exe_or_dyn_lib) {
+ try comp.work_queue.writeItem(.{ .libcompiler_rt = {} });
+ if (!comp.bin_file.options.link_libc) {
+ try comp.work_queue.writeItem(.{ .zig_libc = {} });
+ }
+ }
return comp;
}
@@ -852,8 +879,14 @@ pub fn destroy(self: *Compilation) void {
self.crt_files.deinit(gpa);
}
- if (self.libunwind_static_lib) |*unwind_crt_file| {
- unwind_crt_file.deinit(gpa);
+ if (self.libunwind_static_lib) |*crt_file| {
+ crt_file.deinit(gpa);
+ }
+ if (self.compiler_rt_static_lib) |*crt_file| {
+ crt_file.deinit(gpa);
+ }
+ if (self.libc_static_lib) |*crt_file| {
+ crt_file.deinit(gpa);
}
for (self.c_object_table.items()) |entry| {
@@ -889,41 +922,46 @@ pub fn update(self: *Compilation) !void {
self.work_queue.writeItemAssumeCapacity(.{ .c_object = entry.key });
}
- if (self.bin_file.options.module) |module| {
- module.generation += 1;
-
- // TODO Detect which source files changed.
- // Until then we simulate a full cache miss. Source files could have been loaded for any reason;
- // to force a refresh we unload now.
- if (module.root_scope.cast(Module.Scope.File)) |zig_file| {
- zig_file.unload(module.gpa);
- module.analyzeContainer(&zig_file.root_container) catch |err| switch (err) {
- error.AnalysisFail => {
- assert(self.totalErrorCount() != 0);
- },
- else => |e| return e,
- };
- } else if (module.root_scope.cast(Module.Scope.ZIRModule)) |zir_module| {
- zir_module.unload(module.gpa);
- module.analyzeRootZIRModule(zir_module) catch |err| switch (err) {
- error.AnalysisFail => {
- assert(self.totalErrorCount() != 0);
- },
- else => |e| return e,
- };
+ const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_llvm;
+ if (!use_stage1) {
+ if (self.bin_file.options.module) |module| {
+ module.generation += 1;
+
+ // TODO Detect which source files changed.
+ // Until then we simulate a full cache miss. Source files could have been loaded for any reason;
+ // to force a refresh we unload now.
+ if (module.root_scope.cast(Module.Scope.File)) |zig_file| {
+ zig_file.unload(module.gpa);
+ module.analyzeContainer(&zig_file.root_container) catch |err| switch (err) {
+ error.AnalysisFail => {
+ assert(self.totalErrorCount() != 0);
+ },
+ else => |e| return e,
+ };
+ } else if (module.root_scope.cast(Module.Scope.ZIRModule)) |zir_module| {
+ zir_module.unload(module.gpa);
+ module.analyzeRootZIRModule(zir_module) catch |err| switch (err) {
+ error.AnalysisFail => {
+ assert(self.totalErrorCount() != 0);
+ },
+ else => |e| return e,
+ };
+ }
}
}
try self.performAllTheWork();
- if (self.bin_file.options.module) |module| {
- // Process the deletion set.
- while (module.deletion_set.popOrNull()) |decl| {
- if (decl.dependants.items().len != 0) {
- decl.deletion_flag = false;
- continue;
+ if (!use_stage1) {
+ if (self.bin_file.options.module) |module| {
+ // Process the deletion set.
+ while (module.deletion_set.popOrNull()) |decl| {
+ if (decl.dependants.items().len != 0) {
+ decl.deletion_flag = false;
+ continue;
+ }
+ try module.deleteDecl(decl);
}
- try module.deleteDecl(decl);
}
}
@@ -1142,6 +1180,18 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void {
fatal("unable to build libunwind: {}", .{@errorName(err)});
};
},
+ .libcompiler_rt => {
+ self.buildStaticLibFromZig("compiler_rt.zig", &self.compiler_rt_static_lib) catch |err| {
+ // TODO Expose this as a normal compile error rather than crashing here.
+ fatal("unable to build compiler_rt: {}", .{@errorName(err)});
+ };
+ },
+ .zig_libc => {
+ self.buildStaticLibFromZig("c.zig", &self.libc_static_lib) catch |err| {
+ // TODO Expose this as a normal compile error rather than crashing here.
+ fatal("unable to build zig's multitarget libc: {}", .{@errorName(err)});
+ };
+ },
.generate_builtin_zig => {
// This Job is only queued up if there is a zig module.
self.updateBuiltinZigFile(self.bin_file.options.module.?) catch |err| {
@@ -1691,7 +1741,7 @@ pub fn classifyFileExt(filename: []const u8) FileExt {
} else if (mem.endsWith(u8, filename, ".zig")) {
return .zig;
} else if (mem.endsWith(u8, filename, ".zir")) {
- return .zig;
+ return .zir;
} else if (hasSharedLibraryExt(filename)) {
return .shared_library;
} else if (hasStaticLibraryExt(filename)) {
@@ -2030,3 +2080,97 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8
});
return buffer.toOwnedSlice();
}
+
+pub fn updateSubCompilation(sub_compilation: *Compilation) !void {
+ try sub_compilation.update();
+
+ // Look for compilation errors in this sub_compilation
+ var errors = try sub_compilation.getAllErrorsAlloc();
+ defer errors.deinit(sub_compilation.gpa);
+
+ if (errors.list.len != 0) {
+ for (errors.list) |full_err_msg| {
+ std.log.err("{}:{}:{}: {}\n", .{
+ full_err_msg.src_path,
+ full_err_msg.line + 1,
+ full_err_msg.column + 1,
+ full_err_msg.msg,
+ });
+ }
+ return error.BuildingLibCObjectFailed;
+ }
+}
+
+fn buildStaticLibFromZig(comp: *Compilation, basename: []const u8, out: *?CRTFile) !void {
+ const tracy = trace(@src());
+ defer tracy.end();
+
+ const special_sub = "std" ++ std.fs.path.sep_str ++ "special";
+ const special_path = try comp.zig_lib_directory.join(comp.gpa, &[_][]const u8{special_sub});
+ defer comp.gpa.free(special_path);
+
+ var special_dir = try comp.zig_lib_directory.handle.openDir(special_sub, .{});
+ defer special_dir.close();
+
+ var root_pkg: Package = .{
+ .root_src_directory = .{
+ .path = special_path,
+ .handle = special_dir,
+ },
+ .root_src_path = basename,
+ };
+
+ const emit_bin = Compilation.EmitLoc{
+ .directory = null, // Put it in the cache directory.
+ .basename = basename,
+ };
+ const optimize_mode: std.builtin.Mode = blk: {
+ if (comp.is_test)
+ break :blk comp.bin_file.options.optimize_mode;
+ switch (comp.bin_file.options.optimize_mode) {
+ .Debug, .ReleaseFast, .ReleaseSafe => break :blk .ReleaseFast,
+ .ReleaseSmall => break :blk .ReleaseSmall,
+ }
+ };
+ const sub_compilation = try Compilation.create(comp.gpa, .{
+ // TODO use the global cache directory here
+ .zig_cache_directory = comp.zig_cache_directory,
+ .zig_lib_directory = comp.zig_lib_directory,
+ .target = comp.getTarget(),
+ .root_name = mem.split(basename, ".").next().?,
+ .root_pkg = &root_pkg,
+ .output_mode = .Lib,
+ .rand = comp.rand,
+ .libc_installation = comp.bin_file.options.libc_installation,
+ .emit_bin = emit_bin,
+ .optimize_mode = optimize_mode,
+ .link_mode = .Static,
+ .function_sections = true,
+ .want_sanitize_c = false,
+ .want_stack_check = false,
+ .want_valgrind = false,
+ .want_pic = comp.bin_file.options.pic,
+ .emit_h = null,
+ .strip = comp.bin_file.options.strip,
+ .is_native_os = comp.bin_file.options.is_native_os,
+ .self_exe_path = comp.self_exe_path,
+ .verbose_cc = comp.verbose_cc,
+ .verbose_link = comp.bin_file.options.verbose_link,
+ .verbose_tokenize = comp.verbose_tokenize,
+ .verbose_ast = comp.verbose_ast,
+ .verbose_ir = comp.verbose_ir,
+ .verbose_llvm_ir = comp.verbose_llvm_ir,
+ .verbose_cimport = comp.verbose_cimport,
+ .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
+ .clang_passthrough_mode = comp.clang_passthrough_mode,
+ });
+ defer sub_compilation.destroy();
+
+ try sub_compilation.updateSubCompilation();
+
+ assert(out.* == null);
+ out.* = Compilation.CRTFile{
+ .full_object_path = try sub_compilation.bin_file.options.directory.join(comp.gpa, &[_][]const u8{basename}),
+ .lock = sub_compilation.bin_file.toOwnedLock(),
+ };
+}
diff --git a/src-self-hosted/Package.zig b/src-self-hosted/Package.zig
index 027aaafe7d..14be8b64d6 100644
--- a/src-self-hosted/Package.zig
+++ b/src-self-hosted/Package.zig
@@ -1,32 +1,41 @@
pub const Table = std.StringHashMapUnmanaged(*Package);
root_src_directory: Compilation.Directory,
-/// Relative to `root_src_directory`.
-root_src_path: []u8,
-table: Table,
+/// Relative to `root_src_directory`. May contain path separators.
+root_src_path: []const u8,
+table: Table = .{},
+
+const std = @import("std");
+const mem = std.mem;
+const Allocator = std.mem.Allocator;
+const assert = std.debug.assert;
+const Package = @This();
+const Compilation = @import("Compilation.zig");
/// No references to `root_src_dir` and `root_src_path` are kept.
pub fn create(
gpa: *Allocator,
- base_dir: std.fs.Dir,
- /// Relative to `base_dir`.
+ base_directory: Compilation.Directory,
+ /// Relative to `base_directory`.
root_src_dir: []const u8,
/// Relative to `root_src_dir`.
root_src_path: []const u8,
) !*Package {
const ptr = try gpa.create(Package);
errdefer gpa.destroy(ptr);
+
+ const root_src_dir_path = try base_directory.join(gpa, &[_][]const u8{root_src_dir});
+ errdefer gpa.free(root_src_dir_path);
+
const root_src_path_dupe = try mem.dupe(gpa, u8, root_src_path);
errdefer gpa.free(root_src_path_dupe);
- const root_src_dir_path = try mem.dupe(gpa, u8, root_src_dir);
- errdefer gpa.free(root_src_dir_path);
+
ptr.* = .{
.root_src_directory = .{
.path = root_src_dir_path,
- .handle = try base_dir.openDir(root_src_dir, .{}),
+ .handle = try base_directory.handle.openDir(root_src_dir, .{}),
},
.root_src_path = root_src_path_dupe,
- .table = .{},
};
return ptr;
}
@@ -50,10 +59,3 @@ pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package)
const name_dupe = try mem.dupe(gpa, u8, name);
pkg.table.putAssumeCapacityNoClobber(name_dupe, package);
}
-
-const std = @import("std");
-const mem = std.mem;
-const Allocator = std.mem.Allocator;
-const assert = std.debug.assert;
-const Package = @This();
-const Compilation = @import("Compilation.zig");
diff --git a/src-self-hosted/glibc.zig b/src-self-hosted/glibc.zig
index 5e34302c06..9ede436f63 100644
--- a/src-self-hosted/glibc.zig
+++ b/src-self-hosted/glibc.zig
@@ -713,11 +713,17 @@ fn build_crt_file(
.c_source_files = c_source_files,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.bin_file.options.verbose_link,
+ .verbose_tokenize = comp.verbose_tokenize,
+ .verbose_ast = comp.verbose_ast,
+ .verbose_ir = comp.verbose_ir,
+ .verbose_llvm_ir = comp.verbose_llvm_ir,
+ .verbose_cimport = comp.verbose_cimport,
+ .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
});
defer sub_compilation.destroy();
- try updateSubCompilation(sub_compilation);
+ try sub_compilation.updateSubCompilation();
try comp.crt_files.ensureCapacity(comp.gpa, comp.crt_files.count() + 1);
const artifact_path = if (sub_compilation.bin_file.options.directory.path) |p|
@@ -989,6 +995,12 @@ fn buildSharedLib(
.self_exe_path = comp.self_exe_path,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.bin_file.options.verbose_link,
+ .verbose_tokenize = comp.verbose_tokenize,
+ .verbose_ast = comp.verbose_ast,
+ .verbose_ir = comp.verbose_ir,
+ .verbose_llvm_ir = comp.verbose_llvm_ir,
+ .verbose_cimport = comp.verbose_cimport,
+ .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
.version = version,
.version_script = map_file_path,
@@ -997,25 +1009,5 @@ fn buildSharedLib(
});
defer sub_compilation.destroy();
- try updateSubCompilation(sub_compilation);
-}
-
-fn updateSubCompilation(sub_compilation: *Compilation) !void {
- try sub_compilation.update();
-
- // Look for compilation errors in this sub_compilation
- var errors = try sub_compilation.getAllErrorsAlloc();
- defer errors.deinit(sub_compilation.gpa);
-
- if (errors.list.len != 0) {
- for (errors.list) |full_err_msg| {
- std.log.err("{}:{}:{}: {}\n", .{
- full_err_msg.src_path,
- full_err_msg.line + 1,
- full_err_msg.column + 1,
- full_err_msg.msg,
- });
- }
- return error.BuildingLibCObjectFailed;
- }
+ try sub_compilation.updateSubCompilation();
}
diff --git a/src-self-hosted/libunwind.zig b/src-self-hosted/libunwind.zig
index 3ba52573ce..0bb44808ff 100644
--- a/src-self-hosted/libunwind.zig
+++ b/src-self-hosted/libunwind.zig
@@ -109,12 +109,18 @@ pub fn buildStaticLib(comp: *Compilation) !void {
.c_source_files = &c_source_files,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.bin_file.options.verbose_link,
+ .verbose_tokenize = comp.verbose_tokenize,
+ .verbose_ast = comp.verbose_ast,
+ .verbose_ir = comp.verbose_ir,
+ .verbose_llvm_ir = comp.verbose_llvm_ir,
+ .verbose_cimport = comp.verbose_cimport,
+ .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
.link_libc = true,
});
defer sub_compilation.destroy();
- try updateSubCompilation(sub_compilation);
+ try sub_compilation.updateSubCompilation();
assert(comp.libunwind_static_lib == null);
comp.libunwind_static_lib = Compilation.CRTFile{
@@ -122,23 +128,3 @@ pub fn buildStaticLib(comp: *Compilation) !void {
.lock = sub_compilation.bin_file.toOwnedLock(),
};
}
-
-fn updateSubCompilation(sub_compilation: *Compilation) !void {
- try sub_compilation.update();
-
- // Look for compilation errors in this sub_compilation
- var errors = try sub_compilation.getAllErrorsAlloc();
- defer errors.deinit(sub_compilation.gpa);
-
- if (errors.list.len != 0) {
- for (errors.list) |full_err_msg| {
- std.log.err("{}:{}:{}: {}\n", .{
- full_err_msg.src_path,
- full_err_msg.line + 1,
- full_err_msg.column + 1,
- full_err_msg.msg,
- });
- }
- return error.BuildingLibCObjectFailed;
- }
-}
diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig
index 88a964f2ff..3ec81715e4 100644
--- a/src-self-hosted/link.zig
+++ b/src-self-hosted/link.zig
@@ -387,13 +387,15 @@ pub const File = struct {
// If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (base.options.module) |module| blk: {
+ const use_stage1 = build_options.is_stage1 and base.options.use_llvm;
+ if (use_stage1) {
+ const obj_basename = try std.fmt.allocPrint(arena, "{}.o", .{base.options.root_name});
+ const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
+ break :blk full_obj_path;
+ }
try base.flushModule(comp);
-
const obj_basename = base.intermediary_basename.?;
- const full_obj_path = if (directory.path) |dir_path|
- try std.fs.path.join(arena, &[_][]const u8{ dir_path, obj_basename })
- else
- obj_basename;
+ const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
break :blk full_obj_path;
} else null;
diff --git a/src-self-hosted/link/Elf.zig b/src-self-hosted/link/Elf.zig
index 5257b46279..0a44665176 100644
--- a/src-self-hosted/link/Elf.zig
+++ b/src-self-hosted/link/Elf.zig
@@ -1253,8 +1253,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
const is_lib = self.base.options.output_mode == .Lib;
const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
+ const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe;
const have_dynamic_linker = self.base.options.link_libc and
- self.base.options.link_mode == .Dynamic and (is_dyn_lib or self.base.options.output_mode == .Exe);
+ self.base.options.link_mode == .Dynamic and is_exe_or_dyn_lib;
try ch.addOptionalFile(self.base.options.linker_script);
try ch.addOptionalFile(self.base.options.version_script);
@@ -1489,16 +1490,13 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
try argv.append(p);
}
- // TODO compiler-rt and libc
- //if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) {
- // if (g->libc_link_lib == nullptr) {
- // Buf *libc_a_path = build_c(g, OutTypeLib, lj->build_dep_prog_node);
- // try argv.append(buf_ptr(libc_a_path));
- // }
-
- // Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib, lj->build_dep_prog_node);
- // try argv.append(buf_ptr(compiler_rt_o_path));
- //}
+ // compiler-rt and libc
+ if (is_exe_or_dyn_lib) {
+ if (!self.base.options.link_libc) {
+ try argv.append(comp.libc_static_lib.?.full_object_path);
+ }
+ try argv.append(comp.compiler_rt_static_lib.?.full_object_path);
+ }
// Shared libraries.
try argv.ensureCapacity(argv.items.len + self.base.options.system_libs.len);
@@ -1545,7 +1543,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a"));
} else if (target.isMusl()) {
try argv.append(comp.libunwind_static_lib.?.full_object_path);
- try argv.append(comp.libc_static_lib.?);
+ try argv.append(comp.libc_static_lib.?.full_object_path);
} else if (self.base.options.link_libcpp) {
try argv.append(comp.libunwind_static_lib.?.full_object_path);
} else {
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index 6aa4be7c41..430a85b93e 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -1108,8 +1108,14 @@ pub fn buildOutputType(
.yes => |p| p,
};
- const root_pkg = if (root_src_file) |src_path| try Package.create(gpa, fs.cwd(), ".", src_path) else null;
- defer if (root_pkg) |pkg| pkg.destroy(gpa);
+ var root_pkg_memory: Package = undefined;
+ const root_pkg: ?*Package = if (root_src_file) |src_path| blk: {
+ root_pkg_memory = .{
+ .root_src_directory = .{ .path = null, .handle = fs.cwd() },
+ .root_src_path = src_path,
+ };
+ break :blk &root_pkg_memory;
+ } else null;
const self_exe_path = try fs.selfExePathAlloc(arena);
var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| {