# 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)