1 /*
2  * Copyright (c) 2020 Andrew Kelley
3  *
4  * This file is part of zig, which is MIT licensed.
5  * See http://opensource.org/licenses/MIT
6  */
7 
8 #include "stage1.h"
9 #include "os.hpp"
10 #include "all_types.hpp"
11 #include "codegen.hpp"
12 
zig_stage1_os_init(void)13 void zig_stage1_os_init(void) {
14     os_init();
15     mem::init();
16     init_all_targets();
17 }
18 
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)19 struct ZigStage1 *zig_stage1_create(BuildMode optimize_mode,
20     const char *main_pkg_path_ptr, size_t main_pkg_path_len,
21     const char *root_src_path_ptr, size_t root_src_path_len,
22     const char *zig_lib_dir_ptr, size_t zig_lib_dir_len,
23     const ZigTarget *target, bool is_test_build)
24 {
25     Buf *main_pkg_path = (main_pkg_path_len == 0) ?
26         nullptr : buf_create_from_mem(main_pkg_path_ptr, main_pkg_path_len);
27     Buf *root_src_path = buf_create_from_mem(root_src_path_ptr, root_src_path_len);
28     Buf *zig_lib_dir = buf_create_from_mem(zig_lib_dir_ptr, zig_lib_dir_len);
29     CodeGen *g = codegen_create(main_pkg_path, root_src_path, target, optimize_mode,
30             zig_lib_dir, is_test_build);
31     return &g->stage1;
32 }
33 
zig_stage1_destroy(struct ZigStage1 * stage1)34 void zig_stage1_destroy(struct ZigStage1 *stage1) {
35     CodeGen *codegen = reinterpret_cast<CodeGen *>(stage1);
36     codegen_destroy(codegen);
37 }
38 
add_package(CodeGen * g,ZigStage1Pkg * stage1_pkg,ZigPackage * pkg)39 static void add_package(CodeGen *g, ZigStage1Pkg *stage1_pkg, ZigPackage *pkg) {
40     for (size_t i = 0; i < stage1_pkg->children_len; i += 1) {
41         ZigStage1Pkg *child_cli_pkg = stage1_pkg->children_ptr[i];
42 
43         Buf *dirname = buf_alloc();
44         Buf *basename = buf_alloc();
45         os_path_split(buf_create_from_mem(child_cli_pkg->path_ptr, child_cli_pkg->path_len), dirname, basename);
46 
47         ZigPackage *child_pkg = codegen_create_package(g, buf_ptr(dirname), buf_ptr(basename),
48                 buf_ptr(buf_sprintf("%s.%.*s", buf_ptr(&pkg->pkg_path),
49                         (int)child_cli_pkg->name_len, child_cli_pkg->name_ptr)));
50         auto entry = pkg->package_table.put_unique(
51                 buf_create_from_mem(child_cli_pkg->name_ptr, child_cli_pkg->name_len),
52                 child_pkg);
53         if (entry) {
54             ZigPackage *existing_pkg = entry->value;
55             Buf *full_path = buf_alloc();
56             os_path_join(&existing_pkg->root_src_dir, &existing_pkg->root_src_path, full_path);
57             fprintf(stderr, "Unable to add package '%.*s'->'%.*s': already exists as '%s'\n",
58                     (int)child_cli_pkg->name_len, child_cli_pkg->name_ptr,
59                     (int)child_cli_pkg->path_len, child_cli_pkg->path_ptr,
60                     buf_ptr(full_path));
61             exit(EXIT_FAILURE);
62         }
63 
64         add_package(g, child_cli_pkg, child_pkg);
65     }
66 }
67 
zig_stage1_build_object(struct ZigStage1 * stage1)68 void zig_stage1_build_object(struct ZigStage1 *stage1) {
69     CodeGen *g = reinterpret_cast<CodeGen *>(stage1);
70 
71     g->root_out_name = buf_create_from_mem(stage1->root_name_ptr, stage1->root_name_len);
72     buf_init_from_mem(&g->o_file_output_path, stage1->emit_o_ptr, stage1->emit_o_len);
73     buf_init_from_mem(&g->h_file_output_path, stage1->emit_h_ptr, stage1->emit_h_len);
74     buf_init_from_mem(&g->asm_file_output_path, stage1->emit_asm_ptr, stage1->emit_asm_len);
75     buf_init_from_mem(&g->llvm_ir_file_output_path, stage1->emit_llvm_ir_ptr, stage1->emit_llvm_ir_len);
76     buf_init_from_mem(&g->bitcode_file_output_path, stage1->emit_bitcode_ptr, stage1->emit_bitcode_len);
77     buf_init_from_mem(&g->analysis_json_output_path, stage1->emit_analysis_json_ptr, stage1->emit_analysis_json_len);
78     buf_init_from_mem(&g->docs_output_path, stage1->emit_docs_ptr, stage1->emit_docs_len);
79 
80     if (stage1->builtin_zig_path_len != 0) {
81         g->builtin_zig_path = buf_create_from_mem(stage1->builtin_zig_path_ptr, stage1->builtin_zig_path_len);
82     }
83     if (stage1->test_filter_len != 0) {
84         g->test_filter = buf_create_from_mem(stage1->test_filter_ptr, stage1->test_filter_len);
85     }
86     if (stage1->test_name_prefix_len != 0) {
87         g->test_name_prefix = buf_create_from_mem(stage1->test_name_prefix_ptr, stage1->test_name_prefix_len);
88     }
89 
90     g->link_mode_dynamic = stage1->link_mode_dynamic;
91     g->dll_export_fns = stage1->dll_export_fns;
92     g->have_pic = stage1->pic;
93     g->have_pie = stage1->pie;
94     g->have_lto = stage1->lto;
95     g->unwind_tables = stage1->unwind_tables;
96     g->have_stack_probing = stage1->enable_stack_probing;
97     g->red_zone = stage1->red_zone;
98     g->omit_frame_pointer = stage1->omit_frame_pointer;
99     g->is_single_threaded = stage1->is_single_threaded;
100     g->valgrind_enabled = stage1->valgrind_enabled;
101     g->tsan_enabled = stage1->tsan_enabled;
102     g->link_libc = stage1->link_libc;
103     g->link_libcpp = stage1->link_libcpp;
104     g->function_sections = stage1->function_sections;
105     g->include_compiler_rt = stage1->include_compiler_rt;
106 
107     g->subsystem = stage1->subsystem;
108 
109     g->enable_time_report = stage1->enable_time_report;
110     g->enable_stack_report = stage1->enable_stack_report;
111     g->test_is_evented = stage1->test_is_evented;
112 
113     g->verbose_ir = stage1->verbose_ir;
114     g->verbose_llvm_ir = stage1->verbose_llvm_ir;
115     g->verbose_cimport = stage1->verbose_cimport;
116     g->verbose_llvm_cpu_features = stage1->verbose_llvm_cpu_features;
117 
118     g->err_color = stage1->err_color;
119     g->code_model = stage1->code_model;
120 
121     {
122         g->strip_debug_symbols = stage1->strip;
123         if (!target_has_debug_info(g->zig_target)) {
124             g->strip_debug_symbols = true;
125         }
126     }
127 
128     g->main_progress_node = stage1->main_progress_node;
129 
130     add_package(g, stage1->main_pkg, g->main_pkg);
131 
132     codegen_build_object(g);
133 }
134