Built-in Jambase Reference
The KJam program implements a programming language designed to implement build systems. Users implement their build systems by writing jamfiles which specify to KJam how to build the user's project. Normally a user will want to divide up their Jamfiles into two, one which specifies rules and actions and which is shared across the user's projects, and another which calls rules to build specific target files from specific source files. By convention the former is usually called the jambase and the latter the jamfile. The KJam language is designed to make it possible to move all the complexity into the jambase file, and to keep the jamfile very easy to read and edit.
KJam ships with a default jambase, integrated into the KJam binary. This built-in jambase file makes it very easy for users to manage most standard c and c++ projects using MSVC on Windows and GCC on Linux. The built-in Jambase is simple to use, and extremely flexible. Here is an example of what a jamfile using the built-in jambase would look like:
StaticLibrary mylib : libsrc1.cpp libsrc2.cpp libsrc3.cpp ; StaticExecutable myprog : main.cpp : mylib.lib ;One of the advantages of the built-in jambase file, is that the resulting jamfiles are completely portable between Windows and Linux. The jamfile above would build equally well under Linux or Windows.
To write jamfiles using the built-in jambase, users only need to call one of the build in rules. Most of the rules take the name of the target file as their first argument and the names of the source files as the second argument. There are rules for generating libraries and executables, either linked with static libraries or with shared libraries.
The operation of the rules can be modified by setting variables which have a special meaning to the built-in rules. For example there are variables to more directories to to search for include files, and more directories to search for header files. The names and locations of specific tools may be overriden as well. For example, to create a jamfile that links libraries in additional directories:
LIB_DIRS = ../other ; StaticExecutable myprog : main.cpp : other.lib ;
Variables may also be used to pass special compile options to individual object files. For example:
StaticObject special.obj : special.cpp : /DSPECIAL_DEF ; StaticExecutable myprog : main.cpp special.obj ;
Most rules also allow the list of sources to include all the files in a particular directory, by listing the directory name in place of all the source files, like so:
StaticExecutable myprog : srcdir ;
By default the built-in rules will automatically generate a 'clean' target and an 'all' target.
In order to support new languages and tools, users will need to extend the built-in jambase file, or to write their own. KJam will use the built-in jambase file unless the user specifically overrides it with the -D command line option. Using the -X and -P options users may extract the built-in jambase files, modify them and if desired reintegrate them with the KJam binary.
It is important to note that in addition to the built-in jambase file, which can be overridden with a user jambase file, many built-in rules such as the includes and depends rules are an integral part of KJam and cannot be overridden.
Variables
All PlatformsINCLUDE_DIRS
By default KJam will search for headers in the local directory and in the system header files directories. To search for headers in other directories set this variable to the list of directories to search. On windows KJam will also search for headers in any subdirectory of these directories called win32.
LIB_DIRS
By default KJam will search for libraries in the local directory and in the system library directories. To search for libraries in other directories set this variable to the list of directories to search.
CCOPTS
All elements of this variable are passed as additional options to the c compiler. The built-in rules already define most standard compilation options to control the type of build, and where to search for headers etc. Sometimes it is necessary to specify special additional compilation options. It is possible to pass additional CC options to all objects by defining this variable globally. To pass additional options to a single object file, set this variable on that object like this:
CCOPTS on special.o = /DSPECIAL ;
On Windows KJam's built-in rules will compile c and cpp sources in batches. This may give you unexpected results when defining CCOPTS on a single target. It is safer to use the StaticObject or SharedObject rules.
CCDEFINES
All elements of this variable are passed as additional options to the c compiler as command line definitions. For MSVC this will mean that each element will be passed as a /D option, for GCC each element will be passed in as a -D option. This differs from defining CCOPTS directly. CCOPTS will set compiler exactly as they are specified, so the settings will be specific to a given compiler. CCDEFINES will set use the appropriate syntax for all compiler which support setting command line definitions, and is therefore more portable.
LINKOPTS
All elements of this variable are passed as additional options to the linker. The built-in rules already define most standard link options. Sometimes it is necessary to specify special additional link options. It is possible to pass these additional link options to all libraries and executables by defining this variable globally. To pass additional options to a single target, set this variable on that target like this:
LINKOPTS on special.exe = -lspecial ;
These options are passed to the linker exactly as they are specified, and may not be portable from one platform to another.
BIN_DIR
By default the built-in rules will generate all target files in the defaule target directory. By default the target directory is defined as bin/$(PLATFORM)/$(CURFLAV). To build in a special non-default directory, set this variable to the desired directory. If this is set globally then all targets will be built in that given directory. To build only a certain target in a special directory, set this variables on that target like this:
BIN_DIR on special.lib = special_dir ;
CURFLAV
KJam's built-in rules are designed to build targets in one of 4 configurations, with different amounts of debugging support. The level of debugging support is controlled by the CURFLAV variable. Normally this variable can be set as an environment variable in the user shell. On linux you must remember to 'export' the variable after setting it. Or this variable may be passed on KJam's command line as a -s option. You can also set CURFLAV in the jamfile, but this would be of limited usefulness.
The four settings are:
| release | All targets are compiled with maximum compiler optimizations turned on, including options which makes using a debugger very difficult, including building without a frame pointer, debugger stack frame support and without debugging symbols. When using GCC all libraries and executables are stripped. All code is compiled with NDEBUG and RELEASE defined. This is useful for compiling release builds which will be distributed to end users. |
| optimized | All targets are compiled with most compiler optimizations, and should run at nearly full speed. Optimizations which make attaching a debugger difficult are not used. All binaries are build with complete symbol tables. Binaries produced with this level of optimization can be debugged, but due to some optimization object code will no longer match with source line for line. All code is compiled with NDEBUG defined. This is useful for internal testing of builds at nearly release speeds, but with some debugging support. |
| debug | All targets are compiled with no compiler optimizations, and with all debugging features turned on. The resulting binaries may be significantly slower than optimized and release builds. All code is compiled with DEBUG defined. This is useful for debugging development code. |
| extra_debug | All targets are compiled with the same options as DEBUG, but code is compiled with DEBUG and EXTRA_DEBUG defined. This allows programmers to write certain time consuming error detection code which may cause very significant performance penalties. Such code may be necessary to address certain difficult bugs. |
All targets are generated into a directory which includes the current CURFLAV, such that targets build with different levels of debugging support should never intermix. It is recommened when manually defining BIN_DIR that the new definition include $(CURFLAV) somewhere to avoid problems with mixing targets at different debugging levels.
Defining CURFLAV also causes the build rules to defined a single letter BUILD_CODE, ( r o d or x ). This BUILD_CODE may also be used to differentiate targets in places where a very short string is desired.
LEX
The name of the lexical analyzer generator to use. By default on Windows this is set to flex.exe. On Linux this is set to flex.
YACC
The name of the parser generator to use. By default on Windows this is set to bison.exe. On Linux this is set to bison.
CC_VER
This variable defines compiler version to use. On Windows this can be get to MSVC6, MSVC7, MSVC8, gcc and djgpp. On linux it is always set to gcc. KJam will attempt to discover the which compilers are installed, and will set CC_VER to an appropriate value. Setting CC_VER manually change which compiler toolset KJam will use. For versions of MSVC, this also sets the default MSVCDIR that the build rules use, and some of the compiler options.
CC_IS_MSVC
This is set to a non-null value if a version of MSVC is being used.
CC_IS_GCC
This is set to a non-null value if a version of GCC is being used.
MSVCDIR
This variable defines where the currently installed version of MSVC may be found. The build rules come predefined to look for the compiler in the default installation directories. If MSVC is installed in a different directory on your system, it may be necessary to define it here.
DLL_DEFINES
All elements of this variable are passed to MSVC as /D definitions when compiling a c or cpp file to be linked into a .dll. This variable is useful for code which is written to compile as both a .dll and as a static .lib. The definitions can be used to define special dllimport and dllexport declarations for dll interfaces.
LINKER
The name if the linker to use. By default this is set to link.exe.
Rules
StaticExecutable TARGET : SOURCES : LIBS : DLLS : TARGET_DIRThis rule will build an executable binary. It takes the following arguments:
| TARGET | This is the name of the executable to generate. On windows this will have .exe appeneded to it, if it doesn't already end in .exe. On Linux, the .exe will be stripped off if it exists. |
| SOURCES | This is a list of the sources. The sources can be source files, such as
.c .cpp .l .y. They can be finished
object files ending in .o or .obj.
The source list may also include directories. Directories listed will cause the entire contents of the directory to be treated as source files for this rule. All source files will be passed to the appropriate compiler. All generated files will be written to the currently defined $(BIN_DIR), and will be linked into the final target binary. |
| LIBS | This is a list of libraries to link with. These can be .lib, .dll, .a or .so files. On Linux .a and .so files will be converted to .lib and .dll files respectively. On Windows the opposite conversion will happen. |
| DLLS | This is a list of dynamically linked or shared libraries to link with and to copy to the target directory $(BIN_DIR). Many programs which use .dlls or shared libraries will only run if the libraries can be found in the LD_PATH. By copying these libraries locally it makes the job of testing binaries which link to non-standard libraries ( which may not be found in system library directories ) easier. The only difference between the DLLS and LIBS arguments is the copying step. As such it never makes sense to pass statically linked libraries through the DLLS argument. |
| TARGET_DIR | All generated build files are output to $(BIN_DIR). If TARGET_DIR is set, then the final target file will be written to $(TARGET_DIR) instead of $(BIN_DIR). The same effect can be achieved by setting BIN_DIR on the target, but using this argument is often briefer and more readable. It is adivsable when setting TARGET_DIR that it include $(CURFLAV) or $(BIN_DIR) to avoid problems with different debugging levels. |
This rule will build an executable binary. On Windows it will compile all object files with $(DLL_DEFINES) defined. This is useful when building an executable that can either link statically with a static version of a library or dynamically with a .dll version. On Linux this rule is identical to StateExecutable.
This rule will build a static library. It takes the following arguments:
| TARGET | This is the name of the library to generate. On windows this will have .lib appeneded to it, if it doesn't already end in .lib. On Linux, the it will have .a appeneded to it. |
| SOURCES | This is a list of the sources. The sources can be source files, such as
.c .cpp .l .y. They can be finished
object files ending in .o or .obj.
The source list may also include directories. Directories listed will cause the entire contents of the directory to be treated as source files for this rule. All source files will be passed to the appropriate compiler. All generated files will be written to the currently defined $(BIN_DIR), and will be linked into the final target library. |
| LIBS | This is a list of libraries to link with. These can be .lib, .dll, .a or .so files. On Linux .a and .so files will be converted to .lib and .dll files respectively. On Windows the opposite conversion will happen. |
| DLLS | This is a list of dynamically linked or shared libraries to link with and to copy to the target directory $(BIN_DIR). Many programs which use .dlls or shared libraries will only run if the libraries can be found in the LD_PATH. By copying these libraries locally it makes the job of testing binaries which link to non-standard libraries ( which may not be found in system library directories ) easier. The only difference between the DLLS and LIBS arguments is the copying step. As such it never makes sense to pass statically linked libraries through the DLLS argument. |
| TARGET_DIR | All generated build files are output to $(BIN_DIR). If TARGET_DIR is set, then the final target file will be written to $(TARGET_DIR) instead of $(BIN_DIR). The same effect can be achieved by setting BIN_DIR on the target, but using this argument is often briefer and more readable. It is adivsable when setting TARGET_DIR that it include $(CURFLAV) or $(BIN_DIR) to avoid problems with different debugging levels. |
This rule will build a shared library, either a pair of .dll and .lib on Windows, or a .so on Linux. On Windows it will compile all object files with $(DLL_DEFINES) defined. It takes the following arguments:
| TARGET | This is the name of the library to generate. On windows this will generate a .dll file and a .lib export library file. On Linux, the it will generate a .so file. |
| SOURCES | This is a list of the sources. The sources can be source files, such as
.c .cpp .l .y. They can be finished
object files ending in .o or .obj.
The source list may also include directories. Directories listed will cause the entire contents of the directory to be treated as source files for this rule. All source files will be passed to the appropriate compiler. All generated files will be written to the currently defined $(BIN_DIR), and will be linked into the final target library. |
| LIBS | This is a list of libraries to link with. These can be .lib, .dll, .a or .so files. On Linux .a and .so files will be converted to .lib and .dll files respectively. On Windows the opposite conversion will happen. |
| DLLS | This is a list of dynamically linked or shared libraries to link with and to copy to the target directory $(BIN_DIR). Many programs which use .dlls or shared libraries will only run if the libraries can be found in the LD_PATH. By copying these libraries locally it makes the job of testing binaries which link to non-standard libraries ( which may not be found in system library directories ) easier. The only difference between the DLLS and LIBS arguments is the copying step. As such it never makes sense to pass statically linked libraries through the DLLS argument. |
| TARGET_DIR | All generated build files are output to $(BIN_DIR). If TARGET_DIR is set, then the final target file will be written to $(TARGET_DIR) instead of $(BIN_DIR). The same effect can be achieved by setting BIN_DIR on the target, but using this argument is often briefer and more readable. It is adivsable when setting TARGET_DIR that it include $(CURFLAV) or $(BIN_DIR) to avoid problems with different debugging levels. |
This rule is identical to the SharedLibrary rule, except on Windows this rule does not expect that a .lib export library will be generated. This is useful for .dll files which define no exported symbols. This is sometimes the case for plug-in style shared libraries which are loaded manually by an application.
Creates all directories specified by $(TARGET). The directories are created relative to where KJam is run. $(BIN_DIR) is not appended to the directories. If a deep path is given requiring that a series of intermediate directories be created, those directories will be automatically created also.
Compile a single object file from a single source file. This rule is not normally needed. Usually it is enough to list he desired source files in the source argument to one of the library or executable rules. However it is sometimes necessary to pass special options when generating a single object file. To do this, process the object file using StaticObject, and then pass the resulting object file as a source to the appropriate library or executable rule. For example:
StaticObject special.obj : special.cpp : /DSPECIAL_DEF ;
StaticExecutable myprog : main.cpp special.obj ;
The object file may be specified with the extension .o or .obj, and the extension will be autmatically changed to the
appropriate extension depending on the platform.
This rule operates exactly like StaticObject, except that on Windows $(DLL_DEFINES) will be defined.
Define a non-file pseudo target which will build a set of targets.
| TARGET | This is the name of the pseudo target to generate |
| SOURCES | This is the list of targets which will be generated. |
Group all : lib1 lib2 prog ;
StaticLibrary lib1 : src/lib1 ;
StaticLibrary lib2 : src/lib2 ;
StaticExecutable prog : src/prog : lib1.lib lib2.lib ;
StaticLibrary special : src/special ; // not built unless you specifically ask for it.
This rule will execute KJam in the directory given by TARGET. By default it will build 'all', unless it is called with PROJTARGET set to one or more targets.
| TARGET | The name of the directory of the subproject to build. |
| DEPENDENTS | A list of the targets this subproject depends on. |
| PROJTARGET | This is argument is set, then KJam will build the named target instead of all. |
This rule is useful for making jamfiles which act as drivers for building the contents of other jamfiles. For example, suppose you have several libraries ( lib1, lib2, lib3 ) each in their own project directory, with their own jamfiles to build those libraries. To build those libraries and an application which depends on them:
SubProject lib1 ;
SubProject lib2 ;
SubProject lib3 ;
SubProject app1 : lib1 lib2 lib3 ; // the application depends on
// successful building of the libs
This rule will delete all the files given by $(SOURCES) when the user asks to build the pseudo target given by $(TARGET). By default the built-in rules will configure the clean rule automatically such that it is not usually necessary for users to call this rule directly. If there is a file generated that is not automitically cleaned up, then it may be necessary for the clean rule to be called manually.
This rule is also sometimes useful when multiple clean targets are desired. Suppose for example that in addition to the normal clean target, a clean_binaries target was desired which only removed the final binaries and not the intermediate object files. This could be done like so:
StaticExecutable prog1 : prog1/src ;
StaticExecutable prog2 : prog2/src ;
StaticExecutable prog3 : prog3/src ;
Clean clean_binaries : prog1 prog2 prog3 ;
Now when the user builds clean the binaries and objects are removed, and when they build clean_binaries only the final binaries are removed.