Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Build system: Option LIBSTDCXX_COMPAT for compatibility with an old l…

…ibstdc++

Jira: MADLIB-263

This commit follows ideas proposed here: http://glandium.org/blog/?p=1901
Unfortunately, MADlib seems to use libstdc++ to a greater extend than Firefox 4.0
did, so we need to do a bit more.

The declarations and definitions in this commit make it possible to build MADlib
with the following versions of gcc (please add to the list), while continuing to
only rely on, e.g., libstdc++.so.6.0.8 (which corresponds to gcc 4.1.2, and
labels GLIBCXX_3.4.8, CXXABI_1.3.1).

Tested with the following versions of gcc:

- gcc 4.4.2
- gcc 4.5.4
- gcc 4.6.2

It should most likely also work with other recent gcc versions.

To use, add the option "-DLIBSTDCXX_COMPAT=40102" when running cmake.
  • Loading branch information...
commit c3db418c0d34d6813608f2137fef1012ce03043d 1 parent aa1f657
Florian Schoppmann authored
15 ReadMe_Build.txt
@@ -134,6 +134,21 @@ root directory) for more options, after having run `cmake` the first time.
134 134 Note: If no `GREENPLUM<...>_PG_CONFIG` is specified, the build script will
135 135 look for `/usr/local/greenplum-db/bin/pg_config`.
136 136
  137 +- `LIBSTDCXX_COMPAT` (default: *empty*)
  138 +
  139 + If GNU gcc is used to build MADlib and link against the GNU libstdc++, this
  140 + option may be used to set the maximum version of libstdc++ acceptable as a
  141 + runtime dependency (not supported on Mac OS X). E.g., if MADlib should
  142 + require no more than the libstdc++ shipped with gcc 4.1.2, call
  143 + `./configure` with `-DLIBSTDCXX_COMPAT=40102`.
  144 +
  145 + The current minimum value supported for option `LIBSTDCXX_COMPAT` is
  146 + `40102`, and the latest version of gcc supported when setting this option is
  147 + gcc 4.6.x.
  148 +
  149 + Setting this option will enable workarounds in
  150 + `src/utils/libstdcxx-compatibility.cpp`.
  151 +
137 152 - `BOOST_TAR_SOURCE` (default: *empty*)
138 153
139 154 If no recent version of Boost is found (>= 1.46), Boost is downloaded
20 license/third_party/_M_widen_init.txt
... ... @@ -0,0 +1,20 @@
  1 +std::ctype<char>::_M_widen_init() is a function authored by Jerry Quinn
  2 +<jlquinn@optonline.net>, which was added to libstdc++ with revision 74662 on
  3 +Dec 16, 2003 [1].
  4 +
  5 +With permission from Jerry (thankfully received on Oct 9, 2012), we include a
  6 +copy of this function in the MADlib repository. The sole intention is to allow
  7 +compiling MADlib with recent versions of gcc while still keeping the runtime
  8 +dependencies limited to earlier versions of libstdc++. Technical details are
  9 +given in src/utils/libstdcxx-compatibility.cpp.
  10 +
  11 +Revision 74662 of the libstdc++-v3 file include/bits/locale_facets.h, where
  12 +std::ctype<char>::_M_widen_init() has been copied from, also included the
  13 +following notice in the file header [2]:
  14 +
  15 +// As a special exception, you may use this file as part of a free software
  16 +// library without restriction. [...]
  17 +
  18 +Links:
  19 +[1] http://gcc.gnu.org/viewcvs?diff_format=h&view=revision&revision=74662
  20 +[2] http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/include/bits/locale_facets.h?diff_format=h&view=markup&pathrev=74662
