stage2 now supports using stage1 as a backend for compiling zig code
* move stage2.cpp code into zig0.cpp for simplicity * add -ftime-report and some more CLI options to stage2 * stage2 compites the llvm cpu features string * classifyFileExt understands more file extensions * correction to generateBuiltinZigSource using the wrong allocator (thanks dbandstra!) * stage2 is now able to build hello.zig into hello.o using stage1 as a library however it fails linking due to missing compiler-rt * remove dead code * simplify zig0 builtin.zig source * fix not resolving builtin.zig source path causing duplicate imports * fix stage1.h not being valid C code * fix stage2.h not being valid C codemaster
parent
333b12a8f9
commit
2ef68631cb
|
@ -1,3 +1,6 @@
|
||||||
|
* build & link against compiler-rt
|
||||||
|
* build & link against freestanding libc
|
||||||
|
* Cache integration for stage1 zig code compilation
|
||||||
* `zig test`
|
* `zig test`
|
||||||
* `zig build`
|
* `zig build`
|
||||||
* `-ftime-report`
|
* `-ftime-report`
|
||||||
|
@ -14,10 +17,7 @@
|
||||||
- using it as a preprocessor (-E)
|
- using it as a preprocessor (-E)
|
||||||
- try building some software
|
- try building some software
|
||||||
* support rpaths in ELF linker code
|
* support rpaths in ELF linker code
|
||||||
* build & link against compiler-rt
|
|
||||||
- stage1 C++ code integration
|
|
||||||
* repair @cImport
|
* repair @cImport
|
||||||
* build & link against freestanding libc
|
|
||||||
* add CLI support for a way to pass extra flags to c source files
|
* add CLI support for a way to pass extra flags to c source files
|
||||||
* capture lld stdout/stderr better
|
* capture lld stdout/stderr better
|
||||||
* musl
|
* musl
|
||||||
|
@ -35,10 +35,12 @@
|
||||||
* implement emit-h in stage2
|
* implement emit-h in stage2
|
||||||
* implement -fno-emit-bin
|
* implement -fno-emit-bin
|
||||||
* audit the base cache hash
|
* audit the base cache hash
|
||||||
|
* --main-pkg-path
|
||||||
* audit the CLI options for stage2
|
* audit the CLI options for stage2
|
||||||
* `zig init-lib`
|
* `zig init-lib`
|
||||||
* `zig init-exe`
|
* `zig init-exe`
|
||||||
* `zig run`
|
* `zig run`
|
||||||
|
* restore error messages for stage2_add_link_lib
|
||||||
|
|
||||||
* implement serialization/deserialization of incremental compilation metadata
|
* implement serialization/deserialization of incremental compilation metadata
|
||||||
* incremental compilation - implement detection of which source files changed
|
* incremental compilation - implement detection of which source files changed
|
||||||
|
|
|
@ -258,7 +258,6 @@ find_package(Threads)
|
||||||
# This is our shim which will be replaced by stage1.zig.
|
# This is our shim which will be replaced by stage1.zig.
|
||||||
set(ZIG0_SOURCES
|
set(ZIG0_SOURCES
|
||||||
"${CMAKE_SOURCE_DIR}/src/zig0.cpp"
|
"${CMAKE_SOURCE_DIR}/src/zig0.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/stage2.cpp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(ZIG_SOURCES
|
set(ZIG_SOURCES
|
||||||
|
|
|
@ -19,6 +19,7 @@ const libunwind = @import("libunwind.zig");
|
||||||
const fatal = @import("main.zig").fatal;
|
const fatal = @import("main.zig").fatal;
|
||||||
const Module = @import("Module.zig");
|
const Module = @import("Module.zig");
|
||||||
const Cache = @import("Cache.zig");
|
const Cache = @import("Cache.zig");
|
||||||
|
const stage1 = @import("stage1.zig");
|
||||||
|
|
||||||
/// General-purpose allocator. Used for both temporary and long-term storage.
|
/// General-purpose allocator. Used for both temporary and long-term storage.
|
||||||
gpa: *Allocator,
|
gpa: *Allocator,
|
||||||
|
@ -26,6 +27,7 @@ gpa: *Allocator,
|
||||||
arena_state: std.heap.ArenaAllocator.State,
|
arena_state: std.heap.ArenaAllocator.State,
|
||||||
bin_file: *link.File,
|
bin_file: *link.File,
|
||||||
c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
|
c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
|
||||||
|
stage1_module: ?*stage1.Module,
|
||||||
|
|
||||||
link_error_flags: link.File.ErrorFlags = .{},
|
link_error_flags: link.File.ErrorFlags = .{},
|
||||||
|
|
||||||
|
@ -122,6 +124,8 @@ const Job = union(enum) {
|
||||||
|
|
||||||
/// Generate builtin.zig source code and write it into the correct place.
|
/// Generate builtin.zig source code and write it into the correct place.
|
||||||
generate_builtin_zig: void,
|
generate_builtin_zig: void,
|
||||||
|
/// Use stage1 C++ code to compile zig code into an object file.
|
||||||
|
stage1_module: void,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CObject = struct {
|
pub const CObject = struct {
|
||||||
|
@ -274,6 +278,7 @@ pub const InitOptions = struct {
|
||||||
strip: bool = false,
|
strip: bool = false,
|
||||||
single_threaded: bool = false,
|
single_threaded: bool = false,
|
||||||
is_native_os: bool,
|
is_native_os: bool,
|
||||||
|
time_report: bool = false,
|
||||||
link_eh_frame_hdr: bool = false,
|
link_eh_frame_hdr: bool = false,
|
||||||
linker_script: ?[]const u8 = null,
|
linker_script: ?[]const u8 = null,
|
||||||
version_script: ?[]const u8 = null,
|
version_script: ?[]const u8 = null,
|
||||||
|
@ -288,12 +293,20 @@ pub const InitOptions = struct {
|
||||||
clang_passthrough_mode: bool = false,
|
clang_passthrough_mode: bool = false,
|
||||||
verbose_cc: bool = false,
|
verbose_cc: bool = false,
|
||||||
verbose_link: bool = false,
|
verbose_link: bool = false,
|
||||||
|
verbose_tokenize: bool = false,
|
||||||
|
verbose_ast: bool = false,
|
||||||
|
verbose_ir: bool = false,
|
||||||
|
verbose_llvm_ir: bool = false,
|
||||||
|
verbose_cimport: bool = false,
|
||||||
|
verbose_llvm_cpu_features: bool = false,
|
||||||
is_test: bool = false,
|
is_test: bool = false,
|
||||||
stack_size_override: ?u64 = null,
|
stack_size_override: ?u64 = null,
|
||||||
self_exe_path: ?[]const u8 = null,
|
self_exe_path: ?[]const u8 = null,
|
||||||
version: ?std.builtin.Version = null,
|
version: ?std.builtin.Version = null,
|
||||||
libc_installation: ?*const LibCInstallation = null,
|
libc_installation: ?*const LibCInstallation = null,
|
||||||
machine_code_model: std.builtin.CodeModel = .default,
|
machine_code_model: std.builtin.CodeModel = .default,
|
||||||
|
/// This is for stage1 and should be deleted upon completion of self-hosting.
|
||||||
|
color: @import("main.zig").Color = .Auto,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
|
@ -332,11 +345,27 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
{
|
{
|
||||||
break :blk true;
|
break :blk true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (build_options.is_stage1) {
|
||||||
|
// If stage1 generates an object file, self-hosted linker is not
|
||||||
|
// yet sophisticated enough to handle that.
|
||||||
|
break :blk options.root_pkg != null;
|
||||||
|
}
|
||||||
|
|
||||||
break :blk false;
|
break :blk false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make a decision on whether to use LLVM or our own backend.
|
// Make a decision on whether to use LLVM or our own backend.
|
||||||
const use_llvm = if (options.use_llvm) |explicit| explicit else blk: {
|
const use_llvm = if (options.use_llvm) |explicit| explicit else blk: {
|
||||||
|
// If we have no zig code to compile, no need for LLVM.
|
||||||
|
if (options.root_pkg == null)
|
||||||
|
break :blk false;
|
||||||
|
|
||||||
|
// If we are the stage1 compiler, we depend on the stage1 c++ llvm backend
|
||||||
|
// to compile zig code.
|
||||||
|
if (build_options.is_stage1)
|
||||||
|
break :blk true;
|
||||||
|
|
||||||
// We would want to prefer LLVM for release builds when it is available, however
|
// We would want to prefer LLVM for release builds when it is available, however
|
||||||
// we don't have an LLVM backend yet :)
|
// we don't have an LLVM backend yet :)
|
||||||
// We would also want to prefer LLVM for architectures that we don't have self-hosted support for too.
|
// We would also want to prefer LLVM for architectures that we don't have self-hosted support for too.
|
||||||
|
@ -580,6 +609,118 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
.ReleaseFast, .ReleaseSmall => false,
|
.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);
|
||||||
|
stage2_target.* = .{
|
||||||
|
.arch = @enumToInt(options.target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch
|
||||||
|
.os = @enumToInt(options.target.os.tag),
|
||||||
|
.abi = @enumToInt(options.target.abi),
|
||||||
|
.is_native_os = options.is_native_os,
|
||||||
|
.is_native_cpu = false, // Only true when bootstrapping the compiler.
|
||||||
|
.llvm_cpu_name = if (options.target.cpu.model.llvm_name) |s| s.ptr else null,
|
||||||
|
.llvm_cpu_features = llvm_cpu_features.?,
|
||||||
|
};
|
||||||
|
const progress = try arena.create(std.Progress);
|
||||||
|
const main_progress_node = try progress.start("", 100);
|
||||||
|
if (options.color == .Off) progress.terminal = null;
|
||||||
|
|
||||||
|
const mod = module.?;
|
||||||
|
const main_zig_file = 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);
|
||||||
|
|
||||||
|
const stage1_module = stage1.create(
|
||||||
|
@enumToInt(options.optimize_mode),
|
||||||
|
undefined,
|
||||||
|
0, // TODO --main-pkg-path
|
||||||
|
main_zig_file.ptr,
|
||||||
|
main_zig_file.len,
|
||||||
|
zig_lib_dir.ptr,
|
||||||
|
zig_lib_dir.len,
|
||||||
|
stage2_target,
|
||||||
|
options.is_test,
|
||||||
|
) orelse return error.OutOfMemory;
|
||||||
|
|
||||||
|
const output_dir = bin_directory.path orelse ".";
|
||||||
|
|
||||||
|
const stage1_pkg = try arena.create(stage1.Pkg);
|
||||||
|
stage1_pkg.* = .{
|
||||||
|
.name_ptr = undefined,
|
||||||
|
.name_len = 0,
|
||||||
|
.path_ptr = undefined,
|
||||||
|
.path_len = 0,
|
||||||
|
.children_ptr = undefined,
|
||||||
|
.children_len = 0,
|
||||||
|
.parent = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
stage1_module.* = .{
|
||||||
|
.root_name_ptr = root_name.ptr,
|
||||||
|
.root_name_len = root_name.len,
|
||||||
|
.output_dir_ptr = output_dir.ptr,
|
||||||
|
.output_dir_len = output_dir.len,
|
||||||
|
.builtin_zig_path_ptr = builtin_zig_path.ptr,
|
||||||
|
.builtin_zig_path_len = builtin_zig_path.len,
|
||||||
|
.test_filter_ptr = "",
|
||||||
|
.test_filter_len = 0,
|
||||||
|
.test_name_prefix_ptr = "",
|
||||||
|
.test_name_prefix_len = 0,
|
||||||
|
.userdata = @ptrToInt(comp),
|
||||||
|
.root_pkg = stage1_pkg,
|
||||||
|
.code_model = @enumToInt(options.machine_code_model),
|
||||||
|
.subsystem = stage1.TargetSubsystem.Auto,
|
||||||
|
.err_color = @enumToInt(options.color),
|
||||||
|
.pic = pic,
|
||||||
|
.link_libc = options.link_libc,
|
||||||
|
.link_libcpp = options.link_libcpp,
|
||||||
|
.strip = options.strip,
|
||||||
|
.is_single_threaded = single_threaded,
|
||||||
|
.dll_export_fns = dll_export_fns,
|
||||||
|
.link_mode_dynamic = link_mode == .Dynamic,
|
||||||
|
.valgrind_enabled = valgrind,
|
||||||
|
.function_sections = options.function_sections orelse false,
|
||||||
|
.enable_stack_probing = stack_check,
|
||||||
|
.enable_time_report = options.time_report,
|
||||||
|
.enable_stack_report = false,
|
||||||
|
.dump_analysis = false,
|
||||||
|
.enable_doc_generation = false,
|
||||||
|
.emit_bin = true,
|
||||||
|
.emit_asm = false,
|
||||||
|
.emit_llvm_ir = false,
|
||||||
|
.test_is_evented = false,
|
||||||
|
.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,
|
||||||
|
.main_progress_node = main_progress_node,
|
||||||
|
};
|
||||||
|
break :blk stage1_module;
|
||||||
|
} else null;
|
||||||
|
|
||||||
const bin_file = try link.File.openPath(gpa, .{
|
const bin_file = try link.File.openPath(gpa, .{
|
||||||
.directory = bin_directory,
|
.directory = bin_directory,
|
||||||
.sub_path = emit_bin.basename,
|
.sub_path = emit_bin.basename,
|
||||||
|
@ -626,6 +767,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
.machine_code_model = options.machine_code_model,
|
.machine_code_model = options.machine_code_model,
|
||||||
.dll_export_fns = dll_export_fns,
|
.dll_export_fns = dll_export_fns,
|
||||||
.error_return_tracing = error_return_tracing,
|
.error_return_tracing = error_return_tracing,
|
||||||
|
.llvm_cpu_features = llvm_cpu_features,
|
||||||
});
|
});
|
||||||
errdefer bin_file.destroy();
|
errdefer bin_file.destroy();
|
||||||
|
|
||||||
|
@ -635,6 +777,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
.zig_lib_directory = options.zig_lib_directory,
|
.zig_lib_directory = options.zig_lib_directory,
|
||||||
.zig_cache_directory = options.zig_cache_directory,
|
.zig_cache_directory = options.zig_cache_directory,
|
||||||
.bin_file = bin_file,
|
.bin_file = bin_file,
|
||||||
|
.stage1_module = stage1_module,
|
||||||
.work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
|
.work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
|
||||||
.keep_source_files_loaded = options.keep_source_files_loaded,
|
.keep_source_files_loaded = options.keep_source_files_loaded,
|
||||||
.use_clang = use_clang,
|
.use_clang = use_clang,
|
||||||
|
@ -681,6 +824,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||||
try comp.work_queue.writeItem(.{ .libunwind = {} });
|
try comp.work_queue.writeItem(.{ .libunwind = {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (comp.stage1_module) |module| {
|
||||||
|
try comp.work_queue.writeItem(.{ .stage1_module = {} });
|
||||||
|
}
|
||||||
|
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,6 +836,11 @@ pub fn destroy(self: *Compilation) void {
|
||||||
self.bin_file.destroy();
|
self.bin_file.destroy();
|
||||||
if (optional_module) |module| module.deinit();
|
if (optional_module) |module| module.deinit();
|
||||||
|
|
||||||
|
if (self.stage1_module) |module| {
|
||||||
|
module.main_progress_node.?.end();
|
||||||
|
module.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
const gpa = self.gpa;
|
const gpa = self.gpa;
|
||||||
self.work_queue.deinit();
|
self.work_queue.deinit();
|
||||||
|
|
||||||
|
@ -997,6 +1149,10 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void {
|
||||||
fatal("unable to update builtin.zig file: {}", .{@errorName(err)});
|
fatal("unable to update builtin.zig file: {}", .{@errorName(err)});
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
.stage1_module => {
|
||||||
|
// This Job is only queued up if there is a zig module.
|
||||||
|
self.stage1_module.?.build_object();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1365,7 +1521,7 @@ pub fn addCCArgs(
|
||||||
try argv.append("-fPIC");
|
try argv.append("-fPIC");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.so, .assembly, .ll, .bc, .unknown => {},
|
.shared_library, .assembly, .ll, .bc, .unknown, .static_library, .object, .zig, .zir => {},
|
||||||
}
|
}
|
||||||
if (out_dep_path) |p| {
|
if (out_dep_path) |p| {
|
||||||
try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p });
|
try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p });
|
||||||
|
@ -1445,17 +1601,39 @@ pub const FileExt = enum {
|
||||||
ll,
|
ll,
|
||||||
bc,
|
bc,
|
||||||
assembly,
|
assembly,
|
||||||
so,
|
shared_library,
|
||||||
|
object,
|
||||||
|
static_library,
|
||||||
|
zig,
|
||||||
|
zir,
|
||||||
unknown,
|
unknown,
|
||||||
|
|
||||||
pub fn clangSupportsDepFile(ext: FileExt) bool {
|
pub fn clangSupportsDepFile(ext: FileExt) bool {
|
||||||
return switch (ext) {
|
return switch (ext) {
|
||||||
.c, .cpp, .h => true,
|
.c, .cpp, .h => true,
|
||||||
.ll, .bc, .assembly, .so, .unknown => false,
|
|
||||||
|
.ll,
|
||||||
|
.bc,
|
||||||
|
.assembly,
|
||||||
|
.shared_library,
|
||||||
|
.object,
|
||||||
|
.static_library,
|
||||||
|
.zig,
|
||||||
|
.zir,
|
||||||
|
.unknown,
|
||||||
|
=> false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn hasObjectExt(filename: []const u8) bool {
|
||||||
|
return mem.endsWith(u8, filename, ".o") or mem.endsWith(u8, filename, ".obj");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hasStaticLibraryExt(filename: []const u8) bool {
|
||||||
|
return mem.endsWith(u8, filename, ".a") or mem.endsWith(u8, filename, ".lib");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn hasCExt(filename: []const u8) bool {
|
pub fn hasCExt(filename: []const u8) bool {
|
||||||
return mem.endsWith(u8, filename, ".c");
|
return mem.endsWith(u8, filename, ".c");
|
||||||
}
|
}
|
||||||
|
@ -1471,6 +1649,32 @@ pub fn hasAsmExt(filename: []const u8) bool {
|
||||||
return mem.endsWith(u8, filename, ".s") or mem.endsWith(u8, filename, ".S");
|
return mem.endsWith(u8, filename, ".s") or mem.endsWith(u8, filename, ".S");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hasSharedLibraryExt(filename: []const u8) bool {
|
||||||
|
if (mem.endsWith(u8, filename, ".so") or
|
||||||
|
mem.endsWith(u8, filename, ".dll") or
|
||||||
|
mem.endsWith(u8, filename, ".dylib"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Look for .so.X, .so.X.Y, .so.X.Y.Z
|
||||||
|
var it = mem.split(filename, ".");
|
||||||
|
_ = it.next().?;
|
||||||
|
var so_txt = it.next() orelse return false;
|
||||||
|
while (!mem.eql(u8, so_txt, "so")) {
|
||||||
|
so_txt = it.next() orelse return false;
|
||||||
|
}
|
||||||
|
const n1 = it.next() orelse return false;
|
||||||
|
const n2 = it.next();
|
||||||
|
const n3 = it.next();
|
||||||
|
|
||||||
|
_ = std.fmt.parseInt(u32, n1, 10) catch return false;
|
||||||
|
if (n2) |x| _ = std.fmt.parseInt(u32, x, 10) catch return false;
|
||||||
|
if (n3) |x| _ = std.fmt.parseInt(u32, x, 10) catch return false;
|
||||||
|
if (it.next() != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn classifyFileExt(filename: []const u8) FileExt {
|
pub fn classifyFileExt(filename: []const u8) FileExt {
|
||||||
if (hasCExt(filename)) {
|
if (hasCExt(filename)) {
|
||||||
return .c;
|
return .c;
|
||||||
|
@ -1484,26 +1688,19 @@ pub fn classifyFileExt(filename: []const u8) FileExt {
|
||||||
return .assembly;
|
return .assembly;
|
||||||
} else if (mem.endsWith(u8, filename, ".h")) {
|
} else if (mem.endsWith(u8, filename, ".h")) {
|
||||||
return .h;
|
return .h;
|
||||||
} else if (mem.endsWith(u8, filename, ".so")) {
|
} else if (mem.endsWith(u8, filename, ".zig")) {
|
||||||
return .so;
|
return .zig;
|
||||||
|
} else if (mem.endsWith(u8, filename, ".zir")) {
|
||||||
|
return .zig;
|
||||||
|
} else if (hasSharedLibraryExt(filename)) {
|
||||||
|
return .shared_library;
|
||||||
|
} else if (hasStaticLibraryExt(filename)) {
|
||||||
|
return .static_library;
|
||||||
|
} else if (hasObjectExt(filename)) {
|
||||||
|
return .object;
|
||||||
|
} else {
|
||||||
|
return .unknown;
|
||||||
}
|
}
|
||||||
// Look for .so.X, .so.X.Y, .so.X.Y.Z
|
|
||||||
var it = mem.split(filename, ".");
|
|
||||||
_ = it.next().?;
|
|
||||||
var so_txt = it.next() orelse return .unknown;
|
|
||||||
while (!mem.eql(u8, so_txt, "so")) {
|
|
||||||
so_txt = it.next() orelse return .unknown;
|
|
||||||
}
|
|
||||||
const n1 = it.next() orelse return .unknown;
|
|
||||||
const n2 = it.next();
|
|
||||||
const n3 = it.next();
|
|
||||||
|
|
||||||
_ = std.fmt.parseInt(u32, n1, 10) catch return .unknown;
|
|
||||||
if (n2) |x| _ = std.fmt.parseInt(u32, x, 10) catch return .unknown;
|
|
||||||
if (n3) |x| _ = std.fmt.parseInt(u32, x, 10) catch return .unknown;
|
|
||||||
if (it.next() != null) return .unknown;
|
|
||||||
|
|
||||||
return .so;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "classifyFileExt" {
|
test "classifyFileExt" {
|
||||||
|
@ -1681,7 +1878,7 @@ pub fn dump_argv(argv: []const []const u8) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 {
|
pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 {
|
||||||
var buffer = std.ArrayList(u8).init(comp.gpa);
|
var buffer = std.ArrayList(u8).init(allocator);
|
||||||
defer buffer.deinit();
|
defer buffer.deinit();
|
||||||
|
|
||||||
const target = comp.getTarget();
|
const target = comp.getTarget();
|
||||||
|
@ -1691,9 +1888,9 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8
|
||||||
try buffer.writer().print(
|
try buffer.writer().print(
|
||||||
\\usingnamespace @import("std").builtin;
|
\\usingnamespace @import("std").builtin;
|
||||||
\\/// Deprecated
|
\\/// Deprecated
|
||||||
\\pub const arch = std.Target.current.cpu.arch;
|
\\pub const arch = Target.current.cpu.arch;
|
||||||
\\/// Deprecated
|
\\/// Deprecated
|
||||||
\\pub const endian = std.Target.current.cpu.arch.endian();
|
\\pub const endian = Target.current.cpu.arch.endian();
|
||||||
\\pub const output_mode = OutputMode.{};
|
\\pub const output_mode = OutputMode.{};
|
||||||
\\pub const link_mode = LinkMode.{};
|
\\pub const link_mode = LinkMode.{};
|
||||||
\\pub const is_test = {};
|
\\pub const is_test = {};
|
||||||
|
|
|
@ -69,6 +69,7 @@ pub const Options = struct {
|
||||||
linker_script: ?[]const u8 = null,
|
linker_script: ?[]const u8 = null,
|
||||||
version_script: ?[]const u8 = null,
|
version_script: ?[]const u8 = null,
|
||||||
override_soname: ?[]const u8 = null,
|
override_soname: ?[]const u8 = null,
|
||||||
|
llvm_cpu_features: ?[*:0]const u8 = null,
|
||||||
/// Extra args passed directly to LLD. Ignored when not linking with LLD.
|
/// Extra args passed directly to LLD. Ignored when not linking with LLD.
|
||||||
extra_lld_args: []const []const u8 = &[0][]const u8,
|
extra_lld_args: []const []const u8 = &[0][]const u8,
|
||||||
|
|
||||||
|
@ -134,6 +135,18 @@ pub const File = struct {
|
||||||
/// rewriting it. A malicious file is detected as incremental link failure
|
/// rewriting it. A malicious file is detected as incremental link failure
|
||||||
/// and does not cause Illegal Behavior. This operation is not atomic.
|
/// and does not cause Illegal Behavior. This operation is not atomic.
|
||||||
pub fn openPath(allocator: *Allocator, options: Options) !*File {
|
pub fn openPath(allocator: *Allocator, options: Options) !*File {
|
||||||
|
const use_stage1 = build_options.is_stage1 and options.use_llvm;
|
||||||
|
if (use_stage1) {
|
||||||
|
return switch (options.object_format) {
|
||||||
|
.coff, .pe => &(try Coff.createEmpty(allocator, options)).base,
|
||||||
|
.elf => &(try Elf.createEmpty(allocator, options)).base,
|
||||||
|
.macho => &(try MachO.createEmpty(allocator, options)).base,
|
||||||
|
.wasm => &(try Wasm.createEmpty(allocator, options)).base,
|
||||||
|
.c => unreachable, // Reported error earlier.
|
||||||
|
.hex => return error.HexObjectFormatUnimplemented,
|
||||||
|
.raw => return error.RawObjectFormatUnimplemented,
|
||||||
|
};
|
||||||
|
}
|
||||||
const use_lld = build_options.have_llvm and options.use_lld; // comptime known false when !have_llvm
|
const use_lld = build_options.have_llvm and options.use_lld; // comptime known false when !have_llvm
|
||||||
const sub_path = if (use_lld) blk: {
|
const sub_path = if (use_lld) blk: {
|
||||||
if (options.module == null) {
|
if (options.module == null) {
|
||||||
|
|
|
@ -1222,13 +1222,16 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||||
// If there is no Zig code to compile, then we should skip flushing the output file because it
|
// 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.
|
// will not be part of the linker line anyway.
|
||||||
const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {
|
const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {
|
||||||
try self.flushModule(comp);
|
const use_stage1 = build_options.is_stage1 and self.base.options.use_llvm;
|
||||||
|
if (use_stage1) {
|
||||||
|
const obj_basename = try std.fmt.allocPrint(arena, "{}.o", .{self.base.options.root_name});
|
||||||
|
const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
|
||||||
|
break :blk full_obj_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
try self.flushModule(comp);
|
||||||
const obj_basename = self.base.intermediary_basename.?;
|
const obj_basename = self.base.intermediary_basename.?;
|
||||||
const full_obj_path = if (directory.path) |dir_path|
|
const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
|
||||||
try std.fs.path.join(arena, &[_][]const u8{dir_path, obj_basename})
|
|
||||||
else
|
|
||||||
obj_basename;
|
|
||||||
break :blk full_obj_path;
|
break :blk full_obj_path;
|
||||||
} else null;
|
} else null;
|
||||||
|
|
||||||
|
@ -1504,7 +1507,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||||
// (the check for that needs to be earlier), but they could be full paths to .so files, in which
|
// (the check for that needs to be earlier), but they could be full paths to .so files, in which
|
||||||
// case we want to avoid prepending "-l".
|
// case we want to avoid prepending "-l".
|
||||||
const ext = Compilation.classifyFileExt(link_lib);
|
const ext = Compilation.classifyFileExt(link_lib);
|
||||||
const arg = if (ext == .so) link_lib else try std.fmt.allocPrint(arena, "-l{}", .{link_lib});
|
const arg = if (ext == .shared_library) link_lib else try std.fmt.allocPrint(arena, "-l{}", .{link_lib});
|
||||||
argv.appendAssumeCapacity(arg);
|
argv.appendAssumeCapacity(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,21 +222,27 @@ const usage_build_generic =
|
||||||
\\ --libc [file] Provide a file which specifies libc paths
|
\\ --libc [file] Provide a file which specifies libc paths
|
||||||
\\
|
\\
|
||||||
\\Link Options:
|
\\Link Options:
|
||||||
\\ -l[lib], --library [lib] Link against system library
|
\\ -l[lib], --library [lib] Link against system library
|
||||||
\\ -L[d], --library-directory [d] Add a directory to the library search path
|
\\ -L[d], --library-directory [d] Add a directory to the library search path
|
||||||
\\ -T[script] Use a custom linker script
|
\\ -T[script] Use a custom linker script
|
||||||
\\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
|
\\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
|
||||||
\\ --version [ver] Dynamic library semver
|
\\ --version [ver] Dynamic library semver
|
||||||
\\ -rdynamic Add all symbols to the dynamic symbol table
|
\\ -rdynamic Add all symbols to the dynamic symbol table
|
||||||
\\ -rpath [path] Add directory to the runtime library search path
|
\\ -rpath [path] Add directory to the runtime library search path
|
||||||
\\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker
|
\\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker
|
||||||
\\ -dynamic Force output to be dynamically linked
|
\\ -dynamic Force output to be dynamically linked
|
||||||
\\ -static Force output to be statically linked
|
\\ -static Force output to be statically linked
|
||||||
\\
|
\\
|
||||||
\\Debug Options (Zig Compiler Development):
|
\\Debug Options (Zig Compiler Development):
|
||||||
\\ -ftime-report Print timing diagnostics
|
\\ -ftime-report Print timing diagnostics
|
||||||
\\ --verbose-link Display linker invocations
|
\\ --verbose-link Display linker invocations
|
||||||
\\ --verbose-cc Display C compiler invocations
|
\\ --verbose-cc Display C compiler invocations
|
||||||
|
\\ --verbose-tokenize Enable compiler debug output for tokenization
|
||||||
|
\\ --verbose-ast Enable compiler debug output for AST parsing
|
||||||
|
\\ --verbose-ir Enable compiler debug output for Zig IR
|
||||||
|
\\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
|
||||||
|
\\ --verbose-cimport Enable compiler debug output for C imports
|
||||||
|
\\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
|
||||||
\\
|
\\
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -278,6 +284,12 @@ pub fn buildOutputType(
|
||||||
var watch = false;
|
var watch = false;
|
||||||
var verbose_link = false;
|
var verbose_link = false;
|
||||||
var verbose_cc = false;
|
var verbose_cc = false;
|
||||||
|
var verbose_tokenize = false;
|
||||||
|
var verbose_ast = false;
|
||||||
|
var verbose_ir = false;
|
||||||
|
var verbose_llvm_ir = false;
|
||||||
|
var verbose_cimport = false;
|
||||||
|
var verbose_llvm_cpu_features = false;
|
||||||
var time_report = false;
|
var time_report = false;
|
||||||
var show_builtin = false;
|
var show_builtin = false;
|
||||||
var emit_bin: Emit = .yes_default_path;
|
var emit_bin: Emit = .yes_default_path;
|
||||||
|
@ -548,6 +560,18 @@ pub fn buildOutputType(
|
||||||
verbose_link = true;
|
verbose_link = true;
|
||||||
} else if (mem.eql(u8, arg, "--verbose-cc")) {
|
} else if (mem.eql(u8, arg, "--verbose-cc")) {
|
||||||
verbose_cc = true;
|
verbose_cc = true;
|
||||||
|
} else if (mem.eql(u8, arg, "--verbose-tokenize")) {
|
||||||
|
verbose_tokenize = true;
|
||||||
|
} else if (mem.eql(u8, arg, "--verbose-ast")) {
|
||||||
|
verbose_ast = true;
|
||||||
|
} else if (mem.eql(u8, arg, "--verbose-ir")) {
|
||||||
|
verbose_ir = true;
|
||||||
|
} else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
|
||||||
|
verbose_llvm_ir = true;
|
||||||
|
} else if (mem.eql(u8, arg, "--verbose-cimport")) {
|
||||||
|
verbose_cimport = true;
|
||||||
|
} else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
|
||||||
|
verbose_llvm_cpu_features = true;
|
||||||
} else if (mem.startsWith(u8, arg, "-T")) {
|
} else if (mem.startsWith(u8, arg, "-T")) {
|
||||||
linker_script = arg[2..];
|
linker_script = arg[2..];
|
||||||
} else if (mem.startsWith(u8, arg, "-L")) {
|
} else if (mem.startsWith(u8, arg, "-L")) {
|
||||||
|
@ -563,28 +587,27 @@ pub fn buildOutputType(
|
||||||
} else {
|
} else {
|
||||||
fatal("unrecognized parameter: '{}'", .{arg});
|
fatal("unrecognized parameter: '{}'", .{arg});
|
||||||
}
|
}
|
||||||
} else if (mem.endsWith(u8, arg, ".o") or
|
} else switch (Compilation.classifyFileExt(arg)) {
|
||||||
mem.endsWith(u8, arg, ".obj") or
|
.object, .static_library => {
|
||||||
mem.endsWith(u8, arg, ".a") or
|
try link_objects.append(arg);
|
||||||
mem.endsWith(u8, arg, ".lib"))
|
},
|
||||||
{
|
.assembly, .c, .cpp, .h, .ll, .bc => {
|
||||||
try link_objects.append(arg);
|
// TODO a way to pass extra flags on the CLI
|
||||||
} else if (Compilation.hasAsmExt(arg) or Compilation.hasCExt(arg) or Compilation.hasCppExt(arg)) {
|
try c_source_files.append(.{ .src_path = arg });
|
||||||
// TODO a way to pass extra flags on the CLI
|
},
|
||||||
try c_source_files.append(.{ .src_path = arg });
|
.shared_library => {
|
||||||
} else if (mem.endsWith(u8, arg, ".so") or
|
fatal("linking against dynamic libraries not yet supported", .{});
|
||||||
mem.endsWith(u8, arg, ".dylib") or
|
},
|
||||||
mem.endsWith(u8, arg, ".dll"))
|
.zig, .zir => {
|
||||||
{
|
if (root_src_file) |other| {
|
||||||
fatal("linking against dynamic libraries not yet supported", .{});
|
fatal("found another zig file '{}' after root source file '{}'", .{ arg, other });
|
||||||
} else if (mem.endsWith(u8, arg, ".zig") or mem.endsWith(u8, arg, ".zir")) {
|
} else {
|
||||||
if (root_src_file) |other| {
|
root_src_file = arg;
|
||||||
fatal("found another zig file '{}' after root source file '{}'", .{ arg, other });
|
}
|
||||||
} else {
|
},
|
||||||
root_src_file = arg;
|
.unknown => {
|
||||||
}
|
fatal("unrecognized file extension of parameter '{}'", .{arg});
|
||||||
} else {
|
},
|
||||||
fatal("unrecognized file extension of parameter '{}'", .{arg});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -617,7 +640,16 @@ pub fn buildOutputType(
|
||||||
const file_ext = Compilation.classifyFileExt(mem.spanZ(it.only_arg));
|
const file_ext = Compilation.classifyFileExt(mem.spanZ(it.only_arg));
|
||||||
switch (file_ext) {
|
switch (file_ext) {
|
||||||
.assembly, .c, .cpp, .ll, .bc, .h => try c_source_files.append(.{ .src_path = it.only_arg }),
|
.assembly, .c, .cpp, .ll, .bc, .h => try c_source_files.append(.{ .src_path = it.only_arg }),
|
||||||
.unknown, .so => try link_objects.append(it.only_arg),
|
.unknown, .shared_library, .object, .static_library => {
|
||||||
|
try link_objects.append(it.only_arg);
|
||||||
|
},
|
||||||
|
.zig, .zir => {
|
||||||
|
if (root_src_file) |other| {
|
||||||
|
fatal("found another zig file '{}' after root source file '{}'", .{ it.only_arg, other });
|
||||||
|
} else {
|
||||||
|
root_src_file = it.only_arg;
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.l => {
|
.l => {
|
||||||
|
@ -1173,7 +1205,15 @@ pub fn buildOutputType(
|
||||||
.libc_installation = if (libc_installation) |*lci| lci else null,
|
.libc_installation = if (libc_installation) |*lci| lci else null,
|
||||||
.verbose_cc = verbose_cc,
|
.verbose_cc = verbose_cc,
|
||||||
.verbose_link = verbose_link,
|
.verbose_link = verbose_link,
|
||||||
|
.verbose_tokenize = verbose_tokenize,
|
||||||
|
.verbose_ast = verbose_ast,
|
||||||
|
.verbose_ir = verbose_ir,
|
||||||
|
.verbose_llvm_ir = verbose_llvm_ir,
|
||||||
|
.verbose_cimport = verbose_cimport,
|
||||||
|
.verbose_llvm_cpu_features = verbose_llvm_cpu_features,
|
||||||
.machine_code_model = machine_code_model,
|
.machine_code_model = machine_code_model,
|
||||||
|
.color = color,
|
||||||
|
.time_report = time_report,
|
||||||
}) catch |err| {
|
}) catch |err| {
|
||||||
fatal("unable to create compilation: {}", .{@errorName(err)});
|
fatal("unable to create compilation: {}", .{@errorName(err)});
|
||||||
};
|
};
|
||||||
|
@ -1193,6 +1233,10 @@ pub fn buildOutputType(
|
||||||
fatal("TODO: implement `zig cc` when using it as a preprocessor", .{});
|
fatal("TODO: implement `zig cc` when using it as a preprocessor", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (build_options.is_stage1 and comp.stage1_module != null and watch) {
|
||||||
|
std.log.warn("--watch is not recommended with the stage1 backend; it leaks memory and is not capable of incremental compilation", .{});
|
||||||
|
}
|
||||||
|
|
||||||
const stdin = std.io.getStdIn().inStream();
|
const stdin = std.io.getStdIn().inStream();
|
||||||
const stderr = std.io.getStdErr().outStream();
|
const stderr = std.io.getStdErr().outStream();
|
||||||
var repl_buf: [1024]u8 = undefined;
|
var repl_buf: [1024]u8 = undefined;
|
||||||
|
|
|
@ -10,6 +10,7 @@ const stage2 = @import("main.zig");
|
||||||
const fatal = stage2.fatal;
|
const fatal = stage2.fatal;
|
||||||
const CrossTarget = std.zig.CrossTarget;
|
const CrossTarget = std.zig.CrossTarget;
|
||||||
const Target = std.Target;
|
const Target = std.Target;
|
||||||
|
const Compilation = @import("Compilation.zig");
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
assert(std.builtin.link_libc);
|
assert(std.builtin.link_libc);
|
||||||
|
@ -23,6 +24,8 @@ pub const log_level = stage2.log_level;
|
||||||
pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int {
|
pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int {
|
||||||
std.debug.maybeEnableSegfaultHandler();
|
std.debug.maybeEnableSegfaultHandler();
|
||||||
|
|
||||||
|
zig_stage1_os_init();
|
||||||
|
|
||||||
const gpa = std.heap.c_allocator;
|
const gpa = std.heap.c_allocator;
|
||||||
var arena_instance = std.heap.ArenaAllocator.init(gpa);
|
var arena_instance = std.heap.ArenaAllocator.init(gpa);
|
||||||
defer arena_instance.deinit();
|
defer arena_instance.deinit();
|
||||||
|
@ -36,6 +39,106 @@ pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Matches stage2.Color;
|
||||||
|
pub const ErrColor = c_int;
|
||||||
|
/// Matches std.builtin.CodeModel
|
||||||
|
pub const CodeModel = c_int;
|
||||||
|
/// Matches std.Target.Os.Tag
|
||||||
|
pub const OS = c_int;
|
||||||
|
/// Matches std.builtin.BuildMode
|
||||||
|
pub const BuildMode = c_int;
|
||||||
|
|
||||||
|
pub const TargetSubsystem = extern enum(c_int) {
|
||||||
|
Console,
|
||||||
|
Windows,
|
||||||
|
Posix,
|
||||||
|
Native,
|
||||||
|
EfiApplication,
|
||||||
|
EfiBootServiceDriver,
|
||||||
|
EfiRom,
|
||||||
|
EfiRuntimeDriver,
|
||||||
|
Auto,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Pkg = extern struct {
|
||||||
|
name_ptr: [*]const u8,
|
||||||
|
name_len: usize,
|
||||||
|
path_ptr: [*]const u8,
|
||||||
|
path_len: usize,
|
||||||
|
children_ptr: [*]*Pkg,
|
||||||
|
children_len: usize,
|
||||||
|
parent: ?*Pkg,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Module = extern struct {
|
||||||
|
root_name_ptr: [*]const u8,
|
||||||
|
root_name_len: usize,
|
||||||
|
output_dir_ptr: [*]const u8,
|
||||||
|
output_dir_len: usize,
|
||||||
|
builtin_zig_path_ptr: [*]const u8,
|
||||||
|
builtin_zig_path_len: usize,
|
||||||
|
test_filter_ptr: [*]const u8,
|
||||||
|
test_filter_len: usize,
|
||||||
|
test_name_prefix_ptr: [*]const u8,
|
||||||
|
test_name_prefix_len: usize,
|
||||||
|
userdata: usize,
|
||||||
|
root_pkg: *Pkg,
|
||||||
|
main_progress_node: ?*std.Progress.Node,
|
||||||
|
code_model: CodeModel,
|
||||||
|
subsystem: TargetSubsystem,
|
||||||
|
err_color: ErrColor,
|
||||||
|
pic: bool,
|
||||||
|
link_libc: bool,
|
||||||
|
link_libcpp: bool,
|
||||||
|
strip: bool,
|
||||||
|
is_single_threaded: bool,
|
||||||
|
dll_export_fns: bool,
|
||||||
|
link_mode_dynamic: bool,
|
||||||
|
valgrind_enabled: bool,
|
||||||
|
function_sections: bool,
|
||||||
|
enable_stack_probing: bool,
|
||||||
|
enable_time_report: bool,
|
||||||
|
enable_stack_report: bool,
|
||||||
|
dump_analysis: bool,
|
||||||
|
enable_doc_generation: bool,
|
||||||
|
emit_bin: bool,
|
||||||
|
emit_asm: bool,
|
||||||
|
emit_llvm_ir: bool,
|
||||||
|
test_is_evented: bool,
|
||||||
|
verbose_tokenize: bool,
|
||||||
|
verbose_ast: bool,
|
||||||
|
verbose_ir: bool,
|
||||||
|
verbose_llvm_ir: bool,
|
||||||
|
verbose_cimport: bool,
|
||||||
|
verbose_llvm_cpu_features: bool,
|
||||||
|
|
||||||
|
pub fn build_object(mod: *Module) void {
|
||||||
|
zig_stage1_build_object(mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(mod: *Module) void {
|
||||||
|
zig_stage1_destroy(mod);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern fn zig_stage1_os_init() void;
|
||||||
|
|
||||||
|
pub const create = zig_stage1_create;
|
||||||
|
extern fn zig_stage1_create(
|
||||||
|
optimize_mode: BuildMode,
|
||||||
|
main_pkg_path_ptr: [*]const u8,
|
||||||
|
main_pkg_path_len: usize,
|
||||||
|
root_src_path_ptr: [*]const u8,
|
||||||
|
root_src_path_len: usize,
|
||||||
|
zig_lib_dir_ptr: [*c]const u8,
|
||||||
|
zig_lib_dir_len: usize,
|
||||||
|
target: [*c]const Stage2Target,
|
||||||
|
is_test_build: bool,
|
||||||
|
) ?*Module;
|
||||||
|
|
||||||
|
extern fn zig_stage1_build_object(*Module) void;
|
||||||
|
extern fn zig_stage1_destroy(*Module) void;
|
||||||
|
|
||||||
// ABI warning
|
// ABI warning
|
||||||
export fn stage2_panic(ptr: [*]const u8, len: usize) void {
|
export fn stage2_panic(ptr: [*]const u8, len: usize) void {
|
||||||
@panic(ptr[0..len]);
|
@panic(ptr[0..len]);
|
||||||
|
@ -199,297 +302,50 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
|
||||||
}
|
}
|
||||||
|
|
||||||
// ABI warning
|
// ABI warning
|
||||||
const Stage2Target = extern struct {
|
pub const Stage2Target = extern struct {
|
||||||
arch: c_int,
|
arch: c_int,
|
||||||
vendor: c_int,
|
os: OS,
|
||||||
|
|
||||||
abi: c_int,
|
abi: c_int,
|
||||||
os: c_int,
|
|
||||||
|
|
||||||
is_native_os: bool,
|
is_native_os: bool,
|
||||||
is_native_cpu: bool,
|
is_native_cpu: bool,
|
||||||
|
|
||||||
llvm_cpu_name: ?[*:0]const u8,
|
llvm_cpu_name: ?[*:0]const u8,
|
||||||
llvm_cpu_features: ?[*:0]const u8,
|
llvm_cpu_features: ?[*:0]const u8,
|
||||||
cpu_builtin_str: ?[*:0]const u8,
|
|
||||||
os_builtin_str: ?[*:0]const u8,
|
|
||||||
|
|
||||||
dynamic_linker: ?[*:0]const u8,
|
|
||||||
|
|
||||||
llvm_cpu_features_asm_ptr: [*]const [*:0]const u8,
|
|
||||||
llvm_cpu_features_asm_len: usize,
|
|
||||||
|
|
||||||
fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void {
|
|
||||||
const allocator = std.heap.c_allocator;
|
|
||||||
|
|
||||||
var dynamic_linker: ?[*:0]u8 = null;
|
|
||||||
const target = try crossTargetToTarget(cross_target, &dynamic_linker);
|
|
||||||
|
|
||||||
const generic_arch_name = target.cpu.arch.genericName();
|
|
||||||
var cpu_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator,
|
|
||||||
\\Cpu{{
|
|
||||||
\\ .arch = .{},
|
|
||||||
\\ .model = &Target.{}.cpu.{},
|
|
||||||
\\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{
|
|
||||||
\\
|
|
||||||
, .{
|
|
||||||
@tagName(target.cpu.arch),
|
|
||||||
generic_arch_name,
|
|
||||||
target.cpu.model.name,
|
|
||||||
generic_arch_name,
|
|
||||||
generic_arch_name,
|
|
||||||
});
|
|
||||||
defer cpu_builtin_str_buffer.deinit();
|
|
||||||
|
|
||||||
var llvm_features_buffer = try std.ArrayListSentineled(u8, 0).initSize(allocator, 0);
|
|
||||||
defer llvm_features_buffer.deinit();
|
|
||||||
|
|
||||||
// Unfortunately we have to do the work twice, because Clang does not support
|
|
||||||
// the same command line parameters for CPU features when assembling code as it does
|
|
||||||
// when compiling C code.
|
|
||||||
var asm_features_list = std.ArrayList([*:0]const u8).init(allocator);
|
|
||||||
defer asm_features_list.deinit();
|
|
||||||
|
|
||||||
for (target.cpu.arch.allFeaturesList()) |feature, index_usize| {
|
|
||||||
const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
|
|
||||||
const is_enabled = target.cpu.features.isEnabled(index);
|
|
||||||
|
|
||||||
if (feature.llvm_name) |llvm_name| {
|
|
||||||
const plus_or_minus = "-+"[@boolToInt(is_enabled)];
|
|
||||||
try llvm_features_buffer.append(plus_or_minus);
|
|
||||||
try llvm_features_buffer.appendSlice(llvm_name);
|
|
||||||
try llvm_features_buffer.appendSlice(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_enabled) {
|
|
||||||
// TODO some kind of "zig identifier escape" function rather than
|
|
||||||
// unconditionally using @"" syntax
|
|
||||||
try cpu_builtin_str_buffer.appendSlice(" .@\"");
|
|
||||||
try cpu_builtin_str_buffer.appendSlice(feature.name);
|
|
||||||
try cpu_builtin_str_buffer.appendSlice("\",\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (target.cpu.arch) {
|
|
||||||
.riscv32, .riscv64 => {
|
|
||||||
if (Target.riscv.featureSetHas(target.cpu.features, .relax)) {
|
|
||||||
try asm_features_list.append("-mrelax");
|
|
||||||
} else {
|
|
||||||
try asm_features_list.append("-mno-relax");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else => {
|
|
||||||
// TODO
|
|
||||||
// Argh, why doesn't the assembler accept the list of CPU features?!
|
|
||||||
// I don't see a way to do this other than hard coding everything.
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
try cpu_builtin_str_buffer.appendSlice(
|
|
||||||
\\ }),
|
|
||||||
\\};
|
|
||||||
\\
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(mem.endsWith(u8, llvm_features_buffer.span(), ","));
|
|
||||||
llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
|
|
||||||
|
|
||||||
var os_builtin_str_buffer = try std.ArrayListSentineled(u8, 0).allocPrint(allocator,
|
|
||||||
\\Os{{
|
|
||||||
\\ .tag = .{},
|
|
||||||
\\ .version_range = .{{
|
|
||||||
, .{@tagName(target.os.tag)});
|
|
||||||
defer os_builtin_str_buffer.deinit();
|
|
||||||
|
|
||||||
// We'll re-use the OS version range builtin string for the cache hash.
|
|
||||||
const os_builtin_str_ver_start_index = os_builtin_str_buffer.len();
|
|
||||||
|
|
||||||
@setEvalBranchQuota(2000);
|
|
||||||
switch (target.os.tag) {
|
|
||||||
.freestanding,
|
|
||||||
.ananas,
|
|
||||||
.cloudabi,
|
|
||||||
.dragonfly,
|
|
||||||
.fuchsia,
|
|
||||||
.ios,
|
|
||||||
.kfreebsd,
|
|
||||||
.lv2,
|
|
||||||
.solaris,
|
|
||||||
.haiku,
|
|
||||||
.minix,
|
|
||||||
.rtems,
|
|
||||||
.nacl,
|
|
||||||
.cnk,
|
|
||||||
.aix,
|
|
||||||
.cuda,
|
|
||||||
.nvcl,
|
|
||||||
.amdhsa,
|
|
||||||
.ps4,
|
|
||||||
.elfiamcu,
|
|
||||||
.tvos,
|
|
||||||
.watchos,
|
|
||||||
.mesa3d,
|
|
||||||
.contiki,
|
|
||||||
.amdpal,
|
|
||||||
.hermit,
|
|
||||||
.hurd,
|
|
||||||
.wasi,
|
|
||||||
.emscripten,
|
|
||||||
.uefi,
|
|
||||||
.other,
|
|
||||||
=> try os_builtin_str_buffer.appendSlice(" .none = {} }\n"),
|
|
||||||
|
|
||||||
.freebsd,
|
|
||||||
.macosx,
|
|
||||||
.netbsd,
|
|
||||||
.openbsd,
|
|
||||||
=> try os_builtin_str_buffer.outStream().print(
|
|
||||||
\\ .semver = .{{
|
|
||||||
\\ .min = .{{
|
|
||||||
\\ .major = {},
|
|
||||||
\\ .minor = {},
|
|
||||||
\\ .patch = {},
|
|
||||||
\\ }},
|
|
||||||
\\ .max = .{{
|
|
||||||
\\ .major = {},
|
|
||||||
\\ .minor = {},
|
|
||||||
\\ .patch = {},
|
|
||||||
\\ }},
|
|
||||||
\\ }}}},
|
|
||||||
\\
|
|
||||||
, .{
|
|
||||||
target.os.version_range.semver.min.major,
|
|
||||||
target.os.version_range.semver.min.minor,
|
|
||||||
target.os.version_range.semver.min.patch,
|
|
||||||
|
|
||||||
target.os.version_range.semver.max.major,
|
|
||||||
target.os.version_range.semver.max.minor,
|
|
||||||
target.os.version_range.semver.max.patch,
|
|
||||||
}),
|
|
||||||
|
|
||||||
.linux => try os_builtin_str_buffer.outStream().print(
|
|
||||||
\\ .linux = .{{
|
|
||||||
\\ .range = .{{
|
|
||||||
\\ .min = .{{
|
|
||||||
\\ .major = {},
|
|
||||||
\\ .minor = {},
|
|
||||||
\\ .patch = {},
|
|
||||||
\\ }},
|
|
||||||
\\ .max = .{{
|
|
||||||
\\ .major = {},
|
|
||||||
\\ .minor = {},
|
|
||||||
\\ .patch = {},
|
|
||||||
\\ }},
|
|
||||||
\\ }},
|
|
||||||
\\ .glibc = .{{
|
|
||||||
\\ .major = {},
|
|
||||||
\\ .minor = {},
|
|
||||||
\\ .patch = {},
|
|
||||||
\\ }},
|
|
||||||
\\ }}}},
|
|
||||||
\\
|
|
||||||
, .{
|
|
||||||
target.os.version_range.linux.range.min.major,
|
|
||||||
target.os.version_range.linux.range.min.minor,
|
|
||||||
target.os.version_range.linux.range.min.patch,
|
|
||||||
|
|
||||||
target.os.version_range.linux.range.max.major,
|
|
||||||
target.os.version_range.linux.range.max.minor,
|
|
||||||
target.os.version_range.linux.range.max.patch,
|
|
||||||
|
|
||||||
target.os.version_range.linux.glibc.major,
|
|
||||||
target.os.version_range.linux.glibc.minor,
|
|
||||||
target.os.version_range.linux.glibc.patch,
|
|
||||||
}),
|
|
||||||
|
|
||||||
.windows => try os_builtin_str_buffer.outStream().print(
|
|
||||||
\\ .windows = .{{
|
|
||||||
\\ .min = {s},
|
|
||||||
\\ .max = {s},
|
|
||||||
\\ }}}},
|
|
||||||
\\
|
|
||||||
, .{
|
|
||||||
target.os.version_range.windows.min,
|
|
||||||
target.os.version_range.windows.max,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
try os_builtin_str_buffer.appendSlice("};\n");
|
|
||||||
|
|
||||||
const glibc_or_darwin_version = blk: {
|
|
||||||
if (target.isGnuLibC()) {
|
|
||||||
const stage1_glibc = try std.heap.c_allocator.create(Stage2SemVer);
|
|
||||||
const stage2_glibc = target.os.version_range.linux.glibc;
|
|
||||||
stage1_glibc.* = .{
|
|
||||||
.major = stage2_glibc.major,
|
|
||||||
.minor = stage2_glibc.minor,
|
|
||||||
.patch = stage2_glibc.patch,
|
|
||||||
};
|
|
||||||
break :blk stage1_glibc;
|
|
||||||
} else if (target.isDarwin()) {
|
|
||||||
const stage1_semver = try std.heap.c_allocator.create(Stage2SemVer);
|
|
||||||
const stage2_semver = target.os.version_range.semver.min;
|
|
||||||
stage1_semver.* = .{
|
|
||||||
.major = stage2_semver.major,
|
|
||||||
.minor = stage2_semver.minor,
|
|
||||||
.patch = stage2_semver.patch,
|
|
||||||
};
|
|
||||||
break :blk stage1_semver;
|
|
||||||
} else {
|
|
||||||
break :blk null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const std_dl = target.standardDynamicLinkerPath();
|
|
||||||
const std_dl_z = if (std_dl.get()) |dl|
|
|
||||||
(try mem.dupeZ(std.heap.c_allocator, u8, dl)).ptr
|
|
||||||
else
|
|
||||||
null;
|
|
||||||
|
|
||||||
const asm_features = asm_features_list.toOwnedSlice();
|
|
||||||
self.* = .{
|
|
||||||
.arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch
|
|
||||||
.vendor = 0,
|
|
||||||
.os = @enumToInt(target.os.tag),
|
|
||||||
.abi = @enumToInt(target.abi),
|
|
||||||
.llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null,
|
|
||||||
.llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr,
|
|
||||||
.llvm_cpu_features_asm_ptr = asm_features.ptr,
|
|
||||||
.llvm_cpu_features_asm_len = asm_features.len,
|
|
||||||
.cpu_builtin_str = cpu_builtin_str_buffer.toOwnedSlice().ptr,
|
|
||||||
.os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr,
|
|
||||||
.is_native_os = cross_target.isNativeOs(),
|
|
||||||
.is_native_cpu = cross_target.isNativeCpu(),
|
|
||||||
.glibc_or_darwin_version = glibc_or_darwin_version,
|
|
||||||
.dynamic_linker = dynamic_linker,
|
|
||||||
.standard_dynamic_linker_path = std_dl_z,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target {
|
|
||||||
var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target);
|
|
||||||
if (info.cpu_detection_unimplemented) {
|
|
||||||
// TODO We want to just use detected_info.target but implementing
|
|
||||||
// CPU model & feature detection is todo so here we rely on LLVM.
|
|
||||||
const llvm = @import("llvm.zig");
|
|
||||||
const llvm_cpu_name = llvm.GetHostCPUName();
|
|
||||||
const llvm_cpu_features = llvm.GetNativeFeatures();
|
|
||||||
const arch = Target.current.cpu.arch;
|
|
||||||
info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features);
|
|
||||||
cross_target.updateCpuFeatures(&info.target.cpu.features);
|
|
||||||
info.target.cpu.arch = cross_target.getCpuArch();
|
|
||||||
}
|
|
||||||
if (info.dynamic_linker.get()) |dl| {
|
|
||||||
dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl);
|
|
||||||
} else {
|
|
||||||
dynamic_linker_ptr.* = null;
|
|
||||||
}
|
|
||||||
return info.target;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ABI warning
|
// ABI warning
|
||||||
const Stage2SemVer = extern struct {
|
const Stage2SemVer = extern struct {
|
||||||
major: u32,
|
major: u32,
|
||||||
minor: u32,
|
minor: u32,
|
||||||
patch: u32,
|
patch: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ABI warning
|
||||||
|
export fn stage2_cimport(stage1: *Module) [*:0]const u8 {
|
||||||
|
@panic("TODO implement stage2_cimport");
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn stage2_add_link_lib(
|
||||||
|
stage1: *Module,
|
||||||
|
lib_name_ptr: [*c]const u8,
|
||||||
|
lib_name_len: usize,
|
||||||
|
symbol_name_ptr: [*c]const u8,
|
||||||
|
symbol_name_len: usize,
|
||||||
|
) ?[*:0]const u8 {
|
||||||
|
return null; // no error
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn stage2_fetch_file(
|
||||||
|
stage1: *Module,
|
||||||
|
path_ptr: [*]const u8,
|
||||||
|
path_len: usize,
|
||||||
|
result_len: *usize,
|
||||||
|
) ?[*]const u8 {
|
||||||
|
const comp = @intToPtr(*Compilation, stage1.userdata);
|
||||||
|
// TODO integrate this with cache hash
|
||||||
|
const file_path = path_ptr[0..path_len];
|
||||||
|
const contents = std.fs.cwd().readFileAlloc(comp.gpa, file_path, std.math.maxInt(u32)) catch return null;
|
||||||
|
result_len.* = contents.len;
|
||||||
|
return contents.ptr;
|
||||||
|
}
|
||||||
|
|
|
@ -7987,7 +7987,7 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents_buf) {
|
||||||
size_t len;
|
size_t len;
|
||||||
const char *contents = stage2_fetch_file(&g->stage1, buf_ptr(resolved_path), buf_len(resolved_path), &len);
|
const char *contents = stage2_fetch_file(&g->stage1, buf_ptr(resolved_path), buf_len(resolved_path), &len);
|
||||||
if (contents == nullptr)
|
if (contents == nullptr)
|
||||||
return ErrorNoMem;
|
return ErrorFileNotFound;
|
||||||
buf_init_from_mem(contents_buf, contents, len);
|
buf_init_from_mem(contents_buf, contents, len);
|
||||||
return ErrorNone;
|
return ErrorNone;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8809,33 +8809,18 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||||
static_assert(TargetSubsystemEfiBootServiceDriver == 5, "");
|
static_assert(TargetSubsystemEfiBootServiceDriver == 5, "");
|
||||||
static_assert(TargetSubsystemEfiRom == 6, "");
|
static_assert(TargetSubsystemEfiRom == 6, "");
|
||||||
static_assert(TargetSubsystemEfiRuntimeDriver == 7, "");
|
static_assert(TargetSubsystemEfiRuntimeDriver == 7, "");
|
||||||
{
|
|
||||||
const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
|
buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch`\n");
|
||||||
buf_appendf(contents, "pub const endian = %s;\n", endian_str);
|
buf_append_str(contents, "pub const arch = Target.current.cpu.arch;\n");
|
||||||
}
|
buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch.endian()`\n");
|
||||||
|
buf_append_str(contents, "pub const endian = Target.current.cpu.arch.endian();\n");
|
||||||
buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n");
|
buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n");
|
||||||
buf_appendf(contents, "pub const link_mode = LinkMode.Static;\n");
|
buf_appendf(contents, "pub const link_mode = LinkMode.Static;\n");
|
||||||
buf_appendf(contents, "pub const is_test = false;\n");
|
buf_appendf(contents, "pub const is_test = false;\n");
|
||||||
buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
|
buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
|
||||||
buf_append_str(contents, "/// Deprecated: use `std.Target.cpu.arch`\n");
|
|
||||||
buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch);
|
|
||||||
buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);
|
buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);
|
||||||
{
|
buf_appendf(contents, "pub const cpu: Cpu = Target.Cpu.baseline(.%s);\n", cur_arch);
|
||||||
buf_append_str(contents, "pub const cpu: Cpu = ");
|
buf_appendf(contents, "pub const os = Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os);
|
||||||
if (g->zig_target->cpu_builtin_str != nullptr) {
|
|
||||||
buf_append_str(contents, g->zig_target->cpu_builtin_str);
|
|
||||||
} else {
|
|
||||||
buf_appendf(contents, "Target.Cpu.baseline(.%s);\n", cur_arch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
buf_append_str(contents, "pub const os = ");
|
|
||||||
if (g->zig_target->os_builtin_str != nullptr) {
|
|
||||||
buf_append_str(contents, g->zig_target->os_builtin_str);
|
|
||||||
} else {
|
|
||||||
buf_appendf(contents, "Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt);
|
buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt);
|
||||||
buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode));
|
buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode));
|
||||||
buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->link_libc));
|
buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->link_libc));
|
||||||
|
@ -8866,6 +8851,8 @@ static Error define_builtin_compile_vars(CodeGen *g) {
|
||||||
if (g->std_package == nullptr)
|
if (g->std_package == nullptr)
|
||||||
return ErrorNone;
|
return ErrorNone;
|
||||||
|
|
||||||
|
assert(g->main_pkg);
|
||||||
|
|
||||||
const char *builtin_zig_basename = "builtin.zig";
|
const char *builtin_zig_basename = "builtin.zig";
|
||||||
|
|
||||||
Buf *contents;
|
Buf *contents;
|
||||||
|
@ -8879,17 +8866,22 @@ static Error define_builtin_compile_vars(CodeGen *g) {
|
||||||
fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err));
|
fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin");
|
||||||
} else {
|
} else {
|
||||||
|
Buf *resolve_paths[] = { g->builtin_zig_path, };
|
||||||
|
*g->builtin_zig_path = os_path_resolve(resolve_paths, 1);
|
||||||
|
|
||||||
contents = buf_alloc();
|
contents = buf_alloc();
|
||||||
if ((err = os_fetch_file_path(g->builtin_zig_path, contents))) {
|
if ((err = os_fetch_file_path(g->builtin_zig_path, contents))) {
|
||||||
fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err));
|
fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(g->builtin_zig_path), err_str(err));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
Buf builtin_dirname = BUF_INIT;
|
||||||
|
os_path_dirname(g->builtin_zig_path, &builtin_dirname);
|
||||||
|
g->compile_var_package = new_package(buf_ptr(&builtin_dirname), builtin_zig_basename, "builtin");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(g->main_pkg);
|
|
||||||
assert(g->std_package);
|
|
||||||
g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin");
|
|
||||||
if (g->is_test_build) {
|
if (g->is_test_build) {
|
||||||
if (g->test_runner_package == nullptr) {
|
if (g->test_runner_package == nullptr) {
|
||||||
g->test_runner_package = create_test_runner_pkg(g);
|
g->test_runner_package = create_test_runner_pkg(g);
|
||||||
|
@ -8914,6 +8906,13 @@ static void init(CodeGen *g) {
|
||||||
if (g->module)
|
if (g->module)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
codegen_add_time_event(g, "Initialize");
|
||||||
|
{
|
||||||
|
const char *progress_name = "Initialize";
|
||||||
|
codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
|
||||||
|
progress_name, strlen(progress_name), 0));
|
||||||
|
}
|
||||||
|
|
||||||
g->have_err_ret_tracing = detect_err_ret_tracing(g);
|
g->have_err_ret_tracing = detect_err_ret_tracing(g);
|
||||||
|
|
||||||
assert(g->root_out_name);
|
assert(g->root_out_name);
|
||||||
|
@ -9374,19 +9373,11 @@ void codegen_destroy(CodeGen *g) {
|
||||||
|
|
||||||
CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
|
CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
|
||||||
BuildMode build_mode, Buf *override_lib_dir,
|
BuildMode build_mode, Buf *override_lib_dir,
|
||||||
bool is_test_build, Stage2ProgressNode *progress_node)
|
bool is_test_build)
|
||||||
{
|
{
|
||||||
CodeGen *g = heap::c_allocator.create<CodeGen>();
|
CodeGen *g = heap::c_allocator.create<CodeGen>();
|
||||||
g->emit_bin = true;
|
g->emit_bin = true;
|
||||||
g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");
|
g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");
|
||||||
g->main_progress_node = progress_node;
|
|
||||||
|
|
||||||
codegen_add_time_event(g, "Initialize");
|
|
||||||
{
|
|
||||||
const char *progress_name = "Initialize";
|
|
||||||
codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node,
|
|
||||||
progress_name, strlen(progress_name), 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
g->subsystem = TargetSubsystemAuto;
|
g->subsystem = TargetSubsystemAuto;
|
||||||
g->zig_target = target;
|
g->zig_target = target;
|
||||||
|
@ -9440,7 +9431,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
|
||||||
Buf resolved_main_pkg_path = os_path_resolve(&main_pkg_path, 1);
|
Buf resolved_main_pkg_path = os_path_resolve(&main_pkg_path, 1);
|
||||||
|
|
||||||
if (!buf_starts_with_buf(&resolved_root_src_path, &resolved_main_pkg_path)) {
|
if (!buf_starts_with_buf(&resolved_root_src_path, &resolved_main_pkg_path)) {
|
||||||
fprintf(stderr, "Root source path '%s' outside main package path '%s'",
|
fprintf(stderr, "Root source path '%s' outside main package path '%s'\n",
|
||||||
buf_ptr(root_src_path), buf_ptr(main_pkg_path));
|
buf_ptr(root_src_path), buf_ptr(main_pkg_path));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
|
CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
|
||||||
BuildMode build_mode, Buf *zig_lib_dir,
|
BuildMode build_mode, Buf *zig_lib_dir, bool is_test_build);
|
||||||
bool is_test_build, Stage2ProgressNode *progress_node);
|
|
||||||
|
|
||||||
void codegen_build_object(CodeGen *g);
|
void codegen_build_object(CodeGen *g);
|
||||||
void codegen_destroy(CodeGen *);
|
void codegen_destroy(CodeGen *);
|
||||||
|
|
|
@ -20,13 +20,14 @@ struct ZigStage1 *zig_stage1_create(BuildMode optimize_mode,
|
||||||
const char *main_pkg_path_ptr, size_t main_pkg_path_len,
|
const char *main_pkg_path_ptr, size_t main_pkg_path_len,
|
||||||
const char *root_src_path_ptr, size_t root_src_path_len,
|
const char *root_src_path_ptr, size_t root_src_path_len,
|
||||||
const char *zig_lib_dir_ptr, size_t zig_lib_dir_len,
|
const char *zig_lib_dir_ptr, size_t zig_lib_dir_len,
|
||||||
const ZigTarget *target, bool is_test_build, Stage2ProgressNode *progress_node)
|
const ZigTarget *target, bool is_test_build)
|
||||||
{
|
{
|
||||||
Buf *main_pkg_path = buf_create_from_mem(main_pkg_path_ptr, main_pkg_path_len);
|
Buf *main_pkg_path = (main_pkg_path_len == 0) ?
|
||||||
|
nullptr : buf_create_from_mem(main_pkg_path_ptr, main_pkg_path_len);
|
||||||
Buf *root_src_path = buf_create_from_mem(root_src_path_ptr, root_src_path_len);
|
Buf *root_src_path = buf_create_from_mem(root_src_path_ptr, root_src_path_len);
|
||||||
Buf *zig_lib_dir = buf_create_from_mem(zig_lib_dir_ptr, zig_lib_dir_len);
|
Buf *zig_lib_dir = buf_create_from_mem(zig_lib_dir_ptr, zig_lib_dir_len);
|
||||||
CodeGen *g = codegen_create(main_pkg_path, root_src_path, target, optimize_mode,
|
CodeGen *g = codegen_create(main_pkg_path, root_src_path, target, optimize_mode,
|
||||||
zig_lib_dir, is_test_build, progress_node);
|
zig_lib_dir, is_test_build);
|
||||||
return &g->stage1;
|
return &g->stage1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +69,6 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {
|
||||||
CodeGen *g = reinterpret_cast<CodeGen *>(stage1);
|
CodeGen *g = reinterpret_cast<CodeGen *>(stage1);
|
||||||
|
|
||||||
g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len);
|
g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len);
|
||||||
g->zig_lib_dir = buf_create_from_mem(stage1->zig_lib_dir_ptr, stage1->zig_lib_dir_len);
|
|
||||||
g->zig_std_dir = buf_create_from_mem(stage1->zig_std_dir_ptr, stage1->zig_std_dir_len);
|
|
||||||
g->output_dir = buf_create_from_mem(stage1->output_dir_ptr, stage1->output_dir_len);
|
g->output_dir = buf_create_from_mem(stage1->output_dir_ptr, stage1->output_dir_len);
|
||||||
if (stage1->builtin_zig_path_len != 0) {
|
if (stage1->builtin_zig_path_len != 0) {
|
||||||
g->builtin_zig_path = buf_create_from_mem(stage1->builtin_zig_path_ptr, stage1->builtin_zig_path_len);
|
g->builtin_zig_path = buf_create_from_mem(stage1->builtin_zig_path_ptr, stage1->builtin_zig_path_len);
|
||||||
|
@ -119,6 +118,8 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g->main_progress_node = stage1->main_progress_node;
|
||||||
|
|
||||||
add_package(g, stage1->root_pkg, g->main_pkg);
|
add_package(g, stage1->root_pkg, g->main_pkg);
|
||||||
|
|
||||||
codegen_build_object(g);
|
codegen_build_object(g);
|
||||||
|
|
25
src/stage1.h
25
src/stage1.h
|
@ -100,22 +100,14 @@ enum Os {
|
||||||
// ABI warning
|
// ABI warning
|
||||||
struct ZigTarget {
|
struct ZigTarget {
|
||||||
enum ZigLLVM_ArchType arch;
|
enum ZigLLVM_ArchType arch;
|
||||||
enum ZigLLVM_VendorType vendor;
|
enum Os os;
|
||||||
|
|
||||||
enum ZigLLVM_EnvironmentType abi;
|
enum ZigLLVM_EnvironmentType abi;
|
||||||
Os os;
|
|
||||||
|
|
||||||
bool is_native_os;
|
bool is_native_os;
|
||||||
bool is_native_cpu;
|
bool is_native_cpu;
|
||||||
|
|
||||||
const char *llvm_cpu_name;
|
const char *llvm_cpu_name;
|
||||||
const char *llvm_cpu_features;
|
const char *llvm_cpu_features;
|
||||||
const char *cpu_builtin_str;
|
|
||||||
const char *os_builtin_str;
|
|
||||||
const char *dynamic_linker;
|
|
||||||
|
|
||||||
const char **llvm_cpu_features_asm_ptr;
|
|
||||||
size_t llvm_cpu_features_asm_len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ABI warning
|
// ABI warning
|
||||||
|
@ -161,18 +153,13 @@ struct ZigStage1 {
|
||||||
const char *test_name_prefix_ptr;
|
const char *test_name_prefix_ptr;
|
||||||
size_t test_name_prefix_len;
|
size_t test_name_prefix_len;
|
||||||
|
|
||||||
const char *zig_lib_dir_ptr;
|
|
||||||
size_t zig_lib_dir_len;
|
|
||||||
|
|
||||||
const char *zig_std_dir_ptr;
|
|
||||||
size_t zig_std_dir_len;
|
|
||||||
|
|
||||||
void *userdata;
|
void *userdata;
|
||||||
struct ZigStage1Pkg *root_pkg;
|
struct ZigStage1Pkg *root_pkg;
|
||||||
|
struct Stage2ProgressNode *main_progress_node;
|
||||||
|
|
||||||
CodeModel code_model;
|
enum CodeModel code_model;
|
||||||
TargetSubsystem subsystem;
|
enum TargetSubsystem subsystem;
|
||||||
ErrColor err_color;
|
enum ErrColor err_color;
|
||||||
|
|
||||||
bool pic;
|
bool pic;
|
||||||
bool link_libc;
|
bool link_libc;
|
||||||
|
@ -206,7 +193,7 @@ ZIG_EXTERN_C struct ZigStage1 *zig_stage1_create(enum BuildMode optimize_mode,
|
||||||
const char *main_pkg_path_ptr, size_t main_pkg_path_len,
|
const char *main_pkg_path_ptr, size_t main_pkg_path_len,
|
||||||
const char *root_src_path_ptr, size_t root_src_path_len,
|
const char *root_src_path_ptr, size_t root_src_path_len,
|
||||||
const char *zig_lib_dir_ptr, size_t zig_lib_dir_len,
|
const char *zig_lib_dir_ptr, size_t zig_lib_dir_len,
|
||||||
const ZigTarget *target, bool is_test_build, Stage2ProgressNode *progress_node);
|
const struct ZigTarget *target, bool is_test_build);
|
||||||
|
|
||||||
ZIG_EXTERN_C void zig_stage1_build_object(struct ZigStage1 *);
|
ZIG_EXTERN_C void zig_stage1_build_object(struct ZigStage1 *);
|
||||||
|
|
||||||
|
|
241
src/stage2.cpp
241
src/stage2.cpp
|
@ -1,241 +0,0 @@
|
||||||
// This file is a shim for zig1. The real implementations of these are in
|
|
||||||
// src-self-hosted/stage1.zig
|
|
||||||
|
|
||||||
#include "stage2.h"
|
|
||||||
#include "util.hpp"
|
|
||||||
#include "zig_llvm.h"
|
|
||||||
#include "target.hpp"
|
|
||||||
#include "buffer.hpp"
|
|
||||||
#include "os.hpp"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
void stage2_panic(const char *ptr, size_t len) {
|
|
||||||
fwrite(ptr, 1, len, stderr);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
fflush(stderr);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Stage2Progress {
|
|
||||||
int trash;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Stage2ProgressNode {
|
|
||||||
int trash;
|
|
||||||
};
|
|
||||||
|
|
||||||
Stage2Progress *stage2_progress_create(void) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void stage2_progress_destroy(Stage2Progress *progress) {}
|
|
||||||
|
|
||||||
Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
|
|
||||||
const char *name_ptr, size_t name_len, size_t estimated_total_items)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
|
|
||||||
const char *name_ptr, size_t name_len, size_t estimated_total_items)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
void stage2_progress_end(Stage2ProgressNode *node) {}
|
|
||||||
void stage2_progress_complete_one(Stage2ProgressNode *node) {}
|
|
||||||
void stage2_progress_disable_tty(Stage2Progress *progress) {}
|
|
||||||
void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){}
|
|
||||||
|
|
||||||
static Os get_zig_os_type(ZigLLVM_OSType os_type) {
|
|
||||||
switch (os_type) {
|
|
||||||
case ZigLLVM_UnknownOS:
|
|
||||||
return OsFreestanding;
|
|
||||||
case ZigLLVM_Ananas:
|
|
||||||
return OsAnanas;
|
|
||||||
case ZigLLVM_CloudABI:
|
|
||||||
return OsCloudABI;
|
|
||||||
case ZigLLVM_DragonFly:
|
|
||||||
return OsDragonFly;
|
|
||||||
case ZigLLVM_FreeBSD:
|
|
||||||
return OsFreeBSD;
|
|
||||||
case ZigLLVM_Fuchsia:
|
|
||||||
return OsFuchsia;
|
|
||||||
case ZigLLVM_IOS:
|
|
||||||
return OsIOS;
|
|
||||||
case ZigLLVM_KFreeBSD:
|
|
||||||
return OsKFreeBSD;
|
|
||||||
case ZigLLVM_Linux:
|
|
||||||
return OsLinux;
|
|
||||||
case ZigLLVM_Lv2:
|
|
||||||
return OsLv2;
|
|
||||||
case ZigLLVM_Darwin:
|
|
||||||
case ZigLLVM_MacOSX:
|
|
||||||
return OsMacOSX;
|
|
||||||
case ZigLLVM_NetBSD:
|
|
||||||
return OsNetBSD;
|
|
||||||
case ZigLLVM_OpenBSD:
|
|
||||||
return OsOpenBSD;
|
|
||||||
case ZigLLVM_Solaris:
|
|
||||||
return OsSolaris;
|
|
||||||
case ZigLLVM_Win32:
|
|
||||||
return OsWindows;
|
|
||||||
case ZigLLVM_Haiku:
|
|
||||||
return OsHaiku;
|
|
||||||
case ZigLLVM_Minix:
|
|
||||||
return OsMinix;
|
|
||||||
case ZigLLVM_RTEMS:
|
|
||||||
return OsRTEMS;
|
|
||||||
case ZigLLVM_NaCl:
|
|
||||||
return OsNaCl;
|
|
||||||
case ZigLLVM_CNK:
|
|
||||||
return OsCNK;
|
|
||||||
case ZigLLVM_AIX:
|
|
||||||
return OsAIX;
|
|
||||||
case ZigLLVM_CUDA:
|
|
||||||
return OsCUDA;
|
|
||||||
case ZigLLVM_NVCL:
|
|
||||||
return OsNVCL;
|
|
||||||
case ZigLLVM_AMDHSA:
|
|
||||||
return OsAMDHSA;
|
|
||||||
case ZigLLVM_PS4:
|
|
||||||
return OsPS4;
|
|
||||||
case ZigLLVM_ELFIAMCU:
|
|
||||||
return OsELFIAMCU;
|
|
||||||
case ZigLLVM_TvOS:
|
|
||||||
return OsTvOS;
|
|
||||||
case ZigLLVM_WatchOS:
|
|
||||||
return OsWatchOS;
|
|
||||||
case ZigLLVM_Mesa3D:
|
|
||||||
return OsMesa3D;
|
|
||||||
case ZigLLVM_Contiki:
|
|
||||||
return OsContiki;
|
|
||||||
case ZigLLVM_AMDPAL:
|
|
||||||
return OsAMDPAL;
|
|
||||||
case ZigLLVM_HermitCore:
|
|
||||||
return OsHermitCore;
|
|
||||||
case ZigLLVM_Hurd:
|
|
||||||
return OsHurd;
|
|
||||||
case ZigLLVM_WASI:
|
|
||||||
return OsWASI;
|
|
||||||
case ZigLLVM_Emscripten:
|
|
||||||
return OsEmscripten;
|
|
||||||
}
|
|
||||||
zig_unreachable();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_native_target(ZigTarget *target) {
|
|
||||||
// first zero initialize
|
|
||||||
*target = {};
|
|
||||||
|
|
||||||
ZigLLVM_OSType os_type;
|
|
||||||
ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os
|
|
||||||
ZigLLVMGetNativeTarget(
|
|
||||||
&target->arch,
|
|
||||||
&target->vendor,
|
|
||||||
&os_type,
|
|
||||||
&target->abi,
|
|
||||||
&oformat);
|
|
||||||
target->os = get_zig_os_type(os_type);
|
|
||||||
target->is_native_os = true;
|
|
||||||
target->is_native_cpu = true;
|
|
||||||
if (target->abi == ZigLLVM_UnknownEnvironment) {
|
|
||||||
target->abi = target_default_abi(target->arch, target->os);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu,
|
|
||||||
const char *dynamic_linker)
|
|
||||||
{
|
|
||||||
Error err;
|
|
||||||
|
|
||||||
if (zig_triple != nullptr && strcmp(zig_triple, "native") == 0) {
|
|
||||||
zig_triple = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zig_triple == nullptr) {
|
|
||||||
get_native_target(target);
|
|
||||||
|
|
||||||
if (mcpu == nullptr) {
|
|
||||||
target->llvm_cpu_name = ZigLLVMGetHostCPUName();
|
|
||||||
target->llvm_cpu_features = ZigLLVMGetNativeFeatures();
|
|
||||||
} else if (strcmp(mcpu, "baseline") == 0) {
|
|
||||||
target->is_native_os = false;
|
|
||||||
target->is_native_cpu = false;
|
|
||||||
target->llvm_cpu_name = "";
|
|
||||||
target->llvm_cpu_features = "";
|
|
||||||
} else {
|
|
||||||
const char *msg = "stage0 can't handle CPU/features in the target";
|
|
||||||
stage2_panic(msg, strlen(msg));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// first initialize all to zero
|
|
||||||
*target = {};
|
|
||||||
|
|
||||||
SplitIterator it = memSplit(str(zig_triple), str("-"));
|
|
||||||
|
|
||||||
Optional<Slice<uint8_t>> opt_archsub = SplitIterator_next(&it);
|
|
||||||
Optional<Slice<uint8_t>> opt_os = SplitIterator_next(&it);
|
|
||||||
Optional<Slice<uint8_t>> opt_abi = SplitIterator_next(&it);
|
|
||||||
|
|
||||||
if (!opt_archsub.is_some)
|
|
||||||
return ErrorMissingArchitecture;
|
|
||||||
|
|
||||||
if ((err = target_parse_arch(&target->arch, (char*)opt_archsub.value.ptr, opt_archsub.value.len))) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!opt_os.is_some)
|
|
||||||
return ErrorMissingOperatingSystem;
|
|
||||||
|
|
||||||
if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt_abi.is_some) {
|
|
||||||
if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
target->abi = target_default_abi(target->arch, target->os);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) {
|
|
||||||
const char *msg = "stage0 can't handle CPU/features in the target";
|
|
||||||
stage2_panic(msg, strlen(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dynamic_linker != nullptr) {
|
|
||||||
target->dynamic_linker = dynamic_linker;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ErrorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *stage2_fetch_file(struct ZigStage1 *stage1, const char *path_ptr, size_t path_len,
|
|
||||||
size_t *result_len)
|
|
||||||
{
|
|
||||||
Error err;
|
|
||||||
Buf contents_buf = BUF_INIT;
|
|
||||||
Buf path_buf = BUF_INIT;
|
|
||||||
|
|
||||||
buf_init_from_mem(&path_buf, path_ptr, path_len);
|
|
||||||
if ((err = os_fetch_file_path(&path_buf, &contents_buf))) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
*result_len = buf_len(&contents_buf);
|
|
||||||
return buf_ptr(&contents_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *stage2_cimport(struct ZigStage1 *stage1) {
|
|
||||||
const char *msg = "stage0 called stage2_cimport";
|
|
||||||
stage2_panic(msg, strlen(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *stage2_add_link_lib(struct ZigStage1 *stage1,
|
|
||||||
const char *lib_name_ptr, size_t lib_name_len,
|
|
||||||
const char *symbol_name_ptr, size_t symbol_name_len)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
16
src/stage2.h
16
src/stage2.h
|
@ -130,23 +130,23 @@ struct Stage2ErrorMsg {
|
||||||
ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
|
ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
|
||||||
|
|
||||||
// ABI warning
|
// ABI warning
|
||||||
ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void);
|
ZIG_EXTERN_C struct Stage2Progress *stage2_progress_create(void);
|
||||||
// ABI warning
|
// ABI warning
|
||||||
ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress);
|
ZIG_EXTERN_C void stage2_progress_disable_tty(struct Stage2Progress *progress);
|
||||||
// ABI warning
|
// ABI warning
|
||||||
ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress);
|
ZIG_EXTERN_C void stage2_progress_destroy(struct Stage2Progress *progress);
|
||||||
// ABI warning
|
// ABI warning
|
||||||
ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
|
ZIG_EXTERN_C struct Stage2ProgressNode *stage2_progress_start_root(struct Stage2Progress *progress,
|
||||||
const char *name_ptr, size_t name_len, size_t estimated_total_items);
|
const char *name_ptr, size_t name_len, size_t estimated_total_items);
|
||||||
// ABI warning
|
// ABI warning
|
||||||
ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
|
ZIG_EXTERN_C struct Stage2ProgressNode *stage2_progress_start(struct Stage2ProgressNode *node,
|
||||||
const char *name_ptr, size_t name_len, size_t estimated_total_items);
|
const char *name_ptr, size_t name_len, size_t estimated_total_items);
|
||||||
// ABI warning
|
// ABI warning
|
||||||
ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node);
|
ZIG_EXTERN_C void stage2_progress_end(struct Stage2ProgressNode *node);
|
||||||
// ABI warning
|
// ABI warning
|
||||||
ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node);
|
ZIG_EXTERN_C void stage2_progress_complete_one(struct Stage2ProgressNode *node);
|
||||||
// ABI warning
|
// ABI warning
|
||||||
ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node,
|
ZIG_EXTERN_C void stage2_progress_update_node(struct Stage2ProgressNode *node,
|
||||||
size_t completed_count, size_t estimated_total_items);
|
size_t completed_count, size_t estimated_total_items);
|
||||||
|
|
||||||
// ABI warning
|
// ABI warning
|
||||||
|
|
|
@ -380,10 +380,6 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si
|
||||||
return ErrorUnknownABI;
|
return ErrorUnknownABI;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker) {
|
|
||||||
return stage2_target_parse(target, triple, mcpu, dynamic_linker);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *target_arch_name(ZigLLVM_ArchType arch) {
|
const char *target_arch_name(ZigLLVM_ArchType arch) {
|
||||||
return ZigLLVMGetArchTypeName(arch);
|
return ZigLLVMGetArchTypeName(arch);
|
||||||
}
|
}
|
||||||
|
@ -408,7 +404,7 @@ void target_triple_llvm(Buf *triple, const ZigTarget *target) {
|
||||||
buf_resize(triple, 0);
|
buf_resize(triple, 0);
|
||||||
buf_appendf(triple, "%s-%s-%s-%s",
|
buf_appendf(triple, "%s-%s-%s-%s",
|
||||||
ZigLLVMGetArchTypeName(target->arch),
|
ZigLLVMGetArchTypeName(target->arch),
|
||||||
ZigLLVMGetVendorTypeName(target->vendor),
|
ZigLLVMGetVendorTypeName(ZigLLVM_UnknownVendor),
|
||||||
ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
|
ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
|
||||||
ZigLLVMGetEnvironmentTypeName(target->abi));
|
ZigLLVMGetEnvironmentTypeName(target->abi));
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1145,6 @@ void target_libc_enum(size_t index, ZigTarget *out_target) {
|
||||||
out_target->arch = libcs_available[index].arch;
|
out_target->arch = libcs_available[index].arch;
|
||||||
out_target->os = libcs_available[index].os;
|
out_target->os = libcs_available[index].os;
|
||||||
out_target->abi = libcs_available[index].abi;
|
out_target->abi = libcs_available[index].abi;
|
||||||
out_target->vendor = ZigLLVM_UnknownVendor;
|
|
||||||
out_target->is_native_os = false;
|
out_target->is_native_os = false;
|
||||||
out_target->is_native_cpu = false;
|
out_target->is_native_cpu = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ enum CIntType {
|
||||||
CIntTypeCount,
|
CIntTypeCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker);
|
|
||||||
Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len);
|
Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len);
|
||||||
Error target_parse_os(Os *os, const char *os_ptr, size_t os_len);
|
Error target_parse_os(Os *os, const char *os_ptr, size_t os_len);
|
||||||
Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len);
|
Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len);
|
||||||
|
|
251
src/zig0.cpp
251
src/zig0.cpp
|
@ -14,6 +14,9 @@
|
||||||
#include "stage2.h"
|
#include "stage2.h"
|
||||||
#include "target.hpp"
|
#include "target.hpp"
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
|
#include "util.hpp"
|
||||||
|
#include "buffer.hpp"
|
||||||
|
#include "os.hpp"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -33,7 +36,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
|
||||||
" --output-dir [dir] override output directory (defaults to cwd)\n"
|
" --output-dir [dir] override output directory (defaults to cwd)\n"
|
||||||
" --pkg-begin [name] [path] make pkg available to import and push current pkg\n"
|
" --pkg-begin [name] [path] make pkg available to import and push current pkg\n"
|
||||||
" --pkg-end pop current pkg\n"
|
" --pkg-end pop current pkg\n"
|
||||||
" --main-pkg-path set the directory of the root package\n"
|
|
||||||
" --release-fast build with optimizations on and safety off\n"
|
" --release-fast build with optimizations on and safety off\n"
|
||||||
" --release-safe build with optimizations on and safety on\n"
|
" --release-safe build with optimizations on and safety on\n"
|
||||||
" --release-small build with size optimizations on and safety off\n"
|
" --release-small build with size optimizations on and safety off\n"
|
||||||
|
@ -53,6 +55,170 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
|
||||||
return return_code;
|
return return_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Os get_zig_os_type(ZigLLVM_OSType os_type) {
|
||||||
|
switch (os_type) {
|
||||||
|
case ZigLLVM_UnknownOS:
|
||||||
|
return OsFreestanding;
|
||||||
|
case ZigLLVM_Ananas:
|
||||||
|
return OsAnanas;
|
||||||
|
case ZigLLVM_CloudABI:
|
||||||
|
return OsCloudABI;
|
||||||
|
case ZigLLVM_DragonFly:
|
||||||
|
return OsDragonFly;
|
||||||
|
case ZigLLVM_FreeBSD:
|
||||||
|
return OsFreeBSD;
|
||||||
|
case ZigLLVM_Fuchsia:
|
||||||
|
return OsFuchsia;
|
||||||
|
case ZigLLVM_IOS:
|
||||||
|
return OsIOS;
|
||||||
|
case ZigLLVM_KFreeBSD:
|
||||||
|
return OsKFreeBSD;
|
||||||
|
case ZigLLVM_Linux:
|
||||||
|
return OsLinux;
|
||||||
|
case ZigLLVM_Lv2:
|
||||||
|
return OsLv2;
|
||||||
|
case ZigLLVM_Darwin:
|
||||||
|
case ZigLLVM_MacOSX:
|
||||||
|
return OsMacOSX;
|
||||||
|
case ZigLLVM_NetBSD:
|
||||||
|
return OsNetBSD;
|
||||||
|
case ZigLLVM_OpenBSD:
|
||||||
|
return OsOpenBSD;
|
||||||
|
case ZigLLVM_Solaris:
|
||||||
|
return OsSolaris;
|
||||||
|
case ZigLLVM_Win32:
|
||||||
|
return OsWindows;
|
||||||
|
case ZigLLVM_Haiku:
|
||||||
|
return OsHaiku;
|
||||||
|
case ZigLLVM_Minix:
|
||||||
|
return OsMinix;
|
||||||
|
case ZigLLVM_RTEMS:
|
||||||
|
return OsRTEMS;
|
||||||
|
case ZigLLVM_NaCl:
|
||||||
|
return OsNaCl;
|
||||||
|
case ZigLLVM_CNK:
|
||||||
|
return OsCNK;
|
||||||
|
case ZigLLVM_AIX:
|
||||||
|
return OsAIX;
|
||||||
|
case ZigLLVM_CUDA:
|
||||||
|
return OsCUDA;
|
||||||
|
case ZigLLVM_NVCL:
|
||||||
|
return OsNVCL;
|
||||||
|
case ZigLLVM_AMDHSA:
|
||||||
|
return OsAMDHSA;
|
||||||
|
case ZigLLVM_PS4:
|
||||||
|
return OsPS4;
|
||||||
|
case ZigLLVM_ELFIAMCU:
|
||||||
|
return OsELFIAMCU;
|
||||||
|
case ZigLLVM_TvOS:
|
||||||
|
return OsTvOS;
|
||||||
|
case ZigLLVM_WatchOS:
|
||||||
|
return OsWatchOS;
|
||||||
|
case ZigLLVM_Mesa3D:
|
||||||
|
return OsMesa3D;
|
||||||
|
case ZigLLVM_Contiki:
|
||||||
|
return OsContiki;
|
||||||
|
case ZigLLVM_AMDPAL:
|
||||||
|
return OsAMDPAL;
|
||||||
|
case ZigLLVM_HermitCore:
|
||||||
|
return OsHermitCore;
|
||||||
|
case ZigLLVM_Hurd:
|
||||||
|
return OsHurd;
|
||||||
|
case ZigLLVM_WASI:
|
||||||
|
return OsWASI;
|
||||||
|
case ZigLLVM_Emscripten:
|
||||||
|
return OsEmscripten;
|
||||||
|
}
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_native_target(ZigTarget *target) {
|
||||||
|
// first zero initialize
|
||||||
|
*target = {};
|
||||||
|
|
||||||
|
ZigLLVM_OSType os_type;
|
||||||
|
ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os
|
||||||
|
ZigLLVM_VendorType trash;
|
||||||
|
ZigLLVMGetNativeTarget(
|
||||||
|
&target->arch,
|
||||||
|
&trash,
|
||||||
|
&os_type,
|
||||||
|
&target->abi,
|
||||||
|
&oformat);
|
||||||
|
target->os = get_zig_os_type(os_type);
|
||||||
|
target->is_native_os = true;
|
||||||
|
target->is_native_cpu = true;
|
||||||
|
if (target->abi == ZigLLVM_UnknownEnvironment) {
|
||||||
|
target->abi = target_default_abi(target->arch, target->os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error target_parse_triple(struct ZigTarget *target, const char *zig_triple, const char *mcpu,
|
||||||
|
const char *dynamic_linker)
|
||||||
|
{
|
||||||
|
Error err;
|
||||||
|
|
||||||
|
if (zig_triple != nullptr && strcmp(zig_triple, "native") == 0) {
|
||||||
|
zig_triple = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zig_triple == nullptr) {
|
||||||
|
get_native_target(target);
|
||||||
|
|
||||||
|
if (mcpu == nullptr) {
|
||||||
|
target->llvm_cpu_name = ZigLLVMGetHostCPUName();
|
||||||
|
target->llvm_cpu_features = ZigLLVMGetNativeFeatures();
|
||||||
|
} else if (strcmp(mcpu, "baseline") == 0) {
|
||||||
|
target->is_native_os = false;
|
||||||
|
target->is_native_cpu = false;
|
||||||
|
target->llvm_cpu_name = "";
|
||||||
|
target->llvm_cpu_features = "";
|
||||||
|
} else {
|
||||||
|
const char *msg = "stage0 can't handle CPU/features in the target";
|
||||||
|
stage2_panic(msg, strlen(msg));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// first initialize all to zero
|
||||||
|
*target = {};
|
||||||
|
|
||||||
|
SplitIterator it = memSplit(str(zig_triple), str("-"));
|
||||||
|
|
||||||
|
Optional<Slice<uint8_t>> opt_archsub = SplitIterator_next(&it);
|
||||||
|
Optional<Slice<uint8_t>> opt_os = SplitIterator_next(&it);
|
||||||
|
Optional<Slice<uint8_t>> opt_abi = SplitIterator_next(&it);
|
||||||
|
|
||||||
|
if (!opt_archsub.is_some)
|
||||||
|
return ErrorMissingArchitecture;
|
||||||
|
|
||||||
|
if ((err = target_parse_arch(&target->arch, (char*)opt_archsub.value.ptr, opt_archsub.value.len))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!opt_os.is_some)
|
||||||
|
return ErrorMissingOperatingSystem;
|
||||||
|
|
||||||
|
if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_abi.is_some) {
|
||||||
|
if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
target->abi = target_default_abi(target->arch, target->os);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) {
|
||||||
|
const char *msg = "stage0 can't handle CPU/features in the target";
|
||||||
|
stage2_panic(msg, strlen(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool str_starts_with(const char *s1, const char *s2) {
|
static bool str_starts_with(const char *s1, const char *s2) {
|
||||||
size_t s2_len = strlen(s2);
|
size_t s2_len = strlen(s2);
|
||||||
if (strlen(s1) < s2_len) {
|
if (strlen(s1) < s2_len) {
|
||||||
|
@ -90,10 +256,9 @@ int main(int argc, char **argv) {
|
||||||
bool link_libcpp = false;
|
bool link_libcpp = false;
|
||||||
const char *target_string = nullptr;
|
const char *target_string = nullptr;
|
||||||
ZigStage1Pkg *cur_pkg = heap::c_allocator.create<ZigStage1Pkg>();
|
ZigStage1Pkg *cur_pkg = heap::c_allocator.create<ZigStage1Pkg>();
|
||||||
BuildMode build_mode = BuildModeDebug;
|
BuildMode optimize_mode = BuildModeDebug;
|
||||||
TargetSubsystem subsystem = TargetSubsystemAuto;
|
TargetSubsystem subsystem = TargetSubsystemAuto;
|
||||||
const char *override_lib_dir = nullptr;
|
const char *override_lib_dir = nullptr;
|
||||||
const char *main_pkg_path = nullptr;
|
|
||||||
const char *mcpu = nullptr;
|
const char *mcpu = nullptr;
|
||||||
|
|
||||||
for (int i = 1; i < argc; i += 1) {
|
for (int i = 1; i < argc; i += 1) {
|
||||||
|
@ -103,11 +268,11 @@ int main(int argc, char **argv) {
|
||||||
if (strcmp(arg, "--") == 0) {
|
if (strcmp(arg, "--") == 0) {
|
||||||
fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg);
|
fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg);
|
||||||
} else if (strcmp(arg, "--release-fast") == 0) {
|
} else if (strcmp(arg, "--release-fast") == 0) {
|
||||||
build_mode = BuildModeFastRelease;
|
optimize_mode = BuildModeFastRelease;
|
||||||
} else if (strcmp(arg, "--release-safe") == 0) {
|
} else if (strcmp(arg, "--release-safe") == 0) {
|
||||||
build_mode = BuildModeSafeRelease;
|
optimize_mode = BuildModeSafeRelease;
|
||||||
} else if (strcmp(arg, "--release-small") == 0) {
|
} else if (strcmp(arg, "--release-small") == 0) {
|
||||||
build_mode = BuildModeSmallRelease;
|
optimize_mode = BuildModeSmallRelease;
|
||||||
} else if (strcmp(arg, "--help") == 0) {
|
} else if (strcmp(arg, "--help") == 0) {
|
||||||
return print_full_usage(arg0, stdout, EXIT_SUCCESS);
|
return print_full_usage(arg0, stdout, EXIT_SUCCESS);
|
||||||
} else if (strcmp(arg, "--strip") == 0) {
|
} else if (strcmp(arg, "--strip") == 0) {
|
||||||
|
@ -183,8 +348,6 @@ int main(int argc, char **argv) {
|
||||||
dynamic_linker = argv[i];
|
dynamic_linker = argv[i];
|
||||||
} else if (strcmp(arg, "--override-lib-dir") == 0) {
|
} else if (strcmp(arg, "--override-lib-dir") == 0) {
|
||||||
override_lib_dir = argv[i];
|
override_lib_dir = argv[i];
|
||||||
} else if (strcmp(arg, "--main-pkg-path") == 0) {
|
|
||||||
main_pkg_path = argv[i];
|
|
||||||
} else if (strcmp(arg, "--library") == 0 || strcmp(arg, "-l") == 0) {
|
} else if (strcmp(arg, "--library") == 0 || strcmp(arg, "-l") == 0) {
|
||||||
if (strcmp(argv[i], "c") == 0) {
|
if (strcmp(argv[i], "c") == 0) {
|
||||||
link_libc = true;
|
link_libc = true;
|
||||||
|
@ -264,12 +427,13 @@ int main(int argc, char **argv) {
|
||||||
return print_error_usage(arg0);
|
return print_error_usage(arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigStage1 *stage1 = zig_stage1_create(build_mode,
|
ZigStage1 *stage1 = zig_stage1_create(optimize_mode,
|
||||||
main_pkg_path, (main_pkg_path == nullptr) ? 0 : strlen(main_pkg_path),
|
nullptr, 0,
|
||||||
in_file, strlen(in_file),
|
in_file, strlen(in_file),
|
||||||
override_lib_dir, strlen(override_lib_dir), &target, false,
|
override_lib_dir, strlen(override_lib_dir),
|
||||||
root_progress_node);
|
&target, false);
|
||||||
|
|
||||||
|
stage1->main_progress_node = root_progress_node;
|
||||||
stage1->root_name_ptr = out_name;
|
stage1->root_name_ptr = out_name;
|
||||||
stage1->root_name_len = strlen(out_name);
|
stage1->root_name_len = strlen(out_name);
|
||||||
stage1->strip = strip;
|
stage1->strip = strip;
|
||||||
|
@ -295,3 +459,66 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
return main_exit(root_progress_node, EXIT_SUCCESS);
|
return main_exit(root_progress_node, EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stage2_panic(const char *ptr, size_t len) {
|
||||||
|
fwrite(ptr, 1, len, stderr);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fflush(stderr);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Stage2Progress {
|
||||||
|
int trash;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Stage2ProgressNode {
|
||||||
|
int trash;
|
||||||
|
};
|
||||||
|
|
||||||
|
Stage2Progress *stage2_progress_create(void) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stage2_progress_destroy(Stage2Progress *progress) {}
|
||||||
|
|
||||||
|
Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
|
||||||
|
const char *name_ptr, size_t name_len, size_t estimated_total_items)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
|
||||||
|
const char *name_ptr, size_t name_len, size_t estimated_total_items)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
void stage2_progress_end(Stage2ProgressNode *node) {}
|
||||||
|
void stage2_progress_complete_one(Stage2ProgressNode *node) {}
|
||||||
|
void stage2_progress_disable_tty(Stage2Progress *progress) {}
|
||||||
|
void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){}
|
||||||
|
|
||||||
|
const char *stage2_fetch_file(struct ZigStage1 *stage1, const char *path_ptr, size_t path_len,
|
||||||
|
size_t *result_len)
|
||||||
|
{
|
||||||
|
Error err;
|
||||||
|
Buf contents_buf = BUF_INIT;
|
||||||
|
Buf path_buf = BUF_INIT;
|
||||||
|
|
||||||
|
buf_init_from_mem(&path_buf, path_ptr, path_len);
|
||||||
|
if ((err = os_fetch_file_path(&path_buf, &contents_buf))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
*result_len = buf_len(&contents_buf);
|
||||||
|
return buf_ptr(&contents_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *stage2_cimport(struct ZigStage1 *stage1) {
|
||||||
|
const char *msg = "stage0 called stage2_cimport";
|
||||||
|
stage2_panic(msg, strlen(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *stage2_add_link_lib(struct ZigStage1 *stage1,
|
||||||
|
const char *lib_name_ptr, size_t lib_name_len,
|
||||||
|
const char *symbol_name_ptr, size_t symbol_name_len)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue