MMXX Portability
MMXX is highly portable at the source level, requiring minimal
ad-hoc code. Its primary requirements are:
- A highly compliant C++ compiler, which must support at least the
following:
- Template specialization (though partial specialization support
is not required.)
- Implicit user-defined type conversions
- Run-Time Type Information (RTTI)
- Fully compliant C preprocessor (must apply the standard expansion semantics,
with no arbitrary limits on macro size, number of parameters,
expansion recursion depth, etc.)
- Position-independent code generation (unless the linker is capable
of relocating code.)
- A dynamic linker that supports on-demand loading into the host
executable's address space, symbol lookup, as well as code relocation
if the C++ compiler will not generate position-independent code.
Note that the current release of MMXX does not require support for member templates, namespaces, nor the availability
of STL except for reasonably compliant <new>, <exception> and <typeinfo> headers.
Indeed, the design philosophy behind MMXX is to be as orthogonal
as possible to operating system services that are not strictly
required for its operation, such as processes and threads, IPC
services, and network services. Any future extensions to MMXX
(such as automatic gateways that bridge across processes, networks,
and object brokering standards) will always be packaged separately
and remain optional.
Tested Platforms
MMXX has been tested on the following compiler/platform combinations,
on some more summarily than on others. The results of the attempts
are reported here. If you have had a chance to try an unlisted
compiler/platform combination, please let us learn of your experience
so that we can update this list:
Linux/GCC
Versions tested:
- egcs-2.91.66/i386-redhat-linux-gnu-2.2.12 (RedHat 6)
- gcc-2.95.2/powerpc-unknown-linux-gnu-2.2.12 (LinuxPPC 1999 Q3)
- gcc-2.95.2/i386-unknown-freebsdelf (FreeBSD 3.4)
Status:
Fully supported. Linker template problems might require Makefile
workarounds with certain versions of binutils. Older versions of gcc/egcs are unlikely to work since full C++
support is fairly new (2.7.2 is too old, 2.8.1 also fails but
has not been thoroughly investigated.) Oldish linux distributions
with modern ld.so/dlopen() pairs should work. Note that shared objects should be built as
symbolic, meaning that all internally resolvable symbols should be bound
at link time. If this is not done, ld.so will liberally override shared library symbols with like-named
symbols in the executable, misguidedly thinking such behavior
is a good idea whereas it's actually an absolutely devastating
one. This can be done with the -symbolic and -Xlinker -Bsymbolic options.
Comments:
On gcc it makes sense to take advantage of the --include command-line option to specify an include file that contains
the implementation location settings for MMXX-enabled classes
(i.e. the _MMXX_SHADOW_<class_name> macro definitions.) However, the _MMXX_prefix_ scheme can also be used instead, by way of the -D_MMXX_prefix_=<header_name> command line option, where <header_name> is the name of the prefix file without the .h suffix. The -Xlinker -noinhibit-exec option is useful if an oldish version of ld gets confused by multiply-defined templates. Since this circumstance
is triggered by the -fno-default-inlines option, you might want to get rid of that instead. Note that
the mmxx sources directory should be specified on the command line with
the -I flag, since MMXX does not use relative pathnames in #include directives (they're not fully cross-platform.) Also note that
since the test project's shared libraries are created in the same
directory as the executable and ld.so doesn't look for libraries there by default, you will get an
error message unless you add that directory to the search path,
for instance by typing export LD_LIBRARY_PATH=. (in sh, bash and derivatives) or setenv LD_LIBRARY_PATH=. (in csh and derivatives) to add the current directory. An alternative
for user projects is to embed the path to the modules directly
in the main executable by way of the -Xlinker -rpath -Xlinker <path> option to GNU ld.
Extrapolations:
- To gcc on FreeBSD:
Successfully tested on FreeBSD 3.4 with a freshly installed gcc-2.95.2.
Must remove -ldl library linking option from the Makefile as it is Linux-specific.
- To gcc on other unix systems:
Many are scheduled to be tested soon, most urgently Solaris, IRIX,
AIX and HP/UX. Will require Makefile changes, and possibly changes
to the mmxxpfrag.unix.cpp file to reflect different dlopen() header locations, or the use of APIs other than dlopen(). It's also possible at this stage that you may run into ABI's
that have trouble with MMXX's cross-module binary interface.
- To gcc on non-unix systems:
Unknown (though Cygwin and DJGPP are scheduled to be tested.)
- To other compilers on Linux:
Unknown
C++ compliance issues that affect MMXX in particular:
gcc (2.95 included) has problems detecting implicit type conversions,
especially those occurring in return statements, in operator parameters, and within boolean expressions.
This is an issue in MMXX because of the frequent back-and-forth
conversions between cross-module handles and object pointers/references.
They are usually worked around easily by performing explicit casts,
however this remains a minor portability issue (MMXX apps originally
targeted to other compilers might require minor changes.)
MacOS/Metrowerks CodeWarrior
Versions tested:
- Metrowerks CodeWarrior Pro 1/MacOS 8.1
- Metrowerks CodeWarrior Pro 4/MacOS 8.x/9.0
- Metrowerks CodeWarrior Pro 5/MacOS 8.x/9.0
Status:
Fully supported on Pro4 and later. Pro1 is also supported, through
a series of compiler workarounds are used to compensate for missing
C++ grammar and features. Since it hasn't been tested with Pro2
or Pro3, users of those will likely need to reuse some of the
Pro1 workarounds, applying those that are still applicable but
not those that no longer are.
Comments:
A target/project specific prefix file should be used to contain
the implementation location settings for MMXX-enabled classes
(i.e. the _MMXX_SHADOW_<class_name> macro definitions,) since CW has no option to define individual
macros on a per-target basis, and hence the _MMXX_prefix_ scheme isn't available. Note that you'll still be able to use
the prefix file for precompiled headers as well, although if you're
not very experienced in prefixing/precompilation matters this
may just be the time that you have to visit the appropriate section
in the docs. Note that the mmxx sources directory should be added to each target's access paths.
Extrapolations:
- To CW targeting x86:
Hasn't been tested yet, but will be very soon. Pro1's x86 support
is mostly broken - especially with respect to DLL issues, so even
if it works it would be limited to simple projects. Later versions
are yet unknown.
- To CW targeting CFM68K:
Entirely unexplored at the moment, but not impossible in theory.
Even FAT applications/libraries might be possible. Classic 68K
would require the use of code resources, which would require considerably
more infrastructure and programmer pain.
- To other MacOS compilers:
Some preliminary tests have been made with Apple's MrC under MPW,
leading to a bug report to the MrC team, but no conclusive results
yet. gcc under MPW might also work, though again no results are
yet available.
C++ compliance issues that affect MMXX in particular:
MMXX is highly incompatible with #pragma once, and especially its all-too-evil cousin #pragma once on which Metrowerks is known for sticking in the default prefix
files for its project stationery. Abandon this monstruosity once
and for all, and use platform-friendly #if(ndef) guards instead.
Windows/Microsoft Visual C++
Versions tested:
- MSVC 6.0 (MSVSEE)/Windows 95
Status:
Fully supported. No word yet on pre-6.0 versions of MSVC. NT/98/2K
haven't yet been tested but should be fully supported.
Comments:
Since MSVC does not support prefix files per se, the _MMXX_prefix_ facility should be used to specify an include file that contains
the implementation location settings for MMXX-enabled classes
(i.e. the _MMXX_SHADOW_<class_name> macro definitions.) MSVC does support precompilation through
a header, but this seems to cause problems if that header is not
#include'd first in every source file, moreover precompilation apparently
discards macro definitions which is just what MMXX needs. Different
projects should specify different prefix headers by way of _MMXX_prefix_=<header_name> in the box for predefined preprocessor symbols, where <header_name> is the name of the prefix header without the .h suffix. Note that the mmxx sources directory should be specified in the project settings
in the comma-separated list of preprocessor include directories,
since MMXX does not use relative pathnames in #include directives (they're not fully cross-platform.)
[MSVC was the biggest pain to support - MMXX had to be almost
entirely rewritten to accomodate MSVC 6.0's limited C++ compliance
and idiosyncratic C preprocessor.]
Extrapolations:
- To MSVC targeting other platforms:
Unknown
- To Cygwin targeting Win32:
Should work. Has not yet been tested and might require minor tweaking,
in particular the use of Cygwin's DLL scheme (if you try it, remember
that MMXX usually exports a single symbol from DLLs and none from
the host.)
- To DJGPP targeting MSDOS:
Unexplored. Might work but will need to interface with LoadLibrary().
- To Borland compilers targeting Win32:
Unknown. Scheduled to be tested soon.
C++ compliance issues that affect MMXX in particular:
Apparently by default, the global operator new(size_t) in the standard library does not throw bad_alloc if it runs out of memory, but rather behaves like operator new(size_t, nothrow_t&) and returns 0. This issue will be addressed when MMXX's allocation
subsystem is completed.