Created
July 3, 2026 22:24
-
-
Save dbechrd/05d5bda0cafaa824ce1d91b70469fd9b to your computer and use it in GitHub Desktop.
Firebrick build.jai
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SRC_MAIN :: "src/main.jai"; // main file to build | |
| EXE_NAME :: "firebrick"; // required | |
| ICO_FILE :: "icon.ico"; // set to "" to disable | |
| IMPORT_DIR :: "../jai-modules"; // this should probably be an array heh | |
| IPROF :: false; // enable on-screen performance profiler | |
| PERF_REPORT :: false; // print perf report in build output | |
| VERBOSE :: false; // log debug info during build (apparently options.verbose is not a thing that works, mailed this) | |
| #run,stallable build(); | |
| build :: () { | |
| context.print_style.default_format_struct.use_long_form_if_more_than_this_many_members = -1; | |
| context.print_style.default_format_struct.use_newlines_if_long_form = true; | |
| w := compiler_create_workspace("Target Program (via build.jai)"); | |
| args := get_build_options(w).compile_time_command_line; | |
| options := get_build_options(w); | |
| copy_commonly_propagated_fields(get_build_options(), *options); | |
| #if VERBOSE { | |
| log("args: %", args); | |
| } | |
| success, plugins_to_create := parse_plugin_arguments(args); | |
| if !success { | |
| log_error("Failed to parse plugin arguments.\n"); | |
| exit(1); | |
| } | |
| // Only Default_Metaprogram should load the Jails plugin | |
| for * plugins_to_create { | |
| if it.name == "jails_diagnostics" { | |
| remove it; | |
| break; | |
| } | |
| } | |
| #if VERBOSE { | |
| log("plugins_to_create: %", plugins_to_create); | |
| } | |
| array_add(*plugins_to_create, .{name="Check"}); | |
| #if ICO_FILE { | |
| // image_to_ico("icon.png", "icon.ico"); | |
| icon_options: [..] string; | |
| array_copy(*icon_options, .["-icon", ICO_FILE]); | |
| array_add(*plugins_to_create, .{"Icon", icon_options}); | |
| } | |
| #if IPROF { | |
| iprof_options: [..] string; | |
| array_copy(*iprof_options, .[ | |
| "-modules", | |
| // "-min_size", "10" // default is 30 | |
| ]); | |
| array_add(*plugins_to_create, .{"Iprof", iprof_options}); | |
| } | |
| #if PERF_REPORT { | |
| perf_options: [..] string; | |
| array_add(*plugins_to_create, .{"Performance_Report", perf_options}); | |
| } | |
| // Now that we know what the plugins are, init them. | |
| success = init_plugins(plugins_to_create, *plugins, w); | |
| if !success { | |
| log_error("A plugin init() failed. Exiting.\n"); | |
| exit(0); | |
| } | |
| set_working_directory(#filepath); | |
| modules_paths: [..] string; | |
| array_add(*modules_paths, IMPORT_DIR); | |
| array_add(*modules_paths, ..options.import_path); | |
| options.import_path = modules_paths; | |
| options.output_path = "bin"; | |
| options.output_executable_name = EXE_NAME; | |
| // MUST be used with LLVM back-end (i.e. MUST NOT pass '-x64' ) | |
| // MUST be used in release mode (i.e. MUST pass '-release') | |
| options.llvm_options.command_line = string.[ | |
| "anything.exe", // your .exe name (can be any string as far as i can tell) | |
| // "-version", // display LLVM version info | |
| // "--help-list-hidden", // show advanced LLVM help | |
| // "--pass-remarks=.*", // dump info about all optimizations | |
| // "--pass-remarks-missed=.*", // dump info about missed optimizations | |
| // "--pass-remarks-analysis=.*", // honestly idk what this is.. a bunch of info about spills and alignment | |
| // "--debug-pass=Arguments", // Various LLVM pass reports that work | |
| // "--debug-pass=Structure", // Various LLVM pass reports that work | |
| // "--debug-pass=Executions", // Various LLVM pass reports that work | |
| // "--debug-pass=Details", // Various LLVM pass reports that work | |
| ]; | |
| set_build_options(options, w); | |
| set_build_options_dc(.{do_output=false, write_added_strings=false}); | |
| #if VERBOSE { | |
| print("build_options: %\n", options); | |
| } | |
| intercept_flags: Intercept_Flags; | |
| for plugins if it.before_intercept it.before_intercept(it, *intercept_flags); | |
| compiler_begin_intercept(w, intercept_flags); | |
| for plugins if it.add_source it.add_source(it); | |
| #if IPROF { | |
| add_build_string("IPROF :: true;\n", w); | |
| } else { | |
| add_build_string("IPROF :: false;\n", w); | |
| } | |
| add_build_file(SRC_MAIN, w); | |
| message_loop(w); | |
| compiler_end_intercept(w); | |
| for plugins if it.finish it.finish (it); | |
| for plugins if it.shutdown it.shutdown(it); | |
| } | |
| message_loop :: (w: Workspace) { | |
| decls_by_module: Table(string, [..] *Code_Declaration); | |
| while true { | |
| message := compiler_wait_for_message(); | |
| for plugins if it.message it.message(it, message); | |
| if message.kind == { | |
| case .COMPLETE; break; | |
| case .IMPORT; | |
| #if VERBOSE { | |
| import := cast(*Message_Import) message; | |
| print("Import: '%'\n", import.module_name); | |
| } | |
| case .FILE; | |
| #if VERBOSE { | |
| file := cast(*Message_File) message; | |
| print("File: '%'\n", file.fully_pathed_filename); | |
| } | |
| // case .PHASE; | |
| // phase := cast(*Message_Phase) message; | |
| // case .TYPECHECKED; | |
| // tc := cast(*Message_Typechecked) message; | |
| // for tc_decl: tc.declarations { | |
| // decl := tc_decl.expression; | |
| // } | |
| } | |
| } | |
| builder: String_Builder; | |
| for module_decls, module_name: decls_by_module { | |
| print_to_builder(*builder, "%\n", ifx module_name else "[Application]"); | |
| for module_decls { | |
| print_to_builder(*builder, " %\n", it.name); | |
| } | |
| } | |
| log("%", builder_to_string(*builder)); | |
| } | |
| plugins: [..] *Metaprogram_Plugin; | |
| #import "Basic"; | |
| #import "Compiler"; | |
| #import "Metaprogram_Plugins"; | |
| #import "Hash_Table"; | |
| #import "String"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment