#load "build/build.bl"
Compiler-integrated build pipeline. The build pipeline can be used to manage the entire project
compilation process directly in BL. All you need is to create a build file called build.bl.
Example of a minimal build.bl:
main :: fn () s32 {
// create a new executable target
exe :: add_executable("MyProgram");
// add 'main.bl' file into the target 'exe'
add_unit(exe, "main.bl");
// start compilation
compile(exe);
return 0;
}
Start the build pipeline using your build.bl file:
$ blc -build
The compiler will automatically use the build.bl file as a build script and execute the main
function at compile-time. The build/build.bl file containing the compiler API for build pipeline
manipulation is loaded implicitly.
Warning: The Build API is available only at compile-time.
A target represents a single build target consisting of build Units, where each Unit represents one source file required for compilation. It is essentially a target compiled into an executable or binary file. Use the add_executable function to specify your target. Several options related to the target are described later in this documentation.
exe :: add_executable("MyProgram");
Use the add_unit function to add source files to the target. There is no need to add
all files you want to use; the general load and import mechanisms will handle that automatically.
Only main or entry-point files must be included explicitly.
add_unit(exe, "main.bl");
The output directory is the directory where all compiler-produced files will be written (for example, native executables). Use the set_output_dir function to specify this directory. By default, the current directory is used.
set_output_dir(exe, "bin");
compile(exe);
All arguments passed after the -build compiler flag are automatically forwarded to the
command_line_arguments global variable. This allows customization of the build command by
adding project-specific build flags. See the extra/argparse module.
BuilderOptions :: struct {
verbose: bool;
no_color: bool;
silent: bool;
no_jobs: bool;
no_warning: bool;
full_path_reports: bool;
no_usage_check: bool;
stats: bool;
enable_experimental_targets: bool;
do_cleanup_when_done: bool;
error_limit: s32;
legacy_colors: bool;
warnings_as_errors: bool;
_doc_out_dir: *C.char;
}
Global builder options.
verbose - Toggle verbose mode. (Off by default.)
no_color - Toggle coloring the terminal output. (Off by default.)
silent - Silent mode reduces amount of stuff printed to the standard output to minimum. (Off by default.)
no_jobs - Toggle multithreading. (On by default.)
no_warning - Disable all compiler warnings. (Off by default.)
full_path_reports - Use full (absolute) paths in compiler reports. (Off by default.)
no_usage_check - Toggle check of unused symbols. (Off by default.)
stats - Toggle printing of some compilation statistics. (Off by default.)
enable_experimental_targets - Toggle experimantal targets. (Off by default.)
do_cleanup_when_done - Release memory after compilation. When the compiler is executed as a single-shot application
(start -> compile -> exit), memory cleanup can be left to the operating system to improve
compilation speed. (Off by default.)
error_limit - Maximum count of error reported by the compiler.
legacy_colors - Enable legacy color output on Windows for terminals not supporting ANSI color codes.
warnings_as_errors - Report all warnings as errors.
File: build.bl
get_builder_options :: fn () BuilderOptions
Returns copy of current builder options. These are by default initializad from command line arguments passed to the compiler.
File: build.bl
set_builder_options :: fn (opt: BuilderOptions)
Overrides current builder options previously set from the command line or by calling this function.
File: build.bl
Target :: struct {
kind: TargetKind;
build_mode: BuildMode;
debug_info_kind: DebugInfo;
register_split: bool;
verify_llvm: bool;
run_tests: bool;
tests_minimal_output: bool;
no_api: bool;
copy_dependencies: bool;
run: bool;
print_tokens: bool;
print_ast: bool;
print_scopes: bool;
print_scopes_mode: ScopeDumpMode;
emit_llvm: bool;
emit_asm: bool;
emit_mir: bool;
no_bin: bool;
no_llvm: bool;
no_analyze: bool;
x64: bool;
assert_mode: AssertMode;
syntax_only: bool;
vmdbg_enabled: bool;
vmdbg_break_on: s32;
enable_experimental_targets: bool;
triple: TargetTriple;
sanitize_address: bool;
}
Target is representation of whole program workspace, it's a consist of Units, every unit represents one source file.
kind - See TargetKind.build_mode - Specify build mode of the target. See BuildModedebug_info_kind - Specify debug information format used for target in debug mode. See DebugInfo.register_split - Enable split of function arguments and return value into registers.verify_llvm - Verify LLVM module.run_tests - Execute compile-time tests.tests_minimal_output - Reduce compile-time tests output (remove results section).no_api - Disable default API import.copy_dependencies - Copy all known dependencies into output folder.run - Execute main function in compile-time.print_tokens - Print lexer output.print_ast - Print AST.print_scopes - Print assembly scope structure in dot Graphviz format.emit_llvm - Emit LLVM IR code into file.emit_asm - Emit asm code into file.emit_mir - Emit MIR code into file.no_bin - Disable generation of a native binary.no_llvm - Disable LLVM backend.no_analyze - Disable analyze pass of code generation.x64 - Experimental x64 backend (debug only).assert_mode - See AssertMode.syntax_only - Check syntax only.vmdbg_enabled - Enable virtual machine debugger.vmdbg_break_on - Specify the MIR instruction ID to break on when the virtual machine debugger is attached.enable_experimental_targets - Enable experimental build targets.triple - Target triple according to LLVM.sanitize_address - Enable runtime LLVM address sanitizer.File: build.bl
ScopeDumpMode :: enum {
PARENTING = 0;
INJECTION = 1;
}
File: build.bl
TargetKind :: enum {
EXECUTABLE = 0;
SHARED_LIBRARY = 1;
}
Specification of compiler output binary kind.
File: build.bl
TargetArch :: enum s32 {
UNKNOWN = 0;
X86_64 = 1;
AARCH64 = 2;
ARM64 = 3;
}
File: build.bl
TargetVendor :: enum s32 {
UNKNOWN = 0;
PC = 1;
APPLE = 2;
}
File: build.bl
TargetSystem :: enum s32 {
UNKNOWN = 0;
WINDOWS = 1;
DARWIN = 2;
LINUX = 3;
}
File: build.bl
TargetEnvironment :: enum s32 {
UNKNOWN = 0;
MSVC = 1;
GNU = 2;
MUSL = 3;
}
File: build.bl
TargetTriple :: struct {
arch: TargetArch;
vendor: TargetVendor;
os: TargetSystem;
env: TargetEnvironment;
}
File: build.bl
BuildMode :: enum s32 {
DEBUG = 0;
RELEASE_FAST = 1;
RELEASE_SMALL = 2;
RELEASE_WITH_DEBUG_INFO = 3;
}
Specify the target build mode. Each Target can be compiled with various configuration
options. The BuildMode determines which set of compiler options is used.
DEBUG - Generates debug symbols and produces a binary without optimizations. The IS_DEBUG global
variable is set to true in this mode (false in all other modes).
RELEASE_FAST - Fast release mode. No debug symbols are produced, and all possible optimizations are applied
to generate the fastest possible binary.
Assertions are disabled unless Target.assert_mode is ALWAYS_ENABLED.
RELEASE_SMALL - Small release mode. No debug symbols are produced, and optimizations are applied to generate
a reasonably fast and as small as possible binary.
Assertions are disabled unless Target.assert_mode is ALWAYS_ENABLED.
RELEASE_WITH_DEBUG_INFO - Release mode with debug symbols. Optimizations are applied to generate a reasonably fast and
as small as possible binary.
Assertions are disabled unless Target.assert_mode is ALWAYS_ENABLED.
File: build.bl
DebugInfo :: enum s32 {
DWARF = 0;
CODE_VIEW = 1;
}
Debug information format.
File: build.bl
AssertMode :: enum s32 {
DEFAULT = 0;
ALWAYS_ENABLED = 1;
ALWAYS_DISABLED = 2;
}
Specification of the assert mode used for a Target.
DEFAULT - The compiler emits assertions in BuildMode.DEBUG and skips assertions in all
optimized release modes.
ALWAYS_ENABLED - Force-enable assertions in all build modes.
ALWAYS_DISABLED - Force-disable assertions in all build modes.
File: build.bl
add_executable :: fn (name: string_view) *Target
Add a new executable target to the current compilation queue. The newly created target can be compiled explicitly using compile, or compile_all can be used to compile all added targets at once.
main :: fn () s32 {
exe :: add_executable("MyProgram");
add_unit(exe, "src/main.bl");
mode :: get_build_mode(exe);
switch mode {
BuildMode.DEBUG {
set_output_dir(exe, "build/debug");
}
BuildMode.RELEASE_SMALL,
BuildMode.RELEASE_FAST {
set_output_dir(exe, "build/release");
}
}
compile(exe);
return 0;
}
File: build.bl
add_library :: fn (name: string_view) *Target
Add a new shared library target to the current compilation queue.
File: build.bl
add_unit :: fn (target: *Target, filepath: string_view)
Add a new source file to the target. The function does nothing if filepath is already present
in the target assembly.
File: build.bl
compile :: fn (target: *Target) Error
Start compilation of the target assembly and return ok or error if compilation fails.
File: build.bl
compile_all :: fn () Error
Compile all created targets one by one in the order in which they were created. See also compile.
File: build.bl
add_lib_path :: fn (target: *Target, path: string_view)
Add a path for linker library lookup.
File: build.bl
add_bool_constant :: fn (target: *Target, name: string_view, value: bool, loc :: #call_location)
Add a new immutable boolean variable to the global scope of the target assembly.
File: build.bl
link_library :: fn (target: *Target, name: string_view)
Link a dynamic library. Only the name is required (without extension or prefix). The compiler
will look for this library in the working directory, the system PATH, and the linker_lib_path
variable specified in the bl.conf file (use blc --where-is-config to get the file location).
You can add custom search locations using the add_lib_path function.
The linked library can also be used during compile-time execution. In that case, all required
symbols are loaded at compile time using dlopen.
Platform-specific library naming rules:
lib prefix and the .so extension.lib prefix and the .dylib extension..dll extension.main :: fn () s32 {
exe :: add_executable("MyGame");
add_unit(exe, "src/main.bl");
switch PLATFORM {
Platform.WINDOWS { target_windows(exe); }
default { panic("Unknown build target!"); }
}
compile(exe);
return 0;
}
target_windows :: fn (exe: *Target) {
link_library(exe, "freetype");
link_library(exe, "zlib");
link_library(exe, "png");
}
File: build.bl
link_static_library :: fn (target: *Target, name: string_view)
Link a static library. Only the name is required (without extension or prefix). The compiler
will look for this library in the working directory, the system PATH, and the linker_lib_path
variable specified in the bl.conf file (use blc --where-is-config to get the file location).
You can add custom search locations using the add_lib_path function.
The linked library cannot be used during compile-time execution, because the compiler cannot load static libraries at runtime.
Platform-specific library naming rules:
lib prefix and the .a extension..lib extension.File: build.bl
link_framework :: fn (target: *Target, name: string_view)
Link a framework on macOS.
File: build.bl
add_framework_path :: fn (target: *Target, path: string_view)
Add a framework search path on macOS.
File: build.bl
append_linker_options :: fn (target: *Target, option: string_view)
Append raw string directly to the linker command. The passed option is added without any processing or compatibility validation.
File: build.bl
set_output_dir :: fn (target: *Target, dir: string_view)
Set the build output directory. This is the directory where all output files will be written. For example, a different output directory can be set for each build mode.
The directory path dir may contain non-existing directories separated by /. The compiler
will create all missing directories in the specified path.
The specified directory is also used for build temporary files.
File: build.bl
get_output_dir :: fn (target: *Target) string_view
Get output directory specified by set_output_dir or empty string.
File: build.bl
set_module_dir :: fn (target: *Target, dir: string_view)
Set the module directory dir for the target. When the #import directive is used, the
compiler searches this directory first when resolving modules. If the module is not found,
the default compiler API location is used. The default location is specified as lib_dir
in the bl.conf file (use blc --where-is-config to get the file location).
File: build.bl
get_module_dir :: fn (target: *Target) string_view
Get the output directory specified by set_output_dir, or an empty string if no directory was set.
File: build.bl
get_default_module_dir :: fn () string_view
Get the module directory specified by set_module_dir or empty string.
File: build.bl
get_default_triple :: fn () TargetTriple
Return the target triple of the current host machine.
File: build.bl
triple_to_string :: fn (triple: TargetTriple) string_view
Convert a target triple to a string.
Note: The returned string is allocated using the current temporary allocator.
File: build.bl