# ------------------------------------------------------------------------------
# MADlib CMake Build Script
# ------------------------------------------------------------------------------
# -- Initializations that need to run even before project()
# For Solaris, we want to use the Sun compiler
# See http://www.cmake.org/Bug/view.php?id=8530
set(CMAKE_GENERATOR_CC suncc gcc)
set(CMAKE_GENERATOR_CXX sunCC g++)
# -- CMake setup ---------------------------------------------------------------
project(MADlib)
# FindPostgreSQL.cmake needs at least 2.8.3. We are on the safe side and require
# the minimum version tested, which is 2.8.4.
cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
include(ExternalProject)
include(CheckCXXCompilerFlag)
# -- Local definitions (filenames, paths, etc.) --------------------------------
# The default MADlib root directory should be "/usr/local/madlib" and not
# "/usr/local" (which is the CMake default)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "/usr/local/madlib" CACHE PATH
"Install path prefix, prepended onto install directories." FORCE
)
endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(MADLIB_VERSION_YML ${CMAKE_CURRENT_SOURCE_DIR}/src/config/Version.yml)
set(MAD_THIRD_PARTY ${CMAKE_BINARY_DIR}/third_party)
# Set the directory for tools needed during build time
set(MAD_BUILD_TOOLS ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
set(EXTERNALPROJECT_LIST_SEPARATOR "~!~")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(LINUX TRUE)
endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
set(SOLARIS TRUE)
endif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(FREEBSD TRUE)
endif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
endif(NOT CMAKE_BUILD_TYPE)
if (CXX11)
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g"
CACHE STRING
"Flags used by the CXX compiler during RELWITHDEBINFO builds." FORCE)
SET(CMAKE_CXX_FLAGS_RELEASE "-O1 -DNDEBUG"
CACHE STRING
"Flags used by the CXX compiler during RELEASE builds." FORCE)
SET(CMAKE_CXX_FLAGS_DEBUG "-Og -g"
CACHE STRING
"Flags used by the CXX compiler during DEBUG builds." FORCE)
SET(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG"
CACHE STRING
"Flags used by the CXX compiler during MINSIZEREL builds." FORCE)
endif(CXX11)
# 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.
#
# https://cmake.org/cmake/help/git-stage/policy/CMP0093.html
# cmake < 3.15 does not define Boost_VERSION_MACRO but stores the version in
# Boost_VERSION in the format 104700. But cmake > 3.15 stores the version in Boost_VERSION
# in 1.47.0(x.y.z) format which is unsuitable for our comparison. So for cmake > 3.15
# we need to use Boost_VERSION_MACRO instead.
find_package(Boost)
if(Boost_FOUND)
if(Boost_VERSION_MACRO)
set(LOCAL_Boost_VERSION ${Boost_VERSION_MACRO})
else(Boost_VERSION_MACRO)
set(LOCAL_Boost_VERSION ${Boost_VERSION})
endif(Boost_VERSION_MACRO)
# We use BOOST_ASSERT_MSG, which only exists in Boost 1.47 and later.
if(LOCAL_Boost_VERSION LESS 104700)
message(STATUS "Found Boost ${Boost_VERSION_STRING}, but too old for MADlib. Will download a compatible version")
set(Boost_FOUND FALSE)
elseif(CXX11 AND (LOCAL_Boost_VERSION LESS 106500))
message(STATUS "Found Boost ${Boost_VERSION_STRING}, but too old for C++11. Will download a compatible version")
set(Boost_FOUND FALSE)
else()
message(STATUS "Found Boost ${Boost_VERSION_STRING}")
if(106500 LESS LOCAL_Boost_VERSION)
if(NOT CXX11)
message(STATUS "Auto-enabling -DCXX11, because Boost >= v1.65 requires C++11")
set(CXX11 TRUE)
endif(NOT CXX11)
endif(106500 LESS LOCAL_Boost_VERSION)
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
OUTPUT_VARIABLE GNUCC_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
# A useful summary of warning options can be found here:
# http://developer.apple.com/tools/xcode/compilercodewarnings.html
# Note: gcc does not implicitly set _POSIX_C_SOURCE or _XOPEN_SOURCE
# when using -std=c99.
# 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 "-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.
# For CXX11, we've already limited it to -O1 for similar reasons (causes crash)
SET(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG" CACHE STRING
"Flags used by the C compiler during RELEASE builds." FORCE)
endif()
# See comments below for C++:
# Weird enough, the following property is set only for C++ but not for C
# http://stackoverflow.com/questions/3371127/use-isystem-instead-of-i-with-cmake
set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
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
OUTPUT_VARIABLE GNUCXX_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
# This flag is specific for i386 and x86-64 families
# https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/i386-and-x86-64-Options.html
CHECK_CXX_COMPILER_FLAG(-mno-sse2 SSE_DISABLE_OPTIONS_AVAILABLE)
if (SSE_DISABLE_OPTIONS_AVAILABLE)
set(SSE_DISABLE_OPTIONS "-mno-sse2")
endif()
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)
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
# level is -O3 or greater.
SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG" CACHE STRING
"Flags used by the CXX compiler during RELEASE builds." FORCE)
endif()
endif(CXX11)
# We want to include some header files as system header files in order to
# disable warnings. However, on Mac OS X, a CMake variable is not set
# correctly on Mac OS X. http://www.cmake.org/Bug/view.php?id=10837
if(APPLE)
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"
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")
else()
set(M4_ARGUMENTS "--prefix-builtins")
endif()
# -- Local includes ------------------------------------------------------------
list(APPEND CMAKE_MODULE_PATH
"${MAD_BUILD_TOOLS}")
# -- Include all parts ---------------------------------------------------------
include(Utils)
include(LinuxUtils)
include(OSXUtils)
include(Options)
# -- Get madlib version info ----------------------------------------------------
# Read and parse Version.yml file
file(READ "${MADLIB_VERSION_YML}" _MADLIB_VERSION_CONTENTS)
string(REGEX REPLACE "^.*version:[ \t]*([^\n]*)\n.*" "\\1" MADLIB_VERSION_STRING "${_MADLIB_VERSION_CONTENTS}")
string(REPLACE "-" "_" MADLIB_VERSION_STRING_NO_HYPHEN "${MADLIB_VERSION_STRING}")
string(REGEX REPLACE "([0-9]+).*" "\\1" MADLIB_VERSION_MAJOR "${MADLIB_VERSION_STRING}")
string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" MADLIB_VERSION_MINOR "${MADLIB_VERSION_STRING}")
if("${MADLIB_VERSION_STRING}" MATCHES "[0-9]+\\.[0-9]+\\.([0-9]+).*")
string(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" MADLIB_VERSION_PATCH "${MADLIB_VERSION_STRING}")
else()
set(MADLIB_VERSION_PATCH 0)
endif()
# Save build time
execute_process(
COMMAND date -u
OUTPUT_VARIABLE MADLIB_BUILD_TIME
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Save git revision
execute_process(
COMMAND git describe
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE MADLIB_GIT_REVISION
ERROR_QUIET
RESULT_VARIABLE _RESULT
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT _RESULT EQUAL 0)
set(MADLIB_GIT_REVISION "unknown")
endif(NOT _RESULT EQUAL 0)
if(CMAKE_COMPILER_IS_GNUCC)
set(MADLIB_C_COMPILER "gcc ${GNUCC_VERSION}")
else(CMAKE_COMPILER_IS_GNUCC)
set(MADLIB_C_COMPILER ${CMAKE_C_COMPILER_ID})
endif(CMAKE_COMPILER_IS_GNUCC)
if(CMAKE_COMPILER_IS_GNUCXX)
set(MADLIB_CXX_COMPILER "g++ ${GNUCC_VERSION}")
else(CMAKE_COMPILER_IS_GNUCXX)
set(MADLIB_CXX_COMPILER ${CMAKE_CXX_COMPILER_ID})
endif(CMAKE_COMPILER_IS_GNUCXX)
# -- Third-party dependencies: Find m4 -----------------------------------------
# Unfortunately, we currently rely on GNU m4 due to option --prefix-builtins,
# which is not POSIX-standardized.
if(SOLARIS)
# Solaris ships GNU m4 as gm4, so we want to use that
find_program(M4_BINARY gm4
PATHS /usr/sfw/bin
DOC "Path to the GNU m4 preprocessor."
)
else()
find_program(M4_BINARY m4
PATHS /usr/local/bin /usr/bin /bin /opt/local/bin
DOC "Path to the GNU m4 preprocessor."
)
endif()
if(NOT M4_BINARY)
message(FATAL_ERROR "Cannot find the m4 preprocessor.")
endif(NOT M4_BINARY)
# -- Install Read-me files and license directory -------------------------------
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/licenses"
DESTINATION .
COMPONENT core
PATTERN ".DS_Store" EXCLUDE
)
install(
FILES
"${CMAKE_CURRENT_SOURCE_DIR}/README.md"
"${CMAKE_CURRENT_SOURCE_DIR}/RELEASE_NOTES"
DESTINATION doc
COMPONENT core
)
install(
FILES
"${CMAKE_CURRENT_SOURCE_DIR}/NOTICE"
"${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
DESTINATION .
COMPONENT core
)
# -- Add subdirectories --------------------------------------------------------
add_subdirectory(src)
# if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX)
#e.g., Clang/Clang++ does not work
# endif(CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX)
add_subdirectory(doc)
add_subdirectory(deploy)
# -- Install path for specific madlib version ----------------------------------
set(CMAKE_MADLIB_ROOT "${CMAKE_INSTALL_PREFIX}")
set(CMAKE_INSTALL_PREFIX "${CMAKE_MADLIB_ROOT}/Versions/${MADLIB_VERSION_STRING}")
# Move bin to old_bin if upgrading from V0.6 or earlier version
# below script finds a directory named 'bin' and copies to 'old_bin' ignoring
# any error messages (eg. if 'bin' does not exist)
install(CODE "
EXECUTE_PROCESS(
COMMAND find ${CMAKE_MADLIB_ROOT}/bin -type d -exec cp -RPf {} ${CMAKE_MADLIB_ROOT}/old_bin \;
ERROR_FILE /dev/null
)"
)
# remove the 'bin' directory to replace with symbolic link
install(CODE "
EXECUTE_PROCESS(
COMMAND find ${CMAKE_MADLIB_ROOT}/bin -depth -type d -exec rm -r {} \;
ERROR_FILE /dev/null
)"
)
# Move doc to old_doc if upgrading from V0.6 or earlier version
install(CODE "
EXECUTE_PROCESS(
COMMAND find ${CMAKE_MADLIB_ROOT}/doc -type d -exec cp -RPf {} ${CMAKE_MADLIB_ROOT}/old_doc \;
ERROR_FILE /dev/null
)"
)
install(CODE "
EXECUTE_PROCESS(
COMMAND find ${CMAKE_MADLIB_ROOT}/doc -depth -type d -exec rm -r {} \;
ERROR_FILE /dev/null
)"
)
install(CODE "
EXECUTE_PROCESS(COMMAND ln -nsf
${CMAKE_INSTALL_PREFIX}
${CMAKE_MADLIB_ROOT}/Current
)"
)
# Create symlink bin
install(CODE "
EXECUTE_PROCESS(COMMAND ln -nsf
${CMAKE_MADLIB_ROOT}/Current/bin
${CMAKE_MADLIB_ROOT}/bin
)"
)
# Create symlink doc
install(CODE "
EXECUTE_PROCESS(COMMAND ln -nsf
${CMAKE_MADLIB_ROOT}/Current/doc
${CMAKE_MADLIB_ROOT}/doc
)
")