In order to build a client program, you need to specify pretty many compiler
options. Usually, such lengthy commands are stored in a special file Makefile. Then the
compiler can be invoked via short calls of the make utility, which greatly saves your keyboard
and fingers. Moreover, make examines the time stamps of the source code and included header files,
so it rebuilds automatically your clients as soon as it sees something got changed.
Unfortunately, the syntax of the Makefile itself is not for the fearful beginners. Therefore, we
offer rather elaborated Makefile building blocks, which enable the most common client building schemes.
We start the explanation with a simplest case, requiring only a two-line Makefile:
Each client program is built from a single source file, having the same stem name and either .cc
or .C suffix. The executable files are kept in the same directory as the sources. Then the following
ultra-short Makefile will suffice:
ExtendApp := application
include Polymake_Installation_Top_Directory/Makefile
Specifying the application is necessary for the clients to find the correct application-specific header files and libraries.
If your polymake installation is made for several hardware platforms, you must choose the appopriate platform-specific
top directory in the include statement, depending on the type of computer you are working with.
Or, provided a regular naming scheme for the platform-specific directories, you can ask make to choose
it automatically, e.g. this way:
Arch := $(shell uname -m)
include Polymake_Installation_Top_Directory/$(Arch)/Makefile
Note: this naming scheme is only a suggestion, that of your installation
may look entirely differently!
Now let's discuss more complicated settings. You may choose to keep the sources apart from the binaries (a good idea anyway.)
The Makefile has always to reside in the build directory, together with binaries. Thus, you must specify the path
from the build to the source directory:
SourceDir := relative_or_absolute_path
include ...
The most probable variants src, .. , and ../src are checked automatically, so if
you choose one of these names, you don't need the SourceDir assignment.
A client program is assembled from several modules. You must create another tiny file, Makefile.inc, but
this time in the source directory. It should contain following lines:
The last line should collect all additional modules belonging to all clients. The client and module are stem names,
without .cc, .o, or other suffixes.
$(suffix) and $O must be appended verbatim to each client (module) name.
These variables contain an extra suffix if any debugging compile mode is chosen; see various Debug=...
settings below.
The same setting as above, but none of the component modules has the same stem name as the client program.
Such clients must be listed in a separate line in Makefile.inc:
NoPrimaryModule := client_name ...
Some additional modules have to be included in almost all clients. Then it is much easier to bundle such modules into
a library than to specify them as extra modules for each client.
The following line goes again into Makefile.inc:
LibModules := module_name ...
The library modules must not be listed in ExtraModules.
You need to specify some compiler and/or linker options additionally to those used to compile polymake itself.
Then you can store them in Makefile.inc:
The library built from LibModules is treated automatically, you don't need to add any options for this.
Additional compiler and/or linker options should have effect only for some specific clients or library modules.
This can be expressed using a new make feature of pattern-specific variables, in Makefile.inc:
Having prepared the Makefile this way, you can ask make to carry out various tasks:
make
make all
Build all client programs. The highest compiler optimization level is on,
plausibility checks are disabled.
make client_name ...
Build the specified client programs.
make ... Debug=y
Build the client programs with enabled plausibility checks
and symbolic information for debugging. The binary files produced will have a suffix -d.
Hint: if you are going to test your client program with valgrind and
your compiler is gcc, you will increase the probability of error discovery by setting and exporting an enviroment variable
GLIBCXX_FORCE_NEW=1. This will disable the pool memory allocation used in polymake by default, see also
C++ runtime library documentation.
Don't forget to revoke this setting when you are doing real problem computations, as it incurs rather high performance loss.
make ... Debug=profile [Profile=detailed]
Build the client programs prepared for run-time profiling (see gprof(1) documentation about details.)
The binary files produced will have a suffix -p. Profile=detailed disables
function inlining, which makes the profile much more fine-granulated, but the total performance worse;
however, the rest compiler optimization is still on.
make ... Debug=timing
Build the client program with full optimization; define a preprocessor symbol POLY_TIMING.
You may write code fragments protected by this symbol, for example, creating a stopwatch object
at the beginning of the computation and printing the elapsed time at the end. The binary files will have
a suffix -T.
make ... Debug=opt
Build the client programs optimized but also with symbolic information for the debugger.
These monsters are sometimes needed when chasing for compiler optimization bugs.
The binary files produced will have a suffix -dO3, unless you change the default optimization level.
make ... CXXFLAGS=... LDFLAGS=... CXXDEBUG=... CXXOPT=...
Override the settings stored in the Makefile. CXXFLAGS and LDFLAGS can contain additional
compiler and linker options, as explained above.
CXXDEBUG controls the generation of symbolic information for the debugger;
the default setting is -g, which is OK for gdb.
CXXOPT specifies the optimization level; the default setting is -O3, unless it was
changed during the polymake installation.
make install [ client_name ... ]
Copies all (or only specified) clients to a proper location within the polymake installation tree,
where they can be found by the rules (provided you have the write access permission there.)