stage2: enable building freestanding libc with LLVM backend

* LLVM backend: respect `sub_path` just like the other stage2 backends
   do.
 * Compilation has some new logic to only emit work queue jobs for
   building stuff when it believes itself to be capable. The linker
   backends no longer have duplicate logic; instead they respect the
   optional bit on the respective asset.
This commit is contained in:
Andrew Kelley
2021-09-24 00:54:44 -07:00
parent f215d98043
commit ef7fa76001
7 changed files with 60 additions and 61 deletions

View File

@@ -164,15 +164,17 @@ pub const Object = struct {
/// * it works for functions not all globals.
/// Therefore, this table keeps track of the mapping.
decl_map: std.AutoHashMapUnmanaged(*const Module.Decl, *const llvm.Value),
/// Where to put the output object file, relative to bin_file.options.emit directory.
sub_path: []const u8,
pub fn create(gpa: *Allocator, options: link.Options) !*Object {
pub fn create(gpa: *Allocator, sub_path: []const u8, options: link.Options) !*Object {
const obj = try gpa.create(Object);
errdefer gpa.destroy(obj);
obj.* = try Object.init(gpa, options);
obj.* = try Object.init(gpa, sub_path, options);
return obj;
}
pub fn init(gpa: *Allocator, options: link.Options) !Object {
pub fn init(gpa: *Allocator, sub_path: []const u8, options: link.Options) !Object {
const context = llvm.Context.create();
errdefer context.dispose();
@@ -251,6 +253,7 @@ pub const Object = struct {
.context = context,
.target_machine = target_machine,
.decl_map = .{},
.sub_path = sub_path,
};
}
@@ -301,23 +304,18 @@ pub const Object = struct {
const mod = comp.bin_file.options.module.?;
const cache_dir = mod.zig_cache_artifact_directory;
const emit_bin_path: ?[*:0]const u8 = if (comp.bin_file.options.emit != null) blk: {
const obj_basename = try std.zig.binNameAlloc(arena, .{
.root_name = comp.bin_file.options.root_name,
.target = comp.bin_file.options.target,
.output_mode = .Obj,
});
if (cache_dir.joinZ(arena, &[_][]const u8{obj_basename})) |p| {
break :blk p.ptr;
} else |err| {
return err;
}
} else null;
const emit_bin_path: ?[*:0]const u8 = if (comp.bin_file.options.emit) |emit|
try emit.directory.joinZ(arena, &[_][]const u8{self.sub_path})
else
null;
const emit_asm_path = try locPath(arena, comp.emit_asm, cache_dir);
const emit_llvm_ir_path = try locPath(arena, comp.emit_llvm_ir, cache_dir);
const emit_llvm_bc_path = try locPath(arena, comp.emit_llvm_bc, cache_dir);
const debug_emit_path = emit_bin_path orelse "(none)";
log.debug("emit LLVM object to {s}", .{debug_emit_path});
var error_message: [*:0]const u8 = undefined;
if (self.target_machine.emitToFile(
self.llvm_module,