This is an automated email from the ASF dual-hosted git repository. domino pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/madlib.git
commit fa0f42d370bf07d3b9e11dbcddcaa981088e50e1 Author: Domino Valdano <[email protected]> AuthorDate: Mon Feb 1 17:17:00 2021 -0800 boost: Smarter logic for Boost detection & download Auto-enable C++11 flag if detected Boost version is >= 1.65 But don't auto-disable if -DCXX11 was passed and detected Boost version is too old for that. Instead, just download a newer version of Boost that works with C++11 (1.75) Replace throw with _GLIBC_THROW or _GLIBC_USE_NO_EXCEPT gcc's implementation of C++11 requires this, even though clang's doesn't Also, update setting of compiler flags in CMakeLists.txt --- CMakeLists.txt | 86 ++++++++++++++++++++------ src/CMakeLists.txt | 41 +++++------- src/dbal/BoostIntegration/MathToolkit_impl.hpp | 4 +- src/ports/postgres/dbconnector/NewDelete.cpp | 21 ++++--- 4 files changed, 98 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da573e8..a4231fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,32 @@ if(NOT CMAKE_BUILD_TYPE) FORCE) endif(NOT CMAKE_BUILD_TYPE) +# The C++11 standard overlaps a lot with older versions of Boost. +# So before deciding what standard to use for the whole project, we +# first detect Boost to see what version is on the system. +# +# C++11 is required for recent versions of Boost but will cause problems +# for older versions of Boost. Therefore, we detect it here intstead of +# in src/CMakeLists.txt where the other 3rd party libraries are detected. +# +find_package(Boost) +if(Boost_FOUND) + # We use BOOST_ASSERT_MSG, which only exists in Boost 1.47 and later. + if(Boost_VERSION_MACRO LESS 104700) + message(STATUS "Found Boost ${Boost_VERSION_STRING}, but too old for MADlib") + set(Boost_FOUND FALSE) + elseif(CXX11 AND (Boost_VERSION_MACRO LESS 106500)) + message(STATUS "Found Boost ${Boost_VERSION_STRING}, but too old for C++11") + set(Boost_FOUND FALSE) + else() + message(STATUS "Found Boost ${Boost_VERSION_STRING}") + if(106500 LESS Boost_VERSION_MACRO) + message(STATUS "Auto-enabling -DCXX11, because Boost >= v1.65 requires C++11") + set(CXX11 TRUE) + endif(106500 LESS Boost_VERSION_MACRO) + endif() +endif(Boost_FOUND) + if(CMAKE_COMPILER_IS_GNUCC) # Let's store the gcc version in a variable execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion @@ -70,9 +96,7 @@ if(CMAKE_COMPILER_IS_GNUCC) # http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02_01_01 # We specify that we are POSIX.1-2001 compliant and XSI-conforming. We only # need to specify _XOPEN_SOURCE as _POSIX_C_SOURCE will be set implicitly. - set(CMAKE_C_FLAGS "-std=c99 -D_GLIBCXX_USE_CXX11_ABI=0 -pedantic -Wall -Wextra -Wno-clobbered -D_XOPEN_SOURCE=600" - CACHE STRING - "Flags used by the compiler during all build types." FORCE) + set(CMAKE_C_FLAGS "-pedantic -Wall -Wextra -Wno-clobbered -D_XOPEN_SOURCE=600") if((CMAKE_C_COMPILER_VERSION VERSION_EQUAL 5.0) OR (CMAKE_C_COMPILER_VERSION VERSION_GREATER 5.0)) # Versions 5+ fail with the "Release" build type i.e. when optimization # level is -O3 or greater. @@ -86,7 +110,7 @@ if(CMAKE_COMPILER_IS_GNUCC) elseif(CMAKE_C_COMPILER_ID STREQUAL "SunPro") set(CMAKE_C_FLAGS "-xc99=%all") endif() - + if(CMAKE_COMPILER_IS_GNUCXX) # Let's store the gcc version in a variable execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion @@ -100,15 +124,29 @@ if(CMAKE_COMPILER_IS_GNUCXX) set(SSE_DISABLE_OPTIONS "-mno-sse2") endif() - # We need the 1998 standard plus amendments (ISO/IEC 14882:2003) plus TR1 - # Unfortunately, we only get this with gnu++98 - # Special notes: - # - long long is not part of the C++ 1998/2003 standard, but it is such a - # common (and useful) extension that we do not want to hear warnings about - # it. - set(CMAKE_CXX_FLAGS "-std=gnu++98 -D_GLIBCXX_USE_CXX11_ABI=0 -fdiagnostics-show-option -Wall -Wextra -pedantic -Wconversion -Wno-long-long -Wno-clobbered ${SSE_DISABLE_OPTIONS} -fstrict-aliasing" - CACHE STRING - "Flags used by the compiler during all build types." FORCE) + set(CMAKE_CXX_FLAGS "-fdiagnostics-show-option -Wall -Wextra -pedantic -Wconversion -Wno-long-long -Wno-clobbered ${SSE_DISABLE_OPTIONS} -fstrict-aliasing" + ) + if (CXX11) + set(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}" + CACHE STRING + "Flags used by the compiler during all build types." FORCE) + set(CMAKE_C_FLAGS "-std=gnu11 ${CMAKE_C_FLAGS}" + CACHE STRING + "Flags used by the compiler during all build types." FORCE) + else(CXX11) + # We need the 1998 standard plus amendments (ISO/IEC 14882:2003) plus TR1 + # Unfortunately, we only get this with gnu++98 + # Special notes: + # - long long is not part of the C++ 1998/2003 standard, but it is such a + # common (and useful) extension that we do not want to hear warnings about + # it. + set(CMAKE_CXX_FLAGS "-std=gnu++98 ${CMAKE_CXX_FLAGS}" + CACHE STRING + "Flags used by the compiler during all build types." FORCE) + set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}" + CACHE STRING + "Flags used by the compiler during all build types." FORCE) + endif(CXX11) if((CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 5.0) OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0)) # Versions 5+ fail with the "Release" build type i.e. when optimization @@ -122,13 +160,25 @@ if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ") endif(APPLE) elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") -if (CXX11) - set(CMAKE_CXX_FLAGS "-stdlib=libc++ -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=1") -else (CXX11) - set(CMAKE_CXX_FLAGS "-stdlib=libstdc++ -D_GLIBCXX_USE_CXX11_ABI=0") -endif(CXX11) + if(CXX11) + set(CMAKE_CXX_FLAGS "-stdlib=libc++ -std=c++11" + CACHE STRING + "Flags used by the compiler during all build types." FORCE) + else(CXX11) + set(CMAKE_CXX_FLAGS "-stdlib=libstdc++" + CACHE STRING + "Flags used by the compiler during all build types." FORCE) + endif(CXX11) endif(CMAKE_COMPILER_IS_GNUCXX) +if(CXX11) + add_definitions("-D_GLIBCXX_USE_CXX11_ABI=1") + # TODO: for recent cmake, add_compile_definitions("_GLIBCXX_USE_CXX11_ABI=1") +else(CXX11) + add_definitions("-D_GLIBCXX_USE_CXX11_ABI=0") + # TODO: for recent cmake, add_compile_definitions("_GLIBCXX_USE_CXX11_ABI=0") +endif(CXX11) + # force a `m4_' prefix to all builtins if(FREEBSD) set(M4_ARGUMENTS "-P") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 41b475d..7825028 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,21 +34,25 @@ set(EIGEN_BASE_URL # running cmake: # "-DBOOST_TAR_SOURCE=/path/to/boost_x_x_x.tar.gz" -set(BOOST_TAR_VERSION "1.61.0") -set(BOOST_TAR_MD5 874805ba2e2ee415b1877ef3297bf8ad) - -string(REPLACE "." "_" _BOOST_TAR_VERSION_UNDERSCORES ${BOOST_TAR_VERSION}) -set(BOOST_TAR "boost_${_BOOST_TAR_VERSION_UNDERSCORES}.tar.gz") -set(BOOST_URL "${SOURCEFORGE_BASE_URL}/boost/files/${BOOST_TAR}") +if (CXX11) + set(BOOST_TAR_VERSION "1.75.0") # If CXX11 is enabled, we can use latest version of Boost + set(BOOST_TAR_MD5 38813f6feb40387dfe90160debd71251) +else(CXX11) + set(BOOST_TAR_VERSION "1.61.0") # Most recent version that includes TR1 (necessary for old C++ compilers) + set(BOOST_TAR_MD5 874805ba2e2ee415b1877ef3297bf8ad) +endif(CXX11) + string(REPLACE "." "_" _BOOST_TAR_VERSION_UNDERSCORES ${BOOST_TAR_VERSION}) + set(BOOST_TAR "boost_${_BOOST_TAR_VERSION_UNDERSCORES}.tar.gz") + set(BOOST_URL "${SOURCEFORGE_BASE_URL}/boost/files/${BOOST_TAR}") if(NOT BOOST_TAR_SOURCE) - find_file(BOOST_TAR_SOURCE ${BOOST_TAR} + find_file(BOOST_TAR_SOURCE ${BOOST_TAR} # If not user-specified, try finding in downloads dir PATHS ${MAD_THIRD_PARTY}/downloads) -endif(NOT BOOST_TAR_SOURCE) -if(NOT BOOST_TAR_SOURCE) - set(BOOST_TAR_SOURCE ${BOOST_URL}) -endif (NOT BOOST_TAR_SOURCE) + if (NOT BOOST_TAR_SOURCE) + set(BOOST_TAR_SOURCE ${BOOST_URL}) # If not found locally, download + endif() +endif(NOT BOOST_TAR_SOURCE) # We always download Eigen (unless it is already present in # ${CMAKE_CURRENT_BINARY_DIR}/third_party/downloads). It is also possible to @@ -104,19 +108,7 @@ set(MAD_MODULE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/modules) # try this at home. # ============================================================================== -# -- Third-party dependencies: Find or download Boost -------------------------- - -# set(Boost_INCLUDE_DIRS "/usr/local/opt/boost/include") -find_package(Boost 1.47) -if(Boost_FOUND) - # We use BOOST_ASSERT_MSG, which only exists in Boost 1.47 and later. - if(Boost_MACRO_VERSION LESS 104700) - set(Boost_FOUND FALSE) - else(Boost_MACRO_VERSION LESS 104700) - message(STATUS "Actual version of Boost found: ${Boost_VERSION_STRING}") - endif(Boost_MACRO_VERSION LESS 104700) -endif(Boost_FOUND) - +# -- Third-party dependencies: Download the Boost if not previously detected if(Boost_FOUND) message(STATUS "Boost include directory ${Boost_INCLUDE_DIRS}") include_directories(${Boost_INCLUDE_DIRS}) @@ -135,7 +127,6 @@ else(Boost_FOUND) include_directories(BEFORE SYSTEM ${MAD_THIRD_PARTY}/src/EP_boost) endif(Boost_FOUND) - # -- Third-party dependencies: Download the C++ linear-algebra library Eigen --- ExternalProject_Add(EP_eigen PREFIX ${MAD_THIRD_PARTY} diff --git a/src/dbal/BoostIntegration/MathToolkit_impl.hpp b/src/dbal/BoostIntegration/MathToolkit_impl.hpp index 2b93c8c..402aeec 100644 --- a/src/dbal/BoostIntegration/MathToolkit_impl.hpp +++ b/src/dbal/BoostIntegration/MathToolkit_impl.hpp @@ -57,14 +57,12 @@ user_domain_error(const char*, const char* inMessage, const T& inVal) { int prec = 2 + (std::numeric_limits<T>::digits * 30103UL) / 100000UL; #endif // _GLIBCXX_USE_CXX11_ABI - throw std::domain_error(inMessage); - std:: string *msg = new std::string( (boost::format(inMessage) % boost::io::group(std::setprecision(prec), inVal) ).str() ); - + // Some Boost error messages contain a space before the punctuation mark, // which we will remove. std::string::iterator lastChar = msg->end() - 1; diff --git a/src/ports/postgres/dbconnector/NewDelete.cpp b/src/ports/postgres/dbconnector/NewDelete.cpp index a4de2df..8f909a8 100644 --- a/src/ports/postgres/dbconnector/NewDelete.cpp +++ b/src/ports/postgres/dbconnector/NewDelete.cpp @@ -26,6 +26,11 @@ // the search paths, which might point to a port-specific dbconnector.hpp #include <dbconnector/dbconnector.hpp> +#ifdef _LIBCPP_COMPILER_CLANG +#define _GLIBCXX_THROW(a) throw(a) +#define _GLIBCXX_USE_NOEXCEPT noexcept +#endif + /** * @brief operator new for PostgreSQL. Throw on fail. * @@ -34,7 +39,7 @@ * that size. */ void* -operator new(std::size_t size) throw (std::bad_alloc) { +operator new(std::size_t size) _GLIBCXX_THROW (std::bad_alloc) { return madlib::defaultAllocator().allocate< madlib::dbal::FunctionContext, madlib::dbal::DoNotZero, @@ -42,7 +47,7 @@ operator new(std::size_t size) throw (std::bad_alloc) { } void* -operator new[](std::size_t size) throw (std::bad_alloc) { +operator new[](std::size_t size) _GLIBCXX_THROW (std::bad_alloc) { return madlib::defaultAllocator().allocate< madlib::dbal::FunctionContext, madlib::dbal::DoNotZero, @@ -58,12 +63,12 @@ operator new[](std::size_t size) throw (std::bad_alloc) { * <tt>operator new(std::size_t)</tt>. */ void -operator delete(void *ptr) throw() { +operator delete(void *ptr) _GLIBCXX_USE_NOEXCEPT { madlib::defaultAllocator().free<madlib::dbal::FunctionContext>(ptr); } void -operator delete[](void *ptr) throw() { +operator delete[](void *ptr) _GLIBCXX_USE_NOEXCEPT { madlib::defaultAllocator().free<madlib::dbal::FunctionContext>(ptr); } @@ -75,7 +80,7 @@ operator delete[](void *ptr) throw() { * indication, instead of a bad_alloc exception. */ void* -operator new(std::size_t size, const std::nothrow_t&) throw() { +operator new(std::size_t size, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT { return madlib::defaultAllocator().allocate< madlib::dbal::FunctionContext, madlib::dbal::DoNotZero, @@ -83,7 +88,7 @@ operator new(std::size_t size, const std::nothrow_t&) throw() { } void* -operator new[](std::size_t size, const std::nothrow_t&) throw() { +operator new[](std::size_t size, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT { return madlib::defaultAllocator().allocate< madlib::dbal::FunctionContext, madlib::dbal::DoNotZero, @@ -97,11 +102,11 @@ operator new[](std::size_t size, const std::nothrow_t&) throw() { * <tt>operator new(std::size_t, const std::nothrow_t&)</tt>. */ void -operator delete(void *ptr, const std::nothrow_t&) throw() { +operator delete(void *ptr, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT { madlib::defaultAllocator().free<madlib::dbal::FunctionContext>(ptr); } void -operator delete[](void *ptr, const std::nothrow_t&) throw() { +operator delete[](void *ptr, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT { madlib::defaultAllocator().free<madlib::dbal::FunctionContext>(ptr); }
