diff --git a/CMakeLists.txt b/CMakeLists.txt index 38bd9a2a7..1bc9d2f04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -407,6 +407,12 @@ set(SOFTFLOAT_LIBRARIES embedded_softfloat) find_package(Threads) +# CMake doesn't let us create an empty executable, so we hang on to this one separately. +set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp") + +# This is our shim which will be replaced by libuserland written in Zig. +set(ZIG1_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp") + set(ZIG_SOURCES "${CMAKE_SOURCE_DIR}/src/analyze.cpp" "${CMAKE_SOURCE_DIR}/src/ast_render.cpp" @@ -423,7 +429,6 @@ set(ZIG_SOURCES "${CMAKE_SOURCE_DIR}/src/ir_print.cpp" "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp" "${CMAKE_SOURCE_DIR}/src/link.cpp" - "${CMAKE_SOURCE_DIR}/src/main.cpp" "${CMAKE_SOURCE_DIR}/src/os.cpp" "${CMAKE_SOURCE_DIR}/src/parser.cpp" "${CMAKE_SOURCE_DIR}/src/range_set.cpp" @@ -6635,19 +6640,19 @@ add_library(zig_cpp STATIC ${ZIG_CPP_SOURCES}) set_target_properties(zig_cpp PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} ) +install(TARGETS zig_cpp DESTINATION "${ZIG_CPP_LIB_DIR}") add_library(opt_c_util STATIC ${OPTIMIZED_C_SOURCES}) set_target_properties(opt_c_util PROPERTIES COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}" ) -add_executable(zig ${ZIG_SOURCES}) -set_target_properties(zig PROPERTIES +add_library(compiler STATIC ${ZIG_SOURCES}) +set_target_properties(compiler PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} LINK_FLAGS ${EXE_LDFLAGS} ) - -target_link_libraries(zig LINK_PUBLIC +target_link_libraries(compiler LINK_PUBLIC zig_cpp opt_c_util ${SOFTFLOAT_LIBRARIES} @@ -6656,24 +6661,58 @@ target_link_libraries(zig LINK_PUBLIC ${LLVM_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) - if(NOT MSVC) - target_link_libraries(zig LINK_PUBLIC ${LIBXML2}) + target_link_libraries(compiler LINK_PUBLIC ${LIBXML2}) endif() if(MINGW) - target_link_libraries(zig LINK_PUBLIC ${Z3_LIBRARIES}) + target_link_libraries(compiler LINK_PUBLIC ${Z3_LIBRARIES}) endif() if(ZIG_DIA_GUIDS_LIB) - target_link_libraries(zig LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB}) + target_link_libraries(compiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB}) endif() if(MSVC OR MINGW) - target_link_libraries(zig LINK_PUBLIC version) + target_link_libraries(compiler LINK_PUBLIC version) endif() + +add_executable(zig1 "${ZIG_MAIN_SRC}" "${ZIG1_SHIM_SRC}") +set_target_properties(zig1 PROPERTIES + COMPILE_FLAGS ${EXE_CFLAGS} + LINK_FLAGS ${EXE_LDFLAGS} +) +target_link_libraries(zig1 compiler) + +if(WIN32) + set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.lib") +elseif(APPLE) + set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.o") +else() + set(LIBUSERLAND "${CMAKE_BINARY_DIR}/libuserland.a") +endif() +add_custom_command( + OUTPUT "${LIBUSERLAND}" + COMMAND zig1 ARGS build + --override-std-dir std + --override-lib-dir "${CMAKE_SOURCE_DIR}" + libuserland + "-Doutput-dir=${CMAKE_BINARY_DIR}" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + DEPENDS + "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig" + "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig" +) +add_custom_target(userland_target DEPENDS "${LIBUSERLAND}") +add_executable(zig "${ZIG_MAIN_SRC}") +set_target_properties(zig PROPERTIES + COMPILE_FLAGS ${EXE_CFLAGS} + LINK_FLAGS ${EXE_LDFLAGS} +) +target_link_libraries(zig compiler "${LIBUSERLAND}") +add_dependencies(zig userland_target) install(TARGETS zig DESTINATION bin) -install(TARGETS zig_cpp DESTINATION "${ZIG_CPP_LIB_DIR}") + foreach(file ${ZIG_C_HEADER_FILES}) get_filename_component(file_dir "${C_HEADERS_DEST}/${file}" DIRECTORY) diff --git a/build.zig b/build.zig index 2dc9c671e..a53743ca3 100644 --- a/build.zig +++ b/build.zig @@ -65,6 +65,8 @@ pub fn build(b: *Builder) !void { b.default_step.dependOn(&exe.step); + addLibUserlandStep(b); + const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false; const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release; const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release; @@ -380,3 +382,20 @@ const Context = struct { dia_guids_lib: []const u8, llvm: LibraryDep, }; + +fn addLibUserlandStep(b: *Builder) void { + const artifact = if (builtin.os == .macosx) + b.addObject("userland", "src-self-hosted/stage1.zig") + else + b.addStaticLibrary("userland", "src-self-hosted/stage1.zig"); + artifact.disable_gen_h = true; + const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1"); + libuserland_step.dependOn(&artifact.step); + + const output_dir = b.option( + []const u8, + "output-dir", + "For libuserland step, where to put the output", + ) orelse return; + artifact.setOutputDir(output_dir); +} diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 4c3edf6d5..361afc80e 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -858,23 +858,7 @@ fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void { try stdout.write(usage); } -const info_zen = - \\ - \\ * Communicate intent precisely. - \\ * Edge cases matter. - \\ * Favor reading code over writing code. - \\ * Only one obvious way to do things. - \\ * Runtime crashes are better than bugs. - \\ * Compile errors are better than runtime crashes. - \\ * Incremental improvements. - \\ * Avoid local maximums. - \\ * Reduce the amount one must remember. - \\ * Minimize energy spent on coding style. - \\ * Together we serve end users. - \\ - \\ -; - +const info_zen = @import("stage1.zig").info_zen; fn cmdZen(allocator: *Allocator, args: []const []const u8) !void { try stdout.write(info_zen); } diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig new file mode 100644 index 000000000..bf400113e --- /dev/null +++ b/src-self-hosted/stage1.zig @@ -0,0 +1,27 @@ +// This is Zig code that is used by both stage1 and stage2. +// The prototypes in src/userland.h must match these definitions. +comptime { + _ = @import("translate_c.zig"); +} + +pub const info_zen = + \\ + \\ * Communicate intent precisely. + \\ * Edge cases matter. + \\ * Favor reading code over writing code. + \\ * Only one obvious way to do things. + \\ * Runtime crashes are better than bugs. + \\ * Compile errors are better than runtime crashes. + \\ * Incremental improvements. + \\ * Avoid local maximums. + \\ * Reduce the amount one must remember. + \\ * Minimize energy spent on coding style. + \\ * Together we serve end users. + \\ + \\ +; + +export fn stage2_zen(ptr: *[*]const u8, len: *usize) void { + ptr.* = &info_zen; + len.* = info_zen.len; +} diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig new file mode 100644 index 000000000..e182a5a99 --- /dev/null +++ b/src-self-hosted/translate_c.zig @@ -0,0 +1,8 @@ +// This is the userland implementation of translate-c which will be used by both stage1 +// and stage2. Currently it's not used by anything, as it's not feature complete. + +const std = @import("std"); + +export fn stage2_translate_c() void { + std.debug.panic("unimplemented"); +} diff --git a/src/codegen.cpp b/src/codegen.cpp index 8eea4e87f..33049abd6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -19,6 +19,7 @@ #include "target.hpp" #include "util.hpp" #include "zig_llvm.h" +#include "userland.h" #include #include @@ -92,7 +93,7 @@ static const char *symbols_that_llvm_depends_on[] = { }; CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, - OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, Buf *override_std_dir, + OutType out_type, BuildMode build_mode, Buf *override_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc, Buf *cache_dir) { CodeGen *g = allocate(1); @@ -100,19 +101,24 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget codegen_add_time_event(g, "Initialize"); g->libc = libc; - g->zig_lib_dir = zig_lib_dir; g->zig_target = target; g->cache_dir = cache_dir; + if (override_lib_dir == nullptr) { + g->zig_lib_dir = get_zig_lib_dir(); + } else { + g->zig_lib_dir = override_lib_dir; + } + if (override_std_dir == nullptr) { g->zig_std_dir = buf_alloc(); - os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir); + os_path_join(g->zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir); } else { g->zig_std_dir = override_std_dir; } g->zig_c_headers_dir = buf_alloc(); - os_path_join(zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir); + os_path_join(g->zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir); g->build_mode = build_mode; g->out_type = out_type; @@ -8147,7 +8153,7 @@ static void detect_libc(CodeGen *g) { } } -AstNode *codegen_translate_c(CodeGen *g, Buf *full_path) { +AstNode *codegen_translate_c(CodeGen *g, Buf *full_path, bool use_userland_implementation) { Buf *src_basename = buf_alloc(); Buf *src_dirname = buf_alloc(); os_path_split(full_path, src_dirname, src_basename); @@ -8159,6 +8165,12 @@ AstNode *codegen_translate_c(CodeGen *g, Buf *full_path) { init(g); + if (use_userland_implementation) { + // TODO improve this + stage2_translate_c(); + zig_panic("TODO"); + } + ZigList errors = {0}; AstNode *root_node; Error err = parse_h_file(&root_node, &errors, buf_ptr(full_path), g, nullptr); diff --git a/src/codegen.hpp b/src/codegen.hpp index 3befca2de..d6149bf5d 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -50,7 +50,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c void codegen_add_assembly(CodeGen *g, Buf *path); void codegen_add_object(CodeGen *g, Buf *object_path); -AstNode *codegen_translate_c(CodeGen *g, Buf *path); +AstNode *codegen_translate_c(CodeGen *g, Buf *path, bool use_userland_implementation); Buf *codegen_generate_builtin_source(CodeGen *g); diff --git a/src/compiler.cpp b/src/compiler.cpp index af62173db..8bfe87bfc 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -179,24 +179,24 @@ Buf *get_zig_lib_dir(void) { return &saved_lib_dir; } -Buf *get_zig_std_dir() { +Buf *get_zig_std_dir(Buf *zig_lib_dir) { if (saved_std_dir.list.length != 0) { return &saved_std_dir; } buf_resize(&saved_std_dir, 0); - os_path_join(get_zig_lib_dir(), buf_create_from_str("std"), &saved_std_dir); + os_path_join(zig_lib_dir, buf_create_from_str("std"), &saved_std_dir); return &saved_std_dir; } -Buf *get_zig_special_dir() { +Buf *get_zig_special_dir(Buf *zig_lib_dir) { if (saved_special_dir.list.length != 0) { return &saved_special_dir; } buf_resize(&saved_special_dir, 0); - os_path_join(get_zig_std_dir(), buf_sprintf("special"), &saved_special_dir); + os_path_join(get_zig_std_dir(zig_lib_dir), buf_sprintf("special"), &saved_special_dir); return &saved_special_dir; } diff --git a/src/compiler.hpp b/src/compiler.hpp index f2788b999..4d682ba2f 100644 --- a/src/compiler.hpp +++ b/src/compiler.hpp @@ -16,7 +16,7 @@ Error get_compiler_id(Buf **result); Buf *get_self_dynamic_linker_path(void); Buf *get_zig_lib_dir(void); -Buf *get_zig_special_dir(void); -Buf *get_zig_std_dir(void); +Buf *get_zig_special_dir(Buf *zig_lib_dir); +Buf *get_zig_std_dir(Buf *zig_lib_dir); #endif diff --git a/src/main.cpp b/src/main.cpp index 5123512d1..03cf3aad6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ #include "os.hpp" #include "target.hpp" #include "libc_installation.hpp" +#include "userland.h" #include @@ -40,6 +41,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " libc [paths_file] Display native libc paths file or validate one\n" " run [source] [-- [args]] create executable and run immediately\n" " translate-c [source] convert c code to zig code\n" + " translate-c-2 [source] experimental self-hosted translate-c\n" " targets list available compilation targets\n" " test [source] create and run a test build\n" " version print version number and exit\n" @@ -131,19 +133,6 @@ static int print_libc_usage(const char *arg0, FILE *file, int return_code) { return return_code; } -static const char *ZIG_ZEN = "\n" -" * Communicate intent precisely.\n" -" * Edge cases matter.\n" -" * Favor reading code over writing code.\n" -" * Only one obvious way to do things.\n" -" * Runtime crashes are better than bugs.\n" -" * Compile errors are better than runtime crashes.\n" -" * Incremental improvements.\n" -" * Avoid local maximums.\n" -" * Reduce the amount one must remember.\n" -" * Minimize energy spent on coding style.\n" -" * Together we serve end users.\n"; - static bool arch_available_in_llvm(ZigLLVM_ArchType arch) { LLVMTargetRef target_ref; char *err_msg = nullptr; @@ -211,6 +200,7 @@ enum Cmd { CmdTargets, CmdTest, CmdTranslateC, + CmdTranslateCUserland, CmdVersion, CmdZen, CmdLibC, @@ -324,7 +314,7 @@ int main(int argc, char **argv) { return print_error_usage(arg0); } Buf *cmd_template_path = buf_alloc(); - os_path_join(get_zig_special_dir(), buf_create_from_str(init_cmd), cmd_template_path); + os_path_join(get_zig_special_dir(get_zig_lib_dir()), buf_create_from_str(init_cmd), cmd_template_path); Buf *build_zig_path = buf_alloc(); os_path_join(cmd_template_path, buf_create_from_str("build.zig"), build_zig_path); Buf *src_dir_path = buf_alloc(); @@ -453,6 +443,7 @@ int main(int argc, char **argv) { bool want_single_threaded = false; bool disable_gen_h = false; Buf *override_std_dir = nullptr; + Buf *override_lib_dir = nullptr; Buf *main_pkg_path = nullptr; ValgrindSupport valgrind_support = ValgrindSupportAuto; WantPIC want_pic = WantPICAuto; @@ -486,13 +477,27 @@ int main(int argc, char **argv) { } else if (i + 1 < argc && strcmp(argv[i], "--cache-dir") == 0) { cache_dir = argv[i + 1]; i += 1; + } else if (i + 1 < argc && strcmp(argv[i], "--override-std-dir") == 0) { + override_std_dir = buf_create_from_str(argv[i + 1]); + i += 1; + + args.append("--override-std-dir"); + args.append(buf_ptr(override_std_dir)); + } else if (i + 1 < argc && strcmp(argv[i], "--override-lib-dir") == 0) { + override_lib_dir = buf_create_from_str(argv[i + 1]); + i += 1; + + args.append("--override-lib-dir"); + args.append(buf_ptr(override_lib_dir)); } else { args.append(argv[i]); } } + Buf *zig_lib_dir = (override_lib_dir == nullptr) ? get_zig_lib_dir() : override_lib_dir; + Buf *build_runner_path = buf_alloc(); - os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path); + os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); ZigTarget target; get_native_target(&target); @@ -512,7 +517,7 @@ int main(int argc, char **argv) { } CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe, - BuildModeDebug, get_zig_lib_dir(), override_std_dir, nullptr, &full_cache_dir); + BuildModeDebug, override_lib_dir, override_std_dir, nullptr, &full_cache_dir); g->valgrind_support = valgrind_support; g->enable_time_report = timing_info; codegen_set_out_name(g, buf_create_from_str("build")); @@ -532,23 +537,25 @@ int main(int argc, char **argv) { "Usage: %s build [options]\n" "\n" "General Options:\n" - " --help Print this help and exit\n" - " --verbose Print commands before executing them\n" - " --prefix [path] Override default install prefix\n" - " --search-prefix [path] Add a path to look for binaries, libraries, headers\n" + " --help Print this help and exit\n" + " --verbose Print commands before executing them\n" + " --prefix [path] Override default install prefix\n" + " --search-prefix [path] Add a path to look for binaries, libraries, headers\n" "\n" "Project-specific options become available when the build file is found.\n" "\n" "Advanced Options:\n" - " --build-file [file] Override path to build.zig\n" - " --cache-dir [path] Override path to cache directory\n" - " --verbose-tokenize Enable compiler debug output for tokenization\n" - " --verbose-ast Enable compiler debug output for parsing into an AST\n" - " --verbose-link Enable compiler debug output for linking\n" - " --verbose-ir Enable compiler debug output for Zig IR\n" - " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n" - " --verbose-cimport Enable compiler debug output for C imports\n" - " --verbose-cc Enable compiler debug output for C compilation\n" + " --build-file [file] Override path to build.zig\n" + " --cache-dir [path] Override path to cache directory\n" + " --override-std-dir [arg] Override path to Zig standard library\n" + " --override-lib-dir [arg] Override path to Zig lib library\n" + " --verbose-tokenize Enable compiler debug output for tokenization\n" + " --verbose-ast Enable compiler debug output for parsing into an AST\n" + " --verbose-link Enable compiler debug output for linking\n" + " --verbose-ir Enable compiler debug output for Zig IR\n" + " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n" + " --verbose-cimport Enable compiler debug output for C imports\n" + " --verbose-cc Enable compiler debug output for C compilation\n" "\n" , zig_exe_path); return EXIT_SUCCESS; @@ -584,11 +591,12 @@ int main(int argc, char **argv) { init_all_targets(); ZigTarget target; get_native_target(&target); + Buf *zig_lib_dir = (override_lib_dir == nullptr) ? get_zig_lib_dir() : override_lib_dir; Buf *fmt_runner_path = buf_alloc(); - os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path); + os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("fmt_runner.zig"), fmt_runner_path); Buf *cache_dir_buf = buf_create_from_str(cache_dir ? cache_dir : default_zig_cache_name); CodeGen *g = codegen_create(main_pkg_path, fmt_runner_path, &target, OutTypeExe, - BuildModeDebug, get_zig_lib_dir(), nullptr, nullptr, cache_dir_buf); + BuildModeDebug, zig_lib_dir, nullptr, nullptr, cache_dir_buf); g->valgrind_support = valgrind_support; g->want_single_threaded = true; codegen_set_out_name(g, buf_create_from_str("fmt")); @@ -757,6 +765,8 @@ int main(int argc, char **argv) { llvm_argv.append(argv[i]); } else if (strcmp(arg, "--override-std-dir") == 0) { override_std_dir = buf_create_from_str(argv[i]); + } else if (strcmp(arg, "--override-lib-dir") == 0) { + override_lib_dir = buf_create_from_str(argv[i]); } else if (strcmp(arg, "--main-pkg-path") == 0) { main_pkg_path = buf_create_from_str(argv[i]); } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) { @@ -867,6 +877,8 @@ int main(int argc, char **argv) { cmd = CmdLibC; } else if (strcmp(arg, "translate-c") == 0) { cmd = CmdTranslateC; + } else if (strcmp(arg, "translate-c-2") == 0) { + cmd = CmdTranslateCUserland; } else if (strcmp(arg, "test") == 0) { cmd = CmdTest; out_type = OutTypeExe; @@ -883,6 +895,7 @@ int main(int argc, char **argv) { case CmdBuild: case CmdRun: case CmdTranslateC: + case CmdTranslateCUserland: case CmdTest: case CmdLibC: if (!in_file) { @@ -959,7 +972,7 @@ int main(int argc, char **argv) { } case CmdBuiltin: { CodeGen *g = codegen_create(main_pkg_path, nullptr, &target, - out_type, build_mode, get_zig_lib_dir(), override_std_dir, nullptr, nullptr); + out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr); g->valgrind_support = valgrind_support; g->want_pic = want_pic; g->want_single_threaded = want_single_threaded; @@ -973,6 +986,7 @@ int main(int argc, char **argv) { case CmdRun: case CmdBuild: case CmdTranslateC: + case CmdTranslateCUserland: case CmdTest: { if (cmd == CmdBuild && !in_file && objects.length == 0 && asm_files.length == 0 && @@ -985,14 +999,16 @@ int main(int argc, char **argv) { " * --assembly argument\n" " * --c-source argument\n"); return print_error_usage(arg0); - } else if ((cmd == CmdTranslateC || cmd == CmdTest || cmd == CmdRun) && !in_file) { + } else if ((cmd == CmdTranslateC || cmd == CmdTranslateCUserland || + cmd == CmdTest || cmd == CmdRun) && !in_file) + { fprintf(stderr, "Expected source file argument.\n"); return print_error_usage(arg0); } assert(cmd != CmdBuild || out_type != OutTypeUnknown); - bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC); + bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC || cmd == CmdTranslateCUserland); if (cmd == CmdRun) { out_name = "run"; @@ -1026,7 +1042,8 @@ int main(int argc, char **argv) { return print_error_usage(arg0); } - Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf; + Buf *zig_root_source_file = (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) ? + nullptr : in_file_buf; if (cmd == CmdRun && buf_out_name == nullptr) { buf_out_name = buf_create_from_str("run"); @@ -1050,7 +1067,7 @@ int main(int argc, char **argv) { cache_dir_buf = buf_create_from_str(cache_dir); } CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode, - get_zig_lib_dir(), override_std_dir, libc, cache_dir_buf); + override_lib_dir, override_std_dir, libc, cache_dir_buf); if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2); g->valgrind_support = valgrind_support; g->want_pic = want_pic; @@ -1170,8 +1187,8 @@ int main(int argc, char **argv) { } else { zig_unreachable(); } - } else if (cmd == CmdTranslateC) { - AstNode *root_node = codegen_translate_c(g, in_file_buf); + } else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) { + AstNode *root_node = codegen_translate_c(g, in_file_buf, cmd == CmdTranslateCUserland); ast_render(g, stdout, root_node, 4); if (timing_info) codegen_print_timing_report(g, stderr); @@ -1229,9 +1246,13 @@ int main(int argc, char **argv) { case CmdVersion: printf("%s\n", ZIG_VERSION_STRING); return EXIT_SUCCESS; - case CmdZen: - printf("%s\n", ZIG_ZEN); + case CmdZen: { + const char *ptr; + size_t len; + stage2_zen(&ptr, &len); + fwrite(ptr, len, 1, stdout); return EXIT_SUCCESS; + } case CmdTargets: return print_target_list(stdout); case CmdNone: diff --git a/src/userland.cpp b/src/userland.cpp new file mode 100644 index 000000000..25b149229 --- /dev/null +++ b/src/userland.cpp @@ -0,0 +1,10 @@ +// This file is a shim for zig1. The real implementations of these are in +// src-self-hosted/stage1.zig + +#include "userland.h" + +void stage2_translate_c(void) {} +void stage2_zen(const char **ptr, size_t *len) { + *ptr = nullptr; + *len = 0; +} diff --git a/src/userland.h b/src/userland.h new file mode 100644 index 000000000..92557ef99 --- /dev/null +++ b/src/userland.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef ZIG_USERLAND_H +#define ZIG_USERLAND_H + +#include + +#ifdef __cplusplus +#define ZIG_USERLAND_EXTERN_C extern "C" +#else +#define ZIG_USERLAND_EXTERN_C +#endif + +ZIG_USERLAND_EXTERN_C void stage2_translate_c(void); + +ZIG_USERLAND_EXTERN_C void stage2_zen(const char **ptr, size_t *len); + +#endif diff --git a/std/build.zig b/std/build.zig index 2bd4a9b08..4d6c91543 100644 --- a/std/build.zig +++ b/std/build.zig @@ -50,6 +50,8 @@ pub const Builder = struct { build_root: []const u8, cache_root: []const u8, release_mode: ?builtin.Mode, + override_std_dir: ?[]const u8, + override_lib_dir: ?[]const u8, pub const CStd = enum { C89, @@ -133,6 +135,8 @@ pub const Builder = struct { }, .have_install_step = false, .release_mode = null, + .override_std_dir = null, + .override_lib_dir = null, }; self.detectNativeSystemPaths(); self.default_step = self.step("default", "Build the project"); @@ -939,6 +943,7 @@ pub const LibExeObjStep = struct { disable_gen_h: bool, c_std: Builder.CStd, override_std_dir: ?[]const u8, + override_lib_dir: ?[]const u8, main_pkg_path: ?[]const u8, exec_cmd_args: ?[]const ?[]const u8, name_prefix: []const u8, @@ -1039,6 +1044,7 @@ pub const LibExeObjStep = struct { .c_std = Builder.CStd.C99, .system_linker_hack = false, .override_std_dir = null, + .override_lib_dir = null, .main_pkg_path = null, .exec_cmd_args = null, .name_prefix = "", @@ -1528,6 +1534,17 @@ pub const LibExeObjStep = struct { if (self.override_std_dir) |dir| { try zig_args.append("--override-std-dir"); try zig_args.append(builder.pathFromRoot(dir)); + } else if (self.builder.override_std_dir) |dir| { + try zig_args.append("--override-std-dir"); + try zig_args.append(builder.pathFromRoot(dir)); + } + + if (self.override_lib_dir) |dir| { + try zig_args.append("--override-lib-dir"); + try zig_args.append(builder.pathFromRoot(dir)); + } else if (self.builder.override_lib_dir) |dir| { + try zig_args.append("--override-lib-dir"); + try zig_args.append(builder.pathFromRoot(dir)); } if (self.main_pkg_path) |dir| { diff --git a/std/special/build_runner.zig b/std/special/build_runner.zig index 56cfe3bcb..dfc383857 100644 --- a/std/special/build_runner.zig +++ b/std/special/build_runner.zig @@ -94,6 +94,16 @@ pub fn main() !void { return usageAndErr(&builder, false, try stderr_stream); }); builder.addSearchPrefix(search_prefix); + } else if (mem.eql(u8, arg, "--override-std-dir")) { + builder.override_std_dir = try unwrapArg(arg_it.next(allocator) orelse { + warn("Expected argument after --override-std-dir\n\n"); + return usageAndErr(&builder, false, try stderr_stream); + }); + } else if (mem.eql(u8, arg, "--override-lib-dir")) { + builder.override_lib_dir = try unwrapArg(arg_it.next(allocator) orelse { + warn("Expected argument after --override-lib-dir\n\n"); + return usageAndErr(&builder, false, try stderr_stream); + }); } else if (mem.eql(u8, arg, "--verbose-tokenize")) { builder.verbose_tokenize = true; } else if (mem.eql(u8, arg, "--verbose-ast")) { @@ -187,15 +197,17 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void { try out_stream.write( \\ \\Advanced Options: - \\ --build-file [file] Override path to build.zig - \\ --cache-dir [path] Override path to zig cache directory - \\ --verbose-tokenize Enable compiler debug output for tokenization - \\ --verbose-ast Enable compiler debug output for parsing into an AST - \\ --verbose-link Enable compiler debug output for linking - \\ --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-cc Enable compiler debug output for C compilation + \\ --build-file [file] Override path to build.zig + \\ --cache-dir [path] Override path to zig cache directory + \\ --override-std-dir [arg] Override path to Zig standard library + \\ --override-lib-dir [arg] Override path to Zig lib directory + \\ --verbose-tokenize Enable compiler debug output for tokenization + \\ --verbose-ast Enable compiler debug output for parsing into an AST + \\ --verbose-link Enable compiler debug output for linking + \\ --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-cc Enable compiler debug output for C compilation \\ ); }