| # 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 FILENAME OUT_ARCHITECTURE) |
| if (APPLE) |
| # On Mac OS X, "lipo" is a more reliable way of finding out the |
| # architecture of an executable |
| osx_archs("${FILENAME}" _ARCHITECTURE) |
| else(APPLE) |
| execute_process( |
| COMMAND file "${FILENAME}" |
| OUTPUT_VARIABLE _FILE_OUTPUT |
| OUTPUT_STRIP_TRAILING_WHITESPACE) |
| |
| # Filter out known architectures |
| string(REGEX MATCHALL "x86[-_]64|i386|ppc|ppc64" _ARCHITECTURE "${_FILE_OUTPUT}") |
| |
| # Normalize (e.g., some vendors use x86-64 instead of x86_64) |
| string(REGEX REPLACE "x86[-_]64" "x86_64" _ARCHITECTURE "${_ARCHITECTURE}") |
| endif(APPLE) |
| |
| list(REMOVE_DUPLICATES _ARCHITECTURE) |
| list(LENGTH _ARCHITECTURE _ARCHITECTURE_LENGTH) |
| if(_ARCHITECTURE_LENGTH GREATER 1) |
| join_strings(_ARCHITECTURES_STRING ", " "${_ARCHITECTURE}") |
| message(FATAL_ERROR "Unique word length requested, but " |
| "${FILENAME} is fat binary (${_ARCHITECTURES_STRING}).") |
| endif(_ARCHITECTURE_LENGTH GREATER 1) |
| set(${OUT_ARCHITECTURE} ${_ARCHITECTURE}) |
| endmacro(architecture) |
| |
| macro(word_length FILENAME OUT_WORD_LENGTH) |
| architecture(${FILENAME} _ARCHITECTURE) |
| string(REPLACE "ppc" 32 _${OUT_WORD_LENGTH} "${_ARCHITECTURE}") |
| string(REPLACE "ppc64" 64 ${OUT_WORD_LENGTH} "${_ARCHITECTURE}") |
| string(REPLACE "i386" 32 ${OUT_WORD_LENGTH} "${_ARCHITECTURE}") |
| string(REPLACE "x86_64" 64 ${OUT_WORD_LENGTH} "${_ARCHITECTURE}") |
| 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) |