Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
116 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

KJam - a new build tool for game development


Getting Started with KJam

So how do you get started using KJam? First download the binaries. They are currently available for Windows and Linux.

KJam comes configured with a standard set of build rules for c and c++ projects. For many simple projects it is possible to get started using KJam in just a few minutes by writing some very simple, yet surprisingly powerful Jamfiles. For larger projects, or to support custom tools you will need to write your own custom build rules. For now, the fastest way to try KJam is to use the default build rules.

Suppose you have a directory called src full of .cpp source files that you want to build into an application called myprog. You would create a file called jamfile with the following contents:

StaticExecutable myprog : src ;

To build myprog, run KJam in the same directory as the jamfile ( by typing kjam ). KJam will create an output directory, bin for all the generated files. It will search the directory src for source files. It will process any .l and .y files that it finds though flex and bison. It will scan all source files for #include statements and generate dependencies. It will compile all the .c and .cpp files it found or created. And finally it will link all the resulting object files into a binary.

Even though KJam does a full dependency analysis of your sources before every run, it will start building even very large projects almost immediately. KJam is extremely efficient.

This same jamfile should work without modification under Windows or Linux. The generated files will be stored in a directory under bin which specifies the platform and the debugging level.

If your machine has multiple processors, KJam will figure out which build steps can be safely done simultaneously and take advantage of them. If your compiler supports batched building (like MSVC does ) KJam will build sources in batches.

KJam will detect the width of your shell, and format all the output neatly for easy readbility. And even though many build steps will happen simultaneously, KJam will a not allow output from different steps to be interspersed.

Invoking Rules

Suppose you don't want to build every source file in a directory, but would rather name your source files specifically. You can write your jamfile like this:

StaticExecutable myprog : src1.cpp src2.cpp src3.cpp ; 

To build a library you use the StaticLibrary rule:

StaticLibrary mylib : src1.cpp src2.cpp src3.cpp ; 

To build a .dll or a shared library use the SharedLibrary rule:

SharedLibrary mylib : src1.cpp src2.cpp src3.cpp ; 

Under Windows this will create a .dll and its associated export library. Under Linux this will create a .so file. All the details of how to do that on each platform are dealt with for you - portably. The target names do not have to deal with non-portable file extensions like .dll and .so.

To build a program that links with a library, just list the libraries at the end of the rule:

StaticLibrary lib1 : lib1/src ;
StaticLibrary lib2 : lib2/src ;
StaticExecutable myprog : myprog/src : lib1.lib lib2.lib ;

The .lib extension helps KJam to know that you want to link with a static library instead of a dynamic library. But the extensions are portable between Windows and Linux. Under Linux, KJam would link with lib1.a and lib2.a. And if you had passed in lib1.a then under Windows KJam would have automatically converted it to lib1.lib.

You can also easily link with a shared library:

SharedLibrary lib1 : lib1/src ; 
StaticLibrary lib2 : lib2/src ; 
StaticExecutable myprog : myprog/src : lib1.dll lib2.lib ;

Under Windows, KJam will figure out that it needs to look for an export library. Under Linux, it will look for a .so shared library. The user does not have to worry about these non-portable details. KJam will even figure out all the dependencies between these different targets automatically.

By default when you run KJam without any arguments it will try to build the target all, which will build all the targets that have been declared using the above rules. So in the case of the previous jamfile, it would build lib1, lib2 and myprog.

To build only a subset of the declared targets you can declare a Group target:

SharedLibrary lib1 : lib1/src ;
StaticLibrary lib2 : lib2/src ;
StaticExecutable myprog : myprog/src : lib1.dll lib2.lib ;
Group libs : lib1.lib lib2.lib ;

Now when you ask it to build libs, it will only build lib1 and lib2. To exclude a target from the defauilt all target, declare your own all group listing the targets you want. This will override the automatically created all target:

SharedLibrary lib1 : lib1/src ;
StaticLibrary lib2 : lib2/src ;
StaticLibrary special : lib2/src ;
StaticExecutable myprog : myprog/src : lib1.dll lib2.lib ;
Group all : lib1.lib lib2.lib myprog.exe ;

Now when you run KJam with no arguments, it will not build the library special. To get that you would have to ask for it specifically by running kjam special.

These simple jamfiles automatically create clean targets. So if you want to clear out all the generated files just run kjam clean.

Setting Variables

The operation of the built-in rules can be modified by setting variables.

By default KJam will search for header files wherever it finds source files. If you would like it to use headers found in other directories, say the headers for an external library, set the INCLUDE_DIRS variable:

INCLUDE_DIRS = ../otherlib/src ;
StaticExecutable myprog : src ;

By default KJam will look for libraries to link with in the default output directory, and in the default system library directories. To add more places to look for libraries to link with, use the LIB_DIRS variable:

INCLUDE_DIRS = ../otherlib/src ; 
LIB_DIRS = ../otherlib ; 
StaticExecutable myprog : src : otherlib.lib ;

KJam will automatically chose a reasonable set of build flags when running your c compiler. To add additional build flags use the CCOPTS variable.

To add extra link options use the LINKOPTS variable. The new options will be added to every compile or link:

CCOPTS = /DSPECIAL ; 
LINKOPTS = -lspecial ;
StaticExecutable myprog : src ;

To change the output directory set BIN_DIR. By default BIN_DIR is set to bin/$(PLATFORM)/$(CURFLAV). You can set this to anything you want, though it is highly recommended that BIN_DIR always include $(CURFLAV) or $(BUILD_CODE), to avoid problems with mixing generated files built with different debugging levels. So for example if you want to have all your generated files go to a special directory shared by all projects, instead of a local one, and you don't care about multiple platforms, you might set BIN_DIR this way:

BIN_DIR = ../shared_bin/$(CURFLAV) ;

These variables can also be set on a per target basis using the on keyword. For example to add special link options to just lib1:

LINKOPTS on lib1.a = -lspecial ; 
StaticLibrary lib1 : lib1/src ; 
StaticLibrary lib2 : lib2/src ; 
StaticLibrary lib3 : lib3/src ;

To build targets with special compilation options, you can use the StaticObject rule. For example in the following case only special.cpp is built with the extra flags:

StaticObject special : special.cpp : /DSPECIAL ;
StaticExecutable myprog : special.obj src1.cpp src2.cpp src3.cpp ;

Notice that when you need to, you can pass compiled object files as sources.

The built-in Jambase supports building targets at different optimization levels. You can do this by setting the CURFLAV variable. Set this variable in the environment. On Linux remember to export it. There are 4 levels, release, optimized, debug and extra_debug. At each setting the output files will go to their own directory, to avoid mixing output files built with different compiler flags.

KJam can also build projects with platform specific source files. Suppose you have a project with one or more source files which are different on Windows and Linux. Simply create linux and win32 subdirectories in the directory where source files would normally be found, and put the platform specific source files in each directory. KJam will build the appropriate sources for the platform.





Managing Sub-Projects


Contents
  Introduction
  Getting Started with KJam
  Managing Sub-Projects

  Printable version
  Discuss this article