Before undertaking the port of Chimera to Linux, we had to satisfy the software requirement restraints presented by Chimera. We selected the Red Hat 6.2 distribution of Linux [13] because it was stable, reliable, well-supported and commonly used. We believe that other distributions such as Debian would also be acceptable candidates for building Chimera, but due to lack of time resources we did not try them. We have since upgraded from Red Hat 6.2 to Red Hat 7.1, which has better built-in support for OpenGL.
Python, OpenGL, and Tcl/Tk are available on Linux so these did not present challenges; we simply compiled and installed these applications from their primary source distributions. The initial port of Chimera to Linux used Python-1.5.2, Mesa-3.2 (for OpenGL, [14], and Tcl/Tk 8.0. More recent ports of Chimera use Python-2.1, Mesa-3.4, and Tcl/Tk 8.3. Because Mesa-3.4 conforms to the Linux OpenGL ABI, any ABI-compliant implementation of OpenGL for Linux will work with Chimera. For example, the nVidia GeForce2 graphics card requires a vendor-supplied OpenGL driver implementation; Chimera works just fine with this driver.
All C++ code in Chimera is written in standard C++, making heavy use of the standard C++ library, and the object-oriented/generic programming features of C++. The primary challenge in porting Chimera to Linux was to find a standard C++ compiler and library. The C++ compiler (egcs) provided with Red Hat 6.2 was not sufficient; it lacked some required C++ template features and did not have a standards-compliant C++ library. This is understandable because the C++ standard library was finalized only recently; egcs complied to a draft version of the standard and significant changes were made in the published standard. Further, templates are a sophisticated (and very recent) feature of C++ which requires extensive compiler and linker support.
After experimentation with several different C++ compilers available for Linux, we settled on GNU g++ [15] version 2.95.3. Version 2.95.3 supports all of the language features we use, although its standard C++ library is not complete. Even where the library calls are available, there are bugs in the implementations which appear only when the library is used extensively. After looking at several different (and expensive) commercial libraries, we found STLport [16], a freely available implementation of the standard C++ library derived from the SGI STL. STLport is a high-quality implementation of the library, and in addition to supporting GNU g++, it supports 25 other C++ compilers. We are currently using STLport-4.5.
Once we had settled on a platform and required toolset and libraries, the port of Chimera to Linux was straightforward. We simply modified our Makefiles to use g++ and STLport, and compiled the entire application with no major modifications. g++ combined with STLport actually found several lines of non-compliant C++ code (lack of std:: namespace qualifier where required and illegal arguments to standard library functions) which were not flagged by the UNIX compilers (Compaq C++ 6.3 and MIPSPro 7.3.1) and Windows compiler (MetroWorks CodeWarrior) we use.
Although our experience with libstdc++ (the standard C++ library implementation included with g++) was somewhat negative, we are glad to report that the libstdc++ developers fixed every bug that we reported (we always isolated the bugs to simple testcases, typically only several lines long) and prospects of having a complete, reliable libstdc++ in the future are promising.
An interesting problem that we only noticed on Linux was related to the usage of dynamic loading of modules with ``dlopen'' when the main application (for example, Python) is linked with the C compiler and the modules are compiled with the C++ compiler. When Python imports a second module linked against the standard C++ library and uses certain features (such as exceptions combined with ostringstreams), the application will core dump. Close inspection of debugging output from the dynamic linker as well as the linker's source code showed that when the second library was loaded, the standard C++ library was loaded a second time, rather than having its symbols resolved by the first module's linked standard library. This caused problems with the internal state of the library which caused a core dump when a floating point number was output to a stringstream. There are several ``work-arounds'', none of which is completely satisfactory. One is to modify the arguments to dlopen() in the Python module loading code to allow global symbol resolution, but the authors of Python highly discredit this approach. Another workaround is to force the standard C++ shared library to be loaded before the main program starts using the LD_PRELOAD environment variable; further loads of the library always use the initially loaded library. A third option is to explicitly link Python against the standard C++ library when compiling. We are currently using the second option because this allows Chimera to use the distribution-installed python without any modifications The second option was causing core dumps on application exit). We have determined that the core dump was actually due to mistaken linking of one of Chimera's subsidiary libraries against the STLport static library. Later, the chimera shared library was linked against the subsidiary library as well as the dynamic STLport library. Therefore, there were two copies of the standard library resident in the program and when objects were passed between the main Chimera application and the subsidiary library some memory was likely corrupted (the standard library maintains some internal state for its objects, and there were two copies of the internal state). When the proper linking was applied, the segmentation fault on exit went away.