mirror of https://github.com/CGAL/cgal
395 lines
12 KiB
Plaintext
395 lines
12 KiB
Plaintext
/*!
|
|
|
|
\page devman_portability Portability Issues
|
|
|
|
\author Michael Hoffmann (<TT>hoffmann@inf.ethz.ch</TT>)
|
|
\author Stefan Schirra
|
|
\author Sylvain Pion
|
|
|
|
This chapter gives an overview of issues related to the
|
|
configuration of \cgal that allow you to answer such questions as:
|
|
<UL>
|
|
<LI>Is \em LEDA / \gmp there? (Section \ref secleda_gmp_support)
|
|
<LI>Which compiler is this? (Section \ref secwhich_compiler )
|
|
<LI>Does the compiler support feature X? (Section \ref secworkaround_flags )
|
|
</UL>
|
|
|
|
Also addressed here are issues related to writing code for
|
|
non-standard-compliant compilers. Compilers have made a lot of progress toward
|
|
the \cpp-standard recently. But still they do not fully implement it. There
|
|
are a few features you may assume; others you may not
|
|
assume. Especially you may assume that the compiler
|
|
<UL>
|
|
<LI>supports namespaces
|
|
<LI>supports member templates
|
|
<LI>support for <TT>std::iterator_traits</TT>.
|
|
</UL>
|
|
Still, there are many bugs (sometimes known as "features") left in the
|
|
compilers. Have a look at the list of (non-obsolete) workarounds in
|
|
Section \ref secworkaround_flags to get an idea of which "features" are
|
|
still present.
|
|
|
|
\section secleda_gmp_support Checking for LEDA or GMP support
|
|
|
|
In the makefiles included for the compilation of every \cgal program
|
|
(<I>i.e.</I>, those to which the environment variable <TT>CGAL_MAKEFILE</TT> refers),
|
|
|
|
we define command line switches that set the flags
|
|
\code{.cpp}
|
|
CGAL_USE_LEDA, CGAL_USE_GMP
|
|
\endcode
|
|
|
|
iff \cgal is configured with \leda or GMP support, respectively.
|
|
|
|
\section secboost_support Using Boost
|
|
|
|
\cgal code can rely on Boost libraries to some extent.
|
|
|
|
Boost was shipped with \cgal Release 3.1, and is no longer
|
|
shipped within \cgal, as it is mainstream, and already distributed
|
|
with Linux and Cygwin.
|
|
|
|
Since portability and backward compatibility are a concern in \cgal,
|
|
we have decided that the list of Boost libraries usable in \cgal will be
|
|
decided by the \cgal editorial board. The requirements are higher
|
|
when it appears in the user visible interface than when Boost code
|
|
is used only internally. Requirements are lower for code that
|
|
is not released such as the test-suite. Boost libraries already accepted
|
|
in the C++ Standard Library Technical Report will be the first easy
|
|
candidates (these are marked <TT>[TR1]</TT> in the list below). However,
|
|
wrapping the use within \cgal is generally advised (like what is done
|
|
in the `cpp11` namespace).
|
|
Finally, the policy is that if a better alternative exists in Boost and is
|
|
allowed, then \cgal code must use it instead of a \cgal version (which
|
|
probably must be deprecated and phased out), trying not to break backward
|
|
compatibility too much.
|
|
|
|
A list of reasonable Boost libraries to use in the \cgal API is
|
|
Graph, Optional, Parameter (for packages already using it),
|
|
Property Map, Smart Pointers (for packages already using it),
|
|
Variant.
|
|
|
|
Before using a Boost libraries internally, first check whether it is already
|
|
used, and if not indicate it while submitting your changes (feature, small-feature
|
|
or pull request), or even by sending an email to cgal-develop during the development.
|
|
|
|
|
|
\section secusing_version_macros Using the version-number and configuration macros and flags
|
|
|
|
Here is a short example on how these macros can be used. Assume you have some
|
|
piece of code that depends on whether you have \leda-4.0 or later.
|
|
\code{.cpp}
|
|
#ifdef CGAL_USE_LEDA
|
|
#include <LEDA/basic.h>
|
|
#endif
|
|
|
|
#if defined(CGAL_USE_LEDA) && __LEDA__ >= 400
|
|
... put your code for LEDA 4.0 or later ...
|
|
#else
|
|
... put your code for the other case ...
|
|
#endif
|
|
\endcode
|
|
|
|
\section secwhich_compiler Identifying compilers and architectures
|
|
|
|
Every compiler defines some macros that allow you to identify it; see
|
|
the following table.
|
|
|
|
<TABLE BORDER=2><TR><TD>
|
|
<TABLE CELLSPACING=5 >
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
GNU 3.2.1
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__GNUC__`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
3
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
GNU 3.2.1
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__GNUC_MINOR__`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
2
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
GNU 3.2.1
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__GNUC_PATCHLEVEL__`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
1
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
Microsoft VC7.1
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`_MSC_VER`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
1310
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
Microsoft VC8.0
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`_MSC_VER`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
1400
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
Intel 11.1
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__INTEL_COMPILER`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
1110
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
Clang 2.9
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__clang_major__`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
2
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
Clang 2.9
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__clang_minor__`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
9
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
SUN 5.3
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__SUNPRO_CC`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
0x530
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
SUN 5.10
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__SUNPRO_CC`
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
0x5100
|
|
</TABLE>
|
|
</TABLE>
|
|
|
|
There are also flags to identify the architecture.
|
|
|
|
<TABLE BORDER=2><TR><TD>
|
|
<TABLE CELLSPACING=5 >
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
SGI
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__sgi`
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
SUN
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__sun`
|
|
<TR>
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
Linux
|
|
<TD ALIGN=LEFT NOWRAP>
|
|
`__linux`
|
|
</TABLE>
|
|
</TABLE>
|
|
|
|
\section secproblems_and_workarounds Known problems and workarounds
|
|
|
|
For (good) reasons that will not be discussed here, it was decided to
|
|
use \cpp for the development of \cgal. An international standard for
|
|
\cpp has been sanctioned in 1998 \cgalCite{cgal:ansi-is14882-98} and the
|
|
level of compliance varies widely between different
|
|
compilers, let alone bugs.
|
|
|
|
\subsection secworkaround_flags Workaround flags
|
|
|
|
In order to provide a uniform development environment for \cgal that
|
|
looks more standard compliant than what the compilers provide, a number
|
|
of workaround flags and macros have been created. Some of the
|
|
workaround macros are set in `<CGAL/config.h>`.
|
|
|
|
using the macros
|
|
listed in Section \ref secwhich_compiler to identify the compiler.
|
|
But most of them are set in the platform-specific configuration files
|
|
|
|
<CENTER>
|
|
<TT><CGAL/config/</TT><I>os-compiler</I><TT>/CGAL/compiler_config.h></TT>
|
|
|
|
</CENTER>
|
|
where <I>os-compiler</I> refers to a string describing your
|
|
operating system and compiler that is defined as follows.
|
|
|
|
<CENTER>
|
|
<I>`<arch>_<os>-<os-version>_<comp>-<comp-version>`</I>
|
|
|
|
</CENTER>
|
|
|
|
<DL>
|
|
<DT><B>`<arch>`</B><DD> is the system architecture as defined by <TT>uname -p</TT> or <TT>uname -m</TT>,
|
|
<DT><B>`<os>`</B><DD> is the operating system as defined by <TT>uname
|
|
-s</TT>,
|
|
<DT><B>`<os-version>`</B><DD> is the operating system version as defined by
|
|
<TT>uname -r</TT>,
|
|
<DT><B>`<comp>`</B><DD> is the basename of the compiler executable (if it
|
|
contains spaces, these are replaced by "-"), and
|
|
<DT><B>`<comp-version>`</B><DD> is the compiler's version number (which
|
|
unfortunately can not be derived in a uniform manner, since it is
|
|
quite compiler specific).
|
|
</DL>
|
|
|
|
Examples are <TT>mips_IRIX64-6.5_CC-n32-7.30</TT> or <TT>sparc_SunOS-5.6_g++-2.95</TT>.
|
|
For more information, see the \cgal \link usage usage guide \endlink.
|
|
|
|
This platform-specific configuration file is created during
|
|
|
|
installation by the script <TT>install_cgal</TT>. The flags listed below
|
|
are set according to the results of test programs that are compiled and run.
|
|
These test programs reside in the directory
|
|
<CENTER>
|
|
<TT>$(CGAL_ROOT)/config/testfiles</TT>
|
|
|
|
</CENTER>
|
|
where <TT>$(CGAL_ROOT)</TT> represents the installation directory for the library.
|
|
The names of all testfiles, which correspond to the names of the flags,
|
|
|
|
start with <TT>CGAL_CFG_</TT> followed by
|
|
<UL>
|
|
<LI><I>either</I> a description of a bug ending with
|
|
<TT>_BUG</TT>
|
|
<LI><I>or</I> a description of a feature starting with
|
|
<TT>NO_</TT>.
|
|
</UL>
|
|
For any of these files a corresponding flag is set in the
|
|
platform-specific configuration file, iff either compilation or execution
|
|
fails. The reasoning behind this sort of negative scheme is that on
|
|
standard-compliant platforms there should be no flags at all.
|
|
|
|
Currently (CGAL-3.4-I-181), we have the following configuration
|
|
test files (and flags). The short descriptions that are given in the files are
|
|
included here. In some cases, it is probably necessary to have a look at the
|
|
actual files to understand what the flag is for. This list is just to
|
|
give an overview.
|
|
Be sure to have a look at <TT>Installation/config/testfiles/</TT> to have an
|
|
up-to-date version of this list.
|
|
|
|
<DL>
|
|
<DT><B><TT>CGAL_CFG_LONGNAME_BUG</TT></B><DD>
|
|
|
|
This flag is set if a compiler (or assembler or linker) has problems
|
|
with long symbol names.
|
|
|
|
<DT><B><TT>CGAL_CFG_NET2003_MATCHING_BUG</TT></B><DD>
|
|
|
|
This flag is set, if the compiler does not match a member definition
|
|
to an existing declaration. This bug shows up on VC 7.1 Beta
|
|
(`cl1310`).
|
|
|
|
<DT><B><TT>CGAL_CFG_NO_LIMITS</TT></B><DD>
|
|
|
|
This flag is set if a compiler does not know the limits.
|
|
|
|
<DT><B><TT>CGAL_CFG_NO_LONG_LONG</TT></B><DD>
|
|
|
|
The `long long` built-in integral type is not part of the
|
|
\iso C++ standard, but many compilers support it
|
|
nevertheless, since it is part of the \iso C standard. This
|
|
flag is set if it is supported.
|
|
|
|
<DT><B><TT>CGAL_CFG_NO_TMPL_IN_TMPL_PARAM</TT></B><DD>
|
|
|
|
Nested templates in template parameter, such as `template <
|
|
template <class T> class A>` are not supported by any compiler.
|
|
This flag is set if they are not supported.
|
|
</DL>
|
|
|
|
\subsection secworkaround_macros Macros connected to workarounds/compilers
|
|
|
|
Some macros are defined according to certain workaround flags. This is
|
|
done to avoid some `ifdef`s in our actual code.
|
|
|
|
<DL>
|
|
<DT><B><TT>CGAL_LITTLE_ENDIAN</TT></B><DD> set, iff
|
|
|
|
|
|
<TT>CGAL_CFG_NO_BIG_ENDIAN</TT> is set.
|
|
<DT><B><TT>CGAL_BIG_ENDIAN</TT></B><DD> set, iff
|
|
|
|
|
|
<TT>CGAL_CFG_NO_BIG_ENDIAN</TT> is not set.
|
|
|
|
<DT><B><TT>CGAL_DEPRECATED</TT></B><DD>
|
|
|
|
|
|
used to declare a function as deprecated - just add it before the
|
|
function declaration. You may also surround deprecated code with
|
|
<TT>CGAL_NO_DEPRECATED_CODE</TT>, such that it is easy to test
|
|
if a piece of code uses deprecated code or not:
|
|
\code{.cpp}
|
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
|
CGAL_DEPRECATED void foo(int i)
|
|
{
|
|
...
|
|
}
|
|
#endif // CGAL_NO_DEPRECATED_CODE
|
|
\endcode
|
|
</DL>
|
|
|
|
\subsection secvarious_problems Various other problems and solutions
|
|
|
|
<DL>
|
|
<DT><B><B>min and max</B></B><DD>
|
|
Visual \cpp headers (and others) sometimes define `min` and `max` as macros. If you write `max` followed by an opening parenthesis, this can lead to unwanted substitutions. In order to work around it, you should use one of the following tricks:
|
|
\code{.cpp}
|
|
max BOOST_PREVENT_MACRO_SUBSTITUTION (a, b);
|
|
(max) (a, b);
|
|
\endcode
|
|
|
|
<DT><B><B>Templated member functions</B></B><DD>
|
|
|
|
For SunPRO \cpp member function templates with dependent return type
|
|
must be defined in the body of the class.
|
|
|
|
<DT><B><B>Function parameter matching</B></B><DD>
|
|
|
|
The function parameter matching capacities of Visual \cpp are rather limited.
|
|
Failures occur when your function `bar` is like
|
|
\code{.cpp}
|
|
bar(std::some_iterator<std::some_container<T>>....) ...
|
|
...
|
|
bar(std::some_iterator<std::some_other_container<T>>....) ...
|
|
\endcode
|
|
VC++ fails to distinguish that these parameters have different types.
|
|
A workaround is to add some dummy parameters that are defaulted to
|
|
certain values, and this affects only the places where the functions
|
|
are defined, not the places where they are called.
|
|
This may not be true anymore for recent VC++ versions.
|
|
|
|
<DT><B><B>typedefs of derived classes</B></B><DD>
|
|
Microsoft VC++ does not like the following sorts of typedefs that are
|
|
standard
|
|
\code{.cpp}
|
|
class A : public B::C {
|
|
typedef B::C C;
|
|
};
|
|
\endcode
|
|
It says that the typedef is "redefinition". So such typedefs should be
|
|
enclosed by
|
|
\code{.cpp}
|
|
#ifndef _MSC_VER
|
|
|
|
#endif
|
|
\endcode
|
|
This may not be true anymore for recent VC++ versions.
|
|
</DL>
|
|
|
|
\section secportability_req_and_rec Requirements and recommendations
|
|
|
|
Recommendations:
|
|
<UL>
|
|
<LI>Workarounds for a compiler bug or a missing feature should not
|
|
be treated on a per-compiler basis. When you detect a deficiency,
|
|
you should rather write a short test program that triggers the setting
|
|
of a flag for this deficiency during configuration.
|
|
</UL>
|
|
|
|
*/
|