<<
path:
root/public/blog.git/html/build.jai
blob: 3af44725300c96cea70141cbcf6b08abd36cf4e0
[raw]
[clear marker]
7#placeholder MEMORY_DEBUGGER_ENABLED;
8#placeholder IS_DEVELOPER;
9#placeholder IS_UA_ALLOCATOR;
12program_args: [..]string;
14/** TODO: Different parsing regime.
15 This is very ugly to maintain, maybe we just use `Command_Line` here.
18args_compiler_silent: bool;
19args_program_run: bool;
20args_build_release: bool;
22args_memory_debug: bool;
24args_dev_server_only: bool;
27args_fuzz_request: bool;
35 args := get_build_options().compile_time_command_line;
38 args_help = array_find(args, "help");
39 args_compiler_silent = array_find(args, "silent");
40 args_program_run = array_find(args, "run");
41 args_build_release = array_find(args, "release");
42 args_build_lib = array_find(args, "lib");
43 args_memory_debug = array_find(args, "memory");
44 args_dev_server = array_find(args, "server");
45 args_dev_server_only = array_find(args, "oserver");
46 args_gen = array_find(args, "gen");
47 args_search = array_find(args, "search");
48 args_fuzz_request = array_find(args, "request");
49 args_fuzz_e2e = array_find(args, "e2e");
50 args_fuzzer = array_find(args, "fuzzer");
51 args_tests = array_find(args, "tests");
52 args_um_alloc = array_find(args, "unmap");
56 program_args = program_args_collect(args); // @OS GC
58 // -----------------------------------------
60 prog_gen := compiler_create_workspace();
62 log("Workspace creation failed: Gen");
66 prog_search := compiler_create_workspace();
68 log("Workspace creation failed: Search");
72 prog_fuzzer := compiler_create_workspace();
74 log("Workspace creation failed: Fuzzer");
78 prog_tests := compiler_create_workspace();
80 log("Workspace creation failed: Tests");
84 prog_store := compiler_create_workspace();
86 log("Workspace creation failed: store");
91 set_build_options_dc(.{ do_output = false });
98 if args_dev_server || args_dev_server_only {
100 if args_dev_server_only return;
103 make_directory_if_it_does_not_exist("bin");
104 make_directory_if_it_does_not_exist("bin/debug");
105 make_directory_if_it_does_not_exist("bin/release");
106 make_directory_if_it_does_not_exist("bin/lib");
110 corpus_dir :: "fuzzer/corpus_search/";
112 add_build_file(tprint("%src/fuzzer/fuzzer_search.jai", #filepath), w);
115 fuzzer_run_pipeline(prog_fuzzer, "fuzzer_search", corpus_dir, intercept=code);
117 else if args_fuzz_request {
118 corpus_dir :: "fuzzer/corpus_request/";
120 add_build_file(tprint("%src/fuzzer/fuzzer_request.jai", #filepath), w);
123 fuzzer_run_pipeline(prog_fuzzer, "fuzzer_request", corpus_dir, intercept=code);
125 else if args_fuzz_e2e {
126 corpus_dir :: "fuzzer/corpus_e2e/";
128 add_build_file(tprint("%src/fuzzer/fuzzer_e2e.jai", #filepath), w);
131 fuzzer_run_pipeline(prog_fuzzer, "fuzzer_e2e", corpus_dir, intercept=code);
135 workspace_setup(prog_gen, "generator", #code {
136 add_build_file(tprint("%src/gen/main.jai", #filepath), w);
138 tprint("MEMORY_DEBUGGER_ENABLED :: %;", args_memory_debug), w
142 else if args_search {
143 workspace_setup(prog_search, "search", #code {
144 add_build_file(tprint("%src/search/main.jai", #filepath), w);
146 tprint("MEMORY_DEBUGGER_ENABLED :: %;", args_memory_debug), w
151 workspace_setup(prog_tests, "tests", #code {
152 add_build_file(tprint("%tests/main.jai", #filepath), w);
157build_debug :: (w: Workspace, target_options: *Build_Options) {
158 log("Choosing debug options ...");
159 target_options.backend =.X64;
160 target_options.output_path = "bin/debug";
161 set_optimization(target_options, Optimization_Type.DEBUG, true);
162 set_build_options(target_options.*, w);
165build_release :: (w: Workspace, target_options: *Build_Options) {
166 log("Choosing release options ...");
167 target_options.backend = .LLVM;
168 target_options.output_path = "bin/release";
169 target_options.stack_trace = false;
170 target_options.backtrace_on_crash = .OFF;
171 target_options.emit_debug_info = .DEFAULT;
172 set_optimization(target_options, Optimization_Type.VERY_OPTIMIZED);
173 set_build_options(target_options.*, w);
176build_lib_static :: (w: Workspace, target_options: *Build_Options) {
177 log("Choosing dyn lib options ...");
178 target_options.backend = .LLVM;
179 target_options.output_type = .DYNAMIC_LIBRARY;
180 target_options.output_path = "bin/lib";
181 set_optimization(target_options, Optimization_Type.VERY_OPTIMIZED);
182 set_build_options(target_options.*, w);
185workspace_setup :: (w: Workspace, program_name: string, $intercept: Code) #expand {
186 print("The workspace w is %\n", w);
187 target_options := get_build_options(w);
188 target_options.output_executable_name = program_name;
190 if args_compiler_silent target_options.text_output_flags = 0;
192 if args_build_release {
193 build_release(w, *target_options);
195 else if args_build_lib {
196 build_lib_static(w, *target_options);
199 build_debug(w, *target_options);
202 compiler_begin_intercept(w);
204 #insert,scope() intercept;
206 if args_build_release {
207 add_build_string("IS_DEVELOPER :: false;", w);
209 add_build_string("IS_DEVELOPER :: true;", w);
213 add_build_string("IS_UA_ALLOCATOR :: true;", w);
215 add_build_string("IS_UA_ALLOCATOR :: false;", w);
218 compiler_response := message_loop();
219 compiler_end_intercept(w);
221 if !compiler_response {
222 log("Compiler response failed.");
226 if args_program_run run_build_result_of_workspace(w, program_args);
229dev_server_run :: () {
230 cmd :: string.[ "python", "dev/server.py" ];
234fuzzer_run_pipeline :: (
236 program_name: string,
241 log("The workspace w is %", w);
242 target_options := get_build_options(w);
243 target_options.output_executable_name = program_name;
244 target_options.text_output_flags = 0;
246 fp_exec := tprint("fuzzer/%", program_name);
248 build_lib_static(w, *target_options);
249 compiler_begin_intercept(w);
251 #insert,scope() intercept;
253 compiler_response := message_loop();
254 compiler_end_intercept(w);
256 if !compiler_response {
257 log("Compiler response failed.");
261 log("Building fuzzer via clang ...");
262 clang_cmd := string.[
264 "-fsanitize=fuzzer,address",
265 tprint("bin/lib/%.so", program_name),
269 run_command(..clang_cmd);
273 tprint("-runs=%", runs),
274 "-max_total_time=60",
276 "-max_total_time=60",
277 "-artifact_prefix=fuzzer/",
280 if args_program_run then run_command(..fuzz_cmd);
283program_args_collect :: (args: []string, divider: string = "::") -> [..]string {
286 success, match := array_find(args, divider);
287 if success for i: match+1..args.count-1 array_add(*buf, args[i]);
292message_loop :: () -> ok: bool {
294 message := compiler_wait_for_message();
298 message_complete := cast(*Message_Complete) message;
299 return message_complete.error_code == 0;
305args_help_print :: () {
306 help_message :: #string _END_
307Usage: jai build.jai - [OPTIONS] :: [PROGRAM ARGS]
310 help Prints this help menu.
311 silent Disables compiler/linker statistics.
312 run Runs your program afterwards.
313 release Builds with release options. If omitted, it builds a debug build.
314 memory Enables the memory leak detector.
316Passing Args to your Program:
317 If you want to supply args to your program, pass it like that:
319 `jai build.jai - run :: my_arg1 foo bar abc ABC`
321 Everything after the `::` get's forwarded to your program.