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.