libk  kbuild.md at tip

File mod/kbuild/kbuild.md from the latest check-in


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.