authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-16 16:47:47-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-16 19:12:20-04:00
log89763c9a0d9a838439bcc6cd996c0ff2d3d0daca
treec29a0a77f248a33d02c7146488d130eae9d81bd6
parent4c03746926562e4e9650eec7c4361836fabba5af
signature Commit is signed but in an unrecognized format.

stage1 is now a hybrid of C++ and Zig

This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964

14 files changed, 261 insertions(+), 89 deletions(-)

CMakeLists.txt+50-11
......@@ -407,6 +407,12 @@ set(SOFTFLOAT_LIBRARIES embedded_softfloat)
407407
408408find_package(Threads)
409409
410# CMake doesn't let us create an empty executable, so we hang on to this one separately.
411set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp")
412
413# This is our shim which will be replaced by libuserland written in Zig.
414set(ZIG1_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp")
415
410416set(ZIG_SOURCES
411417 "${CMAKE_SOURCE_DIR}/src/analyze.cpp"
412418 "${CMAKE_SOURCE_DIR}/src/ast_render.cpp"
......@@ -423,7 +429,6 @@ set(ZIG_SOURCES
423429 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"
424430 "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"
425431 "${CMAKE_SOURCE_DIR}/src/link.cpp"
426 "${CMAKE_SOURCE_DIR}/src/main.cpp"
427432 "${CMAKE_SOURCE_DIR}/src/os.cpp"
428433 "${CMAKE_SOURCE_DIR}/src/parser.cpp"
429434 "${CMAKE_SOURCE_DIR}/src/range_set.cpp"
......@@ -6635,19 +6640,19 @@ add_library(zig_cpp STATIC ${ZIG_CPP_SOURCES})
66356640set_target_properties(zig_cpp PROPERTIES
66366641 COMPILE_FLAGS ${EXE_CFLAGS}
66376642)
6643install(TARGETS zig_cpp DESTINATION "${ZIG_CPP_LIB_DIR}")
66386644
66396645add_library(opt_c_util STATIC ${OPTIMIZED_C_SOURCES})
66406646set_target_properties(opt_c_util PROPERTIES
66416647 COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
66426648)
66436649
6644add_executable(zig ${ZIG_SOURCES})
6645set_target_properties(zig PROPERTIES
6650add_library(compiler STATIC ${ZIG_SOURCES})
6651set_target_properties(compiler PROPERTIES
66466652 COMPILE_FLAGS ${EXE_CFLAGS}
66476653 LINK_FLAGS ${EXE_LDFLAGS}
66486654)
6649
6650target_link_libraries(zig LINK_PUBLIC
6655target_link_libraries(compiler LINK_PUBLIC
66516656 zig_cpp
66526657 opt_c_util
66536658 ${SOFTFLOAT_LIBRARIES}
......@@ -6656,24 +6661,58 @@ target_link_libraries(zig LINK_PUBLIC
66566661 ${LLVM_LIBRARIES}
66576662 ${CMAKE_THREAD_LIBS_INIT}
66586663)
6659
66606664if(NOT MSVC)
6661 target_link_libraries(zig LINK_PUBLIC ${LIBXML2})
6665 target_link_libraries(compiler LINK_PUBLIC ${LIBXML2})
66626666endif()
66636667
66646668if(MINGW)
6665 target_link_libraries(zig LINK_PUBLIC ${Z3_LIBRARIES})
6669 target_link_libraries(compiler LINK_PUBLIC ${Z3_LIBRARIES})
66666670endif()
66676671
66686672if(ZIG_DIA_GUIDS_LIB)
6669 target_link_libraries(zig LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
6673 target_link_libraries(compiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
66706674endif()
66716675
66726676if(MSVC OR MINGW)
6673 target_link_libraries(zig LINK_PUBLIC version)
6677 target_link_libraries(compiler LINK_PUBLIC version)
6678endif()
6679
6680add_executable(zig1 "${ZIG_MAIN_SRC}" "${ZIG1_SHIM_SRC}")
6681set_target_properties(zig1 PROPERTIES
6682 COMPILE_FLAGS ${EXE_CFLAGS}
6683 LINK_FLAGS ${EXE_LDFLAGS}
6684)
6685target_link_libraries(zig1 compiler)
6686
6687if(WIN32)
6688 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.lib")
6689elseif(APPLE)
6690 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.o")
6691else()
6692 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/libuserland.a")
66746693endif()
6694add_custom_command(
6695 OUTPUT "${LIBUSERLAND}"
6696 COMMAND zig1 ARGS build
6697 --override-std-dir std
6698 --override-lib-dir "${CMAKE_SOURCE_DIR}"
6699 libuserland
6700 "-Doutput-dir=${CMAKE_BINARY_DIR}"
6701 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
6702 DEPENDS
6703 "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"
6704 "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"
6705)
6706add_custom_target(userland_target DEPENDS "${LIBUSERLAND}")
6707add_executable(zig "${ZIG_MAIN_SRC}")
6708set_target_properties(zig PROPERTIES
6709 COMPILE_FLAGS ${EXE_CFLAGS}
6710 LINK_FLAGS ${EXE_LDFLAGS}
6711)
6712target_link_libraries(zig compiler "${LIBUSERLAND}")
6713add_dependencies(zig userland_target)
66756714install(TARGETS zig DESTINATION bin)
6676install(TARGETS zig_cpp DESTINATION "${ZIG_CPP_LIB_DIR}")
6715
66776716
66786717foreach(file ${ZIG_C_HEADER_FILES})
66796718 get_filename_component(file_dir "${C_HEADERS_DEST}/${file}" DIRECTORY)
build.zig+19
......@@ -65,6 +65,8 @@ pub fn build(b: *Builder) !void {
6565
6666 b.default_step.dependOn(&exe.step);
6767
68 addLibUserlandStep(b);
69
6870 const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;
6971 const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release;
7072 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 {
380382 dia_guids_lib: []const u8,
381383 llvm: LibraryDep,
382384};
385
386fn addLibUserlandStep(b: *Builder) void {
387 const artifact = if (builtin.os == .macosx)
388 b.addObject("userland", "src-self-hosted/stage1.zig")
389 else
390 b.addStaticLibrary("userland", "src-self-hosted/stage1.zig");
391 artifact.disable_gen_h = true;
392 const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1");
393 libuserland_step.dependOn(&artifact.step);
394
395 const output_dir = b.option(
396 []const u8,
397 "output-dir",
398 "For libuserland step, where to put the output",
399 ) orelse return;
400 artifact.setOutputDir(output_dir);
401}
src-self-hosted/main.zig+1-17
......@@ -858,23 +858,7 @@ fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void {
858858 try stdout.write(usage);
859859}
860860
861const info_zen =
862 \\
863 \\ * Communicate intent precisely.
864 \\ * Edge cases matter.
865 \\ * Favor reading code over writing code.
866 \\ * Only one obvious way to do things.
867 \\ * Runtime crashes are better than bugs.
868 \\ * Compile errors are better than runtime crashes.
869 \\ * Incremental improvements.
870 \\ * Avoid local maximums.
871 \\ * Reduce the amount one must remember.
872 \\ * Minimize energy spent on coding style.
873 \\ * Together we serve end users.
874 \\
875 \\
876;
877
861const info_zen = @import("stage1.zig").info_zen;
878862fn cmdZen(allocator: *Allocator, args: []const []const u8) !void {
879863 try stdout.write(info_zen);
880864}
src-self-hosted/stage1.zig created+27
......@@ -0,0 +1,27 @@
1// This is Zig code that is used by both stage1 and stage2.
2// The prototypes in src/userland.h must match these definitions.
3comptime {
4 _ = @import("translate_c.zig");
5}
6
7pub const info_zen =
8 \\
9 \\ * Communicate intent precisely.
10 \\ * Edge cases matter.
11 \\ * Favor reading code over writing code.
12 \\ * Only one obvious way to do things.
13 \\ * Runtime crashes are better than bugs.
14 \\ * Compile errors are better than runtime crashes.
15 \\ * Incremental improvements.
16 \\ * Avoid local maximums.
17 \\ * Reduce the amount one must remember.
18 \\ * Minimize energy spent on coding style.
19 \\ * Together we serve end users.
20 \\
21 \\
22;
23
24export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
25 ptr.* = &info_zen;
26 len.* = info_zen.len;
27}
src-self-hosted/translate_c.zig created+8
......@@ -0,0 +1,8 @@
1// This is the userland implementation of translate-c which will be used by both stage1
2// and stage2. Currently it's not used by anything, as it's not feature complete.
3
4const std = @import("std");
5
6export fn stage2_translate_c() void {
7 std.debug.panic("unimplemented");
8}
src/codegen.cpp+17-5
......@@ -19,6 +19,7 @@
1919#include "target.hpp"
2020#include "util.hpp"
2121#include "zig_llvm.h"
22#include "userland.h"
2223
2324#include <stdio.h>
2425#include <errno.h>
......@@ -92,7 +93,7 @@ static const char *symbols_that_llvm_depends_on[] = {
9293};
9394
9495CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
95 OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, Buf *override_std_dir,
96 OutType out_type, BuildMode build_mode, Buf *override_lib_dir, Buf *override_std_dir,
9697 ZigLibCInstallation *libc, Buf *cache_dir)
9798{
9899 CodeGen *g = allocate<CodeGen>(1);
......@@ -100,19 +101,24 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
100101 codegen_add_time_event(g, "Initialize");
101102
102103 g->libc = libc;
103 g->zig_lib_dir = zig_lib_dir;
104104 g->zig_target = target;
105105 g->cache_dir = cache_dir;
106106
107 if (override_lib_dir == nullptr) {
108 g->zig_lib_dir = get_zig_lib_dir();
109 } else {
110 g->zig_lib_dir = override_lib_dir;
111 }
112
107113 if (override_std_dir == nullptr) {
108114 g->zig_std_dir = buf_alloc();
109 os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
115 os_path_join(g->zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
110116 } else {
111117 g->zig_std_dir = override_std_dir;
112118 }
113119
114120 g->zig_c_headers_dir = buf_alloc();
115 os_path_join(zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
121 os_path_join(g->zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
116122
117123 g->build_mode = build_mode;
118124 g->out_type = out_type;
......@@ -8147,7 +8153,7 @@ static void detect_libc(CodeGen *g) {
81478153 }
81488154}
81498155
8150AstNode *codegen_translate_c(CodeGen *g, Buf *full_path) {
8156AstNode *codegen_translate_c(CodeGen *g, Buf *full_path, bool use_userland_implementation) {
81518157 Buf *src_basename = buf_alloc();
81528158 Buf *src_dirname = buf_alloc();
81538159 os_path_split(full_path, src_dirname, src_basename);
......@@ -8159,6 +8165,12 @@ AstNode *codegen_translate_c(CodeGen *g, Buf *full_path) {
81598165
81608166 init(g);
81618167
8168 if (use_userland_implementation) {
8169 // TODO improve this
8170 stage2_translate_c();
8171 zig_panic("TODO");
8172 }
8173
81628174 ZigList<ErrorMsg *> errors = {0};
81638175 AstNode *root_node;
81648176 Error err = parse_h_file(&root_node, &errors, buf_ptr(full_path), g, nullptr);
src/codegen.hpp+1-1
......@@ -50,7 +50,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
5050void codegen_add_assembly(CodeGen *g, Buf *path);
5151void codegen_add_object(CodeGen *g, Buf *object_path);
5252
53AstNode *codegen_translate_c(CodeGen *g, Buf *path);
53AstNode *codegen_translate_c(CodeGen *g, Buf *path, bool use_userland_implementation);
5454
5555Buf *codegen_generate_builtin_source(CodeGen *g);
5656
src/compiler.cpp+4-4
......@@ -179,24 +179,24 @@ Buf *get_zig_lib_dir(void) {
179179 return &saved_lib_dir;
180180}
181181
182Buf *get_zig_std_dir() {
182Buf *get_zig_std_dir(Buf *zig_lib_dir) {
183183 if (saved_std_dir.list.length != 0) {
184184 return &saved_std_dir;
185185 }
186186 buf_resize(&saved_std_dir, 0);
187187
188 os_path_join(get_zig_lib_dir(), buf_create_from_str("std"), &saved_std_dir);
188 os_path_join(zig_lib_dir, buf_create_from_str("std"), &saved_std_dir);
189189
190190 return &saved_std_dir;
191191}
192192
193Buf *get_zig_special_dir() {
193Buf *get_zig_special_dir(Buf *zig_lib_dir) {
194194 if (saved_special_dir.list.length != 0) {
195195 return &saved_special_dir;
196196 }
197197 buf_resize(&saved_special_dir, 0);
198198
199 os_path_join(get_zig_std_dir(), buf_sprintf("special"), &saved_special_dir);
199 os_path_join(get_zig_std_dir(zig_lib_dir), buf_sprintf("special"), &saved_special_dir);
200200
201201 return &saved_special_dir;
202202}
src/compiler.hpp+2-2
......@@ -16,7 +16,7 @@ Error get_compiler_id(Buf **result);
1616Buf *get_self_dynamic_linker_path(void);
1717
1818Buf *get_zig_lib_dir(void);
19Buf *get_zig_special_dir(void);
20Buf *get_zig_std_dir(void);
19Buf *get_zig_special_dir(Buf *zig_lib_dir);
20Buf *get_zig_std_dir(Buf *zig_lib_dir);
2121
2222#endif
src/main.cpp+61-40
......@@ -14,6 +14,7 @@
1414#include "os.hpp"
1515#include "target.hpp"
1616#include "libc_installation.hpp"
17#include "userland.h"
1718
1819#include <stdio.h>
1920
......@@ -40,6 +41,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
4041 " libc [paths_file] Display native libc paths file or validate one\n"
4142 " run [source] [-- [args]] create executable and run immediately\n"
4243 " translate-c [source] convert c code to zig code\n"
44 " translate-c-2 [source] experimental self-hosted translate-c\n"
4345 " targets list available compilation targets\n"
4446 " test [source] create and run a test build\n"
4547 " version print version number and exit\n"
......@@ -131,19 +133,6 @@ static int print_libc_usage(const char *arg0, FILE *file, int return_code) {
131133 return return_code;
132134}
133135
134static const char *ZIG_ZEN = "\n"
135" * Communicate intent precisely.\n"
136" * Edge cases matter.\n"
137" * Favor reading code over writing code.\n"
138" * Only one obvious way to do things.\n"
139" * Runtime crashes are better than bugs.\n"
140" * Compile errors are better than runtime crashes.\n"
141" * Incremental improvements.\n"
142" * Avoid local maximums.\n"
143" * Reduce the amount one must remember.\n"
144" * Minimize energy spent on coding style.\n"
145" * Together we serve end users.\n";
146
147136static bool arch_available_in_llvm(ZigLLVM_ArchType arch) {
148137 LLVMTargetRef target_ref;
149138 char *err_msg = nullptr;
......@@ -211,6 +200,7 @@ enum Cmd {
211200 CmdTargets,
212201 CmdTest,
213202 CmdTranslateC,
203 CmdTranslateCUserland,
214204 CmdVersion,
215205 CmdZen,
216206 CmdLibC,
......@@ -324,7 +314,7 @@ int main(int argc, char **argv) {
324314 return print_error_usage(arg0);
325315 }
326316 Buf *cmd_template_path = buf_alloc();
327 os_path_join(get_zig_special_dir(), buf_create_from_str(init_cmd), cmd_template_path);
317 os_path_join(get_zig_special_dir(get_zig_lib_dir()), buf_create_from_str(init_cmd), cmd_template_path);
328318 Buf *build_zig_path = buf_alloc();
329319 os_path_join(cmd_template_path, buf_create_from_str("build.zig"), build_zig_path);
330320 Buf *src_dir_path = buf_alloc();
......@@ -453,6 +443,7 @@ int main(int argc, char **argv) {
453443 bool want_single_threaded = false;
454444 bool disable_gen_h = false;
455445 Buf *override_std_dir = nullptr;
446 Buf *override_lib_dir = nullptr;
456447 Buf *main_pkg_path = nullptr;
457448 ValgrindSupport valgrind_support = ValgrindSupportAuto;
458449 WantPIC want_pic = WantPICAuto;
......@@ -486,13 +477,27 @@ int main(int argc, char **argv) {
486477 } else if (i + 1 < argc && strcmp(argv[i], "--cache-dir") == 0) {
487478 cache_dir = argv[i + 1];
488479 i += 1;
480 } else if (i + 1 < argc && strcmp(argv[i], "--override-std-dir") == 0) {
481 override_std_dir = buf_create_from_str(argv[i + 1]);
482 i += 1;
483
484 args.append("--override-std-dir");
485 args.append(buf_ptr(override_std_dir));
486 } else if (i + 1 < argc && strcmp(argv[i], "--override-lib-dir") == 0) {
487 override_lib_dir = buf_create_from_str(argv[i + 1]);
488 i += 1;
489
490 args.append("--override-lib-dir");
491 args.append(buf_ptr(override_lib_dir));
489492 } else {
490493 args.append(argv[i]);
491494 }
492495 }
493496
497 Buf *zig_lib_dir = (override_lib_dir == nullptr) ? get_zig_lib_dir() : override_lib_dir;
498
494499 Buf *build_runner_path = buf_alloc();
495 os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path);
500 os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path);
496501
497502 ZigTarget target;
498503 get_native_target(&target);
......@@ -512,7 +517,7 @@ int main(int argc, char **argv) {
512517 }
513518
514519 CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe,
515 BuildModeDebug, get_zig_lib_dir(), override_std_dir, nullptr, &full_cache_dir);
520 BuildModeDebug, override_lib_dir, override_std_dir, nullptr, &full_cache_dir);
516521 g->valgrind_support = valgrind_support;
517522 g->enable_time_report = timing_info;
518523 codegen_set_out_name(g, buf_create_from_str("build"));
......@@ -532,23 +537,25 @@ int main(int argc, char **argv) {
532537 "Usage: %s build [options]\n"
533538 "\n"
534539 "General Options:\n"
535 " --help Print this help and exit\n"
536 " --verbose Print commands before executing them\n"
537 " --prefix [path] Override default install prefix\n"
538 " --search-prefix [path] Add a path to look for binaries, libraries, headers\n"
540 " --help Print this help and exit\n"
541 " --verbose Print commands before executing them\n"
542 " --prefix [path] Override default install prefix\n"
543 " --search-prefix [path] Add a path to look for binaries, libraries, headers\n"
539544 "\n"
540545 "Project-specific options become available when the build file is found.\n"
541546 "\n"
542547 "Advanced Options:\n"
543 " --build-file [file] Override path to build.zig\n"
544 " --cache-dir [path] Override path to cache directory\n"
545 " --verbose-tokenize Enable compiler debug output for tokenization\n"
546 " --verbose-ast Enable compiler debug output for parsing into an AST\n"
547 " --verbose-link Enable compiler debug output for linking\n"
548 " --verbose-ir Enable compiler debug output for Zig IR\n"
549 " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n"
550 " --verbose-cimport Enable compiler debug output for C imports\n"
551 " --verbose-cc Enable compiler debug output for C compilation\n"
548 " --build-file [file] Override path to build.zig\n"
549 " --cache-dir [path] Override path to cache directory\n"
550 " --override-std-dir [arg] Override path to Zig standard library\n"
551 " --override-lib-dir [arg] Override path to Zig lib library\n"
552 " --verbose-tokenize Enable compiler debug output for tokenization\n"
553 " --verbose-ast Enable compiler debug output for parsing into an AST\n"
554 " --verbose-link Enable compiler debug output for linking\n"
555 " --verbose-ir Enable compiler debug output for Zig IR\n"
556 " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n"
557 " --verbose-cimport Enable compiler debug output for C imports\n"
558 " --verbose-cc Enable compiler debug output for C compilation\n"
552559 "\n"
553560 , zig_exe_path);
554561 return EXIT_SUCCESS;
......@@ -584,11 +591,12 @@ int main(int argc, char **argv) {
584591 init_all_targets();
585592 ZigTarget target;
586593 get_native_target(&target);
594 Buf *zig_lib_dir = (override_lib_dir == nullptr) ? get_zig_lib_dir() : override_lib_dir;
587595 Buf *fmt_runner_path = buf_alloc();
588 os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path);
596 os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("fmt_runner.zig"), fmt_runner_path);
589597 Buf *cache_dir_buf = buf_create_from_str(cache_dir ? cache_dir : default_zig_cache_name);
590598 CodeGen *g = codegen_create(main_pkg_path, fmt_runner_path, &target, OutTypeExe,
591 BuildModeDebug, get_zig_lib_dir(), nullptr, nullptr, cache_dir_buf);
599 BuildModeDebug, zig_lib_dir, nullptr, nullptr, cache_dir_buf);
592600 g->valgrind_support = valgrind_support;
593601 g->want_single_threaded = true;
594602 codegen_set_out_name(g, buf_create_from_str("fmt"));
......@@ -757,6 +765,8 @@ int main(int argc, char **argv) {
757765 llvm_argv.append(argv[i]);
758766 } else if (strcmp(arg, "--override-std-dir") == 0) {
759767 override_std_dir = buf_create_from_str(argv[i]);
768 } else if (strcmp(arg, "--override-lib-dir") == 0) {
769 override_lib_dir = buf_create_from_str(argv[i]);
760770 } else if (strcmp(arg, "--main-pkg-path") == 0) {
761771 main_pkg_path = buf_create_from_str(argv[i]);
762772 } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) {
......@@ -867,6 +877,8 @@ int main(int argc, char **argv) {
867877 cmd = CmdLibC;
868878 } else if (strcmp(arg, "translate-c") == 0) {
869879 cmd = CmdTranslateC;
880 } else if (strcmp(arg, "translate-c-2") == 0) {
881 cmd = CmdTranslateCUserland;
870882 } else if (strcmp(arg, "test") == 0) {
871883 cmd = CmdTest;
872884 out_type = OutTypeExe;
......@@ -883,6 +895,7 @@ int main(int argc, char **argv) {
883895 case CmdBuild:
884896 case CmdRun:
885897 case CmdTranslateC:
898 case CmdTranslateCUserland:
886899 case CmdTest:
887900 case CmdLibC:
888901 if (!in_file) {
......@@ -959,7 +972,7 @@ int main(int argc, char **argv) {
959972 }
960973 case CmdBuiltin: {
961974 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,
962 out_type, build_mode, get_zig_lib_dir(), override_std_dir, nullptr, nullptr);
975 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);
963976 g->valgrind_support = valgrind_support;
964977 g->want_pic = want_pic;
965978 g->want_single_threaded = want_single_threaded;
......@@ -973,6 +986,7 @@ int main(int argc, char **argv) {
973986 case CmdRun:
974987 case CmdBuild:
975988 case CmdTranslateC:
989 case CmdTranslateCUserland:
976990 case CmdTest:
977991 {
978992 if (cmd == CmdBuild && !in_file && objects.length == 0 && asm_files.length == 0 &&
......@@ -985,14 +999,16 @@ int main(int argc, char **argv) {
985999 " * --assembly argument\n"
9861000 " * --c-source argument\n");
9871001 return print_error_usage(arg0);
988 } else if ((cmd == CmdTranslateC || cmd == CmdTest || cmd == CmdRun) && !in_file) {
1002 } else if ((cmd == CmdTranslateC || cmd == CmdTranslateCUserland ||
1003 cmd == CmdTest || cmd == CmdRun) && !in_file)
1004 {
9891005 fprintf(stderr, "Expected source file argument.\n");
9901006 return print_error_usage(arg0);
9911007 }
9921008
9931009 assert(cmd != CmdBuild || out_type != OutTypeUnknown);
9941010
995 bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC);
1011 bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC || cmd == CmdTranslateCUserland);
9961012
9971013 if (cmd == CmdRun) {
9981014 out_name = "run";
......@@ -1026,7 +1042,8 @@ int main(int argc, char **argv) {
10261042 return print_error_usage(arg0);
10271043 }
10281044
1029 Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf;
1045 Buf *zig_root_source_file = (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) ?
1046 nullptr : in_file_buf;
10301047
10311048 if (cmd == CmdRun && buf_out_name == nullptr) {
10321049 buf_out_name = buf_create_from_str("run");
......@@ -1050,7 +1067,7 @@ int main(int argc, char **argv) {
10501067 cache_dir_buf = buf_create_from_str(cache_dir);
10511068 }
10521069 CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode,
1053 get_zig_lib_dir(), override_std_dir, libc, cache_dir_buf);
1070 override_lib_dir, override_std_dir, libc, cache_dir_buf);
10541071 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
10551072 g->valgrind_support = valgrind_support;
10561073 g->want_pic = want_pic;
......@@ -1170,8 +1187,8 @@ int main(int argc, char **argv) {
11701187 } else {
11711188 zig_unreachable();
11721189 }
1173 } else if (cmd == CmdTranslateC) {
1174 AstNode *root_node = codegen_translate_c(g, in_file_buf);
1190 } else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) {
1191 AstNode *root_node = codegen_translate_c(g, in_file_buf, cmd == CmdTranslateCUserland);
11751192 ast_render(g, stdout, root_node, 4);
11761193 if (timing_info)
11771194 codegen_print_timing_report(g, stderr);
......@@ -1229,9 +1246,13 @@ int main(int argc, char **argv) {
12291246 case CmdVersion:
12301247 printf("%s\n", ZIG_VERSION_STRING);
12311248 return EXIT_SUCCESS;
1232 case CmdZen:
1233 printf("%s\n", ZIG_ZEN);
1249 case CmdZen: {
1250 const char *ptr;
1251 size_t len;
1252 stage2_zen(&ptr, &len);
1253 fwrite(ptr, len, 1, stdout);
12341254 return EXIT_SUCCESS;
1255 }
12351256 case CmdTargets:
12361257 return print_target_list(stdout);
12371258 case CmdNone:
src/userland.cpp created+10
......@@ -0,0 +1,10 @@
1// This file is a shim for zig1. The real implementations of these are in
2// src-self-hosted/stage1.zig
3
4#include "userland.h"
5
6void stage2_translate_c(void) {}
7void stage2_zen(const char **ptr, size_t *len) {
8 *ptr = nullptr;
9 *len = 0;
10}
src/userland.h created+23
......@@ -0,0 +1,23 @@
1/*
2 * Copyright (c) 2019 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_USERLAND_H
9#define ZIG_USERLAND_H
10
11#include <stddef.h>
12
13#ifdef __cplusplus
14#define ZIG_USERLAND_EXTERN_C extern "C"
15#else
16#define ZIG_USERLAND_EXTERN_C
17#endif
18
19ZIG_USERLAND_EXTERN_C void stage2_translate_c(void);
20
21ZIG_USERLAND_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
22
23#endif
std/build.zig+17
......@@ -50,6 +50,8 @@ pub const Builder = struct {
5050 build_root: []const u8,
5151 cache_root: []const u8,
5252 release_mode: ?builtin.Mode,
53 override_std_dir: ?[]const u8,
54 override_lib_dir: ?[]const u8,
5355
5456 pub const CStd = enum {
5557 C89,
......@@ -133,6 +135,8 @@ pub const Builder = struct {
133135 },
134136 .have_install_step = false,
135137 .release_mode = null,
138 .override_std_dir = null,
139 .override_lib_dir = null,
136140 };
137141 self.detectNativeSystemPaths();
138142 self.default_step = self.step("default", "Build the project");
......@@ -939,6 +943,7 @@ pub const LibExeObjStep = struct {
939943 disable_gen_h: bool,
940944 c_std: Builder.CStd,
941945 override_std_dir: ?[]const u8,
946 override_lib_dir: ?[]const u8,
942947 main_pkg_path: ?[]const u8,
943948 exec_cmd_args: ?[]const ?[]const u8,
944949 name_prefix: []const u8,
......@@ -1039,6 +1044,7 @@ pub const LibExeObjStep = struct {
10391044 .c_std = Builder.CStd.C99,
10401045 .system_linker_hack = false,
10411046 .override_std_dir = null,
1047 .override_lib_dir = null,
10421048 .main_pkg_path = null,
10431049 .exec_cmd_args = null,
10441050 .name_prefix = "",
......@@ -1528,6 +1534,17 @@ pub const LibExeObjStep = struct {
15281534 if (self.override_std_dir) |dir| {
15291535 try zig_args.append("--override-std-dir");
15301536 try zig_args.append(builder.pathFromRoot(dir));
1537 } else if (self.builder.override_std_dir) |dir| {
1538 try zig_args.append("--override-std-dir");
1539 try zig_args.append(builder.pathFromRoot(dir));
1540 }
1541
1542 if (self.override_lib_dir) |dir| {
1543 try zig_args.append("--override-lib-dir");
1544 try zig_args.append(builder.pathFromRoot(dir));
1545 } else if (self.builder.override_lib_dir) |dir| {
1546 try zig_args.append("--override-lib-dir");
1547 try zig_args.append(builder.pathFromRoot(dir));
15311548 }
15321549
15331550 if (self.main_pkg_path) |dir| {
std/special/build_runner.zig+21-9
......@@ -94,6 +94,16 @@ pub fn main() !void {
9494 return usageAndErr(&builder, false, try stderr_stream);
9595 });
9696 builder.addSearchPrefix(search_prefix);
97 } else if (mem.eql(u8, arg, "--override-std-dir")) {
98 builder.override_std_dir = try unwrapArg(arg_it.next(allocator) orelse {
99 warn("Expected argument after --override-std-dir\n\n");
100 return usageAndErr(&builder, false, try stderr_stream);
101 });
102 } else if (mem.eql(u8, arg, "--override-lib-dir")) {
103 builder.override_lib_dir = try unwrapArg(arg_it.next(allocator) orelse {
104 warn("Expected argument after --override-lib-dir\n\n");
105 return usageAndErr(&builder, false, try stderr_stream);
106 });
97107 } else if (mem.eql(u8, arg, "--verbose-tokenize")) {
98108 builder.verbose_tokenize = true;
99109 } else if (mem.eql(u8, arg, "--verbose-ast")) {
......@@ -187,15 +197,17 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
187197 try out_stream.write(
188198 \\
189199 \\Advanced Options:
190 \\ --build-file [file] Override path to build.zig
191 \\ --cache-dir [path] Override path to zig cache directory
192 \\ --verbose-tokenize Enable compiler debug output for tokenization
193 \\ --verbose-ast Enable compiler debug output for parsing into an AST
194 \\ --verbose-link Enable compiler debug output for linking
195 \\ --verbose-ir Enable compiler debug output for Zig IR
196 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
197 \\ --verbose-cimport Enable compiler debug output for C imports
198 \\ --verbose-cc Enable compiler debug output for C compilation
200 \\ --build-file [file] Override path to build.zig
201 \\ --cache-dir [path] Override path to zig cache directory
202 \\ --override-std-dir [arg] Override path to Zig standard library
203 \\ --override-lib-dir [arg] Override path to Zig lib directory
204 \\ --verbose-tokenize Enable compiler debug output for tokenization
205 \\ --verbose-ast Enable compiler debug output for parsing into an AST
206 \\ --verbose-link Enable compiler debug output for linking
207 \\ --verbose-ir Enable compiler debug output for Zig IR
208 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
209 \\ --verbose-cimport Enable compiler debug output for C imports
210 \\ --verbose-cc Enable compiler debug output for C compilation
199211 \\
200212 );
201213}