0

I'd like to switch to using Jam as my build system. Currently, I have a src, include and build directories and I'm wondering how I can get Jam to put object files in the build directory and search for include files in the include directory.

Tom Leese
  • 17,977
  • 11
  • 41
  • 65

1 Answers1

3

Good for you for using Jam! I think you'll find it a lot easier than makefiles, once you get past a few of its oddities.

What you are asking about is a setup I have often used. At the top level, I have three directories: src, inc, and build. There is also a file called Jamfile:

# top-level Jamfile
SubDir . ;
SubInclude src ;
SubInclude build ;

The SubDir line establishes the location of this file within the directory structure, and seems to be necessary for Jam to work. (I think Jam could have been designed to not need it, but there it is, so be it.) The SubInclude lines tell Jam to include two subdirectories. The inc subdirectory is not included because there is nothing there that needs to be compiled directly; all its contents will be included by other files.

Within inc, I have a header file called header.h:

/* header.h */
#define MESSAGE "Hello world!"

Within src, I have the source of the main program, main.c:

/* main.c */
#include "header.h"
#include <stdio.h>

int main(int argc, char** argv)
{
    printf("%s\n", MESSAGE);
    return 0;
}

Also within src is another Jamfile with these contents:

# src/Jamfile
SubDir .. src ;
HDRS += ../inc ;
Library helloworld : main.c ;

The SubDir line locates the Jamfile within the directory structure. The HDRS line tells Jam where additional headers can be found (it will pass this on to the compiler when the time comes). Note the use of the += operator, which appends to an existing variable. The Library line tells Jam to build a library out of main.c (yes, a library with a main() is a little weird, but OK on a small project like this).

Within build is a single Jamfile:

# build/Jamfile
SubDir .. build ;
Main helloworld ;
LinkLibraries helloworld : helloworld ;
SubInclude .. src ;

The SubDir line locates the Jamfile within the directory structure. The Main line tells Jam to build an executable called helloworld. Note that it has no source file dependencies. If it did, it would look like Main hello world : foo.c ;. The LinkLibraries line tells Jam to link the helloworld executable with a library, also called helloworld. It is OK in this case that the executable and library have the same name, but in a real program you might want to give them different (and better) names. The SubInclude line tells Jam to look in the src directory for more code to build. This is how the dependency between the executable and the library gets resolved. It is important that this line come last.

Now, if you navigate to the build directory and execute the jam command, Jam will build a helloworld.a file in src, and link it into a helloworld executable in build.

Because all the code in src is being compiled into a library, there are no .o files left over. They are all stored inside the .a file, which is an archive, after all. If you have additional source files in build (like the hypothetical foo.c mentioned above), then you would have .o files left over in the build directory after compiling.

Good luck with all this. I learned most of what I know about Jam from the Perforce website and through experimentation. The main Perforce page for Jam is here.

Randall Cook
  • 6,320
  • 4
  • 28
  • 65