7. Compiling and Porting TCM
Keywords: TechDoc

Next: 8. Wish List and Up: Toolkit for Conceptual Modeling Previous: 6. Output Files
Subsections

- 7.1 Compiling TCM
  - 7.1.1 Compilation configuration files
  - 7.1.2 Makefiles
- 7.2 Porting TCM
- 7.3 G++ specific problems

#
7. Compiling and Porting TCM

Before you start compiling or porting TCM you first have to unzip and untar the source code distribution in the same manner as the executable distribution. See then the file `$TCM_HOME/INSTALL` which contains the most up-to-date installation instructions. See chapter 3 for what files are included. Make sure that before compilation the `TCM_HOME` environment variable is set to the directory where the distribution resides (the ``root'' directory of the entire distribution, not the src directory!).

The TCM directory tree contains a set of Makefiles and configuration files. The `Makefile` in the src directory should be a symbolic link to `Makefile.compiler`. `Config.tmpl` should be a link to `Config.tmpl_platform`. `src/Makefile` contains the targets specific for some compiler (g++, Sun CC, etc.) and `Config.tmpl` contains settings for the system. For each operating system to which TCM has been ported (Linux, Solaris, HP-UX, etc.) a distinct Config.tmpl file is supplied. The default make targets are in `src/Makefile.GEN` and the default settings of the various Config.tmpl files are in `src/Config.GEN`.

# 7.1 Compiling TCM

The most simple way to compile and install TCM is to type `make` for the Makefile in `$TCM_HOME`. This default target will set the right links for the `src/Makefile` and `src/Config.tmpl` and then it will write to standard output what are the following targets that you can build. Of course it wise to check the setting of `src/Config.tmpl` yourself first before you continue. The next possible targets are:

- `make depend`, for making file dependencies.
- `make execs`, for making the object libraries and binaries and then move them in the `lib` and `bin` directories respectively.
- `make install`, for copying the binaries and all the other files of a binary distribution to the directory where you would like to install TCM. `/opt/tcm` is the default directory but that can be changed in the Makefile by setting `TCM_INSTALL_DIR`.
- `make all`, which is the same as `make depend execs install`.
- `make docs`, which tries to (re)generate all documentation in HTML, PostScript and PDF format in the `doc` subdirectory. This works only of course if you have installed the document sources in `docsrc`.
- `make clean`, which removes all binaries, object and temporary files.

Instead of `make install` you can also call the scripts `mkbindist` or `mksrcdist` to build a tar.gz file with the binaries and the source code respectively. They were treated in chapter 3.2.

For compiling TCM you can also go directly into the src directory. There you are able to build individual editors and individual libraries. As usual, compilation is controlled by a set of Makefiles. In the src directory there are a number of configuration files and Makefiles.

## 7.1.1 Compilation configuration files

The configuration files in the `src` directory are called `Config.tmpl_suffix`, one for each of the different platforms (platform as file name suffix). There is a file called `Config.GEN` which contains reasonable default values and is included in the Config.tmpl files. The configuration file defines which compiler is used, the compiler flags, the location of the Unix and X include files, the needed Unix and X libraries and their locations. Ideally, this is the only file you need to tailor for compiling TCM on a Unix system. To compile TCM you also need `lex` and `yacc` (or the GNU variants `flex` and `bison`). The files that are generated have to be compiled by an ordinary C compiler. Therefore, define in Config.tmpl, `LEX`, `YACC` and `Cc`. Before compiling TCM, make a symbolic link called `Config.tmpl` to the configuration file of the desired platform. The declarations in the `Config.tmpl` will be included in the Makefiles.

Configuration options consist of `Variable name = Value`. To append a value to a variable name you can use `+=` instead of `=`. A value can contain the contents of a variable that was defined before, by using the notation `$(variable name)`. The following configuration options can be set:

- `CC`. This is the C++ compiler. This is `/usr/bin/g++` by default.
- `Cc`. This is the C compiler. This is `/usr/bin/gcc` by default.
- `CFLAGS`. These are the flags given to the C++ compiler. By default these are `-Wall -pedantic`. You can add compiler-specific options for C++ templates, optimizing options or add the option `-g` to add debugging information.
- `INCLUDEDIRS`, the system include directories (-I flags) for the compiler.
- `LD_FLAGS`, the library flags (-L and -R flags) for linking.
- `LD_LIBS`, the libraries against which TCM is linked.
- `LEX`, the (f)lex lexical analyzer.
- `MKDEPEND`, the command that is called for `make depend`.
- `MKDEPENDFLAGS`, the flags for `make depend`.
- `MOTIF_HOME`, the directory where Motif or LessTif is installed.
- `STRIP`, the Unix command to strip binaries. When you don't want to strip (because debugging information would be lost), set it to `/bin/echo`.
- `SHAREDFLAG`, special compiler flag, such as `-shared` or `-G`, to generate shared object libraries.
- `SYSFLAGS`, a number of TCM-specific flags for the compiler:
  - `-DLINUX`, `-DSOLARIS`, `-DIRIX`, etc. Set this to the target operating system.
  - `-DLESSTIF`. Set this if you compile with LessTif, don't set it if you use Motif.
  - `-DDEBUG`, `-DDUMPWINDOWTREE`, output some debugging information.
