blob: 4a6e496fc411be051d7b942617ba41fa8fc8dc4b [file] [log] [blame]
# Define GNU M4 preprocessor macros
#
# Generate M4 code and M4 command-line arguments to define a set of macros that
# will be available to non-compiled source code (SQL, Python).
#
# It is expected that the caller has defined the following variables:
# PORT_UC
# DBMS
# DBMS_UC
# ${DBMS_UC}_VERSION_MAJOR
# ${DBMS_UC}_VERSION_MINOR
# ${DBMS_UC}_VERSION_PATCH
# ${DBMS_UC}_ARCHITECTURE
function(define_m4_macros OUT_M4_CMD_LINE OUT_M4_CODE)
set(IN_FEATURES ${ARGN})
set(MACROS
"__${PORT_UC}__"
"__PORT__=${PORT_UC}"
"__DBMS__=${DBMS}"
"__DBMS_VERSION__=${${DBMS_UC}_VERSION_STRING}"
"__DBMS_VERSION_MAJOR__=${${DBMS_UC}_VERSION_MAJOR}"
"__DBMS_VERSION_MINOR__=${${DBMS_UC}_VERSION_MINOR}"
"__DBMS_VERSION_PATCH__=${${DBMS_UC}_VERSION_PATCH}"
"__DBMS_ARCHITECTURE__=${${DBMS_UC}_ARCHITECTURE}"
"__MADLIB_VERSION__=${MADLIB_VERSION_STRING}"
"__MADLIB_VERSION_MAJOR__=${MADLIB_VERSION_MAJOR}"
"__MADLIB_VERSION_MINOR__=${MADLIB_VERSION_MINOR}"
"__MADLIB_VERSION_PATCH__=${MADLIB_VERSION_PATCH}"
"__MADLIB_GIT_REVISION__=${MADLIB_GIT_REVISION}"
"__MADLIB_BUILD_TIME__=${MADLIB_BUILD_TIME}"
"__MADLIB_BUILD_TYPE__=${CMAKE_BUILD_TYPE}"
"__MADLIB_BUILD_SYSTEM__=${CMAKE_SYSTEM}"
"__MADLIB_C_COMPILER__=${MADLIB_C_COMPILER}"
"__MADLIB_CXX_COMPILER__=${MADLIB_CXX_COMPILER}"
${IN_FEATURES}
)
list_replace("^(.+)$" "-D\\\\1" ${OUT_M4_CMD_LINE} ${MACROS})
list_replace("^([^=]+)$" "m4_define(`\\\\1')" ${OUT_M4_CODE} ${MACROS})
list_replace("^([^=]+)=(.+)$" "m4_define(`\\\\1', `\\\\2')" ${OUT_M4_CODE}
${${OUT_M4_CODE}})
string(REGEX REPLACE ";" "\\n" ${OUT_M4_CODE} "${${OUT_M4_CODE}}")
# Pass values to caller
set(${OUT_M4_CMD_LINE} "${${OUT_M4_CMD_LINE}}" PARENT_SCOPE)
set(${OUT_M4_CODE} "${${OUT_M4_CODE}}" PARENT_SCOPE)
endfunction(define_m4_macros)
macro(join_strings OUT_STRING SEPARATOR LIST)
foreach(ITEM ${LIST})
if("${${OUT_STRING}}" STREQUAL "")
set(${OUT_STRING} "${ITEM}")
else("${${OUT_STRING}}" STREQUAL "")
set(${OUT_STRING} "${${OUT_STRING}}${SEPARATOR}${ITEM}")
endif("${${OUT_STRING}}" STREQUAL "")
endforeach(ITEM ${LIST})
endmacro(join_strings)
macro(get_dir_name OUT_DIR IN_PATH)
if(${IN_PATH} MATCHES "^.+/[^/]*\$")
# If the argument for string(REGEX REPLACE does not match the
# search string, CMake sets the output to the input string
# This is not what we want, hence the if-block.
string(REGEX REPLACE "^(.+)/[^/]*\$" "\\1" ${OUT_DIR} "${IN_PATH}")
else(${IN_PATH} MATCHES "^.+/[^/]*\$")
set(${OUT_DIR} "")
endif(${IN_PATH} MATCHES "^.+/[^/]*\$")
endmacro(get_dir_name)
macro(architecture OUT_ARCHITECTURE)
execute_process(
COMMAND uname -m
OUTPUT_VARIABLE ${OUT_ARCHITECTURE}
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endmacro(architecture)
macro(word_length OUT_WORD_LENGTH)
architecture(_ARCHITECTURE)
if(${_ARCHITECTURE} MATCHES "ppc$|ppcle|i[3456]86")
set(${OUT_WORD_LENGTH} 32)
elseif(${_ARCHITECTURE} MATCHES "ppc64|ppc64le|x86_64")
set(${OUT_WORD_LENGTH} 64)
else()
message(FATAL_ERROR "Unable to determine word length for unknown architecture '${_ARCHITECTURE}'")
endif()
endmacro(word_length)
# Given the length of the parameter list, we require named arguments.
# IN_COMMAND can contain "\${CURRENT_PATH}" and "\${OUTFILE}"
# IN_COMMENT can contain "\${CURRENT_FILE}" which will be substituted by the
# current file
macro(batch_add_command
ARG_NAME_1 IN_TARGET_PREFIX
ARG_NAME_2 IN_SOURCE_PREFIX
ARG_NAME_3 IN_TARGET_SUFFIX
ARG_NAME_4 IN_SOURCE_SUFFIX
ARG_NAME_5 IN_COMMAND
ARG_NAME_6 IN_COMMENT
ARG_NAME_7 OUT_TARGET_FILES
ARG_NAME_8)
if( (NOT ("${ARG_NAME_1}" STREQUAL TARGET_PREFIX)) OR
(NOT ("${ARG_NAME_2}" STREQUAL SOURCE_PREFIX)) OR
(NOT ("${ARG_NAME_3}" STREQUAL TARGET_SUFFIX)) OR
(NOT ("${ARG_NAME_4}" STREQUAL SOURCE_SUFFIX)) OR
(NOT ("${ARG_NAME_5}" STREQUAL RUN)) OR
(NOT ("${ARG_NAME_6}" STREQUAL COMMENT)) OR
(NOT ("${ARG_NAME_7}" STREQUAL TARGET_FILE_LIST_REF)) OR
(NOT ("${ARG_NAME_8}" STREQUAL SOURCE_FILE_LIST)) )
message(FATAL_ERROR "Missing (or misspelled) arguments given to batch_add_command().")
endif()
set(IN_SOURCE_FILE_LIST ${ARGN})
foreach(CURRENT_FILE ${IN_SOURCE_FILE_LIST})
get_filename_component(CURRENT_PATH "${IN_SOURCE_PREFIX}${CURRENT_FILE}" ABSOLUTE)
set(OUTFILE "${IN_TARGET_PREFIX}${CURRENT_FILE}")
if(NOT ("${IN_SOURCE_SUFFIX}" STREQUAL ""))
string(REGEX REPLACE "${IN_SOURCE_SUFFIX}\$" "${IN_TARGET_SUFFIX}"
OUTFILE "${OUTFILE}")
endif(NOT ("${IN_SOURCE_SUFFIX}" STREQUAL ""))
get_dir_name(OUTDIR ${OUTFILE})
string(REPLACE "\${CURRENT_PATH}" "${CURRENT_FILE}" IN_COMMAND "${IN_COMMAND}")
string(REPLACE "\${OUTFILE}" "${OUTFILE}" IN_COMMAND "${IN_COMMAND}")
string(REPLACE "\${OUTDIR}" "${OUTDIR}" IN_COMMAND "${IN_COMMAND}")
string(REPLACE "\${CURRENT_FILE}" "${CURRENT_FILE}" IN_COMMENT "${IN_COMMENT}")
add_custom_command(OUTPUT "${OUTFILE}"
${IN_COMMAND}
DEPENDS "${CURRENT_PATH}"
COMMENT "${IN_COMMENT}")
list(APPEND ${OUT_TARGET_FILES}
${OUTFILE})
endforeach(CURRENT_FILE)
endmacro(batch_add_command)
macro(add_files OUT_TARGET_FILES IN_SOURCE_DIR IN_TARGET_DIR)
set(IN_SOURCE_FILE_LIST ${ARGN})
get_filename_component(SOURCE_DIR_ABS "${IN_SOURCE_DIR}" ABSOLUTE)
get_filename_component(TARGET_DIR_ABS "${IN_TARGET_DIR}" ABSOLUTE)
set(MADLIB_COPY_COMMAND
COMMAND "${CMAKE_COMMAND}" -E copy "\"\${CURRENT_PATH}\"" "\"\${OUTFILE}\""
)
batch_add_command(
TARGET_PREFIX "${TARGET_DIR_ABS}/"
SOURCE_PREFIX "${SOURCE_DIR_ABS}/"
TARGET_SUFFIX ""
SOURCE_SUFFIX ""
RUN "${MADLIB_COPY_COMMAND}"
COMMENT "Copying \${CURRENT_FILE}."
TARGET_FILE_LIST_REF ${OUT_TARGET_FILES}
SOURCE_FILE_LIST ${IN_SOURCE_FILE_LIST}
)
endmacro(add_files)
macro(get_subdirectories IN_DIRECTORY OUT_SUBDIRS)
unset(${OUT_SUBDIRS})
file(GLOB ENTRIES "${IN_DIRECTORY}/*")
foreach(ITEM ${ENTRIES})
if(IS_DIRECTORY "${ITEM}")
get_filename_component(ITEM "${ITEM}" NAME)
list(APPEND ${OUT_SUBDIRS} "${ITEM}")
endif(IS_DIRECTORY "${ITEM}")
endforeach(ITEM)
endmacro(get_subdirectories)
macro(get_min_version OUT_VERSION)
set(IN_VERSION_LIST ${ARGN})
list(GET IN_VERSION_LIST 0 ${OUT_VERSION})
foreach(_VERSION ${IN_VERSION_LIST})
if("${_VERSION}" VERSION_LESS "${${OUT_VERSION}}")
set(${OUT_VERSION} "${_VERSION}")
endif()
endforeach(_VERSION)
endmacro(get_min_version)
macro(get_max_version OUT_VERSION)
set(IN_VERSION_LIST ${ARGN})
list(GET IN_VERSION_LIST 0 ${OUT_VERSION})
foreach(_VERSION ${IN_VERSION_LIST})
if("${_VERSION}" VERSION_GREATER "${${OUT_VERSION}}")
set(${OUT_VERSION} "${_VERSION}")
endif()
endforeach(_VERSION)
endmacro(get_max_version)
macro(get_filtered_list OUT_LIST IN_REGEX)
set(IN_LIST ${ARGN})
set(${OUT_LIST} "")
foreach(ITEM ${IN_LIST})
if("${ITEM}" MATCHES "${IN_REGEX}")
list(APPEND ${OUT_LIST} "${ITEM}")
endif("${ITEM}" MATCHES "${IN_REGEX}")
endforeach(ITEM)
endmacro(get_filtered_list)
macro(list_replace IN_REGEX IN_REPLACE_STRING OUT_LIST)
set(IN_LIST ${ARGN})
set(${OUT_LIST})
foreach(ITEM ${IN_LIST})
string(REGEX REPLACE "${IN_REGEX}" "${IN_REPLACE_STRING}" ITEM_REPLACED "${ITEM}")
list(APPEND ${OUT_LIST} "${ITEM_REPLACED}")
endforeach(ITEM)
endmacro(list_replace)