Metaprogramming: Creating Debug and Release Builds

The following code is an example of how to do simple debug and release builds. Note that there are multiple ways to do this, and that this is just a simple pseudo-code example for how to do it.

#import "Basic";
#import "Compiler";

build_debug :: () {
  // insert debug compile options here...

build_release :: () {
  // insert release compile options here...

#run build_debug(); // change this to 'build_release' to do the release build

Import the Basic and Compiler module, then create build_debug and build_release functions. Put your choice of compiler options inside the build_debug and build_release functions respectively. Finally, run the specific build you want by doing #run build();.

Obtain Compiler Command-line Arguments

To obtain command-line arguments from compile-time, we can use args := compiler_get_command_line_arguments();. From there, we can use the compiler command-line to toggle between debug and release build.

#import "Compiler";

#run {
  args := compiler_get_command_line_arguments();
  for arg : args {
    if arg == {
    case "debug";
    case "release";

To toggle between debug and release build from the command-line, do the following for debug and release:

jai build.jai -- debug
jai build.jai -- release

Recommended debug options

These are some recommended options for a debug build to make the compiler compile faster with as much debugging information, but has some overhead in order to help debug. An executable built in debug mode will, for example, tell the programmer on which line of code the program crashed on, and check for array out of bounds errors. As expected from debug builds, the code is not as optimized as a release build.

target_options := get_build_options(w);
target_options.backend =.X64; // this is the fast backend, LLVM is slower
target_options.optimization_level = .DEBUG;
target_options.array_bounds_check = .ON; // this is on by default
set_build_options(target_options, w);

Recommended release options

These are some recommended options for a release build to make the compiler optimize code to produce the best possible optimized code. An optimized build does not have debug information built into release build, and takes longer to compile.

target_options := get_build_options(w);
target_options.backend = .LLVM;
target_options.optimization_level = .RELEASE;
set_optimization_level(target_options, 2, 0); // same as clang -O2
set_build_options(target_options, w);