Sidebar: Makefile customization


Back to
lesson 0

Introduction

Philosophy

This document describes the makefiles provided in the GLOW tutorials. This material is not really necessary to understand GLOW, especially if you prefer to use your own makefile. But if you prefer to just use the provided makefiles, and your environment is significantly different from mine, you may need some of this information.

My makefile is designed with two goals. (1) To automate as much as possible the handling of dependencies. (2) To allow construction of makefiles that can be used across platforms. For most cases, then, it is sufficient to configure a makefile just once, and reuse it for different OS's, environments, debug/nodebug, etc.

Usage

Once you have configured a makefile, just invoke it with "make" (or "gmake" depending on how gnu-make is installed on your system). If you give it no argument, it will do a complete build, or you may give it arguments as listed below:

gmake all
gmake <program name>
Does a complete build, including updating dependencies.
gmake depend
Only updates dependencies.
gmake clean
Cleans the entire object directory, including dependencies, object files, and template instantiation information.
gmake cleanobjs
Cleans only object files.
gmake cleandeps
Cleans only dependency files.
gmake info
Prints out information on the makefile's configuration.

Configuration basics

To configure a makefile for your project, you need to do three things. First, define a set of symbols describing your project. And next, include the file "glow_base.Makefile" in the glow_src directory, by inserting this line at the end:

include $(GLOWDIR)/glow_base.Makefile

Finally, you should specify whether you want to compile in debug or no-debug mode. No-debug is the default. You specify debug mode by creating a file called ".glowmake.DEBUG" in your build directory.

Here are a list of the symbols you should define. Some of them have default values; if you do not define these symbols, the default will be used. Others do not have default values. Those symbols are required (and are listed below in boldface).

PROG
This symbol should be set to the name of the final program to generate. It has no default; the makefile will throw an error if it is not specified.
SRCDIR
This symbol should be set to the path to the directory containing your source .cpp files. The suffix needs to be .cpp (sorry). If you are compiling into the same directory as your source, you may use the current directory "." for this symbol. There is no default.
GLOWDIR
This symbol should be set to the path to the glow_src directory. The makefile looks for all of GLOW's files in this directory. There is no default.
MODULES
This symbol should be set to a list of modules to compile for your project. These should be your source files WITHOUT the .cpp extension. There is no default.
GLOWMODULES
This symbol should be set to a list of virtuoso GLOW modules to compile for your project. Again, these should be specified WITHOUT the .cpp extension. There is no default.
COMPILE
This symbol should be set to the command for compile. For example, under Linux, you should probably set this to "gcc". There is no default.
LINK
This symbol should be set to the command for link. You should also include the appropriate -o flag (or equivalent directive) for specifying the name of the binary to generate, if it isn't present in LDFLAGS. For example, under Linux, you should probably set this to "gcc -o myprogram". You could also set this to "ar crs mylibrary.a" to create an archive file. The default setting is equal to "$(COMPILE) -o $(PROG)", which should be adequate for generating normal executables.
SHELL
This symbol should be set to a good shell to use. The dependency generator uses this. The default is "/bin/sh".
LIBS
This symbol should be set to a list of libraries to link with your project. For example, with IRIX/MIPSPro, a good value is "-lglut -lGL -lGLU -lX11 -lXmu -lXext -lCio -lm". The default is the empty list.
DEBUGLIBS
This symbol should be set to a list of additional libraries to link with your project when compiling in debug mode. (These are appended to the LIBS value.) The default is the empty list.
NODEBUGLIBS
This symbol should be set to a list of additional libraries to link with your project when compiling in no-debug mode. (These are appended to the LIBS value.) The default is the empty list.
CFLAGS
This symbol should be set to the compiler flags that should be used. This includes optimization options, warning options, -I directives, -D directives and other directives. The default is the empty string.
LDFLAGS
This symbol should be set to the linker flags that should be used. This includes -L directives and other options. The default is the empty string.
DEBUGCFLAGS
This symbol should be set to any additional compiler flags that should be set when compiling in debug mode. (These are appended to the CFLAGS value.) This should include -DGLOW_OPTION_DEBUG, and may also include -g, less aggressive optimization options, and other debugging-related options. The default is "-DGLOW_OPTION_DEBUG".
NODEBUGCFLAGS
This symbol should be set to any additional compiler flags that should be set when compiling in no-debug mode. (These are appended to the CFLAGS value.) This may include -DNODEBUG, and also may include more aggressive optimization options. The default is "-DNODEBUG".
DEBUGLDFLAGS
This symbol should be set to any additional linker flags that should be set when compiling in debug mode. (These are appended to the LDFLAGS value.) The default is the empty string.
NODEBUGLDFLAGS
This symbol should be set to any additional linker flags that should be set when compiling in no-debug mode. (These are appended to the LDFLAGS value.) The default is the empty string.
DEPFLAGS
This symbol should be set to the flag that should be passed to the compiler to tell it to make only dependencies. Typically this is "-M" (which is the default value.) For gcc, however, a better value to give is probably "-MM", which ignores system headers.

Specializing configuration

