The nTec Build System |
| |
The build system we used in-house at Nanosoft Technologies. |
After some investigation, I found out it relied on an in-house tool called mkhead, which is used to generate header-files. The problem is, this tool needs the NBASE library. While this library is now available, I was originally not in a position to distribute it.
The solution, of course, was to rewrite it so that it no longer did. This tool was later deployed as a replacement for the original mkhead at nTec, and is required to build the headers for NBASE. Python is required:
If you're using Netscape, like me, you may find you have to hold down [shift] while clicking this link. Worse yet, Netscape seems to want to uncompress this file by itself, so if you get mkhead.py instead of mkhead.py.gz, then skip step 1 below.
Go through the following steps:
Go through the following steps:
// Inner example file 1
#ifndef __EX_DEFINED_1
#define __EX_DEFINED_1
//@((sysh)){{
#include <stdio.h>
//@}}
//@((example1)){{
// Some example code goes here
void HelloWorld()
{
printf("Hello World\n");
}
//@}}
#endif // __EX_DEFINED_1
// Main header file. //@READ <example.h> // Include System Headers //@BLOCK ((sysh)) // Define Stuff from example.h //@BLOCK ((example1))
If you can follow this, you notice that there are two exported blocks in
example.h, sysh and example1. The main file is
what is used to generate a headerfile with. It reads the external headerfile
first, and then inserts the two blocks it read into itself. You
run mkhead main.h to get:
// Main header file.
// Include System Headers
#include <stdio.h>
// Define Stuff from example.h
// Some example code goes here
void HelloWorld()
{
printf("Hello World\n");
}
Obviously, you may redirect this anywhere you like. But this is not all that composes the build-system! QuickMake is the other side.
You should not actually place any source files in this directory, although the system is set up to allow it. You should instead make subdirectories with names descriptive of the module being defined inside them. You should also create a directory under src called include, to place your application-specific header files in.
You also have the option of creating a doc directory under your project root to place any documentation in. We will assume that you have done this.
This file is not a template, in fact, you should never edit it. It is a fully self-contained build-system.
You should now place copies of this file in any directory which requires one (in this example, that is the src directory, the doc directory, the src/include directory, and any directories you have defined under src.
These files are named qmake.in, and you need one in every directory where you have a QuickMake makefile. The qmake.in in the project root directory is particularly complicated, so we treat that one specially. For now, concentrate on the other ones.
In the src directory, you need to create a qmake.in file like the following:
SRCDIR=(all the directories you added) SUBDIR=include
In each of your source subdirectories (under src), you will need a qmake.in that looks like the following:
SRC=(all the source files you have in this directory)
In src/include, you will need a qmake.in that looks like the following:
HEADERFILE=top.h FILE=(all the header files in this directory)
If you are using QuickMake to build a program, you should omit this line, and thus should not create a top.h file.
The FILE directive is used to specify non-source files used by the project. This is very important when you are using QuickMake to package your project for release, although it makes little difference normally. Thus you should always doublecheck your FILE directives before you package, or your package may not function.
The last place you will need a non-root qmake.in is in doc. This is where you place all your documentation. The file there should look something like this:
DOC=(all the doc files in the directory)
Here we will use an example. This is the root qmake.in from a personal project of mine, the ZAZZ Widget Set, which would have eventually found its way onto this site, but I stopped developing it a while ago...
# toplevel makefile input SUBDIR=doc CC=gcc CFLAGS=-pipe -O0 -mpentium -Wall -g LFLAGS=-pipe -O0 -mpentium -g INCLUDELOCAL=include HEADER=zazz.h MINORVER=0.1 MAJORVER=0 LIB=zazz INSTALLLIB=/usr/lib INSTALLH=/usr/include TARBALL=zazz-0.0.1.tar.gz FILE=zazz.spec
The SUBDIR directive serves the same function it does in src, to identify directories that need to be built, but do not contain source files. Documentation, found in the doc directory, certainly does not contain sources, but it needs to be included in the final packaging.
The CC directive simply sets your C compiler. You actually should be able to omit this if you want, I used to use "color-gcc" as my compiler for a while, since it gave me nice colorful error messages. Be warned that QuickMake expects to be using some form of gcc, and may fail if you use a compiler that does not perfectly conform to gcc's calling conventions.
The CFLAGS and LFLAGS directives specify the C compiler flags and final linker flags, respectively, used when building the project. These are some pretty typical debugging flags (see the gcc docs for details).
The INCLUDELOCAL directive tells QuickMake where your application-specific include files are located, relative to src. This is almost always identical to what is listed here.
The HEADER directive tells QuickMake to build a main headerfile using mkhead. Note that this is really only for building libraries (which ZAZZ certainly is). If you are building an executable, leave this out.
The MINORVER and MAJORVER directives specify the major and minor versions of your project. While currently these are only truly important for library builds, you should include them in any project, since future versions of QuickMake may require them for other things.
The LIB directive tells QuickMake to build a shared library and
static library file from the sources. This is very obviously only applicable
to projects making library files, and you should omit this if you are making
an executable file.
NOTE that the equivalent for executable files is LINKFINAL, which
causes an executable file to be built from the sources. The syntax is
otherwise identical.
The INSTALLLIB and INSTALLH directives set the directories to install libraries and main headerfiles into. Obviously this is only for libraries, and the equivalent for executable-file builds is INSTALLBIN, which specifies the install directory for an executable file.
The TARBALL directive specifies the name of a file to build when making a final distribution package. This should be specified whenever you want to build tarballs or rpms using QuickMake.
The final FILE directive tells QuickMake about an important non-source file, an RPM .spec file in this case. If you write such a .spec file for your project, you can use QuickMake's automatic RPM generator.
| All material on these pages is Copyright (c) Jennifer E. Elaan. |
|