20 src/CMakeLists.txt
@@ -257,13 +257,29 @@ file(GLOB_RECURSE MAD_CPP_SOURCES
257 257 list(APPEND MAD_SOURCES
258 258 ${MAD_CPP_SOURCES}
259 259 )
  260 +if((NOT APPLE) AND LIBSTDCXX_COMPAT AND CMAKE_COMPILER_IS_GNUCXX)
  261 + if(GNUCXX_VERSION VERSION_GREATER 4.1.2)
  262 + math(EXPR LIBSTDCXX_COMPAT_MAJOR "${LIBSTDCXX_COMPAT} / 10000")
  263 + math(EXPR LIBSTDCXX_COMPAT_MINOR "(${LIBSTDCXX_COMPAT} / 100) % 100")
  264 + math(EXPR LIBSTDCXX_COMPAT_PATCH "${LIBSTDCXX_COMPAT} % 100")
  265 + set(LIBSTDCXX_COMPAT_VERSION "${LIBSTDCXX_COMPAT_MAJOR}.${LIBSTDCXX_COMPAT_MINOR}.${LIBSTDCXX_COMPAT_PATCH}")
  266 + message(STATUS "Compatibility with libstdc++ of g++ "
  267 + "${LIBSTDCXX_COMPAT_VERSION} requested (current g++ version is "
  268 + "${GNUCXX_VERSION}).")
  269 + message(STATUS "If this does not work, try option INCLUDE_LIBSTDCXX "
  270 + "instead, in order to redistribute the build-time libstdc++.")
  271 + list(APPEND MAD_SOURCES
  272 + "${CMAKE_CURRENT_SOURCE_DIR}/utils/libstdcxx-compatibility.cpp")
  273 + add_definitions("-DLIBSTDCXX_COMPAT=${LIBSTDCXX_COMPAT}")
  274 + endif(GNUCXX_VERSION VERSION_GREATER 4.1.2)
  275 +endif((NOT APPLE) AND LIBSTDCXX_COMPAT AND CMAKE_COMPILER_IS_GNUCXX)
260 276
261 277 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
262 278
263 279
264 280 if(CMAKE_COMPILER_IS_GNUCXX)
265 281 if(GNUCXX_VERSION VERSION_GREATER 4.4 OR GNUCXX_VERSION VERSION_EQUAL 4.4)
266   - if(_AUTOINCLUDE_LIBSTDCXX)
  282 + if(INCLUDE_LIBSTDCXX)
267 283 # FIXME: The following only takes care of the symbolic link
268 284 # Need to implement copying of files containing version numbers in
269 285 # file name
@@ -288,7 +304,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
288 304 )
289 305 add_custom_target(copyLibStdCXX ALL DEPENDS
290 306 "${CMAKE_CURRENT_BINARY_DIR}/lib/${_LIBSTDCXX_FILENAME}")
291   - endif(_AUTOINCLUDE_LIBSTDCXX)
  307 + endif(INCLUDE_LIBSTDCXX)