The makefile provides facilities for customizing the configuration based on the operating system or environment. I call these two facilities architecture specializations and file-option specializations. Architecture specializations allow you to customize based on the architecture. (Or techincally, the value returned by the unix command "uname".) File-option specializations allow you to customize based on the existence of files that you can create in your build directory.

Architecture specializations

Architecture specializations allow you to specify different configurations depending on the architecture. This can be useful if you're developing in a multiplatform environment and want to work from the same source code base. For example, I develop on a cluster that includes both SGI IRIX workstations and x86-based Linux workstations. Under these two environments, the compiler used is different (CC on IRIX, gcc on Linux), and so are the libraries and CFLAGS necessary to build my programs.

To handle this case without having to keep separate makefiles, you can give an architecture specialization for any of the makefile symbols. To do this, define a symbol named <symbol-name>_<uname>. This value will be used in place of the normal <symbol-name> value if calling the unix command "uname" returns <uname>

For example, in my case, I need the compiler to be set to CC under uname IRIX, and gcc under uname Linux. So my makefiles could include these two lines:

COMPILE_IRIX=CC
COMPILE_LINUX=gcc

But that's not quite how my makefile is set up. Defining a symbol without the architecture specialization provides a default value. This value is used for any platform whose uname does not match any of the provided specializations. So if you wanted to use gcc for EVERY platform except IRIX, you would give gcc as the default, and provide CC as a specialization for IRIX. This is how my makefile actually looks:

COMPILE=gcc
COMPILE_IRIX=CC

Now, if you compile under IRIX, it will use CC, but if you compile under anything else, like Linux, FreeBSD, Solaris, etc., it will use gcc.

Any symbol can carry an architecture specialization. If you look through the makefiles provided in this tutorial, you'll see the defaults set up for gcc, with an IRIX specialization for COMPILE, LIBS, DEPFLAGS, CFLAGS and LDFLAGS.

File-option specializations

File-option specializations allow you to specify different configurations depending on the existence of files in your build directory. This lets you build different versions of your program (such as debug and non-debug versions) using the same makefile.

A file-option is triggered by the existence of a file named ".glowmake.<option-name>" in the build directory. If such a file exists, the file-option is said to be triggered. The makefile doesn't actually read the file or care what is in it; just so long as it exists (i.e. you can just create it using the unix command "touch".) You may trigger multiple file-options for a particular build.

There are three special file-options that are handled specially by the makefile: DEBUG, STRIP and GLOWLIB. If DEBUG is triggered, then the makefile will build a debug version, using the debug versions of some of the symbols (such as CFLAGS). If STRIP is triggered, the makefile will run "strip" on the final binary after the build is completed. If GLOWLIB is triggered, the makefile will not compile the GLOW sources, but instead attempt to use an existing GLOW library archive or shared library. If DEBUG is triggered, the makefile will look for libglowdebug.a or libglowdebug.so. If DEBUG is not triggered, the makefile will look for libglow.a or libglow.so.

You may, however, also define your own file-options, and then make specializations of the makefile symbols for when those file-options are triggered. This is handled a little differently from architecture specializations, in that it makes a distinction between two kinds of makefile symbols.

Makefile symbols that specify just one value handle file-options in the following way. You may provide a specialized symbol <symbol-name>_<file-option>, only for the FIRST file-option provided (in alphabetical order). If such a symbol specialization is provided, the symbol overrides the default symbol. Symbols that support this kind of file-option specialization are PROG, SRCDIR, VSRCDIR, COMPILE, LINK and SHELL.

For example, suppose you have created files ".glowmake.OPTIONA" and ".glowmake.OPTIONB". If you provide a specialized symbol "PROG_OPTIONA", then this will override the default PROG symbol, and give a name for this specialized version of your program. However, if you attempt to define the symbol "PROG_OPTIONB", it will be ignored because OPTIONB is not the first file-option in alphabetical order.

For these symbols, you may provide both file-option specializations and architecture specializations. For example, "PROG_IRIX_OPTIONA" can specify the name of the program if compiled on uname IRIX, with file-option OPTIONA triggered. If a symbol with both specializations is given, the architecture name must precede the file-option name in the symbol's name (i.e. PROG_OPTIONA_IRIX is incorrect). In general, more specialized symbol names will override more general names, and giving only a file-option specialization will override giving only an architecture specialization.

The second type of file-option specialization is for makefile symbols that specify a list of values, such as MODULES. In these cases, all provided file-option specializations (not just the first) are appended to the default value for the symbol. For example, if you have the file-options "USEGAMMA" and "USEWAVELET" triggered, and you include the specializations:

MODULES_USEGAMMA=gamma
MODULES_USEWAVELET=wavelet

...then the modules "gamma" and "wavelet" (i.e. gamma.cpp and wavelet.cpp) will be added to the list of modules to compile. Symbols that support this type of file-option specialization include MODULES, VMODULES, CFLAGS, LDFLAGS, DEBUGCFLAGS, NODEBUGLDFLAGS, DEBUGLDFLAGS, NODEBUGLDFLAGS, LIBS, DEBUGLIBS and NODEBUGLIBS.


Back to
lesson 0


The GLOW Toolkit