Commit 2ef68631cb
Changed files (17)
src/analyze.cpp
@@ -7987,7 +7987,7 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents_buf) {
size_t len;
const char *contents = stage2_fetch_file(&g->stage1, buf_ptr(resolved_path), buf_len(resolved_path), &len);
if (contents == nullptr)
- return ErrorNoMem;
+ return ErrorFileNotFound;
buf_init_from_mem(contents_buf, contents, len);
return ErrorNone;
}
src/codegen.cpp
@@ -8809,33 +8809,18 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
static_assert(TargetSubsystemEfiBootServiceDriver == 5, "");
static_assert(TargetSubsystemEfiRom == 6, "");
static_assert(TargetSubsystemEfiRuntimeDriver == 7, "");
- {
- const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
- buf_appendf(contents, "pub const endian = %s;\n", endian_str);
- }
+
+ buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch`\n");
+ 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 link_mode = LinkMode.Static;\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_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_append_str(contents, "pub const cpu: Cpu = ");
- 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 cpu: Cpu = Target.Cpu.baseline(.%s);\n", cur_arch);
+ buf_appendf(contents, "pub const os = 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 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));
@@ -8866,6 +8851,8 @@ static Error define_builtin_compile_vars(CodeGen *g) {
if (g->std_package == nullptr)
return ErrorNone;
+ assert(g->main_pkg);
+
const char *builtin_zig_basename = "builtin.zig";
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));
exit(1);
}
+
+ g->compile_var_package = new_package(buf_ptr(g->output_dir), builtin_zig_basename, "builtin");
} else {
+ Buf *resolve_paths[] = { g->builtin_zig_path, };
+ *g->builtin_zig_path = os_path_resolve(resolve_paths, 1);
+
contents = buf_alloc();
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));
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->test_runner_package == nullptr) {
g->test_runner_package = create_test_runner_pkg(g);
@@ -8914,6 +8906,13 @@ static void init(CodeGen *g) {
if (g->module)
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);
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,
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>();
g->emit_bin = true;
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->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);
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));
exit(1);
}
src/codegen.hpp
@@ -16,8 +16,7 @@
#include <stdio.h>
CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
- BuildMode build_mode, Buf *zig_lib_dir,
- bool is_test_build, Stage2ProgressNode *progress_node);
+ BuildMode build_mode, Buf *zig_lib_dir, bool is_test_build);
void codegen_build_object(CodeGen *g);
void codegen_destroy(CodeGen *);
src/stage1.cpp
@@ -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 *root_src_path_ptr, size_t root_src_path_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 *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,
- zig_lib_dir, is_test_build, progress_node);
+ zig_lib_dir, is_test_build);
return &g->stage1;
}
@@ -68,8 +69,6 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {
CodeGen *g = reinterpret_cast<CodeGen *>(stage1);
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);
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);
@@ -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);
codegen_build_object(g);
src/stage1.h
@@ -100,22 +100,14 @@ enum Os {
// ABI warning
struct ZigTarget {
enum ZigLLVM_ArchType arch;
- enum ZigLLVM_VendorType vendor;
-
+ enum Os os;
enum ZigLLVM_EnvironmentType abi;
- Os os;
bool is_native_os;
bool is_native_cpu;
const char *llvm_cpu_name;
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
@@ -161,18 +153,13 @@ struct ZigStage1 {
const char *test_name_prefix_ptr;
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;
struct ZigStage1Pkg *root_pkg;
+ struct Stage2ProgressNode *main_progress_node;
- CodeModel code_model;
- TargetSubsystem subsystem;
- ErrColor err_color;
+ enum CodeModel code_model;
+ enum TargetSubsystem subsystem;
+ enum ErrColor err_color;
bool pic;
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 *root_src_path_ptr, size_t root_src_path_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 *);
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;
-}
src/stage2.h
@@ -130,23 +130,23 @@ struct Stage2ErrorMsg {
ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
// ABI warning
-ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void);
+ZIG_EXTERN_C struct Stage2Progress *stage2_progress_create(void);
// 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
-ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress);
+ZIG_EXTERN_C void stage2_progress_destroy(struct Stage2Progress *progress);
// 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);
// 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);
// ABI warning
-ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node);
+ZIG_EXTERN_C void stage2_progress_end(struct Stage2ProgressNode *node);
// 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
-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);
// ABI warning
src/target.cpp
@@ -380,10 +380,6 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si
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) {
return ZigLLVMGetArchTypeName(arch);
}
@@ -408,7 +404,7 @@ void target_triple_llvm(Buf *triple, const ZigTarget *target) {
buf_resize(triple, 0);
buf_appendf(triple, "%s-%s-%s-%s",
ZigLLVMGetArchTypeName(target->arch),
- ZigLLVMGetVendorTypeName(target->vendor),
+ ZigLLVMGetVendorTypeName(ZigLLVM_UnknownVendor),
ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
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->os = libcs_available[index].os;
out_target->abi = libcs_available[index].abi;
- out_target->vendor = ZigLLVM_UnknownVendor;
out_target->is_native_os = false;
out_target->is_native_cpu = false;
}
src/target.hpp
@@ -25,7 +25,6 @@ enum CIntType {
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_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);
src/zig0.cpp
@@ -14,6 +14,9 @@
#include "stage2.h"
#include "target.hpp"
#include "error.hpp"
+#include "util.hpp"
+#include "buffer.hpp"
+#include "os.hpp"
#include <stdio.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"
" --pkg-begin [name] [path] make pkg available to import and push 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-safe build with optimizations on and safety on\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;
}
+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) {
size_t s2_len = strlen(s2);
if (strlen(s1) < s2_len) {
@@ -90,10 +256,9 @@ int main(int argc, char **argv) {
bool link_libcpp = false;
const char *target_string = nullptr;
ZigStage1Pkg *cur_pkg = heap::c_allocator.create<ZigStage1Pkg>();
- BuildMode build_mode = BuildModeDebug;
+ BuildMode optimize_mode = BuildModeDebug;
TargetSubsystem subsystem = TargetSubsystemAuto;
const char *override_lib_dir = nullptr;
- const char *main_pkg_path = nullptr;
const char *mcpu = nullptr;
for (int i = 1; i < argc; i += 1) {
@@ -103,11 +268,11 @@ int main(int argc, char **argv) {
if (strcmp(arg, "--") == 0) {
fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg);
} else if (strcmp(arg, "--release-fast") == 0) {
- build_mode = BuildModeFastRelease;
+ optimize_mode = BuildModeFastRelease;
} else if (strcmp(arg, "--release-safe") == 0) {
- build_mode = BuildModeSafeRelease;
+ optimize_mode = BuildModeSafeRelease;
} else if (strcmp(arg, "--release-small") == 0) {
- build_mode = BuildModeSmallRelease;
+ optimize_mode = BuildModeSmallRelease;
} else if (strcmp(arg, "--help") == 0) {
return print_full_usage(arg0, stdout, EXIT_SUCCESS);
} else if (strcmp(arg, "--strip") == 0) {
@@ -183,8 +348,6 @@ int main(int argc, char **argv) {
dynamic_linker = argv[i];
} else if (strcmp(arg, "--override-lib-dir") == 0) {
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) {
if (strcmp(argv[i], "c") == 0) {
link_libc = true;
@@ -264,12 +427,13 @@ int main(int argc, char **argv) {
return print_error_usage(arg0);
}
- ZigStage1 *stage1 = zig_stage1_create(build_mode,
- main_pkg_path, (main_pkg_path == nullptr) ? 0 : strlen(main_pkg_path),
+ ZigStage1 *stage1 = zig_stage1_create(optimize_mode,
+ nullptr, 0,
in_file, strlen(in_file),
- override_lib_dir, strlen(override_lib_dir), &target, false,
- root_progress_node);
+ override_lib_dir, strlen(override_lib_dir),
+ &target, false);
+ stage1->main_progress_node = root_progress_node;
stage1->root_name_ptr = out_name;
stage1->root_name_len = strlen(out_name);
stage1->strip = strip;
@@ -295,3 +459,66 @@ int main(int argc, char **argv) {
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;
+}
src-self-hosted/link/Elf.zig
@@ -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
// will not be part of the linker line anyway.
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 full_obj_path = if (directory.path) |dir_path|
- try std.fs.path.join(arena, &[_][]const u8{dir_path, obj_basename})
- else
- obj_basename;
+ const full_obj_path = try directory.join(arena, &[_][]const u8{obj_basename});
break :blk full_obj_path;
} else null;
@@ -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
// case we want to avoid prepending "-l".
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);
}
src-self-hosted/Compilation.zig
@@ -19,6 +19,7 @@ const libunwind = @import("libunwind.zig");
const fatal = @import("main.zig").fatal;
const Module = @import("Module.zig");
const Cache = @import("Cache.zig");
+const stage1 = @import("stage1.zig");
/// General-purpose allocator. Used for both temporary and long-term storage.
gpa: *Allocator,
@@ -26,6 +27,7 @@ gpa: *Allocator,
arena_state: std.heap.ArenaAllocator.State,
bin_file: *link.File,
c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
+stage1_module: ?*stage1.Module,
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: void,
+ /// Use stage1 C++ code to compile zig code into an object file.
+ stage1_module: void,
};
pub const CObject = struct {
@@ -274,6 +278,7 @@ pub const InitOptions = struct {
strip: bool = false,
single_threaded: bool = false,
is_native_os: bool,
+ time_report: bool = false,
link_eh_frame_hdr: bool = false,
linker_script: ?[]const u8 = null,
version_script: ?[]const u8 = null,
@@ -288,12 +293,20 @@ pub const InitOptions = struct {
clang_passthrough_mode: bool = false,
verbose_cc: 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,
stack_size_override: ?u64 = null,
self_exe_path: ?[]const u8 = null,
version: ?std.builtin.Version = null,
libc_installation: ?*const LibCInstallation = null,
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 {
@@ -332,11 +345,27 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
{
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;
};
// Make a decision on whether to use LLVM or our own backend.
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 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.
@@ -580,6 +609,118 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.ReleaseFast, .ReleaseSmall => false,
};
+ const llvm_cpu_features: ?[*:0]const u8 = if (build_options.have_llvm and use_llvm) blk: {
+ var buf = std.ArrayList(u8).init(arena);
+ for (options.target.cpu.arch.allFeaturesList()) |feature, index_usize| {
+ const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
+ const is_enabled = options.target.cpu.features.isEnabled(index);
+
+ if (feature.llvm_name) |llvm_name| {
+ const plus_or_minus = "-+"[@boolToInt(is_enabled)];
+ try buf.ensureCapacity(buf.items.len + 2 + llvm_name.len);
+ buf.appendAssumeCapacity(plus_or_minus);
+ buf.appendSliceAssumeCapacity(llvm_name);
+ buf.appendSliceAssumeCapacity(",");
+ }
+ }
+ assert(mem.endsWith(u8, buf.items, ","));
+ buf.items[buf.items.len - 1] = 0;
+ buf.shrink(buf.items.len);
+ break :blk buf.items[0 .. buf.items.len - 1 :0].ptr;
+ } else null;
+
+ const stage1_module: ?*stage1.Module = if (build_options.is_stage1 and use_llvm) blk: {
+ // Here we use the legacy stage1 C++ compiler to compile Zig code.
+ const stage2_target = try arena.create(stage1.Stage2Target);
+ 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, .{
.directory = bin_directory,
.sub_path = emit_bin.basename,
@@ -626,6 +767,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.machine_code_model = options.machine_code_model,
.dll_export_fns = dll_export_fns,
.error_return_tracing = error_return_tracing,
+ .llvm_cpu_features = llvm_cpu_features,
});
errdefer bin_file.destroy();
@@ -635,6 +777,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.zig_lib_directory = options.zig_lib_directory,
.zig_cache_directory = options.zig_cache_directory,
.bin_file = bin_file,
+ .stage1_module = stage1_module,
.work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
.keep_source_files_loaded = options.keep_source_files_loaded,
.use_clang = use_clang,
@@ -681,6 +824,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
try comp.work_queue.writeItem(.{ .libunwind = {} });
}
+ if (comp.stage1_module) |module| {
+ try comp.work_queue.writeItem(.{ .stage1_module = {} });
+ }
+
return comp;
}
@@ -689,6 +836,11 @@ pub fn destroy(self: *Compilation) void {
self.bin_file.destroy();
if (optional_module) |module| module.deinit();
+ if (self.stage1_module) |module| {
+ module.main_progress_node.?.end();
+ module.destroy();
+ }
+
const gpa = self.gpa;
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)});
};
},
+ .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");
}
},
- .so, .assembly, .ll, .bc, .unknown => {},
+ .shared_library, .assembly, .ll, .bc, .unknown, .static_library, .object, .zig, .zir => {},
}
if (out_dep_path) |p| {
try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p });
@@ -1445,17 +1601,39 @@ pub const FileExt = enum {
ll,
bc,
assembly,
- so,
+ shared_library,
+ object,
+ static_library,
+ zig,
+ zir,
unknown,
pub fn clangSupportsDepFile(ext: FileExt) bool {
return switch (ext) {
.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 {
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");
}
+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 {
if (hasCExt(filename)) {
return .c;
@@ -1484,26 +1688,19 @@ pub fn classifyFileExt(filename: []const u8) FileExt {
return .assembly;
} else if (mem.endsWith(u8, filename, ".h")) {
return .h;
- } else if (mem.endsWith(u8, filename, ".so")) {
- return .so;
- }
- // 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;
+ } else if (mem.endsWith(u8, filename, ".zig")) {
+ 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;
}
- 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" {
@@ -1681,7 +1878,7 @@ pub fn dump_argv(argv: []const []const u8) void {
}
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();
const target = comp.getTarget();
@@ -1691,9 +1888,9 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8
try buffer.writer().print(
\\usingnamespace @import("std").builtin;
\\/// Deprecated
- \\pub const arch = std.Target.current.cpu.arch;
+ \\pub const arch = Target.current.cpu.arch;
\\/// 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 link_mode = LinkMode.{};
\\pub const is_test = {};
src-self-hosted/link.zig
@@ -69,6 +69,7 @@ pub const Options = struct {
linker_script: ?[]const u8 = null,
version_script: ?[]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_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
/// and does not cause Illegal Behavior. This operation is not atomic.
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 sub_path = if (use_lld) blk: {
if (options.module == null) {
src-self-hosted/main.zig
@@ -222,21 +222,27 @@ const usage_build_generic =
\\ --libc [file] Provide a file which specifies libc paths
\\
\\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
- \\ -T[script] Use a custom linker script
- \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
- \\ --version [ver] Dynamic library semver
- \\ -rdynamic Add all symbols to the dynamic symbol table
- \\ -rpath [path] Add directory to the runtime library search path
- \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker
- \\ -dynamic Force output to be dynamically linked
- \\ -static Force output to be statically linked
+ \\ -T[script] Use a custom linker script
+ \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
+ \\ --version [ver] Dynamic library semver
+ \\ -rdynamic Add all symbols to the dynamic symbol table
+ \\ -rpath [path] Add directory to the runtime library search path
+ \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker
+ \\ -dynamic Force output to be dynamically linked
+ \\ -static Force output to be statically linked
\\
\\Debug Options (Zig Compiler Development):
- \\ -ftime-report Print timing diagnostics
- \\ --verbose-link Display linker invocations
- \\ --verbose-cc Display C compiler invocations
+ \\ -ftime-report Print timing diagnostics
+ \\ --verbose-link Display linker 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 verbose_link = 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 show_builtin = false;
var emit_bin: Emit = .yes_default_path;
@@ -548,6 +560,18 @@ pub fn buildOutputType(
verbose_link = true;
} else if (mem.eql(u8, arg, "--verbose-cc")) {
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")) {
linker_script = arg[2..];
} else if (mem.startsWith(u8, arg, "-L")) {
@@ -563,28 +587,27 @@ pub fn buildOutputType(
} else {
fatal("unrecognized parameter: '{}'", .{arg});
}
- } else if (mem.endsWith(u8, arg, ".o") or
- mem.endsWith(u8, arg, ".obj") or
- mem.endsWith(u8, arg, ".a") or
- mem.endsWith(u8, arg, ".lib"))
- {
- try link_objects.append(arg);
- } else if (Compilation.hasAsmExt(arg) or Compilation.hasCExt(arg) or Compilation.hasCppExt(arg)) {
- // TODO a way to pass extra flags on the CLI
- try c_source_files.append(.{ .src_path = arg });
- } else if (mem.endsWith(u8, arg, ".so") or
- mem.endsWith(u8, arg, ".dylib") or
- mem.endsWith(u8, arg, ".dll"))
- {
- fatal("linking against dynamic libraries not yet supported", .{});
- } else if (mem.endsWith(u8, arg, ".zig") or mem.endsWith(u8, arg, ".zir")) {
- if (root_src_file) |other| {
- fatal("found another zig file '{}' after root source file '{}'", .{ arg, other });
- } else {
- root_src_file = arg;
- }
- } else {
- fatal("unrecognized file extension of parameter '{}'", .{arg});
+ } else switch (Compilation.classifyFileExt(arg)) {
+ .object, .static_library => {
+ try link_objects.append(arg);
+ },
+ .assembly, .c, .cpp, .h, .ll, .bc => {
+ // TODO a way to pass extra flags on the CLI
+ try c_source_files.append(.{ .src_path = arg });
+ },
+ .shared_library => {
+ fatal("linking against dynamic libraries not yet supported", .{});
+ },
+ .zig, .zir => {
+ if (root_src_file) |other| {
+ 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 {
@@ -617,7 +640,16 @@ pub fn buildOutputType(
const file_ext = Compilation.classifyFileExt(mem.spanZ(it.only_arg));
switch (file_ext) {
.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 => {
@@ -1173,7 +1205,15 @@ pub fn buildOutputType(
.libc_installation = if (libc_installation) |*lci| lci else null,
.verbose_cc = verbose_cc,
.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,
+ .color = color,
+ .time_report = time_report,
}) catch |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", .{});
}
+ 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 stderr = std.io.getStdErr().outStream();
var repl_buf: [1024]u8 = undefined;
src-self-hosted/stage1.zig
@@ -10,6 +10,7 @@ const stage2 = @import("main.zig");
const fatal = stage2.fatal;
const CrossTarget = std.zig.CrossTarget;
const Target = std.Target;
+const Compilation = @import("Compilation.zig");
comptime {
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 {
std.debug.maybeEnableSegfaultHandler();
+ zig_stage1_os_init();
+
const gpa = std.heap.c_allocator;
var arena_instance = std.heap.ArenaAllocator.init(gpa);
defer arena_instance.deinit();
@@ -36,6 +39,106 @@ pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int {
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
export fn stage2_panic(ptr: [*]const u8, len: usize) void {
@panic(ptr[0..len]);
@@ -199,297 +302,50 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
}
// ABI warning
-const Stage2Target = extern struct {
+pub const Stage2Target = extern struct {
arch: c_int,
- vendor: c_int,
-
+ os: OS,
abi: c_int,
- os: c_int,
is_native_os: bool,
is_native_cpu: bool,
llvm_cpu_name: ?[*: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
const Stage2SemVer = extern struct {
major: u32,
minor: 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;
+}
BRANCH_TODO
@@ -1,3 +1,6 @@
+ * build & link against compiler-rt
+ * build & link against freestanding libc
+ * Cache integration for stage1 zig code compilation
* `zig test`
* `zig build`
* `-ftime-report`
@@ -14,10 +17,7 @@
- using it as a preprocessor (-E)
- try building some software
* support rpaths in ELF linker code
- * build & link against compiler-rt
- - stage1 C++ code integration
* repair @cImport
- * build & link against freestanding libc
* add CLI support for a way to pass extra flags to c source files
* capture lld stdout/stderr better
* musl
@@ -35,10 +35,12 @@
* implement emit-h in stage2
* implement -fno-emit-bin
* audit the base cache hash
+ * --main-pkg-path
* audit the CLI options for stage2
* `zig init-lib`
* `zig init-exe`
* `zig run`
+ * restore error messages for stage2_add_link_lib
* implement serialization/deserialization of incremental compilation metadata
* incremental compilation - implement detection of which source files changed
CMakeLists.txt
@@ -258,7 +258,6 @@ find_package(Threads)
# This is our shim which will be replaced by stage1.zig.
set(ZIG0_SOURCES
"${CMAKE_SOURCE_DIR}/src/zig0.cpp"
- "${CMAKE_SOURCE_DIR}/src/stage2.cpp"
)
set(ZIG_SOURCES