Configuring Compilers

Overview

If you are a developer using $G, at some point you may want to compile. Traditionally, all $G code had been compiled (at least on linux) with version 2 of the gcc. This was not feasible as a long term solution since an increasing number of useful libraries require version 3 of the gcc.

Why is this a problem?

Shamelessly plagiarised from Apple

"The application binary interface (ABI) for C++ programs changed between GCC 2 and GCC 3.1, and again between GCC 3.1 and GCC 3.3. The changes between GCC 2 and GCC 3.1 were comprehensive, including changes to name mangling, exception handling, and class layout and alignment. The changes between 3.1 and 3.3 are much smaller, but are still large enough to prevent a mixed C++ program from operating correctly. Do not link C++ modules compiled with one of these compilers against modules compiled with any of the other two compilers. Even if the modules appear to link correctly, C++ ABI differences may still cause problems that will not manifest themselves until run time."

The dollar G solution

In the quest for clarity, the $G approach to solving this dilemma is to adopt a specific naming scheme to identify the compiler that was used to make object files, static and shared libraries, and executables. Such naming is enabled by a new variable defined in the $G makefile system (source in $G/src/make, installed in $G/lib) called G_COMPILER_VER.
Penny explanation

Set G_COMPILER_VER to be gcc2 or gcc3 in your Makefile before you include $(G)/lib/Make.gfxtools.rules.

For example...

G_COMPILER_VER = gcc3
include $(G)/lib/Make.gfxtools.rules

Nickel explanation

Either you set G_COMPILER_VER in your makefile before you include the Make.gfxtools.rules file or it is set for you to the default (currently "gcc2"). If the value of G_COMPILER_VER is not the default, then another variable, G_COMPILER_SUFFIX is set to the name of the compiler used (e.g. "gcc3"). Then, much like the convention is to append "-d" to debuggable versions of code, so will the G_COMPILER_SUFFIX be appened to object files, static and shared libraries, and executables.

For example, if you were to compile a program called "test-inspace" with your G_COMPILER_VER set to gcc3, then the object files it created would be like...

main-gcc3.og
TestApp-gcc3.og
...and the executable would be like...
test-inspace-3.0-gcc3-d
...where the added text is shown in bold.

Of course, the whole point of naming in such a way is to make it clear with what libraries your program ought to be linking. A typical $G-style Makefile has sections like this...

DEBUG_LIBS =   	inspace$(INSPACE_VER)-d
OPT_LIBS =      inspace$(INSPACE_VER)
PROF_LIBS =     inspace$(INSPACE_VER)-p

DEBUG_SHLIBS =  gluebase$(GLUE_VER)-sd
OPT_SHLIBS =    gluebase$(GLUE_VER)-s
PROF_SHLIBS =   gluebase$(GLUE_VER)-sp
...this will link with the libraries without a suffix for the compiler, which will be the default compilers (currently "gcc2"). So, if you want to use gcc3, in your Makefile change the above to...
DEBUG_LIBS =   	inspace$(INSPACE_VER)$(G_COMPILER_SUFFIX)-d
OPT_LIBS =      inspace$(INSPACE_VER)$(G_COMPILER_SUFFIX)
PROF_LIBS =     inspace$(INSPACE_VER)$(G_COMPILER_SUFFIX)-p

DEBUG_SHLIBS =  gluebase$(GLUE_VER)$(G_COMPILER_SUFFIX)-sd
OPT_SHLIBS =    gluebase$(GLUE_VER)$(G_COMPILER_SUFFIX)-s
PROF_SHLIBS =   gluebase$(GLUE_VER)$(G_COMPILER_SUFFIX)-sp

Since G_COMPILER_SUFFIX is empty for the default compiler, this is a safe library naming scheme for the default case as well. To maximize generality, naming libraries with the $(G_COMPILER_SUFFIX) embedded is encouraged.

Dime explanation

The question remains, how exactly are the specific compilers to be used set? These are set in $G/lib/Make.compiler-config.local, which is generated by running compiler-setup, called by make all in the $G/src/make directory. Then, the .local file gets installed in $G/lib when you run make install in $G/src/make. The compiler-setup program tries to determine good values for the C and C++ versions of gcc2 and gcc3. It tries to file the compiler executables in the usual places, like /bin, /usr/bin, etc.. If you have your compilers installed in some strange place on your system, then you should edit the top of the compiler-setup script to include the path to your compilers in it. The Make.compiler-config.local file may also append directories into your INCLUDE_DIRS and LIB_DIRS so that the correct header files and libraries are used for your compiler choice. This is only necessary if they are not somewhere normal.

Advanced Issues

Dynamically loaded libraries
This scheme works for libraries that are known at link time. In order to load arbitrary libraries during program execution (as gluebase does for device drivers), you have to embed this naming scheme into the code itself. In compiling gluebase, this is done by defining the compiler suffix (i.e. compiling with -DG_COMPILER_SUFFIX=\"-gcc3\").
MPI
Programs relying on the Message Passing Interface (MPI) must be compiled with a special "wrapper" compiler called mpiCC. Of course, MPI itself must first be compiled with gcc2 or gcc3, and these will not inter-operate. It may be a nice idea to try and integrate mpi family of compilers into the possiblities for G_COMPILER_VER, but also a bit tricky, so this is not done yet.


Dmitri Lemmerman dlemmerm@cs.brown.edu