libk  kbuild.md at [49b6e9c7f6]

File mod/kbuild/kbuild.md artifact a7d1456a88 part of check-in 49b6e9c7f6


# kbuild

**kbuild** is a small build tool designed to maximize the ease of writing portable libk applications. kbuild is included because most C compilers automatically assume their input should be linked with libc, inserting several implicit flags that need to be changed or removed for libk. while it is fully possible to build libk programs without using kbuild, it can be somewhat tedious, especially for code too small to warrant a makefile.

kbuild is not intended to replace complex build systems like gmake, nor is it intended to be used only with libk binaries.

unlike most build systems, kbuild does not use a makefile or project file. kbuild is invoked simply by passing it a list of C files, which it will build and link together. kbuild recursively calculates dependencies for each file, by parsing `#include` directives and kbuild-specific pragmas.

kbuild passes a series of variables through to the preprocessor, providing information about the current system that can be useful for conditional compilation.

these are the phases of the kbuild process:


# pragmas

to support automatic linking, kbuild handles the following pragmas.

 * `#pragma k lib` adds a library name to the list of libraries to include. on linux, pkg-config will be used to locate the library and add the appropriate flags to the command line. link flags will be applied to the final binary, while all other flags will apply only to the compilation of the source unit; for this reason, library pragmas should precede `#include` directives. `#pragma k lib c` can be used to link the standard C library; if it is present, libk will not be linked unless it is explicitly named (`#pragma k lib k`).
 * `#pragma k flag` indicates that a file should be compiled with a specific flag. this will be passed directly to the compiler, so it should be used within `#if` statements to detect the operating system and/or compiler being used.
 * `#pragma k link` adds a flag to the final linker command line
 * `#pragma k env` requests a specific environment variable be passed to the compiler with the -D flag; `#pragma k env EDITOR` will create a macro `KE_EDITOR` if `$EDITOR` is set in the user's environment. on encountering an `env` predicate for a variable it has not already passed, `kbuild` will terminate parsing and re-run cpp with the new variable set. this allows the use of environment variables to make first-pass decisions, though its effects may be somewhat unintuitive - a `#pragma k env` directive can affect the evaluation of a macro expression earlier in the same file. `#pragma k env` without an argument requests all host environment variables be passed through to the program.

pragmas are scanned from the preprocessed file, meaning `#if` blocks can be used to control whether a library is linked or flag is passed.

the `_Pragma` form is not currently supported, but supporting it is a long-term goal.