Jam is a software build tool. It is an alternative the the GNU make tools. Jam was written by
Jam includes an interpreted procedural language to define the rules and actions processed by Jam. The Jam language is case sensitive. Jam uses these rules (from a Jamfile or a group of Jamfiles) to define how Jam should build a set of targets, which can be object files, libraries, or executables.
Jam's features include automatically generating C & C++ header dependencies, eliminating the necessity to declare header or object files in the Jamfile.
While no prior knowledge of Jam is assumed, a basic understanding of the C++ language and the GNU toolchain and a working knoledge of the bash shell is reccomended.
First of all Jam needs to be installed on your system.
# emerge dev-util/jam
The next step is to create a small set of files to test the build process.
#include <iostream> using namespace std; int main (int argc, char *argv[]) { cout << "hello world" << endl; }
C++ = g++ ; LINK = $(C++) ; Main hello : hello.cc ;
$ jam ...found 11 target(s)... ...updating 2 target(s)... Link hello Chmod1 hello ...updated 2 target(s)...
$ ./hello hello world
$ jam clean ...found 1 target(s)... ...updating 1 target(s)... Clean clean ...updated 1 target(s)...
You can remove the object and executable files by typing
#ifndef _MYTOOLS_ #define _MYTOOLS_ #include <string> namespace std { void whatever (string s); } #endif
#include <iostream> #include "mytools.h" using namespace std; void std::whatever (string s) { cout << "whatever [" << s << ']' << endl; }
The new header file needs to be included, and the procedure
#include <iostream> #include "mytools.h" using namespace std; int main (int argc, char *argv[]) { cout << "hello world" << endl; whatever ("test"); }
The file
C++ = g++ ; LINK = $(C++) ; Main hello : hello.cc mytools.cc ;
The executable may now be built as normal.
The header file
#include <iostream> #include <math.h> #include "mytools.h" using namespace std; void whatever (string s) { cout << "whatever [" << s << ']' << endl; cout << "atan (1.0) = " << atan (1.0) << endl; }
The math library
C++ = g++ ; LINK = $(C++) ; LINKLIBS += -lm ; Main hello : hello.cc mytools.cc ;
Run Jam with the
$ jam -an ...found 29 target(s)... ...updating 3 target(s)... C++ hello.o g++ -c -o hello.o -O hello.cc C++ mytools.o g++ -c -o mytools.o -O mytools.cc Link hello g++ -o hello hello.o mytools.o -lm Chmod1 hello chmod 711 hello ...updated 3 target(s)...
Two rules,
The SubDir rule identifies the directory which contains a Jamfile. At the root of the tree containing Jamfiles there should be a
The SubInclude rule causes another Jamfile to be read in. Typically the Jamfile in the root directory (where the Jamrules file is) will contain a SubInclude rule for each subdirectory one level down. Multiple levels of subdirectories may be managed by writing SubInclude rules for a particular directory in the Jamfile of the parent directory, rather that putting all of the SubInclude rules in the Jamfile in the root directory.
An environment variable should be used to define the root of the directory tree which contains Jamfiles. In this guide the variable
export JAMR=~/jam
An example directory structure may be set up with the following commands:
$ mkdir $JAMR $ cd $JAMR $ mkdir main tools
The files
The Jamfile in the JAMR directory should be as follows:
SubDir JAMR ; SubInclude JAMR tools ; SubInclude JAMR main ;
The Jamrules file belongs in the JAMR directory. Here are the rules for variables which are commonly referenced by the individual Jamfiles.
The Jam language assigns values to strings in a fashion similar to that of the bash shell. Here the string variable
Echo "Parsing Jamrules" ; C++ = g++ ; LINK = $(C++) ; TOOLS = $(JAMR)/tools ;
The Jamfile in the tools subdirectory uses the Objects rule to specify that only the compilation of the object file is desired.
SubDir JAMR tools ; Objects mytools.cc ;
The Jamfile in the main directory refers to the tools directory for a dependecy. The HDRS variable is a list of directories that the compiler will search for header files, and must include the tools subdirectory in this case.
SubDir JAMR main ; HDRS += $(TOOLS) ; Main hello : hello.cc $(TOOLS)/mytools.cc ;