292 308
293 309 # Also install it
294 310 install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib
232 src/utils/libstdcxx-compatibility.cpp
... ... @@ -0,0 +1,232 @@
  1 +/* ----------------------------------------------------------------------- *//**
  2 + *
  3 + * @file libstdcxx-compatibility.cpp
  4 + *
  5 + * @brief Declarations/definitions for using an "old" libstdc++ with a newer g++
  6 + *
  7 + * This file follows ideas proposed here: http://glandium.org/blog/?p=1901
  8 + * Unfortunately, MADlib seems to use libstdc++ to a greater extend than
  9 + * Firefox 4.0 did, so we need to do a bit more.
  10 + *
  11 + * The declarations and definitions in this file make it possible to build
  12 + * MADlib with the following versions of gcc (please add to the list), while
  13 + * continuing to only rely on libstdc++.so.6.0.8 (which corresponds to
  14 + * gcc 4.1.2, and labels GLIBCXX_3.4.8, CXXABI_1.3.1).
  15 + *
  16 + * As of September 2012, there is still the need to support libstdc++.so.6.0.8,
  17 + * as this is the libstdc++ that shipped with RedHad/CentOS 5.
  18 + *
  19 + * Tested with the following versions of gcc:
  20 + * - gcc 4.4.2
  21 + * - gcc 4.5.4
  22 + * - gcc 4.6.2
  23 + *
  24 + * For a mapping between gcc versions, libstdc++ versions, and symbol versioning
  25 + * on the libstdc++.so binary, see:
  26 + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
  27 + *
  28 + *//* ----------------------------------------------------------------------- */
  29 +
  30 +#include <ostream>
  31 +
  32 +// The following macro was introduced with this commit:
  33 +// http://gcc.gnu.org/viewcvs?diff_format=h&view=revision&revision=173774
  34 +#ifndef _GLIBCXX_USE_NOEXCEPT
  35 + #define _GLIBCXX_USE_NOEXCEPT throw()
  36 +#endif
  37 +
  38 +#define GCC_VERSION ( __GNUC__ * 10000 \
  39 + + __GNUC_MINOR__ * 100 \
  40 + + __GNUC_PATCHLEVEL__)
  41 +
  42 +// CXXABI_1.3.2 symbols
  43 +
  44 +#if (LIBSTDCXX_COMPAT < 40300 && GCC_VERSION >= 40300)
  45 +
  46 +namespace __cxxabiv1 {
  47 +
  48 +/**
  49 + * @brief Virtual destructor for forced-unwinding class
  50 + *
  51 + * We provide an implementation to avoid CXXABI_1.3.2 symbol versions.
  52 + *
  53 + * Older versions of libstdc++ had the problem that POSIX thread cancellations
  54 + * while writing to an ostream caused an abort:
  55 + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28145
  56 + *
  57 + * Newer versions have an additional catch block for references of type
  58 + * __cxxabiv1::__forced_unwind, which represents the POSIX cancellation object:
  59 + * http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html
  60 + * See, e.g., file <bits/ostream.tcc> included from <ostream>. Catching
  61 + * exceptions of this type requires its \c type_info object. However, this
  62 + * object is not normally present in the current binary, as explained in the
  63 + * following.
  64 + *
  65 + * The type __cxxabiv1::__forced_unwind was only introduced in May 2007 (see
  66 + * attachments to the previous bug report) and thus after the release of
  67 + * gcc 4.1.2 (Feb 13, 2007, see http://gcc.gnu.org/releases.html).
  68 + *
  69 + * As http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html explains:
  70 + * <blockquote>
  71 + * If the class declares any non-inline, non-pure virtual functions, the
  72 + * first one is chosen as the "key method" for the class, and the vtable is
  73 + * only emitted in the translation unit where the key method is defined.
  74 + * <blockquote>
  75 + *
  76 + * And later on the same page:
  77 + * <blockquote>
  78 + * For polymorphic classes (classes with virtual functions), the
  79 + * \c type_info object is written out along with the vtable [...].
  80 + * <blockquote>
  81 + *
  82 + * Hence, to include a vtable, we need a definition for the key method, which is
  83 + * the constructor. See the declaration here:
  84 + * http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/libsupc%2B%2B/cxxabi_forced.h
  85 + */
  86 +__forced_unwind::~__forced_unwind() _GLIBCXX_USE_NOEXCEPT { }
  87 +
  88 +} // namespace __cxxabiv1
  89 +
  90 +#endif // (LIBSTDCXX_COMPAT < 40300 && GCC_VERSION >= 40300)
  91 +
  92 +
  93 +// GLIBCXX_3.4.9 symbols
  94 +
  95 +#if (LIBSTDCXX_COMPAT < 40200 && GCC_VERSION >= 40200)
  96 +
  97 +namespace std {
  98 +
  99 +/**
  100 + * @brief Write a value to an ostream
  101 + *
  102 + * In recent versions of libstdc++, \c _M_insert contains the implementation for
  103 + * the various operator<<() overloads. Now, as http://glandium.org/blog/?p=1901
  104 + * explains, newer libstdc++ versions contain various instantiations for
  105 + * \c _M_insert, even though <bits/ostream.tcc> contains a general (template)
  106 + * definition.
  107 + *
  108 + * Older versions of libstdc++ did not contain implementations for \c _M_insert,
  109 + * so we instantiate them here. See this change:
  110 + * http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/include/bits/ostream.tcc?r1=109235&r2=109236&
  111 + */
  112 +template ostream& ostream::_M_insert(bool);
  113 +// The following four lines are not needed and commented out. Specialized
  114 +// implementations exist for ostream<<([unsigned] {short|int}).
  115 +// template ostream& ostream::_M_insert(short);
  116 +// template ostream& ostream::_M_insert(unsigned short);
  117 +// template ostream& ostream::_M_insert(int);
  118 +// template ostream& ostream::_M_insert(unsigned int);
  119 +template ostream& ostream::_M_insert(long);
  120 +template ostream& ostream::_M_insert(unsigned long);
  121 +#ifdef _GLIBCXX_USE_LONG_LONG
  122 +template ostream& ostream::_M_insert(long long);
  123 +template ostream& ostream::_M_insert(unsigned long long);
  124 +#endif
  125 +template ostream& ostream::_M_insert(float);
  126 +template ostream& ostream::_M_insert(double);
  127 +template ostream& ostream::_M_insert(long double);
  128 +template ostream& ostream::_M_insert(const void*);
  129 +
  130 +/**
  131 + * @brief Write a sequence of characters to an ostream
  132 + *
  133 + * This function was only added with this commit:
  134 + * http://gcc.gnu.org/viewcvs?view=revision&revision=123692
  135 + */
  136 +template ostream& __ostream_insert(ostream&, const char*, streamsize);
  137 +
  138 +} // namespace std
  139 +
  140 +#endif // (LIBSTDCXX_COMPAT < 40200 && GCC_VERSION >= 40200)
  141 +
  142 +
  143 +// GLIBCXX_3.4.11 symbols
  144 +
  145 +#if (LIBSTDCXX_COMPAT < 40400 && GCC_VERSION >= 40400)
  146 +
  147 +namespace std {
  148 +
  149 +/**
  150 + * @brief Initialize an internal data structure of ctype<char>
  151 + *
  152 + * This was previously an inline function and moved out of line with this
  153 + * commit:
  154 + * http://gcc.gnu.org/viewcvs?view=revision&revision=140238
  155 + *
  156 + * See also this bug report:
  157 + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37455
  158 + *
  159 + * std::ctype<char>::_M_widen_init() is a function added to libstdc++ by
  160 + * Jerry Quinn with revision 74662 on Dec 16, 2003:
  161 + * http://gcc.gnu.org/viewcvs?diff_format=h&view=revision&revision=74662
  162 + *
  163 + * With explicit permission by Jerry Quinn from Oct 9, 2012, we include a
  164 + * verbatim copy of _M_widen_init() here. However, a static_cast was added to
  165 + * avoid a warning.
  166 + *
  167 + * Revision 74662 of the libstdc++-v3 file include/bits/locale_facets.h, where
  168 + * std::ctype<char>::_M_widen_init() has been copied from, also included the
  169 + * following notice in the file header:
  170 + * http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/include/bits/locale_facets.h?diff_format=h&view=markup&pathrev=74662
  171 + *
  172 + * <blockquote>
  173 + * As a special exception, you may use this file as part of a free software
  174 + * library without restriction. [...]
  175 + * <blockquote>
  176 + */
  177 +void
  178 +ctype<char>::_M_widen_init() const {
  179 + char __tmp[sizeof(_M_widen)];
  180 + for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
  181 + __tmp[__i] = __i;
  182 + do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
  183 +
  184 + _M_widen_ok = 1;
  185 + // Set _M_widen_ok to 2 if memcpy can't be used.
  186 + for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
  187 + if (__tmp[__i] != _M_widen[__i]) {
  188 + _M_widen_ok = 2;
  189 + break;
  190 + }
  191 +}
  192 +
  193 +} // namespace std
  194 +
  195 +#endif // (LIBSTDCXX_COMPAT < 40400 && GCC_VERSION >= 40400)
  196 +
  197 +
  198 +// GLIBCXX_3.5.15 symbols
  199 +
  200 +#if (LIBSTDCXX_COMPAT < 40600 && GCC_VERSION >= 40600)
  201 +
  202 +#include <stdexcept>
  203 +
  204 +namespace std {
  205 +
  206 +/**
  207 + * @brief Empty dtors for standard exceptions
  208 + *
  209 + * Later versions of libstdc++ added destructors to some standard exceptions.
  210 + * Definitions for these are missing in older versions of libstdc++.
  211 + *
  212 + * Of course, additing destructors is potentially dangerous and can change the
  213 + * ABI. However, these classes derived from \c runtime_error and \c logic_error
  214 + * before and therefore have always had virtual members.
  215 + *
  216 + * The first commit that added these destructors is:
  217 + * http://gcc.gnu.org/viewcvs?diff_format=h&view=revision&revision=170975
  218 + * This commit was included already in the first gcc 4.6.0 release:
  219 + * http://gcc.gnu.org/viewcvs/tags/gcc_4_6_0_release/libstdc%2B%2B-v3/src/stdexcept.cc
  220 + */
  221 +domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
  222 +invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
  223 +length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
  224 +out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
  225 +runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
  226 +range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
  227 +overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
  228 +underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
  229 +
  230 +} // namespace std
  231 +
  232 +#endif // (LIBSTDCXX_COMPAT < 40600 && GCC_VERSION >= 40600)

0 comments on commit c3db418

Please sign in to comment.
Something went wrong with that request. Please try again.