- `XWIN_HOME`, the directory where X windows is installed.
- `YACC`, the yacc, compiler compiler.

## 7.1.2 Makefiles

The main Makefile contains the rules for how to build the libraries and the executables in the subdirectories. Per type of compiler there is a distinct Makefile. They are called `Makefile.suffix`. The default make targets are in the file `Makefile.GEN` and it's included in the other Makefiles. Before compiling TCM, make a symbolic link called `Makefile` to the Makefile of the desired compiler. Each src-subdirectory has its own Makefile which is platform- and compiler-independent. If everything goes normal they need not be changed when TCM is recompiled or ported.

The Makefile in the src directory has the following top-level targets:

- `make` or `make all`. Compiles the entire distribution (default compilation).
- `make allx`. Force compilation into a few executables (i.e. all diagram editors and all table editors are each compiled into a single executable). This is the default for `g++`. You can create the needed symbolic links for the different editors with the script `$TCM_HOME/bin/linkx`
- `make ally`. Force compilation into some more executables than `allx`. Related tools such as all data view editors are compiled into one executable. The individual tools have to be soft links, that can be made with the script `$TCM_HOME/bin/linky`
- `make allz`. Force compilation in which each editor is compiled in a separate executable. This is the default for the Solaris CC compiler.
- `make libs`. Compiles all object libraries. These libraries can be static or dynamic, depending on the compiler that is used.
- `make staticlibs`: make all static object libraries (the libXXX.a versions).
- `make dynamiclibs`: make all dynamic object libraries (the libXXX.so versions).
- `make clean`. All object files in the source directories are removed.
- `make depend`. Create dependencies in the Makefiles. You are advised to do a `make depend` for a `make all` when you compile TCM for the first time.
- `make library`. Compile given library.
- `make tool`. Compile given tool (only tool specific part, not the libraries that it needs). So you have to type in `make dynamiclibs tgd` when you want to make TGD and the dynamic libraries that it needs.

When a library is compiled, it will be moved to `$TCM_HOME/lib` and when an executable is compiled it will be moved to `$TCM_HOME/bin`. This means it will overwrite the old version.

Which default compilation is performed, depends on the kind of compiler that is used. The Sun CC compiler, whose Makefile is Makefile.suncc, has `make dynamiclibs allz` as default and the GNU g++, whose Makefile is Makefile.gcc, has `make staticlibs allx` as default.

# 7.2 Porting TCM

In principle, TCM can be ported to any Unix system that has X Windows, Motif and a C++ compiler that can handle templates. The easiest way is to copy and adapt an existing Makefile and Configuration file and then try to do a `make clean`, a `make depend` and then a `make all`.

Most of the source code is platform independent. Only at a few places there are some Unix specific parts which are compiled conditionally. This is indicated in the source code by for instance '#ifdef LINUX'. The Makefile compiles its targets with the `-D` flag (see the Config.tmpl file) for instance `-DLINUX`. The files that probably need some modification, because they use conditional compilation are: `gl/system.c`, `gl/link.c`, `gl/util.h` and `ed/document.c`. The best thing to do before you port is to do some `grep`s on the sources to see what sources should maybe be changed when ported. For instance: `grep SOLARIS ??/*[hc] ??/??/*[hc] ; grep LINUX ??/*[hc] ??/??/*[hc]` (do this in `$TCM_HOME/src`), will show what part of the sources have things specific for Solaris and Linux.

Likewise, a few lines of code could be different for Motif and LessTif. When TCM is compiled with LessTif then the compiler should be supplied with the `-DLESSTIF` flag. In the source code you will find some `#ifdef LESSTIF`s.

# 7.3 G++ specific problems

The GNU C++ compiler g++ is somewhat limited in handling template classes. GNU g++ does not implement a separate pass to instantiate template functions and classes at this point; for this reason, it will not work, for the most part, to declare your template functions in one file and define them in another. The compiler will need to see the entire definition of the function, and will generate a static copy of the function in each file in which it is used. G++ does not automatically instantiate templates defined in other files. Because of this, code written for cfront will often produce undefined symbol errors when compiled with g++. You need to tell g++ the file where they are defined.

The solution for TCM was, when `__GNUC__` is defined, to include in `gl/llist.c` the template declarations that you need from the file `gl/instances.h`. u Because different groups of editors need different declarations, several files with instances are created in different source code directories and during compilation the needed file is copied to `gl/instances.h` and `gl/llist.c` is compiled and `libglobal.a` is generated again. The instance files contain not much more than declarations of template instances. This process is controlled by the Makefiles. This solution only works with static linking of libglobal (because different libglobal libraries are needed by the executables). In principle the other libraries can be linked dynamically by `g++` This can be achieved by issuing the target: `make semistaticlibs`.

By the way, the List class is in the file `gl/llist.[hc]` because the file name `list.[hc]` caused some strange name clashes while using Sun CC compilers.

When you want to compile TCM with g++ on another system (use version 2.7.2 or higher), then take `Makefile.gcc` as a basis for your Makefile and take a look in `Config.tmpl_linux` because on Linux the g++ compiler is used by default.

Next: 8. Wish List and Up: Toolkit for Conceptual Modeling Previous: 6. Output Files