: jms courier code (v3)

Common Compiler Settings

Usually you will build your library or application by using provided build scripts or makefiles. Sometimes that might not work or you are using a different build system from what we're familiar with or you need to integrate proxy types into an existing build.

This page contains a collection of compiler and linker options that we have used to successfully build working integration solutions on various platforms, using a variety of compilers.

Please let us know if you have observations, improvements, or corrections to the information provided here. Also, please note that the settings listed here are not necessarily the only way of building, they're just what we have found to work well.

Overview

Specific settings vary greatly between different compilers, sometimes even between different versions of the same compiler, so it's not easy to provide up-to-date and correct information for all supported platforms and compilers. We therefore break the settings into groups that describe certain compilation features that you might have to configure.

Processor Architecture (32-bit vs. 64-bit Mode)

If you are happy with the default you don't have to worry about this option, but many 64-bit platforms support the execution of 32-bit binaries. On these platforms you might have to tell the compiler whether you are targeting 32-bit or 64-bit binaries in the compilation. Today, unless you have to support legacy platforms, you should always target 64-bit (or the default) architectures.

The g++ and llvm compiler family usually has a -m switch that supports values of 32 and 64 in addition to specific processor architecture names. To build 32-bit binaries, simply use -m32, to build 64-bit binaries simply use -m64. On some operating systems you might need to specify the desired processor architecture via -march= option.

Microsoft Visual C++ takes a totally different tack for selecting the processor architecture. It actually ships different tool chains for different processor architectures and you have to select the proper one by first running a batch file to properly set up all the paths for compiler and platform include files. This page on Microsoft's website gives you all the necessary information.

Exceptions

Java throws exceptions and we faithfully translate those exceptions into C++ exceptions. This means that you need to enable C++ exceptions. Most modern compilers do that by default, but here are the settings that allow you to enable exceptions explicitly.

The g++ and llvm compiler family usually has a -fexceptions switch that turns on exception support.

The Microsoft Visual C++ compiler uses the /EH switch, which we usually set to /EHsc.

Threading

Java is inherently multithreaded and we usually build our C++ applications with threading support, not that that is strictly necessary when your own application is singlethreaded. Our runtime library xmogrt is always built with support for multiple threads and it is usually a good idea to keep the build options for libraries and executables as similar as possible.

For the g++ and llvm compiler families, we usually pass the -lpthread and/or -pthread switches to link with the POSIX threads library.

The Microsoft Visual C++ compiler uses the /MT /MTd /MD /MDd switches, of which you have to use at least one. Please see this page on Microsoft's website for more information.

Position-independent Code and Shared Libraries

When you build shared libraries, be they .dll, .so, or .dylib, you often need to pass a compiler option that instructs the compiler/linker to generate position-independent code. You might also have to instruct the compiler/linker to export the symbols from the build library so that executables can use them.

For the g++ and llvm compiler families, we usually pass the -fpic or -PIC option to the compiler and the -shared option to the linker.

The Microsoft Visual C++ uses the /DLL linker switch to signal that the code should be built into a DLL.

Codemesh Runtime Library

All C++ proxy types (and probably your own executable as well) rely on functions provided by the Codemesh runtime library xmogrt. Whether you build an executable or a shared library, you will need to link with one of the supplied runtime libraries and you might need to import the symbols from it.

We provide different versions of the runtime for different compilers and different platforms. Pick the best match from the supplied set. It usually does not need to match your compiler version exactly, but it does have to match the operating system and the processor architecture. Use the release version unless you have to debug into our runtime library.

The runtime library's symbols are exported using a preprocessor definition called XMOG_DECLSPEC. On most Unix/Linux systems you do not need to do anything special but on Windows you should pass the /DXMOG_DECLSPEC=__declspec(dllimport) option to the compiler.

On most Unix/Linux systems, you use the -L switch to supply a directory in which to search for link libraries and the -l switch to name a library to link with. You always use -lxmogrt to link with the Codemesh runtime library. The directory depends on your concrete operating system, processor architecture and compiler.

For the Microsoft Visual C++ toolchain, the linker search path can be amended via the /LIBPATH: option and you need to add the xmogrt.lib file to the linker invocation.